/* ============================================
   pages.css — Page-specific styles
   Naming: .page-{name}-{section}
   ============================================ */

/* ============================================
   Shared hero pattern
   ============================================ */
.page-hero {
  position: relative;
  background: var(--bg-authority);
  color: var(--text-on-authority);
  overflow: hidden;
}

.page-hero--short {
  padding-block: var(--space-16);
}

@media (min-width: 1024px) {
  .page-hero--short { padding-block: var(--space-20); }
}

.page-hero__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    135deg,
    rgba(77, 0, 39, 0.82) 0%,
    rgba(77, 0, 39, 0.68) 60%,
    rgba(77, 0, 39, 0.55) 100%
  );
  z-index: 1;
}

.page-hero__content {
  position: relative;
  z-index: 2;
  padding-inline: var(--space-5);
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
}

@media (min-width: 768px) {
  .page-hero__content { padding-inline: var(--space-8); }
}

.page-hero__eyebrow {
  color: var(--tan-200);
  margin-bottom: var(--space-4);
  display: block;
}

.page-hero__title {
  color: var(--text-on-authority);
  max-width: 800px;
}

.page-hero__body {
  color: var(--text-on-authority);
  opacity: 0.85;
  max-width: 560px;
  font-size: var(--type-body-lg);
  line-height: 1.7;
  margin-top: var(--space-5);
}

/* ============================================
   Home — About teaser (v7.2 — no image, centered scroll-reveal headline + 2-col body)
   ============================================ */
.home-about {
  padding-top: 314px;   /* 214px slider half + 100px breathing room before About content */
  padding-bottom: var(--space-20);
  position: relative;
  z-index: 1;           /* explicit lower stacking than .home-hero (z:2) so the torch SVG can't paint into the hero band */
  overflow: hidden;   /* clip the oversized torch icon at the section edges */
}

.home-about__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-5);
  position: relative;   /* anchor for absolute-positioned bg icon */
}

/* NBA torch icon as outlined background texture
   v2 — anchored to the section (full viewport width), oversized so it bleeds
   off the top and bottom edges, pushed to the right side of the screen so it
   dominates the open space outside the text columns. */
.home-about__bg-icon {
  position: absolute;
  top: 50%;
  left: 0;                                     /* pulled inward — entire torch visible, left edge of icon meets left edge of screen */
  /* Vertical centering preserved (with -50%+90px offset); JS may add
     horizontal translate for scroll parallax. */
  transform: translate(0, calc(-50% + 90px));
  height: 140%;
  width: auto;
  fill: var(--wine-850);             /* solid fill, one step darker than wine-800 page bg */
  stroke: var(--wine-850);            /* same as fill — trace shows during draw-on, then dissolves into fill */
  stroke-width: 0.4;                  /* SVG viewBox is small (~82×92) so stroke-width is small */
  opacity: 1;
  pointer-events: none;
  z-index: 0;
}

/* Initial state: outline visible (stroked), fill invisible.
   Each path's stroke is hidden (dashoffset=1, dasharray=1 with pathLength=1).
   On reveal, paths trace on, then fill fades in. */
.home-about__bg-icon path {
  fill-opacity: 0;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

.home-about__bg-icon.is-revealed path {
  animation:
    torch-trace 3200ms cubic-bezier(0.65, 0, 0.35, 1) forwards,
    torch-fill 2800ms cubic-bezier(0.22, 1, 0.36, 1) 2600ms forwards;
}

/* Top-down trace order. Each path is at a different y position in the
   SVG (viewBox 0 0 81.87 91.67); we stagger so the topmost paths draw
   first, working down through the torch. The DOM order is fixed; we
   just reorder which nth-of-type gets which delay step.

   Path → starting y:
     3 → y ≈ 0.67   (flame at top)
     5 → y ≈ 26.67
     8 → y ≈ 32.66
     4 → y ≈ 34.66
     6 → y ≈ 65.8
     7 → y ≈ 69.67
     1 → y ≈ 91.67  (base of torch)
     2 → y ≈ 91.67  (base of torch)
*/
.home-about__bg-icon.is-revealed path:nth-of-type(3) { animation-delay: 0ms,    2600ms; }
.home-about__bg-icon.is-revealed path:nth-of-type(5) { animation-delay: 400ms,  3000ms; }
.home-about__bg-icon.is-revealed path:nth-of-type(8) { animation-delay: 800ms,  3400ms; }
.home-about__bg-icon.is-revealed path:nth-of-type(4) { animation-delay: 1200ms, 3800ms; }
.home-about__bg-icon.is-revealed path:nth-of-type(6) { animation-delay: 1600ms, 4200ms; }
.home-about__bg-icon.is-revealed path:nth-of-type(7) { animation-delay: 2000ms, 4600ms; }
.home-about__bg-icon.is-revealed path:nth-of-type(1) { animation-delay: 2200ms, 4800ms; }
.home-about__bg-icon.is-revealed path:nth-of-type(2) { animation-delay: 2400ms, 5000ms; }

@keyframes torch-trace {
  from { stroke-dashoffset: 1; }
  to   { stroke-dashoffset: 0; }
}

@keyframes torch-fill {
  from { fill-opacity: 0; }
  to   { fill-opacity: 1; }
}

/* Lift content above the bg icon */
.home-about__header,
.home-about__body {
  position: relative;
  z-index: 1;
}

@media (max-width: 1024px) {
  .home-about__bg-icon {
    height: 140%;
    left: -10%;
    opacity: 1;
  }
}

@media (max-width: 768px) {
  .home-about__bg-icon {
    height: 110%;
    left: -30%;
    opacity: 1;
  }
}

@media (min-width: 768px) {
  .home-about__inner { padding-inline: var(--space-8); }
}

.home-about__header {
  text-align: center;
  max-width: 1200px;       /* widened so headline lands on 3 lines */
  margin: 0 auto var(--space-16);
}

/* Override eyebrow inside this header — larger, with more tracking */
.home-about__header .eyebrow {
  font-size: 24px;
  letter-spacing: 0.28em;
  font-weight: 700;
  margin-bottom: var(--space-5);
  display: inline-block;
}

.home-about__headline {
  font-size: clamp(30px, 3.6vw, 46px);   /* slightly tuned so it wraps to 3 lines at desktop widths */
  line-height: 1.2;
  margin: 0;
  font-weight: 600;
  text-wrap: pretty;                      /* orphan-only — natural wrap, no aggressive balancing */
}

.home-about__body {
  display: grid;
  gap: var(--space-10);
  max-width: 1200px;
  margin-inline: auto;
}

@media (min-width: 1024px) {
  /* Narrower right column so the quote wraps more and the aside column height
     better matches the body paragraph column for visual balance */
  .home-about__body { grid-template-columns: 1.35fr 1fr; gap: var(--space-16); align-items: start; }
}

.home-about__copy p {
  font-size: 19px;        /* pumped up another step for editorial feel */
  line-height: 1.75;
  margin-bottom: var(--space-5);
}
.home-about__copy p:last-child { margin-bottom: 0; }

.home-about__aside {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.home-about__aside .pull-quote {
  margin: 0;
}

/* Bump the quote so its column height roughly matches the body column */
.home-about__aside .pull-quote__text {
  font-size: clamp(22px, 2vw, 28px);
  line-height: 1.4;
}

.home-about__aside .button,
.home-about__aside .btn-primary {
  align-self: flex-start;
}

/* ============================================
   Home — Region IX at a Glance (map + stats)
   v8 — first LIGHT section. Warm cream bg, dark wine headline,
   crimson eyebrow, bright red stat numbers, dark muted labels.
   ============================================ */
.home-glance {
  background: var(--tan-50);
  color: var(--grey-900);
  padding-block: var(--space-20);
}

.home-glance__inner {
  max-width: 1440px;          /* expanded so left column has room for logo marquee */
  margin-inline: auto;
  padding-inline: var(--space-5);
}

@media (min-width: 768px) {
  .home-glance__inner { padding-inline: var(--space-8); }
}

/* TOP ROW — 2-column: heading + 2x2 stats + affiliate marquee LEFT, map RIGHT */
.home-glance__top {
  display: grid;
  gap: var(--space-12);
  align-items: stretch;
  margin-bottom: 0;            /* no bottom margin — affiliate marquee lives in left col now */
}

@media (min-width: 900px) {
  /* Left col gets more room (1.25fr) so the marquee can fit 2-3 logos at a time */
  .home-glance__top { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: var(--space-16); }
}

.home-glance__main {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: var(--space-10);
}

.home-glance__header {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;              /* very tight — Region IX and at a Glance read as a stack */
}

/* "Region IX" wordmark — all serif, both words equal weight/size */
.home-glance__mark {
  display: inline-block;
  color: var(--crimson-500);
  font-family: var(--font-serif);
  font-size: clamp(18px, 1.6vw, 22px);
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.02em;
}

/* "at a Glance" — sits just above the stat number size */
.home-glance__title {
  color: var(--wine-800);
  font-family: var(--font-serif);
  font-size: clamp(38px, 4vw, 56px);
  line-height: 1;
  font-weight: 700;
  margin: 0;
  letter-spacing: -0.01em;
}

/* 2x2 stat grid */
.stat-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-6);
  align-items: stretch;
}

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

.stat-cell {
  padding: var(--space-6) 0;
  border-top: 1px solid rgba(50, 0, 25, 0.15);
}

.stat-cell__num {
  font-family: var(--font-serif);
  font-size: clamp(36px, 3.6vw, 52px);   /* reduced ~12px so the title reads as the lead element */
  font-weight: 600;
  color: var(--crimson-500);
  line-height: 1;
  margin-bottom: var(--space-2);
  letter-spacing: -0.01em;
}

.stat-cell__label {
  font-size: var(--type-body-sm);
  color: var(--grey-700);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  line-height: 1.4;
  font-weight: 600;
}

/* MAP COLUMN — map sits in its own column, vertically centered */
.home-glance__map-col {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* AFFILIATES section — now lives inside the left column under the stats */
.home-glance__affiliates {
  padding-top: var(--space-6);
  border-top: 1px solid rgba(50, 0, 25, 0.15);
}

.home-glance__affiliates-header {
  text-align: left;
  margin: 0 0 var(--space-3);  /* tighter — was space-6 */
}

.home-glance__affiliates-header .eyebrow {
  color: var(--crimson-500);
  font-size: 14px;
  letter-spacing: 0.22em;
  font-weight: 700;
  display: inline-block;
  margin-bottom: var(--space-2);
}

.home-glance__affiliates-title {
  color: var(--wine-800);
  font-family: var(--font-serif);
  font-size: clamp(20px, 2vw, 26px);
  line-height: 1.2;
  font-weight: 700;
  margin: 0;
}

/* Marquee container itself — trim its own padding so it hugs the header */
.home-glance__affiliates .marquee--logos {
  padding-block: var(--space-2);
}
.home-glance__affiliates .marquee--logos .marquee__track {
  padding-block: var(--space-3);
}

/* View-all link — left-justified, hugs the marquee */
.home-glance__affiliates-link {
  margin: var(--space-2) 0 0;
  text-align: left;
}
.home-glance__affiliates-link a {
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--crimson-700);
  text-decoration: none;
  border-bottom: 1px solid rgba(110, 15, 31, 0.3);
  padding-bottom: 2px;
  transition: color 400ms var(--ease-in-out), border-color 400ms var(--ease-in-out);
}
.home-glance__affiliates-link a:hover {
  color: var(--crimson-500);
  border-color: var(--crimson-500);
}
.home-glance__affiliates-link a span {
  margin-left: 6px;
  display: inline-block;
  transition: transform 400ms var(--ease-in-out);
}
.home-glance__affiliates-link a:hover span {
  transform: translateX(4px);
}

/* ============================================
   Region IX Map (v2 — real geographic SVG, no per-state labels)
   Each state wrapped in a <g> with main fill paths + white detail paths.
   Crimson gradient fill, hover scale + glow + neighbor dim, ambient pulse cycle.
   ============================================ */
.region-map {
  width: 100%;
  max-width: 640px;
  margin-inline: auto;
}
.region-map__svg {
  width: 100%;
  height: auto;
  overflow: visible;
  display: block;
}

/* Main state shape — crimson gradient, hidden until reveal.
   All transitions on ease-in-out at longer durations for that silky feel. */
.region-map__state-fill {
  fill: url(#region-state-grad);
  opacity: 0;
  transition:
    opacity 700ms var(--ease-in-out),
    fill 700ms var(--ease-in-out),
    filter 700ms var(--ease-in-out);
}

/* Detail paths inside each state — subtle warm highlight */
.region-map__state-detail {
  fill: rgba(255, 245, 230, 0.18);
  opacity: 0;
  pointer-events: none;
  transition: opacity 700ms var(--ease-in-out), fill 700ms var(--ease-in-out);
}

/* The whole state group as the hover/scale unit.
   No cursor:pointer — the states have no click target, only a hover
   effect. Pointer cursor would mislead users into expecting an action. */
.region-map__state {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 700ms var(--ease-in-out), filter 700ms var(--ease-in-out);
}

/* Entrance — staggered fade per state, slowed down for a smoother arrival */
.region-map.is-revealed .region-map__state-fill {
  opacity: 1;
  transition-delay: calc(var(--i, 0) * 160ms);
}
.region-map.is-revealed .region-map__state-detail {
  opacity: 1;
  transition-delay: calc(var(--i, 0) * 160ms + 350ms);
}

/* Initial reveal pulse — silky fade in & out through a darker shade */
.region-map__state.is-initial-pulse .region-map__state-fill {
  animation: region-map-pulse-fill 2800ms var(--ease-in-out);
}

/* Ambient slow pulse cycle — same silky deep-fade, even slower */
.region-map__state.is-pulsing .region-map__state-fill {
  animation: region-map-pulse-fill 3200ms var(--ease-in-out);
}

/* Symmetric keyframes — fade in to deep, fade back to base. No hard transitions. */
@keyframes region-map-pulse-fill {
  0%   { fill: url(#region-state-grad); }
  50%  { fill: url(#region-state-grad-deep); }
  100% { fill: url(#region-state-grad); }
}

/* HOVER (simplified):
   - Hovered state ONLY elevates (scale + soft glow). No fill change.
   - All other states fade to the DEEP gradient. No opacity overlay, just fill swap.
   - All transitions silky ease-in-out (handled by base .region-map__state-fill rule).
   - JS reorders hovered state to end of parent so SVG paint order puts it on top. */
.region-map__state:hover {
  transform: scale(1.06);
  filter: drop-shadow(0 4px 22px rgba(50, 0, 25, 0.4));
}
/* Non-hovered states fade to deep gradient. Fill transition is on the base rule. */
.region-map:has(.region-map__state:hover) .region-map__state:not(:hover) .region-map__state-fill {
  fill: url(#region-state-grad-deep);
}

/* Caption underneath the map — pill with gradient bg, white text, red accents */
.region-map__caption {
  margin: var(--space-5) 0 0;
  text-align: center;
  opacity: 0;
  transition: opacity 700ms var(--ease-in-out) 1600ms;
}
.region-map__caption-pill {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 7px 28px 7px 22px;
  background: var(--crimson-600);          /* solid red, no gradient (was crimson→wine) */
  border-radius: 100px;
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #FFFFFF;
  box-shadow: 0 4px 16px rgba(50, 0, 25, 0.18);
  overflow: hidden;
}
/* Left-edge "peel" — small darker accent peeling in from the left.
   Keeps the pill flat-red but still has a subtle visual hook. */
.region-map__caption-pill::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 22%;
  background: linear-gradient(90deg, var(--crimson-800) 0%, transparent 100%);
  pointer-events: none;
}
.region-map__caption-accent {
  color: var(--crimson-400);
  margin: 0 6px;
  font-weight: 800;
}
/* The leading "+" gets a bigger size to really pop as a "plus" */
.region-map__caption-pill .region-map__caption-accent:first-child {
  font-size: 28px;
  line-height: 0;
  margin-right: 10px;
  margin-left: 0;
  transform: translateY(-1px);
}
.region-map.is-revealed .region-map__caption { opacity: 1; }

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .region-map__state-fill,
  .region-map__state-detail,
  .region-map__caption { opacity: 1 !important; transition: none !important; }
  .region-map__state,
  .region-map__state-fill { animation: none !important; transform: none !important; }
}

.home-glance__stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

@media (min-width: 1024px) {
  .home-glance__stats { grid-template-columns: 1fr 1fr; }
}

/* ============================================
   Home — Recent News preview
   Two color variants for comparison: light (warm tan) and dark (deeper wine take)
   ============================================ */
.home-news {
  padding-block: var(--space-20);
}

.home-news__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

@media (min-width: 768px) {
  .home-news__inner { padding-inline: var(--space-8); }
}

.home-news__header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-10);
}

.home-news__title {
  font-family: var(--font-serif);
  font-size: clamp(36px, 4vw, 56px);
  line-height: 1.05;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0;
}

/* 3-column grid; each column stacks its own posts */
.home-news__grid {
  display: grid;
  gap: var(--space-6);
  align-items: start;
}
@media (min-width: 640px) {
  .home-news__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .home-news__grid { grid-template-columns: repeat(3, 1fr); }
}

.home-news__col {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

/* ============================================================
   News & Highlights — crimson background, white cards
   ============================================================ */

/* Solid crimson-800 background (SVG curves removed — placeholder for future bg image) */
.home-news--crimson-linear {
  background: var(--crimson-800);
  color: var(--text-primary);
  position: relative;
}

/* Heading — one step lighter (tan-50) so it sits even brighter against the deep red */
.home-news--crimson-linear .home-news__title {
  color: var(--tan-50);
}

/* Card BASE — common rules. Asymmetric hover timing (1100ms OUT defined
   here on the base, 450ms IN defined on the :hover state below) matches
   the news.html + post-related cards so all news cards across the site
   share the same silky motion language. */
.home-news--crimson-linear .news-card {
  border-radius: var(--radius-lg);
  position: relative;
  overflow: hidden;
  transition: transform 1100ms cubic-bezier(0.4, 0, 0.2, 1),
              border-color 1100ms cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}
.home-news--crimson-linear .news-card:hover {
  transform: translateY(-5px);
  /* IN timing — quick + smooth */
  transition: transform 450ms cubic-bezier(0.4, 0, 0.2, 1),
              border-color 450ms cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 450ms cubic-bezier(0.4, 0, 0.2, 1);
}

.home-news--crimson-linear .news-card__title {
  color: #FFFFFF;
  font-weight: 600;
}
.home-news--crimson-linear .news-card__excerpt {
  color: rgba(255, 255, 255, 0.74);
}

.home-news--crimson-linear .news-card__body {
  /* +5px horizontal so card text + chips sit further off the edge. */
  padding: var(--space-5) calc(var(--space-5) + 5px);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Tighter category pills — tight vertical padding + line-height clamp.
   v24 per Diallo: every category needs a visible dark-on-light combo
   on the white card. Backgrounds are tinted theme colors; text is the
   matching dark tone so contrast lands. */
.home-news--crimson-linear .news-card__category {
  display: inline-block;
  padding: 1px 10px;
  border-radius: 100px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.6;
  margin-bottom: var(--space-2);
  align-self: flex-start;
}

/* Card — white with a tan gradient sweep at the bottom. Hover deepens
   the tan via a pseudo-element overlay (CSS can't tween between two
   gradient values on the same element, so we fade in an overlay layer
   on hover for a true cross-fade). */
.home-news--crimson-linear .news-card {
  background: linear-gradient(180deg, #FFFFFF 0%, #FFFFFF 55%, var(--tan-100) 100%);
  border: 1px solid rgba(255, 255, 255, 0.16);
  box-shadow: 0 6px 24px rgba(15, 5, 12, 0.25);
}
.home-news--crimson-linear .news-card::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, #FFFFFF 0%, #FFFFFF 50%, var(--tan-200) 100%);
  border-radius: inherit;
  opacity: 0;
  pointer-events: none;
  z-index: 0;
  transition: opacity 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}
.home-news--crimson-linear .news-card > * { position: relative; z-index: 1; }
.home-news--crimson-linear .news-card:hover {
  box-shadow: 0 16px 44px rgba(15, 5, 12, 0.35);
}
.home-news--crimson-linear .news-card:hover::before {
  opacity: 1;
  transition: opacity 450ms cubic-bezier(0.4, 0, 0.2, 1);
}
.home-news--crimson-linear .news-card__title    { color: var(--wine-800); font-weight: 500; }
.home-news--crimson-linear .news-card__excerpt  { color: var(--grey-700); }

/* Pills retuned for the white card. v24 — every category now has a
   light tinted background with a matching dark text color so the pill
   reads cleanly on the white card. Every category that appears in
   news-data.js NEWS_CATEGORIES has explicit styling. */
.home-news--crimson-linear .news-card__category--awards            { background: rgba(212, 150, 88, 0.22); color: #8A5A1F; }
.home-news--crimson-linear .news-card__category--scholarship       { background: rgba(212, 150, 88, 0.22); color: #8A5A1F; }
.home-news--crimson-linear .news-card__category--leadership        { background: rgba(208, 76, 74, 0.18); color: var(--crimson-700); }
.home-news--crimson-linear .news-card__category--judicial-pipeline { background: rgba(50, 0, 25, 0.10); color: var(--wine-800); }
.home-news--crimson-linear .news-card__category--programs          { background: rgba(50, 0, 25, 0.10); color: var(--wine-800); }
.home-news--crimson-linear .news-card__category--civil-rights      { background: rgba(208, 76, 74, 0.18); color: var(--crimson-700); }
.home-news--crimson-linear .news-card__category--affiliates        { background: rgba(212, 150, 88, 0.22); color: #8A5A1F; }
.home-news--crimson-linear .news-card__category--video             { background: transparent; color: var(--crimson-700); border: 1.5px solid var(--crimson-700); padding: 2.5px 10.5px; }

/* Read more — crimson on white card. Color transitions adopt the same
   asymmetric pattern (1100ms OUT, 450ms IN on hover) so the read-more
   shifts in lockstep with the card's tan deepening. Arrow + underline
   transforms keep their snappy short durations. */
.home-news--crimson-linear .news-card__read-more {
  color: var(--crimson-500);
  transition: color 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}
.home-news--crimson-linear .news-card__read-more-arrow {
  color: var(--tan-400);
  transition: transform 320ms var(--ease-in-out), color 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}
.home-news--crimson-linear .news-card__read-more::after {
  background: var(--crimson-500);
  transition: transform 360ms var(--ease-in-out), background 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}
.home-news--crimson-linear .news-card:hover .news-card__read-more {
  color: var(--crimson-700);
  transition: color 450ms cubic-bezier(0.4, 0, 0.2, 1);
}
.home-news--crimson-linear .news-card:hover .news-card__read-more-arrow {
  color: var(--crimson-500);
  transition: transform 320ms var(--ease-in-out), color 450ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Centered bottom button — full text "View All News & Highlights" */
.home-news__footer {
  margin-top: var(--space-12);
  display: flex;
  justify-content: center;
}

/* In the news section, the white button gets the crimson-on-light treatment:
   crimson-400 at rest, white circle, red arrow → expands to white with red text on hover. */
.home-news .btn-primary--white {
  background: var(--crimson-400);
  border-color: var(--crimson-400);
  color: #FFFFFF;
}
.home-news .btn-primary--white::before {
  background: #FFFFFF;
}
.home-news .btn-primary--white:hover {
  color: var(--crimson-500);
  border-color: #FFFFFF;
}
.home-news .btn-primary--white:hover::before {
  background: #FFFFFF;
}
.home-news .btn-primary--white .btn-primary__ic { color: var(--crimson-500); }
.home-news .btn-primary--white:hover .btn-primary__ic { color: var(--crimson-500); }

/* Read more link — small text, light color, animated arrow + underline draw */
.news-card__read-more {
  margin-top: var(--space-3);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--tan-200);   /* warm light against dark crimson */
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: color 320ms var(--ease-in-out);
  align-self: flex-start;
  position: relative;
  padding-bottom: 3px;
}
.news-card__read-more::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1.5px;
  background: var(--crimson-400);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 360ms var(--ease-in-out);
}
.news-card__read-more-arrow {
  color: var(--crimson-400);
  display: inline-block;
  font-size: 16px;
  line-height: 1;
  transition: transform 320ms var(--ease-in-out), color 320ms var(--ease-in-out);
}
.news-card:hover .news-card__read-more { color: #FFFFFF; }
.news-card:hover .news-card__read-more::after { transform: scaleX(1); }
.news-card:hover .news-card__read-more-arrow {
  transform: translateX(6px);
  color: #FFFFFF;
}

/* ============================================
   Home — Photo Mosaic v4 (two-row interlocking grid, continuous auto-scroll)
   Tall portraits and stacked landscapes interleave to read like a magazine
   layout. Pauses on hover. Hover-zoom per cell. No captions, no lightbox.
   Source: /assets/images/mosaic/ (32 photos).
   ============================================ */
.photo-mosaic {
  background: var(--wine-850);
  padding-block: 44px 38px;                          /* top: 64→44 (-20), bottom: 48→38 (-10) */
  overflow: hidden;
  position: relative;
}

/* Nav arrows live in a centered bar below the photo grid (was: floating
   absolute on the sides over the photos). Flex centers the two buttons
   with a small gap between them. */
.mosaic-nav-bar {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 12px;
  padding-top: 28px;
}

.mosaic-nav {
  width: 40px;                  /* 25% smaller than the previous 52px */
  height: 40px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: #FFFFFF;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 5;
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  transition: transform 320ms var(--ease-in-out),
              background 320ms var(--ease-in-out),
              border-color 320ms var(--ease-in-out);
}
.mosaic-nav svg {
  width: 15px;                  /* icon scaled to match the smaller button */
  height: 15px;
}
.mosaic-nav:hover {
  transform: scale(1.12);
  background: var(--crimson-500);
  border-color: var(--crimson-500);
}
.mosaic-nav:active {
  background: var(--crimson-400);
  border-color: var(--crimson-400);
}

/* Viewport clips the track and feathers the edges so the scroll feels endless */
.photo-mosaic__viewport {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, black 4%, black 96%, transparent);
          mask-image: linear-gradient(to right, transparent, black 4%, black 96%, transparent);
}

.photo-mosaic__track {
  display: flex;
  gap: 16px;
  width: max-content;
  padding-inline: var(--space-5);
  will-change: transform;
  user-select: none;
  cursor: grab;
}
.photo-mosaic__track.is-dragging {
  cursor: grabbing;
}
.photo-mosaic__track.is-dragging .mosaic-cell { cursor: grabbing; }

/* A "column" in the mosaic — width set INLINE based on actual image aspect ratio
   at the given row height. Tall col: 1 portrait spanning both rows.
   Stack col: 2 landscapes, col width = max of the two image widths. */
.mosaic-col {
  display: flex;
  flex-direction: column;
  gap: 16px;
  height: 436px;          /* 210 + 16 + 210 */
  flex-shrink: 0;
}
.mosaic-col--tall  .mosaic-cell { height: 100%; }
.mosaic-col--stack .mosaic-cell { flex: 1; min-height: 0; }

.mosaic-cell {
  overflow: hidden;
  border-radius: var(--radius-lg);
  position: relative;
  background: var(--wine-850);
  border: 2px solid var(--wine-700);   /* thicker + brighter so the edge actually reads */
  /* Soft drop shadow — lifts each cell off the wine bg */
  box-shadow:
    0 8px 20px -8px rgba(0, 0, 0, 0.55),
    0 4px 10px -4px rgba(0, 0, 0, 0.35);
  transition: box-shadow 400ms var(--ease-out);
}
.mosaic-cell:hover {
  box-shadow:
    0 14px 28px -10px rgba(0, 0, 0, 0.65),
    0 6px 14px -6px rgba(0, 0, 0, 0.45);
}
.mosaic-cell img {
  /* Fill the frame — image covers the whole cell, centered, cropped as needed */
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
  transition: transform 900ms var(--ease-in-out);
  -webkit-user-drag: none;
  user-select: none;
}

.mosaic-cell:hover img {
  transform: scale(1.06);
}

@media (prefers-reduced-motion: reduce) {
  .photo-mosaic__track { animation: none; }
  .mosaic-cell img { transition: none; }
}

/* ============================================
   News index page
   ============================================ */
/* News page hero — creative gradient, no eyebrow, warm tan title.
   Highlight ellipse positioned upper-left so the title sits inside the
   brightest part of the gradient. */
.news-page-hero {
  position: relative;
  overflow: hidden;
  color: #fff;
  /* Per Diallo: 170 top / 50 bottom. Title clears the floating header
     comfortably, and the heading + subheading sit closer to the filter
     row so the rhythm tightens up. */
  padding-block: 170px 50px;
  background:
    radial-gradient(ellipse 75% 90% at 22% 45%, rgba(212, 150, 88, 0.62) 0%, transparent 70%),
    radial-gradient(ellipse 55% 60% at 86% 80%, rgba(135, 20, 39, 0.55) 0%, transparent 75%),
    radial-gradient(ellipse 50% 55% at 65% 25%, rgba(161, 29, 51, 0.32) 0%, transparent 75%),
    linear-gradient(135deg, #4D0027 0%, #320019 60%, #1F000F 100%);
}

.news-page-hero__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-5);
  position: relative;
  z-index: 1;
}

@media (min-width: 768px) {
  .news-page-hero__inner { padding-inline: var(--space-8); }
}

.news-page-hero__title {
  color: var(--tan-200);
  font-family: var(--font-serif);
  font-size: clamp(44px, 7vw, 84px);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.015em;
  margin: 0;
}

.news-page-hero__body {
  color: rgba(255, 255, 255, 0.88);
  font-size: 20px;
  line-height: 1.55;
  margin-top: var(--space-3);
  margin-bottom: 24px;       /* small base; tightening happens via section padding-bottom: 0 */
  /* margin/font tunings continue below; mobile bumps live in a
     dedicated rule lower in this file. */
}

/* Force the subtitle onto one line on viewports wide enough to fit it.
   At narrower widths the nowrap is removed so it wraps naturally. */
@media (min-width: 720px) {
  .news-page-hero__body { white-space: nowrap; }
}

/* News page hero — mobile type tunings per Diallo 2026-05-31.
   Title 44 → 52, body 20 → 18. */
@media (max-width: 768px) {
  .news-page-hero__title { font-size: 52px; }
  .news-page-hero__body  { font-size: 18px; }
}

.news-controls {
  /* Sticky only on desktop. On narrow viewports the 9 chips wrap to
     3-4 rows and eat too much vertical space when pinned — opt out and
     let users scroll past the filter as a normal block. */
  position: static;
  z-index: 50;
  background: var(--bg-page);
  border-bottom: 1px solid var(--border-default);
  padding: var(--space-4) var(--space-5);
}
.news-controls__inner {
  display: flex;
  justify-content: center;     /* center the category chips */
  align-items: center;
  gap: var(--space-4);
}

@media (min-width: 768px) {
  .news-controls {
    /* Sticky removed entirely per Diallo. With only a handful of posts
       per category, there's not much scrolling needed — the filter is
       a one-time choice at the top of the page, then the user scrolls
       through the matching cards without needing the filter again. */
    padding-inline: var(--space-8);
  }
}

/* Light warm gradient backdrop behind the news cards on the gallery page.
   The grid section breathes warmth instead of sitting on the dark wine page bg. */
.news-grid-section {
  padding-block: var(--space-12) var(--space-20);
  background: linear-gradient(180deg, var(--tan-50) 0%, var(--tan-25) 100%);
}

.news-controls__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
}

.news-controls__select {
  font-family: var(--font-sans);
  font-size: var(--type-body-sm);
  font-weight: 500;
  color: var(--text-primary);
  background: var(--bg-surface);
  border: 1.5px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: 6px var(--space-4);
  padding-right: var(--space-8);
  cursor: pointer;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%235F5C61' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  transition: border-color var(--duration-fast) var(--ease-out);
}

.news-controls__select:focus {
  outline: none;
  border-color: var(--cta-primary-bg);
}

.news-controls__count {
  font-size: var(--type-body-sm);
  color: var(--text-muted);
  margin-left: auto;
}

.news-grid-section__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

@media (min-width: 768px) {
  .news-grid-section__inner { padding-inline: var(--space-8); }
}

/* Masonry-style layout using JS column buckets (see news-index.js).
   Cards are distributed round-robin into .news-grid__col wrappers so
   posts read left-to-right in chronological order. Each column stacks
   its cards at their natural content height. */
.news-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  align-items: start;
}

/* Back-to-top — centered button below the news grid */
.news-back-to-top {
  margin-top: var(--space-12);
  display: flex;
  justify-content: center;
}
.back-to-top {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 1px solid rgba(50, 0, 25, 0.25);
  border-radius: 999px;
  padding: 14px 28px;
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--wine-800);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  transition: background 280ms var(--ease-in-out),
              color 280ms var(--ease-in-out),
              border-color 280ms var(--ease-in-out),
              transform 320ms var(--ease-in-out);
}
.back-to-top__arrow {
  display: inline-block;
  color: var(--crimson-500);
  font-size: 14px;
  line-height: 1;
  transition: transform 360ms var(--ease-in-out), color 280ms var(--ease-in-out);
}
.back-to-top:hover {
  /* Brighter crimson gradient — crimson-400 (top-left) into crimson-500
     (bottom-right) for warm depth without going dark. */
  background: linear-gradient(135deg, var(--crimson-400) 0%, var(--crimson-500) 100%);
  border-color: var(--crimson-400);
  color: #FFFFFF;
}
.back-to-top:hover .back-to-top__arrow {
  color: var(--tan-100);   /* warm light arrow against the crimson bg */
  transform: translateY(-4px);
}
.news-grid__col {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

@media (min-width: 640px) {
  .news-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1024px) {
  .news-grid { grid-template-columns: repeat(3, 1fr); }
}

/* News.html cards — DARK card variant on light tan section background.
   Same layout/font system as the homepage news cards (category chip,
   title, excerpt, read-more), inverted color palette: deep wine fill,
   warm light text, crimson accents. */

/* Multiple tag chips per card — display all categories, wrap if needed. */
.news-card__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: var(--space-2); }
.news-card__tags .news-card__category { margin-bottom: 0; }

/* News-page cards — LIGHT default, DARK on hover.
   Rest state matches the homepage news-card palette (white → tan gradient,
   wine title, grey body). Hover smoothly transitions to the deep-crimson
   dark mode that used to be the resting state. Pills shift palette in
   lockstep with the background so they stay readable in both states.

   IMPORTANT — CSS cannot tween between two `linear-gradient()` values
   on the SAME element. It snaps. To get a true silky fade between the
   light card and the dark card, we layer the dark gradient as a
   pseudo-element overlay (.news-card::before) sitting ON TOP of the
   light background. On hover we fade the overlay's OPACITY from 0 to 1,
   which IS animatable. All color/transform transitions run at 1100ms
   on a symmetric cubic-bezier so the whole card transition feels like
   a single coordinated fade, not a switch flip. */
.news-grid .news-card {
  background: linear-gradient(180deg, #FFFFFF 0%, #FFFFFF 55%, var(--tan-100) 100%);
  border: 1px solid rgba(50, 0, 25, 0.06);
  border-radius: var(--radius-lg);
  box-shadow: 0 6px 24px rgba(15, 5, 12, 0.18);
  overflow: hidden;
  position: relative;
  transition: transform 1100ms cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 1100ms cubic-bezier(0.4, 0, 0.2, 1),
              border-color 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}
/* Dark-state overlay — full dark crimson gradient + warm sheen,
   fades in on hover via opacity. This is the trick that gives us a
   real cross-fade between two gradient palettes. */
.news-grid .news-card::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 60% at 20% 0%, rgba(208, 76, 74, 0.22), transparent 60%),
    linear-gradient(145deg, #8A1428 0%, #6E0F1F 45%, #3D001F 100%);
  border-radius: inherit;
  opacity: 0;
  pointer-events: none;
  z-index: 0;
  transition: opacity 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}
.news-grid .news-card > * { position: relative; z-index: 1; }
.news-grid .news-card:hover {
  border-color: rgba(255, 255, 255, 0.06);
  transform: translateY(-5px);
  box-shadow: 0 18px 48px rgba(15, 5, 12, 0.40);
  /* Asymmetric transition: hover IN is quick + smooth (~450ms), hover
     OUT keeps the slower 1100ms ease defined on the base state. */
  transition: transform 450ms cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 450ms cubic-bezier(0.4, 0, 0.2, 1),
              border-color 450ms cubic-bezier(0.4, 0, 0.2, 1);
}
.news-grid .news-card:hover::before {
  opacity: 1;
  transition: opacity 450ms cubic-bezier(0.4, 0, 0.2, 1);
}
/* Asymmetric color transitions on the content — IN ~450ms, OUT stays
   1100ms (defined on the base selectors above). */
.news-grid .news-card:hover .news-card__title,
.news-grid .news-card:hover .news-card__excerpt {
  transition: color 450ms cubic-bezier(0.4, 0, 0.2, 1);
}
.news-grid .news-card:hover .news-card__category {
  transition: background 450ms cubic-bezier(0.4, 0, 0.2, 1),
              color 450ms cubic-bezier(0.4, 0, 0.2, 1),
              border-color 450ms cubic-bezier(0.4, 0, 0.2, 1);
}
.news-grid .news-card:hover .news-card__read-more {
  transition: color 450ms cubic-bezier(0.4, 0, 0.2, 1);
}
.news-grid .news-card:hover .news-card__read-more-arrow {
  transition: transform 320ms var(--ease-in-out),
              color 450ms cubic-bezier(0.4, 0, 0.2, 1);
}
.news-grid .news-card:hover .news-card__read-more::after {
  transition: transform 360ms var(--ease-in-out),
              background 450ms cubic-bezier(0.4, 0, 0.2, 1);
}
.news-grid .news-card__body {
  /* Extra 10px at top (above pills) and 10px at bottom (below read-more)
     so the content has more vertical breathing room than the homepage
     cards. Horizontal gets +5px sitewide bump. */
  padding: calc(var(--space-5) + 10px) calc(var(--space-5) + 5px) calc(var(--space-5) + 10px);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Title + excerpt — dark on light rest, light on dark hover. Smooth
   color transition matches the background transition timing. */
.news-grid .news-card__title {
  color: var(--wine-800);
  font-weight: 500;
  transition: color 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}
.news-grid .news-card__excerpt {
  color: var(--grey-700);
  transition: color 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}
.news-grid .news-card:hover .news-card__title { color: var(--tan-50); }
.news-grid .news-card:hover .news-card__excerpt { color: rgba(255, 255, 255, 0.78); }

/* Pills — same category color identity in both states, just adapted
   for light vs dark backgrounds. Per Diallo the color palette stays
   as it currently reads on the site. */
.news-grid .news-card__category {
  display: inline-block;
  padding: 1px 10px;
  border-radius: 100px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.6;
  align-self: flex-start;
  background: rgba(50, 0, 25, 0.08);
  color: var(--wine-800);
  transition: background 1100ms cubic-bezier(0.4, 0, 0.2, 1),
              color 1100ms cubic-bezier(0.4, 0, 0.2, 1),
              border-color 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Rest — light tinted pills (mirrors homepage palette). */
.news-grid .news-card__category--awards            { background: rgba(212, 150, 88, 0.22); color: #8A5A1F; }
.news-grid .news-card__category--scholarship       { background: rgba(212, 150, 88, 0.22); color: #8A5A1F; }
.news-grid .news-card__category--leadership        { background: rgba(208, 76, 74, 0.18); color: var(--crimson-700); }
.news-grid .news-card__category--judicial-pipeline { background: rgba(50, 0, 25, 0.10); color: var(--wine-800); }
.news-grid .news-card__category--programs          { background: rgba(50, 0, 25, 0.10); color: var(--wine-800); }
.news-grid .news-card__category--civil-rights      { background: rgba(208, 76, 74, 0.18); color: var(--crimson-700); }
.news-grid .news-card__category--affiliates        { background: rgba(212, 150, 88, 0.22); color: #8A5A1F; }

/* Hover — pills shift to the deeper palette tuned for the dark card. */
.news-grid .news-card:hover .news-card__category--awards            { background: rgba(212, 150, 88, 0.30); color: var(--tan-50); }
.news-grid .news-card:hover .news-card__category--scholarship       { background: rgba(212, 150, 88, 0.30); color: var(--tan-50); }
.news-grid .news-card:hover .news-card__category--leadership        { background: rgba(208, 76, 74, 0.32); color: #FFD8C9; }
.news-grid .news-card:hover .news-card__category--judicial-pipeline { background: rgba(255, 255, 255, 0.10); color: var(--tan-50); }
.news-grid .news-card:hover .news-card__category--programs          { background: rgba(255, 255, 255, 0.10); color: var(--tan-50); }
.news-grid .news-card:hover .news-card__category--civil-rights      { background: rgba(208, 76, 74, 0.32); color: #FFD8C9; }
.news-grid .news-card:hover .news-card__category--affiliates        { background: rgba(212, 150, 88, 0.30); color: var(--tan-50); }

/* Video pill — crimson outline both states, depth shifts on hover. */
.news-grid .news-card__category--video {
  background: transparent;
  color: var(--crimson-700);
  border: 1.5px solid var(--crimson-700);
  padding: 2.5px 10.5px;
}
.news-grid .news-card:hover .news-card__category--video {
  color: var(--crimson-400);
  border-color: var(--crimson-400);
}
.news-grid .news-card__category--video::before {
  content: "\25B6";
  display: inline-block;
  margin-right: 6px;
  font-size: 9px;
  transform: translateY(-1px);
}

/* Read-more — crimson on light rest, tan-to-white on dark hover.
   Color transitions extended to 1100ms to flow with the card's
   background cross-fade. Arrow transform keeps its snappy 320ms
   so the arrow nudge still feels alive. */
.news-grid .news-card__read-more {
  color: var(--crimson-500);
  transition: color 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}
.news-grid .news-card__read-more-arrow {
  color: var(--tan-400);
  transition: transform 320ms var(--ease-in-out), color 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}
.news-grid .news-card__read-more::after {
  background: var(--crimson-500);
  transition: transform 360ms var(--ease-in-out), background 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}
.news-grid .news-card:hover .news-card__read-more { color: var(--tan-200); }
.news-grid .news-card:hover .news-card__read-more-arrow { color: #FFFFFF; }
.news-grid .news-card:hover .news-card__read-more::after { background: var(--crimson-400); }

/* Play-icon badge — straddles the image / body boundary at the bottom
   of the thumbnail. Smaller circle inside the same hit area. Resting
   color is brand crimson; color only shifts on DIRECT hover of the
   badge (not the whole card). The card hover still drives a small
   scale lift on the badge so it tracks with card motion. */
.news-card__image-wrap { position: relative; overflow: visible; }
.news-card__video-badge {
  position: absolute;
  bottom: -22px;
  right: 22px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--crimson-500);
  border: 2px solid var(--tan-50);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #FFFFFF;
  font-size: 14px;
  line-height: 1;
  padding-left: 3px;
  z-index: 3;
  box-shadow: 0 6px 16px rgba(15, 5, 12, 0.38);
  transition: transform 360ms var(--ease-in-out),
              background 220ms var(--ease-in-out),
              color 220ms var(--ease-in-out),
              border-color 220ms var(--ease-in-out);
}
/* Card hover — movement only, no color change. */
.news-card:hover .news-card__video-badge {
  transform: scale(1.10);
}
/* Direct badge hover — color shift to crimson-400. */
.news-card__video-badge:hover {
  background: var(--crimson-400);
  border-color: var(--tan-50);
}

/* ============================================
   News post template
   ============================================ */
.post-article {
  padding-block: var(--space-16) var(--space-20);
}

.post-article__inner {
  max-width: var(--container-narrow);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

@media (min-width: 768px) {
  .post-article__inner { padding-inline: var(--space-8); }
}

.post-header {
  margin-bottom: var(--space-8);
}

.post-header .eyebrow {
  margin-bottom: var(--space-4);
}

.post-header h1 {
  font-size: clamp(28px, 5vw, var(--type-h1));
  line-height: 1.15;
  margin-bottom: var(--space-4);
}

.post-meta {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  font-size: var(--type-body-sm);
  color: var(--text-muted);
}

.post-hero-image {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-5);
  margin-bottom: var(--space-10);
}

@media (min-width: 768px) {
  .post-hero-image { padding-inline: var(--space-8); }
}

.post-hero-image img {
  width: 100%;
  aspect-ratio: 16/9;
  object-fit: cover;
  border-radius: var(--radius-xl);
}

.post-hero-image figcaption {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: var(--space-2);
  padding-inline: var(--space-2);
}

/* Legacy .post-body rules removed — superseded by .post-body__article
   in the new post template (template v2+). They were close enough in
   selector name that one was suspected of bleeding into the new
   article element. No production posts still use the legacy class. */

.post-back {
  margin-top: var(--space-10);
  padding-top: var(--space-8);
  border-top: 1px solid var(--border-default);
}

.post-back a {
  font-size: var(--type-body-sm);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.post-related {
  background: var(--bg-surface-tint);
  padding-block: var(--space-16) var(--space-20);
}

.post-related__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

@media (min-width: 768px) {
  .post-related__inner { padding-inline: var(--space-8); }
}

.post-related__grid {
  display: grid;
  gap: var(--space-5);
  margin-top: var(--space-8);
}

@media (min-width: 640px) {
  .post-related__grid { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1024px) {
  .post-related__grid { grid-template-columns: repeat(3, 1fr); }
}

/* ============================================
   POST TEMPLATE v2 — feature-image posts
   (Terrance CLA president as prototype)

   No hero. Two-col body on a light warm gradient section.
   LEFT col:  title (crimson serif), meta pills, separator, article copy
   RIGHT col: feature image + caption — sticky so it stays in view while
              the article scrolls.
   Mobile (<900px) collapses to one column with HTML order:
   title → meta → image → article.
   ============================================ */

.post-body-section {
  /* Directional mesh gradient — tan-25 dominates the left half (behind
     the title + article column, kept airy for readability) and tan-50
     dominates the right half (behind the sticky image column, with a
     touch more warmth). Both colors are very light so the difference
     is intentionally subtle — a painted wash, not a band. */
  background:
    radial-gradient(ellipse 55% 95% at 12% 50%, rgba(253, 249, 237, 0.85) 0%, transparent 70%),
    radial-gradient(ellipse 55% 80% at 82% 35%, rgba(251, 244, 234, 0.95) 0%, transparent 70%),
    radial-gradient(ellipse 45% 60% at 78% 85%, rgba(251, 244, 234, 0.65) 0%, transparent 75%),
    linear-gradient(90deg, var(--tan-25) 0%, var(--tan-50) 100%);
  /* +100px of breathing room at the top of the body (above the title)
     so the transparent light header doesn't sit on top of the content.
     Bottom padding reduced ~30px per Diallo — pulls the related
     section closer to the back link. */
  padding-block: calc(clamp(56px, 10vh, 120px) + 100px) clamp(26px, 7vh, 90px);
}
.post-body-section__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-5);
}
@media (min-width: 768px) {
  .post-body-section__inner { padding-inline: var(--space-8); }
}

.post-body-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  align-items: start;
}
@media (min-width: 900px) {
  /* Desktop: two columns. Image col now gets the wider slot so feature
     images have more presence and titles reflow without leaving lone
     orphan words (e.g. "West") on the last line. */
  .post-body-grid {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    grid-template-areas:
      "title   figure"
      "meta    figure"
      "article figure";
    column-gap: var(--space-12);
    row-gap: var(--space-5);
  }
  .post-body__title    { grid-area: title; }
  .post-body__meta     { grid-area: meta; }
  .post-body__feature  { grid-area: figure; }
  .post-body__article  { grid-area: article; }

  /* Sticky feature image — pins while the text column scrolls past it.
     Top offset clears the floating site header (≈90px) plus a comfort gap. */
  .post-body__feature {
    position: sticky;
    top: 110px;
    align-self: start;
  }
}

/* Title — brighter crimson serif on tan bg (closer to red per Diallo) */
.post-body__title {
  color: var(--crimson-500);
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: clamp(30px, 3.8vw, 52px);
  line-height: 1.1;
  letter-spacing: -0.015em;
  margin: 0;
}

/* Meta — pills row */
.post-body__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
}

/* Pills — TWO ROLES with very different visual logic.
   DATE pill is the constant: one warm-neutral stone color with near-black
   text, used identically on every post so the eye reads it as metadata
   rather than category. CATEGORY pills are dark-reverse — varied shades
   of wine/burgundy/crimson with varied warm-vs-pure whites so each
   category reads as its own thing. Different white shades (pure vs warm)
   add subtle variety on top of the bg variety so pills don't feel like
   one block of red. */
.post-meta-pill {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 100px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.6;
  font-family: var(--font-sans);
}
/* DATE — neutral stone bg + near-black text, consistent across every post */
.post-meta-pill--date              { background: #E0DCD4; color: #1A1A1A; }

/* CATEGORY PILLS — dark-reverse, wines/burgundies/crimsons with varied
   white text. Distinct dark for each category; warm-white vs pure-white
   varied for additional texture. Per Diallo: awards + judicial-pipeline
   bumped to brighter, more saturated tones (the near-black variants
   were reading muddy on the warm tan body). */
.post-meta-pill--category          { background: var(--wine-800);  color: #FFFFFF; } /* default fallback */
.post-meta-pill--awards            { background: #C44E2D;          color: #FFFFFF; } /* vibrant warm brick — celebratory */
.post-meta-pill--scholarship       { background: #6E1424;          color: #FFFFFF; } /* rich burgundy, pure white */
.post-meta-pill--leadership        { background: #9D2A28;          color: #F5EFE6; } /* deep crimson, warm white */
.post-meta-pill--judicial-pipeline { background: #B23048;          color: #FFFFFF; } /* vibrant wine-rose */
.post-meta-pill--programs          { background: #4A0818;          color: #FFFFFF; } /* deepest burgundy, pure white */
.post-meta-pill--civil-rights      { background: #8B1A1A;          color: #F5EFE6; } /* deep crimson, warm white */
.post-meta-pill--affiliates        { background: #A8302E;          color: #FFFFFF; } /* warm crimson, pure white */

/* VIDEO pill — unique treatment, outline-only with no fill. Both the
   stroke and the text use the bright crimson so it reads as its own
   marker rather than as a category. Padding is reduced by 1.5px on
   each side to compensate for the border and keep the outer size
   consistent with the other pills. */
.post-meta-pill--video {
  background: transparent;
  color: var(--crimson-500);
  border: 1.5px solid var(--crimson-500);
  padding: 2.5px 10.5px;
}

/* Feature image — native aspect ratio, full column width, caption below */
.post-body__feature {
  margin: 0;
}
.post-body__feature img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-md);
  /* 10px crimson rule on the right edge — brand accent without
     framing the whole image. Visual chrome now lives on the frame
     wrapper so we can overflow:hidden the frame and let the img scale
     on hover without colliding with the figcaption below. */
}
/* Frame wrapper — holds the visual chrome (border, radius, shadow)
   and clips the image so its hover-scale stays inside this container
   instead of bleeding into the figcaption. */
.post-body__feature-frame {
  display: block;
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-md);
  border-right: 10px solid var(--crimson-400);
  box-shadow: 0 8px 28px rgba(15, 5, 12, 0.18);
  line-height: 0; /* removes inline gap below the contained <img> */
  /* No cursor change — the image isn't clickable and doesn't open a
     lightbox. Hover-grow is decorative only. */
}
.post-body__feature-frame img {
  display: block;
  width: 100%;
  height: auto;
  border: none;
  border-radius: 0;
  box-shadow: none;
  transition: transform 1800ms cubic-bezier(0.33, 0, 0.2, 1);
  will-change: transform;
  transform-origin: center center;
}
.post-body__feature-frame:hover img {
  transform: scale(1.12);
}
.post-body__feature figcaption {
  margin-top: 14px;
  font-family: var(--font-sans);
  font-size: 14px;          /* 12 → 14 per Diallo */
  line-height: 1.65;
  color: #6B6B6B;
  font-style: italic;
  position: relative;
  padding-left: 18px;
}
/* Small crimson rule before the caption — quiet "callout" affordance
   that ties the feature image to the brand without competing with
   the image's right border. Lines up with the first line of caption text. */
.post-body__feature figcaption::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.7em;
  width: 10px;
  height: 2px;
  background: var(--crimson-500);
}

/* Article-start indicator removed per Diallo — paragraph dividers
   below carry the visual rhythm on their own. The rule is dropped from
   the markup; if any legacy page still has the element it hides. */
.post-article-start { display: none; }

/* Article copy — 20px, true neutral dark gray (#333) on warm light bg.
   Paragraph rhythm comes from generous vertical spacing only — the
   short crimson rule between paragraphs was removed per Diallo.
   font-size + paragraph margin kept with !important since the legacy
   .post-body p rule had been silently overriding (now removed). */
.post-body__article {
  color: #333333 !important;
  font-family: var(--font-sans);
  font-size: 20px !important;
  line-height: 1.6 !important;
  /* +30px gap above the article (between meta pills and first paragraph) */
  margin-top: 30px;
}
.post-body__article p {
  margin: 0;
  color: #333333 !important;
  font-size: 20px !important;
  line-height: 1.6 !important;
}
.post-body__article > p + p { margin-top: 1.6em !important; }
.post-body__article > * + * { margin-top: 1.6em; }

/* ============================================
   Text-only post variant — no feature image, no video.
   LEFT col: title + meta pills (no article inside).
   RIGHT col: article copy (the column that would normally hold the
              feature image).
   FULL-WIDTH row underneath: separator + back-to-news link.
   Used for placeholder-only posts (text + thumbnail only).
   ============================================ */
.post-body-grid--text {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  align-items: start;
}
@media (min-width: 900px) {
  .post-body-grid--text {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    grid-template-areas:
      "head    article"
      "footer  footer";
    column-gap: var(--space-12);
    row-gap: var(--space-5);
  }
  /* Backwards-compat: posts that haven't been migrated to the
     .post-body__head wrapper get title in row 1 and meta below it
     without grid stretching by giving them the same grid area. */
  .post-body-grid--text .post-body__head    { grid-area: head; align-self: start; }
  .post-body-grid--text .post-body__title   { grid-area: head; align-self: start; }
  .post-body-grid--text .post-body__meta    { grid-area: head; align-self: start; }
  .post-body-grid--text .post-body__article { grid-area: article; margin-top: 0; }
  .post-body-grid--text .post-body__footer  { grid-area: footer; }
}
/* Head wrapper — stacks title + meta vertically as a single grid item.
   Fixes the row-stretch problem where a tall article on the right was
   forcing the title's row to grow, leaving a visible gap between title
   and date/category pills. */
.post-body__head {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Footer row — full-width band under the 2 columns containing the
   separator + back link. */
.post-body__footer {
  margin-top: var(--space-6);
}

/* ============================================
   Reference post variant — left col sticks with title/meta/copy;
   right col scrolls with the long-form reference content (lists,
   tables, registries). Used when the post's value is the data on
   the right and the intro on the left is a stable anchor.
   ============================================ */
.post-body-grid--reference {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  align-items: start;
}
@media (min-width: 900px) {
  .post-body-grid--reference {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    grid-template-areas:
      "left   reference"
      "footer footer";
    column-gap: var(--space-12);
    row-gap: var(--space-10);
  }
  .post-body-grid--reference .post-body__left      { grid-area: left; }
  .post-body-grid--reference .post-body__reference { grid-area: reference; }
  .post-body-grid--reference .post-body__footer    { grid-area: footer; }
  /* Left column stays put while the reference data scrolls past on the
     right. The 75px padding-bottom is intentional — sticky releases
     when the element's bottom reaches the bottom of its containing
     block, so padding-bottom extends the element's "release zone" up
     by 75px. Net effect: the sticky col stops sticking ~75px earlier,
     before the full-width back-link footer overlaps with it. */
  .post-body-grid--reference .post-body__left {
    position: sticky;
    top: 110px;
    align-self: start;
    padding-bottom: 75px;
  }

  /* Right-sticky variant — flips which column scrolls and which one
     pins. Used on the SCOTUS post where the body article lives on the
     left (long-form scrolling) and the reference callout sits on the
     right (persistent sidebar). Also widens the left column so the
     prose has room. */
  .post-body-grid--right-sticky {
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  }
  .post-body-grid--right-sticky .post-body__left {
    position: static;
    padding-bottom: 0;
  }
  .post-body-grid--right-sticky .post-body__reference {
    position: sticky;
    top: 110px;
    align-self: start;
    padding-bottom: 75px;
  }
}

/* Internal stacking on the left side */
.post-body-grid--reference .post-body__left { display: flex; flex-direction: column; gap: var(--space-5); }
.post-body-grid--reference .post-body__left .post-body__article { margin-top: var(--space-2); }

/* Section header at the top of the reference column — designed to feel
   like an editorial section title. Wide tracking, larger uppercase
   set, plenty of breathing room before the list/table that follows. */
.post-body__reference-header {
  font-family: var(--font-sans);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--crimson-700);
  margin: 0 0 var(--space-8);
}
@media (min-width: 768px) {
  .post-body__reference-header { font-size: 18px; letter-spacing: 0.38em; }
}

/* Prose inside the reference column — when a reference post is
   long-form rather than a list, paragraphs render in the same 20px
   dark-gray treatment as the standard article copy. */
.post-body__reference p {
  color: #333333;
  font-family: var(--font-sans);
  font-size: 20px;
  line-height: 1.6;
  margin: 0;
}
.post-body__reference > p + p,
.post-body__reference > p + ul,
.post-body__reference > ul + p {
  margin-top: 1.6em;
}
.post-body__reference ul.post-body__list {
  color: #333333;
  font-family: var(--font-sans);
  font-size: 20px;
  line-height: 1.6;
  margin: 1.6em 0 0;
  padding-left: 1.4em;
}
.post-body__reference ul.post-body__list li { margin-bottom: 0.5em; }

/* ============================================
   Media-right post variant — left col holds the editorial flow
   (feature image, title, meta, article, inline callout), right col
   is a slim sticky media slot. Designed for posts whose media is a
   9:16 vertical phone video — the column is intentionally narrow so
   the portrait video fits in the viewport without scrolling.
   ============================================ */
.post-body-grid--media-right {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}
@media (min-width: 900px) {
  .post-body-grid--media-right {
    /* Right col tightened again to give the title more room to land
       "of the Year" cleanly on the second line. Video stays usable but
       gives up width to the article column. */
    grid-template-columns: minmax(0, 1fr) clamp(260px, 26vw, 340px);
    grid-template-areas:
      "left   media"
      "footer footer";
    column-gap: var(--space-10);
    row-gap: var(--space-10);
  }
  .post-body-grid--media-right .post-body__left   { grid-area: left; }
  .post-body-grid--media-right .post-body__media  {
    grid-area: media;
    position: sticky;
    top: 110px;
    align-self: start;
    /* Padding-bottom extends the sticky element's "release zone" up by
       this many pixels, so the video unsticks ~90px before the
       back-to-news divider in the footer block — instead of passing
       through it on the way down. */
    padding-bottom: 90px;
  }
  .post-body-grid--media-right .post-body__footer { grid-area: footer; }
}

/* Video header block above the embedded video — small eyebrow + title
   + short crimson rule, gives context for what the video shows. */
.post-body__media-eyebrow {
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--crimson-700);
  margin: 0 0 6px;
}
.post-body__media-title {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 17px;          /* 14 → 17 per Diallo. Sized to fill the right column on one line at the wider end of the 260-340px range. */
  line-height: 1.3;
  color: var(--wine-800);
  margin: 0 0 14px;
}
.post-body__media-rule {
  border: 0;
  border-top: 2px solid var(--crimson-500);
  width: 44px;
  margin: 0 0 18px;
}

/* Left column stacks the editorial flow */
.post-body-grid--media-right .post-body__left {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
/* Feature image at the top of the left column — same border + radius
   treatment as the standard feature image. Opt OUT of the sticky
   behavior inherited from the feature-image template; in this variant
   the feature image scrolls along with the rest of the left column. */
.post-body-grid--media-right .post-body__left .post-body__feature {
  margin: 0;
  position: static;
  top: auto;
  align-self: auto;
}
.post-body-grid--media-right .post-body__left .post-body__feature img {
  display: block;
  width: 100%;
  height: auto;
  /* visual chrome now lives on the frame wrapper; the bare img inside the
     frame scales on hover */
}
.post-body-grid--media-right .post-body__left .post-body__feature figcaption {
  margin-top: 14px;
  font-family: var(--font-sans);
  font-size: 14px;          /* 12 → 14 per Diallo */
  line-height: 1.65;
  color: #6B6B6B;
  font-style: italic;
  position: relative;
  padding-left: 18px;
}
.post-body-grid--media-right .post-body__left .post-body__feature figcaption::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.7em;
  width: 10px;
  height: 2px;
  background: var(--crimson-500);
}

/* Article copy keeps the same 20px / dark-gray styling we use in the
   feature-image template, no top-margin override since the article
   sits below other stacked elements in this variant. */
.post-body-grid--media-right .post-body__article { margin-top: 0; }

/* Right column stacked media — used when the media sidebar holds
   multiple items (e.g. video + secondary photo). Separator gives a
   clean break between items with generous breathing room. */
.post-body__media-divider {
  border: 0;
  border-top: 1px solid rgba(50, 0, 25, 0.18);
  margin: 32px 0;
  width: 60px;
}
.post-body__media-photo {
  margin: 0;
}
.post-body__media-photo .post-body__feature-frame {
  /* Inherit the same frame chrome as feature images so hover-grow
     works consistently across all photos on the site. */
  border-radius: var(--radius-md);
}
.post-body__media-photo figcaption {
  margin-top: 12px;
  font-family: var(--font-sans);
  font-size: 12px;
  line-height: 1.65;
  color: #6B6B6B;
  font-style: italic;
  position: relative;
  padding-left: 18px;
}
.post-body__media-photo figcaption::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.7em;
  width: 10px;
  height: 2px;
  background: var(--crimson-500);
}

/* 9:16 portrait video embed — fills the slim sticky media column */
.post-body__media-video {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: linear-gradient(135deg, var(--wine-800), var(--crimson-800));
  box-shadow: 0 12px 32px rgba(15, 5, 12, 0.30);
}
.post-body__media-video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Inline gallery — a 4-image grid placed inside the article column.
   Used when a post has a small set of supporting photos that work
   better as a contact-sheet style cluster than as a single callout.
   Asymmetric to feel less rigid: first row 2:3, second row 3:2.
   Hover scales the image inside its tile (no lightbox). */
.post-body__gallery {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin: 2.4em 0;
}
.post-body__gallery-item {
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius-md);
  aspect-ratio: 3 / 2;
  position: relative;
  background: var(--tan-100);
}
/* Variable heights — top row leans landscape, bottom row leans more square */
.post-body__gallery-item:nth-child(1),
.post-body__gallery-item:nth-child(2) { aspect-ratio: 4 / 3; }
.post-body__gallery-item:nth-child(3),
.post-body__gallery-item:nth-child(4) { aspect-ratio: 3 / 2; }

.post-body__gallery-item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
}
.post-body__gallery-item:hover img {
  transform: scale(1.07);
}
@media (max-width: 600px) {
  .post-body__gallery { grid-template-columns: 1fr; }
  .post-body__gallery-item { aspect-ratio: 3 / 2 !important; }
}
/* THREE-image variant — single horizontal row, equal columns, all tiles
   the same landscape ratio. Used for posts with 3 secondary images (e.g.
   CLA Legislative Day). */
.post-body__gallery--three {
  grid-template-columns: 1fr 1fr 1fr;
}
.post-body__gallery--three .post-body__gallery-item,
.post-body__gallery--three .post-body__gallery-item:nth-child(1),
.post-body__gallery--three .post-body__gallery-item:nth-child(2),
.post-body__gallery--three .post-body__gallery-item:nth-child(3) {
  aspect-ratio: 4 / 3;
}
@media (max-width: 600px) {
  .post-body__gallery--three { grid-template-columns: 1fr; }
}

/* SPLIT variant — top row holds two images side by side (positions 1
   and 3 in source order), bottom row holds the middle image spanning
   full width. Dense flow lets the middle image (HTML order #2) drop to
   row 2 while #3 backfills the top-right slot. */
.post-body__gallery--split {
  grid-template-columns: 1fr 1fr;
  grid-auto-flow: dense;
}
.post-body__gallery--split .post-body__gallery-item:nth-child(1),
.post-body__gallery--split .post-body__gallery-item:nth-child(3) {
  aspect-ratio: 4 / 3;
}
.post-body__gallery--split .post-body__gallery-item:nth-child(2) {
  grid-column: 1 / -1;
  aspect-ratio: 16 / 9;
}
@media (max-width: 600px) {
  .post-body__gallery--split { grid-template-columns: 1fr; }
  .post-body__gallery--split .post-body__gallery-item:nth-child(2) { grid-column: auto; aspect-ratio: 4 / 3; }
}

/* ============================================
   Feature stack — used when the right column holds the feature image
   plus a secondary content block (separator + gallery row) below it.
   Wraps .post-body__feature and additional content. Drops sticky on
   the inner feature so the whole stack scrolls with the article.
   ============================================ */
.post-body__feature-stack {
  grid-area: figure;
  display: flex;
  flex-direction: column;
}
.post-body__feature-stack .post-body__feature {
  position: static;
  align-self: auto;
  margin: 0;
}
.post-body__feature-stack .post-body__gallery {
  margin: 0;
}
.post-body__feature-divider {
  border: 0;
  border-top: 1px solid rgba(50, 0, 25, 0.10);
  margin: 28px 0;
  width: 100%;
}

/* Default post-body-grid — when a .post-body__head wrapper is present,
   collapse the separate title + meta rows into a single head area so
   title and meta sit tight together and the article gets its own
   spacing below. Same fix as the text variant.
   IMPORTANT: scoped with :not(--text) so this DOESN'T override the
   text variant's own grid template areas. :has() adds specificity
   from its inner selector, which beats .post-body-grid--text. */
@media (min-width: 900px) {
  .post-body-grid:not(.post-body-grid--text):has(.post-body__head) {
    grid-template-areas:
      "head    figure"
      "article figure";
  }
  .post-body-grid:not(.post-body-grid--text) .post-body__head {
    grid-area: head;
    align-self: start;
  }
  .post-body-grid:not(.post-body-grid--text):has(.post-body__head) .post-body__article {
    margin-top: var(--space-2);
  }
}

/* Inline story-break callout — used for secondary images inside the
   article column. Renders as a divider-bordered block with the image
   on the left and its caption on the right, side by side. Acts as a
   visual pause in the article copy. */
.post-inline-callout {
  margin: 2em 0;
  padding: 1.4em 0;
  border-top: 1px solid rgba(50, 0, 25, 0.18);
  border-bottom: 1px solid rgba(50, 0, 25, 0.18);
}
.post-inline-callout__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  align-items: center;
}
@media (min-width: 600px) {
  .post-inline-callout__inner {
    /* Image column gets more room so it can render larger; caption
       sits in the remaining 42% with enough vertical space for a
       3-line caption to land comfortably. */
    grid-template-columns: 1.4fr 1fr;
    gap: 1.6em;
  }
}
.post-inline-callout__img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-md);
}
.post-inline-callout__caption {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 15px;
  line-height: 1.5;        /* slightly tighter to keep 3 lines tidy */
  /* Burnt amber from the brand palette — same warm tone used on the
     Honors post presenter eyebrow. Italic + 15px keeps it understated. */
  color: #9E5A1F;
  margin: 0;
  padding-block: 4px;      /* small breathing room top/bottom so
                              the caption block visually centers without
                              touching the image's top/bottom edges */
}

/* Separator + Back link — sit INSIDE the article column so the divider
   only spans the title/article column (not the sticky image column). */
.post-separator {
  border: 0;
  border-top: 1px solid rgba(50, 0, 25, 0.16);
  margin: var(--space-12) 0 var(--space-6);
}

/* Back link — uppercase, arrow in brighter crimson, label in deeper
   crimson, animated underline draw under the label on hover. */
.post-back-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--crimson-700);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  transition: color 280ms var(--ease-in-out);
}
.post-back-link__arrow {
  display: inline-block;
  color: var(--crimson-400);
  font-size: 18px;
  line-height: 1;
  transform: translateX(0);
  transition: transform 320ms var(--ease-in-out), color 280ms var(--ease-in-out);
}
.post-back-link__label {
  position: relative;
  padding-bottom: 3px;
}
.post-back-link__label::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1.5px;
  background: var(--crimson-400);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 360ms var(--ease-in-out);
}
.post-back-link:hover { color: var(--crimson-500); }
.post-back-link:hover .post-back-link__arrow {
  transform: translateX(-6px);
  color: var(--crimson-500);
}
.post-back-link:hover .post-back-link__label::after { transform: scaleX(1); }

/* Related — dark crimson section variant.
   Top padding reduced ~20px so the section sits closer to the body. */
.post-related--crimson {
  /* Dark crimson gradient — sits in the red family (vs. the wine
     family of the footer below), so there's a clean color shift
     between this section and the footer rather than a continuous
     wine wash. Warm radial sheen at top-left adds depth. */
  background:
    radial-gradient(110% 70% at 20% 0%, rgba(208, 76, 74, 0.22), transparent 60%),
    linear-gradient(180deg, #6E0F1F 0%, #570A17 50%, #3D0A14 100%);
  padding-block: clamp(36px, 7vh, 76px) clamp(56px, 9vh, 96px);
}

/* (Back-to-news on dark related section removed — link lives back
   under the article on the light body section per Diallo.) */
.post-related--crimson .post-related__title {
  color: var(--tan-50);
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: clamp(28px, 3.4vw, 44px);
  margin: 0 0 var(--space-8);
}
/* Grid uses the news-grid hook so it inherits the news.html card
   styling (dark wine card, multi-tag chips, read-more, video badge).
   3 cards across on desktop — fixed count, no masonry. */
.post-related--crimson .post-related__grid.news-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  margin-top: 0;
}
@media (min-width: 640px) {
  .post-related--crimson .post-related__grid.news-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .post-related--crimson .post-related__grid.news-grid { grid-template-columns: repeat(3, 1fr); }
}
/* Cards inside a related grid match the news.html style exactly —
   image at its native aspect ratio (no crop), card height sized to
   its content. Three cards across will be different heights, matching
   the masonry feel of the rest of the site. */
.post-related--crimson .news-card__image-wrap {
  overflow: visible;
  aspect-ratio: auto;
}
.post-related--crimson .news-card__image {
  width: 100%;
  height: auto;
  object-fit: initial;
}
/* Lift cards visually off the dark section bg with a softer warm border */
.post-related--crimson .news-card {
  border-color: rgba(255, 255, 255, 0.08);
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.30);
  align-self: start;
}
.post-related--crimson .news-card:hover {
  box-shadow: 0 20px 56px rgba(0, 0, 0, 0.45);
}
.home-hero {
  position: relative;
  z-index: 2;                        /* sit above .home-about so the about torch SVG never bleeds into the hero during its draw-on animation */
  background: var(--bg-page);
  overflow: hidden;
}
.home-hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.home-hero__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}
.home-hero__content {
  position: relative;
  z-index: 2;
  padding: 100px 80px 314px 180px;   /* 214px slider half + 100px breathing room */
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  justify-content: center;
  align-items: flex-start;
}
.home-hero__lockup {
  margin-bottom: var(--space-2);
}
/* Bump lockup size in the hero specifically */
.home-hero__lockup.lockup-primary .lockup__mark { height: 80px; width: auto; }
.home-hero__lockup.lockup-primary .lockup__sep { height: 80px; }
.home-hero__lockup.lockup-primary .lockup__region { font-size: 14px; }
.home-hero__lockup.lockup-primary .lockup__ix { font-size: 40px; }
@media (min-width: 1024px) {
  .home-hero__lockup.lockup-primary .lockup__mark { height: 96px; }
  .home-hero__lockup.lockup-primary .lockup__sep { height: 96px; }
  .home-hero__lockup.lockup-primary .lockup__region { font-size: 16px; }
  .home-hero__lockup.lockup-primary .lockup__ix { font-size: 48px; }
}

.home-hero__title {
  font-family: var(--font-serif);
  font-size: clamp(40px, 5.5vw, 64px);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--text-primary);
  max-width: 720px;        /* keeps 3-line wrap with "and Service" together */
  text-wrap: balance;      /* stabilizes line distribution across viewports */
  margin: 0;
}
.home-hero__body {
  font-size: var(--type-body-lg);
  line-height: 1.6;
  color: var(--text-secondary);
  max-width: 640px;   /* widened so "profession" pulls up to line 5 instead of orphaning */
  margin: 0;
}
.home-hero__ctas {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-2);
}

@media (max-width: 900px) {
  .home-hero__content { padding: 56px var(--space-5) 200px; }
  .home-hero__title { font-size: clamp(32px, 7vw, 44px); max-width: 100%; }
  .home-hero__body { font-size: var(--type-body); }
}

/* ============================================
   Hero Slider — floating overlay between hero + About
   ============================================ */
.hero-slider-wrap {
  position: relative;
  z-index: 5;
  max-width: 1000px;
  margin-inline: auto;
  padding-inline: var(--space-5);
  /* Pull the slider so its vertical middle aligns with the hero/about seam.
     Width 1000 × 9/21 ≈ 428px tall → half = 214px on each side. */
  margin-top: -214px;
  margin-bottom: -214px;
}

.hero-slider {
  position: relative;
  width: 100%;
  border-radius: 14px;
  overflow: hidden;
  background: var(--wine-900, #1a000c);
  box-shadow:
    0 30px 60px -20px rgba(0, 0, 0, 0.55),
    0 12px 28px -12px rgba(0, 0, 0, 0.45),
    0 0 0 1px rgba(255, 255, 255, 0.06);
}

.hero-slider__viewport {
  position: relative;
  width: 100%;
  aspect-ratio: 21 / 9;
  overflow: hidden;
}
/* Desktop renders at the natural 21/9 height (~428px at 1000px
   wide). The previous 328px cap was removed per Diallo's
   2026-05-31 audit — he wanted to see the original ratio before
   deciding whether to re-introduce any cap. */

.hero-slider__track {
  position: relative;
  width: 100%;
  height: 100%;
}

.hero-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 600ms ease;
  pointer-events: none;
  display: block;
}

.hero-slide.is-active {
  opacity: 1;
  pointer-events: auto;
  z-index: 1;
}

.hero-slide__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero-slide__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
}

/* Generic fallback for any --solid placeholder without a per-slide skin */
.hero-slide__media--solid {
  background:
    radial-gradient(circle at 30% 30%, rgba(209, 76, 74, 0.55), transparent 60%),
    linear-gradient(135deg, #4D0027 0%, #871427 55%, #2B0015 100%);
  position: relative;
  overflow: hidden;
}

/* Diagonal torch motif. Positioned per-slide via custom properties on the
   ::after pseudo-element. We use mask-image (NOT background-image) so the
   torch silhouette is cut from the pseudo-element's solid background-color
   — that's the only way to color an external SVG via CSS context. */
.hero-slide__media--solid::after {
  content: '';
  position: absolute;
  width: var(--torch-size, 580px);
  height: var(--torch-size, 580px);
  top: var(--torch-top, auto);
  bottom: var(--torch-bottom, auto);
  left: var(--torch-left, auto);
  right: var(--torch-right, auto);
  transform: rotate(var(--torch-rot, 0deg));
  transform-origin: center;
  background-color: var(--torch-color, rgba(255, 255, 255, 0.12));
  -webkit-mask-image: url("../assets/icons/torch.svg");
          mask-image: url("../assets/icons/torch.svg");
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-size: contain;
          mask-size: contain;
  -webkit-mask-position: center;
          mask-position: center;
  filter: drop-shadow(0 8px 24px rgba(0, 0, 0, 0.4));
  pointer-events: none;
}

/* ============================================
   Slide 2 — Affiliates
   Mesh: bright warm copper blob top-right, teal pop bottom-left,
   crimson glow center, wine deepening at bottom. Colors pushed
   to fully opaque on the mesh so they actually POP over the wine
   base instead of blending into it.
   Torch: top-right corner, rotated +28°, copper-tinted watermark.
   ============================================ */
.hero-slide--affiliates .hero-slide__media--solid {
  background:
    radial-gradient(ellipse 70% 65% at 88% 12%, #E08A3E 0%, rgba(224, 138, 62, 0) 60%),
    radial-gradient(ellipse 55% 50% at 12% 85%, #2C7588 0%, rgba(44, 117, 136, 0) 65%),
    radial-gradient(ellipse 65% 55% at 50% 45%, #A11D33 0%, rgba(161, 29, 51, 0) 75%),
    linear-gradient(140deg, #4D0027 0%, #320019 50%, #1F000F 100%);
}
.hero-slide--affiliates .hero-slide__media--solid::after {
  --torch-top: -80px;
  --torch-right: -60px;
  --torch-size: 620px;
  --torch-rot: 28deg;
  --torch-color: rgba(243, 200, 132, 0.32);   /* warm copper watermark, brighter */
}

/* ============================================
   Slide 3 — News & Highlights
   Mesh: bright coral blob top-left, deep magenta bottom-right,
   crimson glow rising from bottom, wine base. Distinct color
   personality from Affiliates so the rotation reads as variety.
   Torch: bottom-left corner, rotated -22°, coral-tinted watermark.
   ============================================ */
.hero-slide--news .hero-slide__media--solid {
  background:
    radial-gradient(ellipse 70% 60% at 8% 18%, #E2655F 0%, rgba(226, 101, 95, 0) 60%),
    radial-gradient(ellipse 60% 55% at 92% 78%, #5A1166 0%, rgba(90, 17, 102, 0) 65%),
    radial-gradient(ellipse 80% 50% at 50% 100%, #A11D33 0%, rgba(161, 29, 51, 0) 75%),
    linear-gradient(160deg, #4D0027 0%, #320019 50%, #1F000F 100%);
}
.hero-slide--news .hero-slide__media--solid::after {
  --torch-bottom: -100px;
  --torch-left: -80px;
  --torch-size: 640px;
  --torch-rot: -22deg;
  --torch-color: rgba(248, 168, 162, 0.32);   /* warm coral watermark, brighter */
}

/* Lighter overlay specifically for solid (gradient) slides — the dark
   wine gradient over the heavy default overlay was burying the mesh.
   Solid slides need their colors to read; text legibility is preserved
   by the still-present bottom dim. */
.hero-slide--placeholder .hero-slide__overlay {
  background: linear-gradient(180deg,
    rgba(43, 0, 21, 0) 0%,
    rgba(43, 0, 21, 0) 35%,
    rgba(43, 0, 21, 0.25) 55%,
    rgba(43, 0, 21, 0.55) 75%,
    rgba(43, 0, 21, 0.72) 100%);
}

/* Per-slide CTA tuning — both stay in the crimson palette so the
   buttons read as a Region IX system, not slide-specific accents. */
.hero-slide--affiliates .hero-slide__cta,
.hero-slide--news .hero-slide__cta {
  background: var(--crimson-400);
  border-color: var(--crimson-400);
}
.hero-slide--affiliates .hero-slide__cta:hover,
.hero-slide--news .hero-slide__cta:hover {
  background: var(--crimson-500);
  border-color: var(--crimson-500);
}

.hero-slide__overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* Wine-tinted overlay — softer than pure black, still legible on bright backgrounds.
     Uses wine-850 #2B0015 = rgb(43, 0, 21) at varying transparency. */
  background:
    linear-gradient(180deg,
      rgba(43, 0, 21, 0) 0%,
      rgba(43, 0, 21, 0.08) 25%,
      rgba(43, 0, 21, 0.45) 45%,
      rgba(43, 0, 21, 0.78) 60%,
      rgba(43, 0, 21, 0.9) 80%,
      rgba(43, 0, 21, 0.92) 100%);
  pointer-events: none;
}

.hero-slide__content {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  padding: 32px 48px 36px;
  color: #fff;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
}

.hero-slide__text {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 640px;
  flex: 1 1 auto;
}

.hero-slide__cta-col {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
}

.hero-slide__eyebrow {
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--tan-100, #f3e5d0);
  opacity: 0.9;
  font-weight: 600;
}

.hero-slide__title {
  font-family: var(--font-serif);
  font-size: clamp(24px, 2.6vw, 36px);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: #fff;
  margin: 0;
  text-wrap: balance;
}

.hero-slide__meta {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.82);
  font-weight: 500;
  letter-spacing: 0.02em;
}

.hero-slide__meta-dot {
  opacity: 0.55;
}

/* Per-slide warm color variation on the meta (third) line.
   Slide order: 1=Convention, 2=News, 3=Affiliates. */
.hero-slide:nth-child(1) .hero-slide__meta { color: var(--tan-100); }      /* cream — convention */
.hero-slide:nth-child(2) .hero-slide__meta { color: var(--tan-200); }      /* warm gold — news (over crimson bg) */
.hero-slide:nth-child(3) .hero-slide__meta { color: var(--tan-300); }      /* light golden — affiliates (warmer than the cream eyebrow) */

.hero-slide__cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 22px;
  background: var(--crimson-400);
  border: 1px solid var(--crimson-400);
  border-radius: 999px;
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-decoration: none;
  width: max-content;
  white-space: nowrap;
  transition: background 200ms ease, border-color 200ms ease, transform 200ms ease;
}

/* Whole-slide clickable — JS-driven click handler in main.js navigates
   to the slide's data-slide-href when any non-control element is clicked.
   Cursor signals interactivity across the entire slide area. */
.hero-slide {
  cursor: pointer;
}

.hero-slide__cta:hover {
  background: var(--crimson-500);
  border-color: var(--crimson-500);
  transform: translateY(-1px);
}

.hero-slide__cta svg {
  width: 9px;
  height: 13px;
}

/* Controls — progress bars + arrows */
.hero-slider__controls {
  position: absolute;
  left: 56px;
  right: 56px;
  top: 32px;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  pointer-events: none;
}

.hero-slider__progress {
  display: flex;
  gap: 8px;
  flex: 0 1 320px;
  pointer-events: auto;
}

.hero-slider__bar {
  appearance: none;
  background: rgba(255, 255, 255, 0.22);
  border: none;
  height: 3px;
  flex: 1;
  border-radius: 999px;
  padding: 0;
  overflow: hidden;
  cursor: pointer;
  position: relative;
}

.hero-slider__bar-fill {
  display: block;
  width: 0%;
  height: 100%;
  background: #fff;
  transform-origin: left center;
}

/* Active bar fills via animation so it can be paused via play-state.
   Duration is driven by --bar-duration set on the slider per-slide by JS. */
.hero-slider__bar.is-active .hero-slider__bar-fill {
  width: 100%;
  animation: hero-bar-fill var(--bar-duration, 7000ms) linear forwards;
  animation-play-state: running;
}

/* Pause the active bar when the slider is hovered or off-screen */
.hero-slider.is-paused .hero-slider__bar.is-active .hero-slider__bar-fill {
  animation-play-state: paused;
}

.hero-slider__bar.is-complete .hero-slider__bar-fill {
  width: 100%;
}

@keyframes hero-bar-fill {
  from { width: 0%; }
  to   { width: 100%; }
}

.hero-slider__arrows {
  display: flex;
  gap: 8px;
  pointer-events: auto;
}

.hero-slider__arrow {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(87, 10, 23, 0.55);          /* crimson-800 tinted glass — pops on bright images */
  border: 1px solid rgba(245, 229, 201, 0.35); /* warm tan border for definition */
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
  transition: background 200ms ease, border-color 200ms ease, color 200ms ease, box-shadow 200ms ease;
  padding: 0;
}

.hero-slider__arrow:hover {
  background: var(--crimson-400);
  border-color: var(--crimson-400);
  color: #fff;
  box-shadow: 0 4px 14px rgba(209, 76, 74, 0.45);
}

@media (max-width: 900px) {
  .hero-slider-wrap {
    margin-top: -140px;
    margin-bottom: -140px;
    padding-inline: var(--space-4);
  }
  .hero-slider__viewport {
    aspect-ratio: 4 / 5;
  }
  .hero-slide__content {
    padding: 22px 22px 26px;
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }
  .hero-slider__controls {
    left: 20px;
    right: 20px;
    top: 18px;
  }
  .hero-slider__progress { flex: 0 1 180px; }
  .hero-slider__arrow { width: 32px; height: 32px; }
}


/* ============================================================
   ABOUT PAGE — Editorial layout
   ============================================================
   Design intent: this page is the most editorial surface on the site.
   Typography-led, calmer than home, no ambient motion. Five acts:
   Statement → Lineage → Today's Region → Director → Pillars.

   Reuses sitewide patterns: smooth scroll, data-reveal, .reveal-text
   word reveal. Introduces new BQ patterns: vertical-edge wordmark,
   two-tone pull quote with emphasis, editorial timeline, gradient
   placeholder system.
   ============================================ */

.about-page {
  background: var(--bg-page);
  color: var(--text-primary);
  overflow-x: clip;  /* contain vertical wordmark + bg-torch overflow */
}

/* Editorial container — wider than the home article width, allows
   the page to use the desktop real estate Diallo specifically called out.
   Falls back gracefully on smaller viewports. */
.about-container {
  max-width: 1240px;
  margin-inline: auto;
  padding-inline: var(--space-8);
}
@media (max-width: 900px) {
  .about-container { padding-inline: var(--space-5); }
}

/* --------------------------------------------------------------
   Vertical-edge wordmark — NEW PATTERN
   Brand watermark on the left edge of long sections. Editorial.
   -------------------------------------------------------------- */
/* v19: position: sticky + writing-mode for vertical text. The
   wordmark pins at top: 120px (below floating header + breathing room)
   as the user scrolls through the section, then releases when the
   section's bottom edge catches it. writing-mode: vertical-rl handles
   the rotation natively (no transform hacks, no clipping issues). */
.vertical-wordmark {
  position: sticky;
  top: 120px;
  margin-left: var(--space-4);
  writing-mode: vertical-rl;
  text-orientation: mixed;
  float: left;                              /* take it out of the main content flow */
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: rgba(245, 229, 201, 0.28);
  font-weight: 600;
  white-space: nowrap;
  pointer-events: none;
  z-index: 1;
}

/* v17: Track-in entrance — wordmark starts at much wider letter-spacing
   and zero opacity, then COMPRESSES into its resting tracking + fades
   in. v18: slower so the letters really glide in. JS holds the reveal
   back to fire AFTER the map's entrance has completed. */
[data-vertical-reveal] {
  opacity: 0;
  letter-spacing: 1.4em;
  transition:
    opacity 2200ms cubic-bezier(0.22, 1, 0.36, 1),
    letter-spacing 2600ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: letter-spacing, opacity;
}
[data-vertical-reveal].is-revealed {
  opacity: 1;
  letter-spacing: 0.42em;
}
@media (prefers-reduced-motion: reduce) {
  [data-vertical-reveal] {
    opacity: 1;
    letter-spacing: 0.42em;
    transition: none;
  }
}

@media (max-width: 1100px) {
  .vertical-wordmark { display: none; }
}

/* --------------------------------------------------------------
   Section eyebrow + section title — shared editorial type rhythm
   -------------------------------------------------------------- */
.about-section-eyebrow {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--crimson-400);
  font-weight: 600;
  margin-bottom: var(--space-5);
}
.about-section-title {
  font-family: var(--font-serif);
  font-size: clamp(32px, 3.6vw, 52px);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin: 0;
  max-width: 880px;
}

/* --------------------------------------------------------------
   ACT 1 — The Statement (hero)
   Typography-led. No image, no slider, no torch. Quiet.
   -------------------------------------------------------------- */
.about-hero {
  position: relative;
  padding: clamp(140px, 18vh, 210px) 0 clamp(120px, 14vh, 170px);  /* v15: +10 top */
  min-height: 60vh;
  display: flex;
  align-items: center;
  overflow: hidden;
}
.about-hero__inner {
  position: relative;
  z-index: 1;
}
/* v15: -25% size with wider tracking. Reads as a section label, not
   a heading competitor. */
.about-hero__eyebrow.about-hero__eyebrow--large {
  font-size: clamp(17px, 2vw, 27px);              /* v15: -25% from clamp(22–36) */
  letter-spacing: 0.30em;                          /* v15: wider tracking (was 0.20em) */
  font-weight: 700;
  color: var(--tan-200);
  margin-bottom: var(--space-4);
}

/* Hero torch — mirror of .home-about__bg-icon but positioned for the
   about hero: offset to the right, oversized so the top flame and most
   of the body remain visible, low-contrast color against the crimson
   bg (a deeper, slightly desaturated crimson) so it reads as texture,
   not a foreground icon. Same per-path trace + fill animation. */
.about-hero__torch {
  position: absolute;
  top: 50%;
  right: 2%;                                       /* v12: moved left (was -10%) */
  transform: translateY(-30%);                    /* v12: moved up (was -12%) */
  height: 165%;                                    /* v12: slight decrease (was 175%) */
  width: auto;
  /* Color: crimson-600 (#871427) — brighter than 775 so the torch
     reads as a defined shape against the crimson hero bg rather than
     dissolving into it. Still tone-on-tone via opacity. Drop-shadow
     lifts the silhouette edge for soft depth. */
  fill: rgba(135, 20, 39, 0.55);
  stroke: rgba(135, 20, 39, 0.55);
  stroke-width: 0.35;
  opacity: 1;
  pointer-events: none;
  z-index: 0;
  filter: drop-shadow(0 0 36px rgba(20, 0, 5, 0.55));
}
.about-hero__torch path {
  fill-opacity: 0;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}
.about-hero__torch.is-revealed path {
  /* v11: ~20% trim across the board — trace, fill, and fill offset
     all pulled down so the torch starts sooner and develops quicker
     while keeping the same per-path cascade feel. */
  animation:
    torch-trace 2500ms cubic-bezier(0.65, 0, 0.35, 1) forwards,
    torch-fill 2200ms cubic-bezier(0.22, 1, 0.36, 1) 2000ms forwards;
}
/* Same per-path top-down stagger as the home torch — v11: 320ms steps
   between primary paths, 160ms between the closing accents. */
.about-hero__torch.is-revealed path:nth-of-type(3) { animation-delay: 0ms,    2000ms; }
.about-hero__torch.is-revealed path:nth-of-type(5) { animation-delay: 320ms,  2320ms; }
.about-hero__torch.is-revealed path:nth-of-type(8) { animation-delay: 640ms,  2640ms; }
.about-hero__torch.is-revealed path:nth-of-type(4) { animation-delay: 960ms,  2960ms; }
.about-hero__torch.is-revealed path:nth-of-type(6) { animation-delay: 1280ms, 3280ms; }
.about-hero__torch.is-revealed path:nth-of-type(7) { animation-delay: 1600ms, 3600ms; }
.about-hero__torch.is-revealed path:nth-of-type(1) { animation-delay: 1760ms, 3760ms; }
.about-hero__torch.is-revealed path:nth-of-type(2) { animation-delay: 1920ms, 3920ms; }

@media (max-width: 900px) {
  .about-hero__torch { right: -25%; height: 110%; opacity: 0.85; }
}

/* Crimson-side dark variant — deeper red than the standard wine page bg.
   Eventually this slot will host an artistic hero image with a crimson
   color overlay; for now we render a layered crimson gradient so the
   color story reads complete on its own. */
.about-hero.about-hero--crimson {
  background:
    radial-gradient(ellipse at 75% 25%, rgba(135, 20, 39, 0.55), transparent 55%),
    radial-gradient(ellipse at 25% 85%, rgba(87, 10, 23, 0.65), transparent 55%),
    linear-gradient(160deg, var(--crimson-800) 0%, var(--crimson-700) 50%, #3F0816 100%);
}
.about-hero.about-hero--crimson::after {
  /* Subtle film grain so the flat color reads more cinematic. */
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.45 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  opacity: 0.10;
  mix-blend-mode: overlay;
  pointer-events: none;
}
.about-hero__inner {
  position: relative;
  z-index: 1;
  width: 100%;
}
.about-hero__eyebrow {
  font-family: var(--font-sans);
  font-size: 13px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--crimson-400);
  font-weight: 600;
  margin-bottom: var(--space-6);
  opacity: 0.92;
}
.about-hero__title {
  font-family: var(--font-serif);
  font-size: clamp(44px, 6vw, 84px);
  line-height: 1.05;
  font-weight: 600;
  letter-spacing: -0.018em;
  max-width: 1100px;
  margin: 0;
  color: var(--text-primary);
  text-wrap: balance;
}
.about-hero__title .accent {
  color: var(--crimson-400);
  font-style: italic;
  font-weight: 600;
}
/* About hero title — mobile bump per Diallo 2026-05-31. Base clamp
   pins at 44px on mobile (~393px viewport); bump to 48px. */
@media (max-width: 768px) {
  .about-hero__title { font-size: 48px; }
}
/* Soft wash on the hero background — barely there. Lifts the
   typography off the page without going decorative. */
.about-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 70% 80% at 15% 50%, rgba(161, 29, 51, 0.10), transparent 60%),
    radial-gradient(ellipse 60% 70% at 85% 30%, rgba(209, 76, 74, 0.06), transparent 60%);
  z-index: 0;
}

/* --------------------------------------------------------------
   ACT 3 — Today's Region
   Two-column: prose with inline stats | gradient placeholder visual
   Then the affiliates grid as a full-bleed band below.
   -------------------------------------------------------------- */
.about-region {
  position: relative;
  padding-block: clamp(80px, 12vh, 140px);
  /* Dark wine palette, not black. Sits deeper than the footer (which
     starts at wine-800) so the red map still pops, but everything stays
     in the brand family. Warm crimson radial accent behind the map
     area on the right adds texture without shifting the overall color
     into gray/black territory. */
  background:
    radial-gradient(80% 60% at 70% 50%, rgba(135, 20, 39, 0.12), transparent 70%),
    linear-gradient(180deg, var(--wine-850) 0%, #240012 50%, #1A0009 100%);
}
.about-region__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(40px, 6vw, 80px);
  align-items: center;
}
.about-region__copy { max-width: 560px; }
/* Force the section title onto a single line so "Where the Work Happens"
   doesn't break across two lines, and we never end up with a single
   orphan word on its own line. Mobile-only fallback allows wrap. */
.about-region__copy .about-section-title {
  white-space: nowrap;
  max-width: none;
}
@media (max-width: 720px) {
  .about-region__copy .about-section-title { white-space: normal; }
}
.about-region__body {
  font-size: var(--type-body-lg);
  line-height: 1.65;
  color: var(--tan-50);                  /* v15: warm cream instead of cool grey */
  margin: var(--space-6) 0 var(--space-8);
}
/* Consecutive body paragraphs: tighten the gap so it reads as a single
   paragraph block, not two disconnected blobs. */
.about-region__body + .about-region__body { margin-top: 0; }
/* Emphasis run inside body — used on the verbatim mission phrasing
   ("advances initiatives that promote justice, equity, and excellence
   in the legal profession"). Italic alone reads weak in this scale, so
   we warm it with tan to mark the quoted core. */
.about-region__body em {
  font-style: italic;
  color: var(--tan-200);
  font-weight: 500;
}
.about-region__cta {
  margin-top: var(--space-2);
}
.about-region__stat-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-8) var(--space-10);
  margin-top: clamp(60px, 8vh, 100px);
  padding-top: var(--space-8);
  border-top: 1px solid var(--wine-700);
}
.about-region__stat-num {
  font-family: var(--font-serif);
  font-size: clamp(40px, 4.5vw, 56px);
  font-weight: 600;
  color: var(--tan-50);
  line-height: 1;
  letter-spacing: 0.04em;
  display: block;
}

/* v17: Stats animate in MUCH slower than the default data-reveal so
   the cascade is clearly visible. Overrides the base reveal animation
   duration just for elements inside the stat row. Combined with the
   wider delay spread (50ms → 1100ms across 4 cells), the whole stat
   block takes ~2.7s to settle. */
.about-region__stat-row [data-reveal] {
  animation-duration: 1600ms !important;
}
.about-region__stat-label {
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--crimson-400);                /* v13: was tan-200 (swapped) */
  margin-top: var(--space-3);
  display: block;
  line-height: 1.3;
}

/* Visual slot in the right column — hosts the inline .region-map (SVG)
   copied from the homepage At-a-Glance section. No gradient placeholder
   anymore; the map and its caption pill ARE the visual. */
.about-region__visual {
  position: relative;
}
.about-region__visual .region-map {
  width: 100%;
  max-width: 520px;
  margin-inline: auto;
}
.about-region__visual .region-map__svg {
  width: 100%;
  height: auto;
  display: block;
}
.about-region__visual .region-map__caption {
  text-align: center;
  margin-top: var(--space-5);
}
@media (max-width: 900px) {
  .about-region__grid { grid-template-columns: 1fr; gap: var(--space-10); }
  .about-region__stat-row { grid-template-columns: 1fr 1fr; gap: var(--space-7) var(--space-8); }
  .about-region__visual .region-map { max-width: 420px; }
}

/* --------------------------------------------------------------
   Pull-quote treatment — v5 with rotating badge column.

   Two-column on light bg:
     LEFT  — rotating ring badge (same SVG + rotate animation as the
             footer's badge), sized large as a visual anchor. Hover
             triggers the same color swap pattern.
     RIGHT — mission text + emphasis on the verb triplet.

   On narrow viewports the columns stack with the badge on top.
   -------------------------------------------------------------- */
.about-pull-quote {
  padding-block: clamp(50px, 8vh, 110px) clamp(70px, 11vh, 140px);   /* trimmed top to compensate for shorter hero */
  position: relative;
}
.about-pull-quote__inner {
  max-width: 1440px;            /* widened so the mission lands on 6 lines, not 7 */
  margin-inline: auto;
  padding-inline: clamp(var(--space-8), 4vw, var(--space-16));
}
.about-pull-quote--with-badge .about-pull-quote__inner {
  display: grid;
  grid-template-columns: minmax(260px, 0.55fr) 1.45fr;   /* badge slimmer, text wider */
  gap: clamp(40px, 6vw, 110px);
  align-items: center;
}
.about-pull-quote--with-badge .about-pull-quote__text-col {
  /* Anchor the text column with no max-width override — it gets the
     full right-column space. */
}

/* Badge wrapper — v12 isolates the data-reveal="scale-down" animation
   on this outer div, so the inner <a> can own the hover transform
   without the two fighting on the same CSS property. (The footer
   uses the same wrapper-vs-link split.) */
.about-pull-quote__badge-wrap {
  display: block;
  width: 100%;
  max-width: clamp(240px, 28vw, 380px);
  margin-inline: auto;
}

/* Badge — mirrors the footer badge's structure but sized larger and
   re-colored for a LIGHT background. Same rotation, same hover scale. */
.about-pull-quote__badge {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  margin-inline: auto;
  transition: transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
  transform-origin: center center;
  cursor: pointer;
}
.about-pull-quote__badge--link { text-decoration: none; }
.about-pull-quote__badge:hover { transform: scale(1.06); }

.about-pull-quote__badge svg.ring {
  width: 100%;
  height: 100%;
  animation: spin-aboutquote-badge 28s linear infinite;
}
.about-pull-quote__badge svg.ring text {
  /* On light bg the ring text wants a deeper wine tone; on hover it
     shifts toward crimson to mirror the footer's warm-amber shift. */
  fill: var(--wine-700);
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  transition: fill 700ms cubic-bezier(0.22, 1, 0.36, 1);
}
.about-pull-quote__badge:hover svg.ring text {
  fill: var(--crimson-500);
}

.about-pull-quote__badge-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  pointer-events: none;
}
/* Badge typography — mirrors the FOOTER badge proportions: IX is the
   visual anchor, REGION reads as the eyebrow above it. Just scaled up
   for the about page's larger badge. The footer ratio is ~11:48
   (REGION:IX); we keep that same ratio. */
.about-pull-quote__badge-center .region {
  font-family: var(--font-sans);
  font-size: clamp(17px, 1.7vw, 24px);     /* bumped up — larger than v7 */
  font-weight: 800;                          /* bolder than v7's 600 */
  letter-spacing: 0.20em;
  text-transform: uppercase;
  color: var(--crimson-500);
  line-height: 1;
  transition: color 700ms cubic-bezier(0.22, 1, 0.36, 1);
}
.about-pull-quote__badge-center .ix {
  font-family: var(--font-serif);
  font-size: clamp(56px, 7vw, 96px);
  font-weight: 600;
  color: var(--wine-800);
  line-height: 1;
  margin-top: var(--space-3);
  transition: color 700ms cubic-bezier(0.22, 1, 0.36, 1);
}
/* Hover color swap — REGION shifts to deep wine, IX warms to crimson. */
.about-pull-quote__badge:hover .about-pull-quote__badge-center .region { color: var(--wine-800); }
.about-pull-quote__badge:hover .about-pull-quote__badge-center .ix     { color: var(--crimson-500); }

@keyframes spin-aboutquote-badge { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .about-pull-quote__badge svg.ring { animation: none; }
  .about-pull-quote__badge { transition: none; }
  .about-pull-quote__badge:hover { transform: none; }
}

@media (max-width: 880px) {
  .about-pull-quote--with-badge .about-pull-quote__inner {
    grid-template-columns: 1fr;
    gap: var(--space-10);
  }
  .about-pull-quote__badge { width: 240px; }
}
.about-pull-quote__text {
  font-family: var(--font-serif);
  font-size: clamp(28px, 3.8vw, 52px);             /* v13: reverted from v12 bump (size change wasn't requested) */
  line-height: 1.22;
  font-weight: 500;                                 /* v13: reverted to 500 */
  color: var(--text-primary);
  letter-spacing: -0.01em;
  margin: 0;
  text-wrap: balance;
}
.about-pull-quote__emphasis {
  color: var(--crimson-400);
  font-style: italic;
}
.about-pull-quote__attribution {
  margin-top: var(--space-8);
  font-family: var(--font-sans);
  font-size: clamp(14px, 1.2vw, 18px);     /* v13: nudged up */
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--grey-600);
  font-weight: 500;
}
/* v13: Switch label to Playfair italic 800 — Inter only goes to 700
   self-hosted, so for the heavy/thick feel Diallo wants we use the
   serif which has 800 available. Italic serif on a sans-serif eyebrow
   line creates a deliberate visual hit on the "Mission" word. */
.about-pull-quote__attribution-label {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 800;
  text-transform: none;
  letter-spacing: 0;
  font-size: 1.4em;                          /* relative to the parent attribution */
  color: var(--crimson-400);
  margin-right: 4px;
}

/* --------------------------------------------------------------
   ACT 4 — The Director (restrained — single beat, link out to Leadership)
   -------------------------------------------------------------- */
.about-director {
  padding-block: clamp(80px, 12vh, 140px);
  position: relative;
  background: var(--wine-850);
}
.about-director__inner {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: var(--space-12);
  align-items: center;
}
/* Portrait gradient — radial focus suggesting subject in frame */
.about-director__portrait {
  aspect-ratio: 4 / 5;
  max-height: 600px;
  border-radius: var(--radius-lg);
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 35%, rgba(209, 76, 74, 0.45), transparent 50%),
    linear-gradient(160deg, var(--wine-700) 0%, var(--wine-800) 50%, #1a000c 100%);
  box-shadow:
    0 20px 50px -20px rgba(0, 0, 0, 0.7),
    0 0 0 1px rgba(245, 229, 201, 0.08);
}
.about-director__portrait::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.6 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  opacity: 0.10;
  mix-blend-mode: overlay;
}
.about-director__portrait-label {
  position: absolute;
  bottom: var(--space-5);
  left: var(--space-5);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(245, 229, 201, 0.45);
  font-weight: 600;
  z-index: 1;
}
.about-director__content { max-width: 580px; }
.about-director__quote {
  font-family: var(--font-serif);
  font-size: clamp(22px, 2.4vw, 30px);
  line-height: 1.35;
  font-weight: 500;
  font-style: italic;
  color: var(--text-primary);
  margin: 0;
}
.about-director__quote-mark {
  display: block;
  font-size: 128px;                          /* v20: doubled from 64px */
  line-height: 0.5;
  color: var(--crimson-400);
  margin-bottom: var(--space-6);
  font-family: var(--font-serif);
}
.about-director__attribution {
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid rgba(245, 229, 201, 0.15);
}
.about-director__name {
  font-family: var(--font-serif);
  font-size: 22px;
  font-weight: 600;
  margin: 0 0 var(--space-1);
}
.about-director__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-8);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--crimson-400);
  text-decoration: none;
  transition: color 300ms cubic-bezier(0.22, 1, 0.36, 1), gap 300ms cubic-bezier(0.22, 1, 0.36, 1);
}
.about-director__cta:hover { color: #FFFFFF; gap: var(--space-4); }
.about-director__cta svg { width: 16px; height: 12px; }
@media (max-width: 900px) {
  .about-director__inner { grid-template-columns: 1fr; gap: var(--space-10); }
  .about-director__portrait { aspect-ratio: 4/3; max-height: none; }
}

/* --------------------------------------------------------------
   ACT 5 — Three Pillars (cards, not tabs — full disclosure)
   -------------------------------------------------------------- */
.about-pillars {
  padding-block: clamp(70px, 7vh, 90px) clamp(80px, 12vh, 140px);   /* v12: +20 top again (was 50–70) */
  position: relative;
}
.about-pillars__header {
  text-align: center;
  margin-bottom: clamp(48px, 6vh, 72px);   /* tightened — was 80–130px, felt too airy */
  max-width: 960px;
  margin-inline: auto;
}
/* Dual-line title — NEW FONT COMBO (v6):
   PRIMARY ("What We Do") — Inter ExtraBold uppercase, tracked. A
   display SANS treatment instead of the previous double-serif, so the
   primary and secondary read as different voices.
   SECONDARY ("Three Through-Lines of the Work") — Playfair italic,
   serif accent, smaller. The sans → serif handoff is the visual
   counterpoint. */
.about-pillars__title {
  margin: 0;
  text-align: center;
  text-wrap: balance;
}
.about-pillars__title-primary {
  display: block;
  font-family: var(--font-serif);
  font-size: clamp(30px, 3.8vw, 54px);              /* v10: smaller again */
  font-weight: 600;
  text-transform: none;                              /* Title Case */
  letter-spacing: -0.012em;
  line-height: 1.05;
  color: var(--crimson-400);                         /* v10: lighter — was crimson-500 */
}
.about-pillars__title-secondary {
  display: block;
  margin-top: var(--space-5);
  font-family: var(--font-sans);
  font-size: clamp(18px, 1.7vw, 26px);
  line-height: 1.3;
  font-weight: 700;                                  /* v11: 700 (Inter weight nearest to Diallo's 670) */
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--crimson-600);
  font-style: normal;
}
/* About v14 — back to 3-column layout (alternating-row variant from
   v7–v13 is retired). Each pillar is now a vertical stack: icon on
   top, title, body, accent line. Thin low-contrast vertical
   separators between the three columns visually divide them without
   adding hard chrome. */
.about-pillars__list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(40px, 4.5vw, 88px);
}
/* Full-width section wrapper — wider than the standard container so
   the three columns have real breathing room. Scaled edge padding. */
.about-pillars .about-container {
  max-width: 1440px;
  padding-inline: clamp(var(--space-8), 5vw, 96px);
}
.about-pillar {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  position: relative;
}
/* Vertical separator between columns — sits in the gutter to the
   RIGHT of each pillar except the last. 1px at ~10% wine alpha so
   it reads as a structural beat without competing with the content. */
.about-pillar:not(:last-child)::before {
  content: '';
  position: absolute;
  top: 8%;
  bottom: 8%;
  right: calc(clamp(40px, 4.5vw, 88px) / -2);
  width: 1px;
  background: rgba(50, 0, 25, 0.10);
}
@media (max-width: 900px) {
  .about-pillars__list { grid-template-columns: 1fr; gap: clamp(40px, 6vh, 72px); }
  .about-pillar:not(:last-child)::before { display: none; }
}
.about-pillar__media {
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-lg);
  position: relative;
  overflow: hidden;
  box-shadow:
    0 16px 40px -14px rgba(0, 0, 0, 0.4),
    0 0 0 1px rgba(50, 0, 25, 0.08);
}

/* v13: New SVG line-art icon variant. Drops the gradient card chrome
   in favor of a clean stroke icon centered in a transparent slot.
   Placeholder until real artwork lands. Hover/scroll-driven rotation
   gives a subtle play hook.

   NOTE: must use a 3-class selector (parent variant + media + media--icon)
   to beat the per-pillar gradient rules (.about-pillar--pipeline
   .about-pillar__media) which are also 2 classes and appear later. */
.about-pillar--pipeline .about-pillar__media.about-pillar__media--icon,
.about-pillar--judicial .about-pillar__media.about-pillar__media--icon,
.about-pillar--community .about-pillar__media.about-pillar__media--icon {
  background: transparent;
  border-radius: 0;
  box-shadow: none;
}
.about-pillar--pipeline .about-pillar__media.about-pillar__media--icon::after,
.about-pillar--judicial .about-pillar__media.about-pillar__media--icon::after,
.about-pillar--community .about-pillar__media.about-pillar__media--icon::after {
  display: none;
}
/* v14 — icon variant in vertical-stack 3-col layout. Icon sits at
   the top of the column, smaller than before, left-aligned. Numeral
   slides up next to the icon as a small "01/02/03" label. */
.about-pillar__media--icon {
  aspect-ratio: auto;
  height: auto;
  min-height: 0;
  width: auto;
  overflow: visible;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 0;
  margin-bottom: var(--space-7);
}
.about-pillar__media--icon .about-pillar__numeral {
  position: static;
  font-family: var(--font-serif);
  /* v26 per Diallo: bumped a touch larger and dialed to tan-100 — the
     numerals still sit as quiet anchors but now read with a bit more
     warmth and presence above the grey background. */
  font-size: clamp(18px, 1.4vw, 22px);
  color: var(--tan-100);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.08em;
  line-height: 1;
  color: rgba(135, 20, 39, 0.55);
  font-weight: 600;
  letter-spacing: 0.04em;
}
/* Each pillar has its own gradient identity */
.about-pillar--pipeline .about-pillar__media {
  background:
    radial-gradient(circle at 30% 30%, rgba(212, 150, 88, 0.35), transparent 55%),
    linear-gradient(135deg, var(--crimson-700) 0%, var(--wine-800) 100%);
}
.about-pillar--judicial .about-pillar__media {
  background:
    radial-gradient(circle at 70% 30%, rgba(209, 76, 74, 0.35), transparent 55%),
    linear-gradient(135deg, var(--wine-800) 0%, var(--crimson-800) 100%);
}
.about-pillar--community .about-pillar__media {
  background:
    radial-gradient(circle at 50% 70%, rgba(212, 150, 88, 0.30), transparent 60%),
    linear-gradient(160deg, var(--crimson-600) 0%, var(--wine-850) 100%);
}
.about-pillar__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  opacity: 0.10;
  mix-blend-mode: overlay;
  pointer-events: none;
}
.about-pillar__numeral {
  position: absolute;
  bottom: 18px;
  left: 24px;
  font-family: var(--font-serif);
  font-size: 96px;
  font-weight: 600;
  line-height: 0.8;
  color: rgba(245, 229, 201, 0.18);
  pointer-events: none;
  z-index: 1;
}
.about-pillar__title {
  font-family: var(--font-serif);
  font-size: clamp(24px, 2.4vw, 32px);     /* v14: column-friendly (was 32–48 for alt-rows) */
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin: 0;
  color: var(--text-primary);
}
.about-pillar__body {
  font-size: clamp(15px, 1.2vw, 17px);     /* v14: column-friendly */
  line-height: 1.6;
  color: var(--text-secondary);
  margin: var(--space-4) 0 0;
  max-width: none;                          /* v14: fill the column */
}

/* --------------------------------------------------------------
   Closing CTA — pulls toward engagement
   -------------------------------------------------------------- */
.about-cta {
  padding-block: 30px;                         /* v20 per Diallo: 30 top, 30 bottom */
  text-align: center;
  background: linear-gradient(180deg, var(--bg-page) 0%, var(--wine-850) 100%);
  position: relative;
}
/* v21 — Leadership + Affiliates explore-the-site CTAs use 50 top /
   60 bottom padding per Diallo. Other instances of .about-cta keep
   the 30/30. */
.about-cta.about-cta--roomy {
  padding-block: 50px 60px;
}
.about-cta__title {
  font-family: var(--font-serif);
  font-size: clamp(30px, 3.8vw, 48px);          /* slight scale-down so it stays one line */
  font-weight: 600;
  line-height: 1.12;
  margin: 0 auto;
  max-width: 1100px;                            /* widened from 720 — fits one-line titles */
  letter-spacing: -0.01em;
}
/* v10: CTA "Become a Sponsor" and "Get in Touch" had transparent
   bases that read as clear on the crimson CTA gradient. Give each
   a different dark fill so the trio reads as a graduated set:
     Pay Dues       → crimson-500 (default btn-primary--bold, brightest)
     Become Sponsor → crimson-700 (per Diallo's suggestion)
     Get in Touch   → wine-800   (deepest, different family)
   Inner circle colors are PRESERVED (each button keeps the circle
   color its base variant defines), only the button surface changes. */
.about-cta .btn-primary--sponsor {
  background: var(--crimson-700);
}
.about-cta a.btn-primary:not(.btn-primary--bold):not(.btn-primary--sponsor):not(.btn-primary--solid) {
  background: var(--wine-800);
  border-color: var(--wine-700);
}
.about-cta__lede {
  font-size: var(--type-body-lg);
  color: var(--text-secondary);
  margin: var(--space-3) auto 0;               /* tighter top gap matching 30/30 padding */
  max-width: 1000px;                            /* widened from 560 — fits one-line subtitles */
  line-height: 1.55;
}
.about-cta__buttons {
  display: flex;
  gap: var(--space-4);
  justify-content: center;
  flex-wrap: wrap;
  margin-top: var(--space-6);                  /* tighter button gap matching 30/30 padding */
}

/* --------------------------------------------------------------
   Animation choreography — calmer than home.
   Reveals use the global [data-reveal] pattern. Per-element overrides
   below give About a more deliberate, magazine-feature pace.
   -------------------------------------------------------------- */
.about-page [data-reveal].is-revealed {
  animation-duration: 1800ms;
}
.about-hero__eyebrow,
.about-hero__title {
  opacity: 0;
  animation: about-hero-rise 2400ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
.about-hero__eyebrow    { animation-delay: 200ms; }
.about-hero__title      { animation-delay: 500ms; }

@keyframes about-hero-rise {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .about-hero__eyebrow,
  .about-hero__title {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }
}

/* --------------------------------------------------------------
   About — light/dark mix (v3)
   The About page alternates dark and light sections to break up
   what would otherwise be a single-tone read. Light sections use
   the warm cream tint already in the token system, with deep wine
   for body type and crimson as the consistent pop.

   Flow:  Hero DARK → Pull-quote LIGHT → Today DARK → Director LIGHT
          → Pillars DARK → CTA LIGHT
   -------------------------------------------------------------- */
.about-section--light {
  background: var(--bg-light-tint);   /* warm cream (tan-25) */
  color: var(--text-on-light);        /* near-black for body type */
}

/* Pull quote on cream — body becomes deep wine, emphasis stays crimson,
   attribution warms to a muted wine instead of tan. */
.about-pull-quote.about-section--light .about-pull-quote__text {
  color: var(--wine-800);
}
.about-pull-quote.about-section--light .about-pull-quote__emphasis {
  color: var(--crimson-500);          /* slightly deeper than -400 on light bg */
}
.about-pull-quote.about-section--light .about-pull-quote__attribution {
  color: var(--crimson-600);
}

/* Director on cream — quote text, name, title all wine-toned.
   Portrait gradient stays dark by design (subject behind frame). */
.about-director.about-section--light .about-director__quote        { color: var(--wine-800); }
.about-director.about-section--light .about-director__name         { color: var(--wine-800); }
.about-director.about-section--light .about-director__attribution  { border-top-color: rgba(50, 0, 25, 0.18); }
.about-director.about-section--light .about-director__cta          { color: var(--crimson-500); }
.about-director.about-section--light .about-director__cta:hover    { color: var(--wine-800); }

/* No dark 1px seam between sections — those flat lines read as a hack
   and conflict with the editorial feel. Sections rely on gradient
   handoff (matching colors at the seam) or background-color contrast
   alone for separation. */

/* Pull quote — bg is WHITE, pairs with What We Do below.
   v16: pulls up over the hero with a rounded top so the section
   reads as a card slipping up over the hero as the page scrolls.
   The hero gets position: relative + z-index 0, this section gets
   z-index 1 and a negative top margin so they overlap. */
.about-pull-quote.about-section--light {
  background: #FFFFFF;
  position: relative;
  z-index: 1;
  margin-top: -32px;
  border-top-left-radius: 32px;
  border-top-right-radius: 32px;
}
.about-hero { z-index: 0; }

/* What We Do (Pillars) — paired light interlude with the pull quote
   above. Gradient flows from white at top (matches pull quote bottom)
   to a warm tan-tint at the bottom (cream), so by the time the eye
   reaches the Today section, the seam transitions back into wine.

   Color philosophy: less wine-800 on light, more crimson/tan accents.
   Pillar titles flipped from wine-800 to crimson-500, secondary
   heading line uses tan-400. */
.about-section--light-grey {
  color: var(--text-on-light);
}
.about-pillars.about-section--light-grey {
  /* White at center (spotlight effect), warm tan at the edges. The
     center sits slightly above middle so the top seam from the pull
     quote section (also white) flows in cleanly, then the warmth
     blooms outward as the eye moves toward the corners. */
  background: radial-gradient(ellipse 130% 110% at 50% 35%, #FFFFFF 0%, var(--tan-50) 70%, var(--tan-100) 100%);
}

/* Director — independent light band lower on the page, white→cream. */
.about-director.about-section--light {
  background: linear-gradient(180deg, #FFFFFF 0%, var(--bg-light-tint) 100%);
}
/* v11: section overrides for title-primary/secondary REMOVED. Base
   rules at .about-pillars__title-primary (crimson-400) and
   __title-secondary (crimson-600, weight set below) now apply. */
.about-pillars.about-section--light-grey .about-pillar__title {
  color: var(--crimson-500);
}
.about-pillars.about-section--light-grey .about-pillar__body {
  color: var(--grey-700);
}
/* Accent line — was a ::after pseudo-element. v11 converts it to a
   real DOM element (.about-pillar__accent) so it can carry its own
   data-reveal animation independent of the body text. */
.about-pillars.about-section--light-grey .about-pillar__accent {
  display: block;
  width: 56px;
  height: 3px;
  background: var(--crimson-400);
  margin-top: var(--space-6);
}

/* CTA on dark — flip from wine to a true crimson red. This is RED
   (not "dark red" wine), which creates clear visual separation from
   the wine-toned footer beneath it and answers Diallo's call for a
   step-darker / crimson option. Closes the page on the brand's most
   active color.

   Note: this rule must appear AFTER the original .about-cta rule
   (declared earlier in this file) so the cascade picks this one. */
.about-cta.about-cta {     /* doubled selector = +1 specificity nudge over the original */
  background: linear-gradient(180deg, var(--crimson-700) 0%, var(--crimson-800) 100%);
}
.about-cta .about-cta__lede { color: var(--tan-200); }


/* ================================================================
   INNER PAGE STYLES — v2 build (2026-05-27)
   Leadership, Affiliates, Contact, Sponsorship, Dues, Convention.
   Built on the design language established on About v10.

   Each page has its own hero treatment (different dark/light/crimson
   variant) so the inner-page set reads as a graduated family rather
   than a single repeated template. Shared utilities (about-section
   --light, btn-primary variants, vertical-wordmark, etc.) carry over.
   ================================================================ */


/* ---------- Shared inner-page hero base ---------- */
.lead-hero,
.aff-hero,
.contact-hero {
  position: relative;
  padding: clamp(100px, 14vh, 170px) 0 clamp(70px, 8vh, 120px);
  display: flex;
  align-items: center;
  overflow: hidden;
  min-height: 50vh;
}
.lead-hero__inner,
.aff-hero__inner,
.contact-hero__inner {
  position: relative;
  z-index: 1;
}
.aff-hero__eyebrow,
.contact-hero__eyebrow {
  font-family: var(--font-sans);
  font-size: clamp(15px, 1.6vw, 22px);
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--crimson-400);
  font-weight: 700;
  margin: 0 0 var(--space-8);
}
.lead-hero__title,
.aff-hero__title,
.contact-hero__title {
  font-family: var(--font-serif);
  font-size: clamp(40px, 5.4vw, 72px);
  line-height: 1.05;
  font-weight: 600;
  letter-spacing: -0.016em;
  margin: 0 0 var(--space-6);
  text-wrap: balance;
  max-width: 980px;
  color: var(--text-primary);
}
.lead-hero__title .accent,
.aff-hero__title .accent,
.contact-hero__title .accent {
  color: var(--crimson-400);
  font-style: italic;
  font-weight: 600;
}
.contact-hero__lede {
  font-family: var(--font-serif);
  font-size: clamp(18px, 1.6vw, 22px);
  line-height: 1.55;
  color: var(--text-secondary);
  max-width: 720px;
  margin: 0;
}

/* On light heroes (contact), invert text colors */
.contact-hero.about-section--light .contact-hero__title { color: var(--wine-800); }
.contact-hero.about-section--light .contact-hero__title .accent { color: var(--crimson-500); }
.contact-hero.about-section--light .contact-hero__lede { color: var(--grey-700); }
.contact-hero.about-section--light .contact-hero__eyebrow { color: var(--crimson-500); }

/* v27 per Diallo: contact section is no longer full-screen. Fixed
   150px top + 150px bottom padding lets the footer surface beneath
   naturally. The transparent header still overlays the section. */
.contact-page-hero {
  position: relative;
  display: flex;
  align-items: center;
  padding: 150px 0;
  overflow: hidden;
  isolation: isolate;
  color: var(--text-on-authority);
}
.contact-page-hero__overlay {
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(ellipse at 25% 35%, rgba(209, 76, 74, 0.40), transparent 55%),
    radial-gradient(ellipse at 80% 80%, rgba(110, 15, 31, 0.50), transparent 60%),
    linear-gradient(160deg, var(--crimson-800) 0%, var(--wine-800) 55%, var(--wine-850) 100%);
}
.contact-page-hero__overlay::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  opacity: 0.10;
  mix-blend-mode: overlay;
  pointer-events: none;
}
.contact-page-hero__inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(32px, 4vh, 56px);
  width: 100%;
  max-width: 820px;
  margin: 0 auto;
}
.contact-page-hero__head {
  text-align: center;
}
.contact-page-hero__eyebrow {
  font-family: var(--font-sans);
  font-size: clamp(13px, 1.2vw, 16px);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--tan-100);
  font-weight: 700;
  margin: 0 0 var(--space-5);
}
.contact-page-hero__title {
  font-family: var(--font-serif);
  font-size: clamp(36px, 5.2vw, 64px);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.014em;
  color: var(--text-on-authority);
  margin: 0;
  text-wrap: balance;
}

/* Form on the hero — white rounded card. v26: 2-column layout per
   Diallo. Rows are explicit (.contact-form__row) for name/email and
   organization/subject pairs. Message and submit span the full width. */
.contact-form--hero {
  background: #FFFCF6;
  border-radius: var(--radius-lg);
  padding: clamp(24px, 3vw, 36px);
  display: grid;
  gap: 12px;
  box-shadow:
    0 30px 80px -28px rgba(0, 0, 0, 0.5),
    0 0 0 1px rgba(180, 140, 90, 0.10);
}
.contact-form__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.contact-form--hero .contact-form__field {
  margin-bottom: 0;
  display: block;
}
.contact-form--hero .contact-form__field--full {
  grid-column: 1 / -1;
}

/* Netlify Forms honeypot — visually hidden but still in the DOM so bots
   fill it. Off-screen, no space taken, hidden from screen readers. */
.contact-form__honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}
.contact-form--hero .contact-form__label {
  display: block;
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--grey-700);
  font-weight: 600;
  margin-bottom: 5px;
}
.contact-form--hero input,
.contact-form--hero select,
.contact-form--hero textarea {
  width: 100%;
  border: 1.5px solid rgba(180, 140, 90, 0.22);
  background: rgba(180, 140, 90, 0.06);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.4;
  color: var(--wine-800);
  outline: none;
  transition: border-color 200ms ease, background-color 200ms ease, box-shadow 200ms ease;
}
.contact-form--hero input:focus,
.contact-form--hero select:focus,
.contact-form--hero textarea:focus {
  border-color: var(--crimson-500);
  background: #FFFCF6;
  box-shadow: 0 0 0 4px rgba(209, 76, 74, 0.10);
}
.contact-form--hero textarea {
  resize: vertical;
  min-height: 110px;
  font-family: var(--font-serif);
  line-height: 1.5;
}
/* v28 per Diallo: same fix as donation submit — let the .btn-primary
   base handle pill geometry, use space-between so the label hugs the
   left and the icon nests cleanly inside the circle on the right. */
.contact-form__submit--full {
  width: 100%;
  justify-content: space-between;
  margin-top: 4px;
}
/* Paper-plane icon visually leans up-right with empty bottom-left
   negative space. Nudge it down-left a hair so it reads optically
   centered inside the circle. */
.contact-form__submit-ic svg {
  transform: translate(-1px, 1px);
}

/* v28 per Diallo: shared required-field indicator. Sits inline next
   to the field label as a small crimson asterisk. Used on the contact
   form and donation form (and any future form). The aria treatment
   keeps it decorative — actual required state is on the input. */
.req {
  color: var(--crimson-500);
  font-weight: 700;
  font-size: 0.95em;
  margin-left: 4px;
  display: inline-block;
  line-height: 1;
  vertical-align: baseline;
}
/* "* Required fields" footnote on contact + donation forms. */
.contact-form__req-note,
.donate-form__req-note {
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--grey-600);
  margin: 16px 0 0;
  letter-spacing: 0.02em;
}
.contact-form__req-note .req,
.donate-form__req-note .req {
  margin-left: 0;
  margin-right: 4px;
}

/* v29 per Diallo: inline validation state for contact + donation
   forms. When a required field is empty on submit, the input gets
   .is-invalid (red outline + soft red wash) and a .field-error note
   appears below it. Both clear on user input. */
input.is-invalid,
textarea.is-invalid,
select.is-invalid {
  border-color: var(--crimson-500) !important;
  background-color: rgba(209, 76, 74, 0.05) !important;
  box-shadow: 0 0 0 3px rgba(209, 76, 74, 0.12) !important;
}
.field-error {
  display: block;
  font-family: var(--font-sans);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--crimson-500);
  margin-top: 6px;
  letter-spacing: 0.02em;
}
/* Top-of-form summary that appears when validation fails. */
.form-error-summary {
  display: none;
  background: rgba(209, 76, 74, 0.08);
  border: 1.5px solid var(--crimson-500);
  border-radius: var(--radius-md);
  padding: 14px 18px;
  margin-bottom: 20px;
  font-family: var(--font-sans);
  font-size: 13px;
  color: var(--crimson-700);
  font-weight: 600;
  letter-spacing: 0.01em;
}
.form-error-summary.is-visible { display: block; }
/* Mobile: collapse the 2-column rows. */
@media (max-width: 640px) {
  .contact-form__row { grid-template-columns: 1fr; }
}

/* NOTE: legacy .contact-hero--crimson + .contact-form-card blocks
   removed — contact page rebuilt as a full-page .contact-page-hero
   per Diallo v26. Shared utility classes that the new form uses
   (.contact-form__optional) live near the new block above. */

.contact-form__optional {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: none;
  color: var(--grey-500);
  font-style: italic;
  font-weight: 600;
  margin-left: 4px;
}

/* Leadership v9 hero — WINE radial gradient (same shape as v4, swapped
   from crimson stops to wine stops). Center brighter (crimson-800
   anchor avoids reading purple), deepens to wine-700/800/850 at the
   edges. Subtle film grain over the top for cinematic feel. This wine
   hero pattern becomes the standard treatment for inner-page heroes
   going forward. Padding stays at 150px top / 75px bottom. */
.lead-hero--minimal {
  padding: 150px 0 75px;
  min-height: 0;
  display: block;
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(ellipse 85% 110% at 22% 55%, var(--crimson-800) 0%, var(--wine-700) 28%, var(--wine-800) 60%, var(--wine-850) 100%);
}
.lead-hero--minimal::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  opacity: 0.10;
  mix-blend-mode: overlay;
  pointer-events: none;
}

/* Torch in the leadership hero — v10: ENLARGED + moved left for more
   horizontal impact on the right side of the hero. Top flame stays
   FULLY visible, the bottom third (lower body / foot) clips below
   the hero's overflow:hidden. Tone-on-tone wine-700 against the wine
   hero bg — low contrast so it reads as texture, not foreground.
   The reveal + trace + fill animation is inherited from the base
   .about-hero__torch rules; only positioning and color are overridden. */
.lead-hero--minimal .about-hero__torch {
  top: 0;                                /* v10: anchor TOP so flame stays fully visible */
  right: 8%;                             /* v10: moved left from 4% — fills more space */
  transform: translateY(-4%);            /* v10: tiny nudge up so flame breathes from top edge */
  height: 170%;                          /* v10: enlarged from 90% — bottom third clips below */
  width: auto;
  fill: rgba(77, 0, 39, 0.65);          /* wine-700 #4D0027 @ 65% */
  stroke: rgba(77, 0, 39, 0.65);
  stroke-width: 0.35;
  opacity: 1;
  pointer-events: none;
  z-index: 0;
  filter: drop-shadow(0 0 28px rgba(20, 0, 8, 0.5));
}
@media (max-width: 900px) {
  .lead-hero--minimal .about-hero__torch {
    right: -5%;
    height: 130%;
    transform: translateY(-2%);
    opacity: 0.85;
  }
}
.lead-hero--minimal .lead-hero__inner {
  z-index: 1;
}
/* Two-line title — serif primary anchor + sans-uppercase secondary
   for the descriptor. Tight gap so the pair reads as one statement. */
.lead-hero--minimal .lead-hero__title {
  margin: 0;
  display: block;
}
.lead-hero--minimal .lead-hero__title-primary {
  display: block;
  font-family: var(--font-serif);
  font-size: clamp(48px, 6vw, 84px);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.016em;
  color: var(--text-primary);
}
.lead-hero--minimal .lead-hero__title-secondary {
  display: block;
  margin-top: var(--space-3);                     /* slightly more room for the bigger size */
  font-family: var(--font-sans);
  font-size: clamp(16px, 1.5vw, 22px);            /* v5: bumped from 13–17 to 16–22 */
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--tan-100);                           /* v5: light warm tan — pops on crimson bg */
  line-height: 1;
}

/* NOTE: The .page-cta block (banner-style bottom CTAs with wine /
   crimson modifiers and an SVG map watermark variant) was removed
   per Diallo's revert request — Leadership and Affiliates bottom
   CTAs went back to the canonical .about-cta shell so the layout,
   color, and animations stay consistent with the pattern used site-
   wide. Only the title, lede, and button content vary per page now.
   Do not re-introduce a .page-cta variant unless we're intentionally
   adding a new bottom-banner pattern.

   The SVG region-ix-map.svg dotted-grid icon should NOT be used as
   decorative background anywhere on the site. The "real" geographic
   map (used on index.html and about.html) is the only map treatment
   approved for decorative use.
   ================================================================ */

/* ================================================================
   DONATION PAGE — Light warm rebuild (v2)
   Diallo's direction: all warm light surfaces, no wine-dark cards.
   Page should feel clean and "ready to give" rather than authoritative.
   Two-column layout on desktop (form + sidebar); stacks on mobile.
   Form is visual-only at this phase. Real Stripe Elements wiring +
   Apple Pay / Google Pay / PayPal express buttons come later when
   the publishable key + payment intent backend are in place.
   ================================================================ */

/* NOTE: legacy .donate-hero block removed per Diallo v26 — donation
   page now uses the standard about-hero--crimson treatment for
   consistency with the rest of the site. Do not reintroduce a
   donation-specific hero shell. */

.donate-form-section {
  padding-block: clamp(40px, 6vh, 80px) clamp(60px, 8vh, 100px);
}
.donate-form-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(32px, 4vw, 56px);
  align-items: start;
}
@media (min-width: 1024px) {
  .donate-form-grid {
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  }
}

/* Form column shell — light warm card on the cream section.
   Soft shadow + thin warm border so it sits gently on the page
   without competing with the hero. */
.donate-form {
  background: #FFFCF6;
  border: 1px solid rgba(180, 140, 90, 0.18);
  border-radius: var(--radius-lg);
  padding: clamp(28px, 4vw, 48px);
  box-shadow:
    0 30px 80px -32px rgba(80, 40, 20, 0.16),
    0 0 0 1px rgba(180, 140, 90, 0.04);
}

.donate-form__intro {
  margin-bottom: clamp(28px, 3vh, 40px);
  padding-bottom: clamp(24px, 3vh, 32px);
  border-bottom: 1px solid rgba(50, 0, 25, 0.10);
}
.donate-form__eyebrow {
  font-family: var(--font-sans);
  font-size: 13px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--crimson-500);
  font-weight: 700;
  margin: 0 0 var(--space-4);
}
.donate-form__heading {
  font-family: var(--font-serif);
  font-size: clamp(26px, 3.2vw, 38px);
  font-weight: 600;
  color: #3D2818;                                         /* warm dark brown, not wine */
  margin: 0 0 var(--space-4);
  line-height: 1.15;
  letter-spacing: -0.012em;
}
/* Field shells */
.donate-field {
  border: 0;
  padding: 0;
  margin: 0 0 clamp(28px, 3vh, 36px);
}
.donate-field:last-of-type {
  margin-bottom: clamp(20px, 2vh, 28px);
}
.donate-field__legend {
  font-family: var(--font-sans);
  font-size: 13px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #3D2818;                                         /* warm dark brown */
  font-weight: 700;
  margin: 0 0 var(--space-4);
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  gap: var(--space-3);
}
.donate-field__optional {
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: none;
  font-weight: 600;
  color: var(--grey-600);
  font-style: italic;
  letter-spacing: 0.04em;
}
.donate-field__stripe-mark {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--grey-600);
  text-transform: uppercase;
  font-weight: 700;
}
.donate-field__stripe-mark svg {
  width: 36px;
  height: 14px;
}

/* Frequency / dedication toggles — pill group. v23 active state
   uses a soft warm copper accent instead of the wine-dark + crimson
   that read aggressive. Card background tints shift to warm-brown
   so the whole page reads cohesive. */
.donate-toggle {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  background: rgba(180, 140, 90, 0.08);
  padding: 6px;
  border-radius: var(--radius-md);
}
.donate-toggle__option {
  position: relative;
  display: block;
  cursor: pointer;
}
.donate-toggle__option input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.donate-toggle__label {
  display: block;
  text-align: center;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  padding: 12px 14px;
  border-radius: calc(var(--radius-md) - 4px);
  color: var(--grey-700);
  transition: background-color 200ms ease, color 200ms ease, box-shadow 200ms ease;
}
/* v26 per Diallo: actively-selected items get the brand crimson
   gradient with light text. Same treatment across the page so the
   selection state is consistent. */
.donate-toggle__option input:checked + .donate-toggle__label {
  background: linear-gradient(135deg, var(--crimson-500) 0%, var(--crimson-700) 100%);
  color: #FFFCF6;
  box-shadow: 0 6px 16px -6px rgba(135, 20, 39, 0.45);
}
.donate-toggle__option:hover .donate-toggle__label {
  color: var(--crimson-600);
}
.donate-toggle__option input:checked:hover + .donate-toggle__label,
.donate-toggle__option input:checked + .donate-toggle__label:hover {
  color: #FFFCF6;                                       /* keep light on hover when active */
}
.donate-toggle--small .donate-toggle__label {
  font-size: 13px;
  padding: 10px 12px;
}

/* Amount grid */
.donate-amount-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-bottom: 16px;
}
.donate-amount-option {
  position: relative;
  cursor: pointer;
}
.donate-amount-option input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.donate-amount-option__label {
  display: block;
  text-align: center;
  font-family: var(--font-serif);
  font-size: clamp(20px, 2vw, 26px);
  font-weight: 600;
  padding: 18px 16px;
  background: rgba(180, 140, 90, 0.10);
  border: 1.5px solid transparent;
  border-radius: var(--radius-md);
  color: #3D2818;
  transition: background-color 200ms ease, border-color 200ms ease, transform 180ms ease;
}
.donate-amount-option:hover .donate-amount-option__label {
  background: rgba(180, 140, 90, 0.18);
}
/* v26 per Diallo: active state is the brand crimson gradient with
   reversed-out cream text. Matches the frequency/dedication toggles
   so selected items read consistently across the form. */
.donate-amount-option input:checked + .donate-amount-option__label {
  background: linear-gradient(135deg, var(--crimson-500) 0%, var(--crimson-700) 100%);
  border-color: var(--crimson-600);
  color: #FFFCF6;
  transform: translateY(-1px);
  box-shadow: 0 8px 20px -8px rgba(135, 20, 39, 0.40);
}

/* Custom amount input */
.donate-field__custom {
  display: block;
  margin-top: 12px;
}
.donate-field__custom-label {
  display: block;
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--grey-700);
  font-weight: 600;
  margin-bottom: 8px;
}
.donate-field__custom-input-wrap {
  display: flex;
  align-items: center;
  background: rgba(180, 140, 90, 0.06);
  border: 1.5px solid rgba(180, 140, 90, 0.20);
  border-radius: var(--radius-md);
  padding: 0 16px;
  transition: border-color 200ms ease, background-color 200ms ease;
}
.donate-field__custom-input-wrap:focus-within {
  border-color: #B05A1F;
  background: #FFFCF6;
}
.donate-field__custom-currency {
  font-family: var(--font-serif);
  font-size: 20px;
  color: #3D2818;
  font-weight: 600;
  margin-right: 8px;
}
.donate-field__custom-input-wrap input {
  flex: 1;
  border: 0;
  background: transparent;
  font-family: var(--font-serif);
  font-size: 18px;
  color: #3D2818;
  padding: 14px 0;
  outline: none;
  min-width: 0;
}
.donate-field__custom-input-wrap input::-webkit-outer-spin-button,
.donate-field__custom-input-wrap input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Standard input row + wrap */
.donate-input-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-bottom: 14px;
}
.donate-input-row--three {
  grid-template-columns: 2fr 1fr 1fr;
}
.donate-input-wrap {
  display: block;
  margin-bottom: 14px;
}
/* v28 per Diallo: breathing room above the dedication name field so
   it doesn't crowd the In Honor / In Memory toggle directly above. */
.donate-dedication-name {
  margin-top: 18px;
}
.donate-input-row > .donate-input-wrap {
  margin-bottom: 0;
}
.donate-input-label {
  display: block;
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--grey-700);
  font-weight: 600;
  margin-bottom: 8px;
}
.donate-input-wrap input,
.donate-select {
  width: 100%;
  border: 1.5px solid rgba(180, 140, 90, 0.20);
  background: rgba(180, 140, 90, 0.06);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  font-family: var(--font-sans);
  font-size: 15px;
  color: #3D2818;
  outline: none;
  transition: border-color 200ms ease, background-color 200ms ease, box-shadow 200ms ease;
}
.donate-input-wrap input::placeholder {
  color: var(--grey-500);
}
.donate-input-wrap input:focus,
.donate-select:focus {
  border-color: #B05A1F;
  background: #FFFCF6;
  box-shadow: 0 0 0 4px rgba(176, 90, 31, 0.14);
}
/* v27 per Diallo: single combined SVG draws a crimson pill with a
   white chevron inside, sitting at the right edge of the select. One
   asset = one render. The previous two-layer approach was finicky. */
.donate-select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28' fill='none'><circle cx='14' cy='14' r='14' fill='%23D14C4A'/><path d='M9 12l5 5 5-5' stroke='white' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 28px 28px;
  padding-right: 56px;
  cursor: pointer;
}

/* Card field — Stripe Elements look */
.donate-card-input {
  display: flex;
  align-items: center;
  border: 1.5px solid rgba(180, 140, 90, 0.20);
  background: rgba(180, 140, 90, 0.06);
  border-radius: var(--radius-md);
  padding: 0 16px;
  gap: 12px;
  transition: border-color 200ms ease, background-color 200ms ease, box-shadow 200ms ease;
}
.donate-card-input:focus-within {
  border-color: #B05A1F;
  background: #FFFCF6;
  box-shadow: 0 0 0 4px rgba(176, 90, 31, 0.14);
}
.donate-card-input input {
  flex: 1;
  border: 0;
  background: transparent;
  padding: 14px 0;
  font-family: var(--font-mono, monospace);
  font-size: 15px;
  letter-spacing: 0.02em;
  color: #3D2818;
  outline: none;
  min-width: 0;
}
.donate-card-input__brands {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}
.donate-card-brand {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-sans);
  font-size: 10px;
  letter-spacing: 0.1em;
  font-weight: 700;
  padding: 4px 8px;
  border-radius: 4px;
  background: rgba(180, 140, 90, 0.14);
  color: var(--grey-700);
}
.donate-field__security {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--grey-600);
  margin: 14px 0 0;
  font-style: italic;
}
.donate-field__security svg {
  color: #B05A1F;
  flex-shrink: 0;
}

/* Consent checkboxes */
.donate-field--consent {
  background: rgba(245, 229, 201, 0.45);
  padding: 20px 22px;
  border-radius: var(--radius-md);
}
.donate-checkbox {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  cursor: pointer;
  margin-bottom: 12px;
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.45;
  color: #3D2818;
}
.donate-checkbox:last-child {
  margin-bottom: 0;
}
.donate-checkbox input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.donate-checkbox__box {
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 1.5px solid rgba(180, 140, 90, 0.35);
  background: #FFFCF6;
  border-radius: 5px;
  flex-shrink: 0;
  margin-top: 1px;
  position: relative;
  transition: background-color 180ms ease, border-color 180ms ease;
}
.donate-checkbox__box::after {
  content: '';
  position: absolute;
  inset: 4px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='10' viewBox='0 0 12 10' fill='none'><path d='M1 5l3.5 3.5L11 1' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-size: contain;
  opacity: 0;
  transition: opacity 180ms ease;
}
.donate-checkbox input:checked + .donate-checkbox__box {
  background: #B05A1F;
  border-color: #B05A1F;
}
.donate-checkbox input:checked + .donate-checkbox__box::after {
  opacity: 1;
}

/* Submit — full-width primary button. v28 per Diallo: justify-content
   space-between lets the icon sit at the right edge (inside the circle
   target zone) while the label hugs the left, so the expanding-circle
   hover lines up correctly. Don't override padding/height — let the
   .btn-primary base handle the pill geometry. */
.donate-form__submit {
  width: 100%;
  justify-content: space-between;
  font-size: 16px;
  margin-top: clamp(24px, 3vh, 32px);
}
.donate-form__legal {
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--grey-600);
  line-height: 1.5;
  margin: 18px 0 0;
  font-style: italic;
}

/* SIDEBAR */
.donate-sidebar {
  display: flex;
  flex-direction: column;
  gap: 20px;
  position: sticky;
  top: 110px;
}
.donate-sidebar__card {
  background: #FFFCF6;
  border-radius: var(--radius-lg);
  padding: clamp(24px, 3vw, 32px);
  border: 1px solid rgba(180, 140, 90, 0.18);
  box-shadow:
    0 30px 80px -32px rgba(80, 40, 20, 0.16),
    0 0 0 1px rgba(180, 140, 90, 0.04);
}
.donate-sidebar__eyebrow {
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--crimson-500);
  font-weight: 700;
  margin: 0 0 var(--space-3);
}
.donate-sidebar__heading {
  font-family: var(--font-serif);
  font-size: clamp(20px, 2vw, 24px);
  font-weight: 600;
  color: var(--wine-800);
  margin: 0 0 var(--space-5);
  line-height: 1.18;
}
.donate-sidebar__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.donate-sidebar__list li {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-bottom: 14px;
  border-bottom: 1px solid rgba(50, 0, 25, 0.08);
}
.donate-sidebar__list li:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}
.donate-sidebar__list-label {
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--crimson-600);
}
.donate-sidebar__list-body {
  font-family: var(--font-serif);
  font-size: 14px;
  line-height: 1.45;
  color: var(--grey-700);
}
@media (max-width: 1023px) {
  .donate-sidebar { position: static; }
}
@media (max-width: 640px) {
  .donate-amount-grid { grid-template-columns: repeat(2, 1fr); }
  .donate-input-row { grid-template-columns: 1fr; }
  .donate-input-row--three { grid-template-columns: 1fr; }
  .donate-toggle { grid-template-columns: 1fr; }
}


/* v25 per Diallo: convention page's coming-soon section sits tighter
   to the banner above. ~30px less top and bottom than the default. */
.convention-page .coming-soon {
  padding-block: clamp(60px, 10vh, 140px);
}

/* ================================================================
   COMING SOON PATTERN
   For pages where client content has not yet been provided. Reuses
   the lead-hero--minimal hero shell (with the torch SVG inside) so
   the page feels launch-ready and on-brand. Body is a centered
   Coming Soon block on the warm cream light section. Wine is the
   default hero gradient; --crimson modifier swaps the gradient for
   pages where wine has already been claimed nearby.
   ================================================================ */

/* Crimson variant of the minimal inner-page hero. v27 per Diallo:
   "more alive" version — center bloom in bright crimson-500 fades
   out into deep wine-800 at the edges. Inversion of the prior pattern
   (which went dark-center to darker-edge). The bloom is what gives
   it life. Same shape, brighter center. */
.lead-hero--minimal.lead-hero--minimal--crimson {
  background:
    radial-gradient(ellipse 85% 110% at 25% 55%, var(--crimson-500) 0%, var(--crimson-700) 30%, var(--wine-800) 70%, var(--wine-850) 100%);
}
/* Flame tone-on-tone with the bright crimson center — deeper crimson
   shadow color so it reads as texture against the bloom, mirroring how
   wine-700 reads on the wine variant. */
.lead-hero--minimal.lead-hero--minimal--crimson .about-hero__torch {
  fill: rgba(110, 15, 31, 0.65);
  stroke: rgba(110, 15, 31, 0.65);
  filter: drop-shadow(0 0 32px rgba(40, 0, 8, 0.45));
}

/* NOTE: previously-added .lead-hero--minimal--sponsorship variant was
   removed per Diallo. Sponsorship reverts to using the established
   --crimson modifier so the inner-page hero treatments stay
   consistent. Don't reintroduce a sponsorship-specific variant. */

/* v25 .donate-hero block removed — donation page uses the
   about-hero--crimson treatment now. See note above the legacy
   .donate-hero comment for the rationale.
   v27 per Diallo: hero has 50px above the text and 75px below. The
   transparent floating header overlays the top of the hero (data-
   page-hero pattern), so the 50px is breathing room beneath where
   the nav chrome sits. */
.donation-page .about-hero {
  padding: 60px 0 95px;
  min-height: 0;
}
/* Top buffer = nav clearance, so the 50px above the title isn't
   eaten by the floating header. */
.donation-page .about-hero__inner {
  padding-top: clamp(70px, 10vh, 110px);
}

/* Coming Soon body — large centered serif wordmark on the warm cream
   light section. Same eyebrow + accent treatment used across the site
   for consistency. Generous vertical padding so the page reads as
   intentional, not empty. */
.coming-soon {
  padding: clamp(120px, 18vh, 200px) 0;
  text-align: center;
  position: relative;
  overflow: hidden;
}
.coming-soon__title {
  font-family: var(--font-serif);
  font-size: clamp(56px, 9vw, 120px);
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.016em;
  color: var(--wine-800);
  margin: 0 0 var(--space-8);
  text-wrap: balance;
}
.coming-soon__title .accent {
  color: var(--crimson-500);
  font-style: italic;
  font-weight: 600;
}
.coming-soon__body {
  font-family: var(--font-serif);
  font-size: clamp(18px, 1.4vw, 22px);
  line-height: 1.55;
  color: var(--grey-700);
  max-width: 640px;
  margin: 0 auto;
}
/* v22 — smaller secondary line for the "Stay tuned" follow-up. Sits
   on its own line below the main sentence with a touch more breathing
   room above to read as a distinct beat. */
.coming-soon__body--small {
  font-size: clamp(15px, 1.1vw, 17px);
  color: var(--grey-600);
  margin-top: var(--space-4);
  font-style: italic;
}

/* ================================================================
   CONVENTION BANNER — Used on the Convention Coming Soon page.
   Full-bleed image strip pulling the same 101st convention hero
   image from the home page rotating banner. Wine gradient overlay
   anchors the dates and location on top. Sits between the hero and
   the Coming Soon body block.
   ================================================================ */
.conv-banner {
  position: relative;
  min-height: clamp(260px, 36vh, 420px);
  overflow: hidden;
  display: flex;
  align-items: center;
  color: var(--text-on-authority);
  isolation: isolate;
}
/* Hero variant per Diallo v26: blur is built into the color overlay
   itself, full-width across the hero, fading in vertically from
   transparent at the top to deep wine at the bottom. One layer does
   both jobs — no boxed strip behind the text. */
.conv-banner--hero {
  /* v26 per Diallo: hero starts BELOW the header chrome — not behind
     it. margin-top equal to the floating-header height so the photo
     starts at the bottom edge of the menu bar instead of bleeding
     up underneath. */
  margin-top: clamp(76px, 9vh, 90px);
  min-height: clamp(480px, 72vh, 760px);
  align-items: flex-end;
  padding-top: clamp(40px, 6vh, 80px);
}
/* The overlay carries both the gradient color AND the backdrop blur.
   mask-image fades the blur effect itself vertically so the top of
   the flyer reads sharp and only the bottom gets the frosted feel.
   Background gradient pairs with mask so color + blur sync exactly. */
.conv-banner--hero .conv-banner__overlay {
  background: linear-gradient(
    180deg,
    rgba(40, 0, 22, 0.00) 0%,
    rgba(40, 0, 22, 0.15) 35%,
    rgba(50, 0, 25, 0.70) 65%,
    rgba(80, 0, 40, 0.94) 100%
  );
  backdrop-filter: blur(10px) saturate(0.92);
  -webkit-backdrop-filter: blur(10px) saturate(0.92);
  mask-image: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.10) 30%, rgba(0, 0, 0, 0.65) 55%, black 80%);
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.10) 30%, rgba(0, 0, 0, 0.65) 55%, black 80%);
}
/* Inner content sits over the overlay — no own background or blur,
   so the gradient strip is the only layer doing the work. */
.conv-banner--hero .conv-banner__inner {
  width: 100%;
  padding-block: clamp(40px, 6vh, 70px);
}
.conv-banner--hero .conv-banner__title {
  font-size: clamp(36px, 5.4vw, 64px);
  max-width: 900px;
  line-height: 1.06;
}
/* Convention hero — mobile tunings per Diallo 2026-05-31.
   Trim hero height to ~400px, lift the overlay gradient stops
   so the dark band starts higher up the hero (stronger backing
   for the title at small viewports). Mask raised in lockstep so
   the blur fades in at the same earlier point.

   Per the 2026-05-31 follow-up:
   - Title breaks to 3 distinct lines via display:block on its
     interior spans ("Region IX at the" / "101st NBA" /
     "Annual Convention").
   - Tighter line-height on the title so the 3 lines feel like one
     compact block.
   - Tighter eyebrow → title gap (eyebrow margin trimmed).
   - Meta splits to 2 lines: city on top, date below, middot hidden.
   - Tight line-height on the meta so the two lines hug. */
@media (max-width: 768px) {
  .conv-banner--hero {
    min-height: 400px;
  }
  .conv-banner--hero .conv-banner__overlay {
    background: linear-gradient(
      180deg,
      rgba(40, 0, 22, 0.00) 0%,
      rgba(40, 0, 22, 0.30) 18%,
      rgba(50, 0, 25, 0.78) 45%,
      rgba(80, 0, 40, 0.96) 100%
    );
    mask-image: linear-gradient(180deg,
      transparent 0%,
      rgba(0,0,0,0.20) 12%,
      rgba(0,0,0,0.75) 35%,
      black 60%);
    -webkit-mask-image: linear-gradient(180deg,
      transparent 0%,
      rgba(0,0,0,0.20) 12%,
      rgba(0,0,0,0.75) 35%,
      black 60%);
  }
  /* Tighten eyebrow → title gap. */
  .conv-banner__eyebrow { margin-bottom: 10px; }
  /* 3-line title block. Tighter line-height; spans go to block so
     the line breaks land exactly where Diallo asked. */
  .conv-banner__title {
    line-height: 1.02;
    margin-bottom: 14px;
  }
  .conv-banner__title-line { display: block; }
  /* 2-line meta: city, then date. Hide middot. Tight rhythm. */
  .conv-banner__meta { line-height: 1.35; }
  .conv-banner__meta-loc,
  .conv-banner__meta-date { display: block; }
  .conv-banner__meta-sep { display: none; }
}
.conv-banner__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  will-change: transform;
}
/* Scale the bg image up ~15% so the parallax translate has room to
   operate without exposing the container edges as the media element
   drifts. Applied only when the parent is opted into bg parallax. */
[data-parallax-bg] .conv-banner__media img,
[data-parallax-bg] [data-parallax-target] img {
  transform: scale(1.15);
  transform-origin: center center;
}
.conv-banner__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.conv-banner__overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(180deg, rgba(40, 0, 22, 0.45) 0%, rgba(80, 0, 40, 0.78) 100%),
    radial-gradient(ellipse at 20% 50%, rgba(135, 20, 39, 0.55), transparent 60%);
}
.conv-banner__inner {
  position: relative;
  z-index: 2;
  padding-block: clamp(40px, 6vh, 80px);
}
.conv-banner__eyebrow {
  font-family: var(--font-sans);
  font-size: clamp(13px, 1.2vw, 16px);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--tan-100);
  font-weight: 700;
  margin: 0 0 var(--space-5);
}
.conv-banner__title {
  font-family: var(--font-serif);
  font-size: clamp(28px, 3.6vw, 44px);
  line-height: 1.12;
  font-weight: 600;
  color: var(--text-on-authority);
  margin: 0 0 var(--space-4);
  letter-spacing: -0.012em;
  max-width: 720px;
}
.conv-banner__meta {
  font-family: var(--font-sans);
  font-size: clamp(14px, 1.2vw, 16px);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--crimson-400);
  margin: 0;
}

/* ================================================================
   LEADERSHIP PAGE
   ================================================================ */

/* ================================================================
   LEADERSHIP v4 — Officer roster on a light warm gradient. Six
   officers, each rendered with a UNIQUE creative card treatment.
   Shared base + per-officer modifier classes for distinct looks.
   ================================================================ */

/* Roster section — v8.2: white center still, but the warm halo at
   the edges is richer and more visible. The tan presence around the
   perimeter grounds the wine cards instead of letting them float on
   a near-flat white. */
.lead-roster {
  padding-block: clamp(80px, 12vh, 140px);
  /* Light-gray + white per Diallo — white center fades to a very subtle
     grey at the edges. Stays neutral so the wine cards carry the color. */
  background:
    radial-gradient(ellipse 78% 68% at 50% 50%,
                    #FFFFFF 0%,
                    #FFFFFF 28%,
                    var(--grey-50) 55%,
                    var(--grey-100) 100%);
  position: relative;
}
.lead-roster__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(40px, 4vw, 64px);
}

/* ----------------------------------------------------------------
   Officer card — UNIFIED v6 (silky-slow, layered animations)

   Design philosophy: every transition is deliberate, slow, confident.
   Hover ENTRANCE and EXIT both take their time. No snap. Multiple
   elements animate on slightly different timings so the card reads
   as a layered scene, not one stiff sync. This becomes the BQ pattern
   for card hover treatments.

   Layers:
     - Card base: radial gradient (white near portrait → tan at edges)
     - Cover: small circle in top-right corner at rest; circular sweep
       takeover on hover (mirrors btn-primary's circle-expands-to-fill)
     - Portrait ring: starts tight, scales outward — different curve
       from the image so the two read as separate movements
     - Subtle image scale (1.03) on hover for layering
     - All text + icon colors invert toward tan/cream for dark mode
   ---------------------------------------------------------------- */
.officer-card {
  position: relative;
  text-align: center;
  padding: clamp(36px, 3.4vw, 56px) clamp(20px, 2.2vw, 36px);
  border-radius: var(--radius-lg);
  /* v9: BACK to CRIMSON palette as the resting state. The wine moved
     up to the hero; the cards return to a more vivid red so the page
     reads as: wine hero (deep / authoritative) → red cards (vibrant /
     present) → cream hover (clean / approachable). Center-bias toward
     crimson-500 lifts the portrait area, deepening into wine at the
     edges for dimensional depth. */
  background: radial-gradient(ellipse 130% 90% at 50% 32%,
              var(--crimson-500) 0%,
              var(--crimson-600) 42%,
              var(--crimson-700) 78%,
              var(--wine-800) 100%);
  box-shadow: 0 12px 32px -10px rgba(50, 0, 25, 0.35);
  overflow: hidden;
  isolation: isolate;
  transition:
    transform 1600ms cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 1600ms cubic-bezier(0.22, 1, 0.36, 1);
}
.officer-card:hover {
  transform: translateY(-8px);
  box-shadow: 0 28px 60px -18px rgba(135, 20, 39, 0.32);
}

/* COVER — v8 FLIP: now the LIGHT corner accent at rest. Small cream
   "tab" blob in the top-right that sweeps out to a giant radius on
   hover, covering the whole card with the warm light gradient. Same
   sweep pattern, inverted palette. Silky in both directions. */
.officer-card__cover {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 130% 90% at 50% 32%,
                    #FFFFFF 0%,
                    #FFFFFF 38%,
                    var(--tan-25) 78%,
                    var(--tan-50) 100%);
  clip-path: circle(55px at calc(100% + 8px) -8px);
  pointer-events: none;
  z-index: 0;
  transition: clip-path 1600ms cubic-bezier(0.22, 1, 0.36, 1);
}
.officer-card:hover .officer-card__cover {
  clip-path: circle(170% at calc(100% + 8px) -8px);
}

/* PORTRAIT — ~90% column width, circular, with a thin crimson outline
   ring. The ring is its OWN animated layer: starts close to the image
   at rest, scales outward on hover. Different easing curve from the
   image's subtle scale so the two motions feel layered, not synced. */
.officer-card__portrait {
  position: relative;
  width: 90%;
  aspect-ratio: 1 / 1;
  margin: 0 auto clamp(20px, 2.4vw, 36px);
  border-radius: 50%;
  z-index: 2;
}
.officer-card__glow {
  position: absolute;
  inset: -22%;
  border-radius: 50%;
  /* v8 FLIP: light cream glow at rest (sits behind portrait on the
     crimson card). On hover the card flips to cream, so the glow
     warms to a tan halo. */
  background:
    radial-gradient(circle, rgba(245, 229, 201, 0.32) 0%, rgba(245, 229, 201, 0.12) 38%, transparent 70%);
  z-index: 0;
  pointer-events: none;
  transition: background 1800ms cubic-bezier(0.22, 1, 0.36, 1),
              opacity 1800ms ease;
}
.officer-card__ring {
  position: absolute;
  inset: -6%;                                 /* breathing room between frame and image */
  border-radius: 50%;
  border: 1px solid var(--tan-100);            /* v8 FLIP: cream ring on red card */
  z-index: 1;
  pointer-events: none;
  transform: scale(1);
  transform-origin: center;
  transition:
    transform 1400ms cubic-bezier(0.34, 1.36, 0.64, 1),
    border-color 1600ms cubic-bezier(0.22, 1, 0.36, 1);
}
.officer-card:hover .officer-card__ring {
  transform: scale(1.08);                     /* still expands, but starts wider so subtle */
  border-color: var(--tan-300);               /* v8 FLIP: warm tan ring on the cream takeover */
}
.officer-card__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 50%;
  position: relative;
  z-index: 2;
  box-shadow: 0 12px 32px -12px rgba(50, 0, 25, 0.35);
  transform: scale(1);
  /* v12: portraits start in black & white at rest, transition to full
     color on hover. Editorial pattern — makes the hover reveal feel
     like the card is "coming alive". Filter transition runs on the
     same silky-slow curve as the rest of the card. */
  filter: grayscale(1);
  transition:
    transform 1800ms cubic-bezier(0.22, 1, 0.36, 1),
    filter 1600ms cubic-bezier(0.22, 1, 0.36, 1);
}
.officer-card:hover .officer-card__image {
  transform: scale(1.03);                     /* subtle zoom on different timing */
  filter: grayscale(0);                       /* v12: full color on hover */
}

/* ============================
   v15 TINT OVERLAY — wine-deep duotone (LOCKED)

   A colored layer sits ABOVE the grayscale portrait inside the
   circular mask. mix-blend-mode: color applies the wine-850 hue +
   saturation to the gray image's luminance, producing a moody
   duotone that reads differently across each photo (warm/cool/neutral
   depending on the source). On hover, the overlay's opacity fades to
   0 and the image's filter drops the grayscale — portrait pops to
   full color.

   Per Diallo: locked on wine-deep across all officer cards. Variants
   tan / wine / crimson / sepia / warm-brand were trialed in v13–v14
   and removed.
   ============================ */
.officer-card__tint {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  z-index: 3;
  pointer-events: none;
  opacity: 1;
  transition: opacity 1600ms cubic-bezier(0.22, 1, 0.36, 1);
}
.officer-card:hover .officer-card__tint {
  opacity: 0;
}

/* Wine-deep color blend — the locked treatment */
.officer-card--tint-wine-deep .officer-card__tint {
  background: var(--wine-850);
  mix-blend-mode: color;
}

/* NAME — Playfair serif. Sized to fit the longest name (Ronni
   Whitehead Otieno) on two lines max in the column width.
   v8 FLIP: resting color is now cream/white on the red card. */
.officer-card__name {
  font-family: var(--font-serif);
  font-size: clamp(26px, 2.5vw, 34px);          /* pulled back slightly so 3-word names break to 2 lines */
  font-weight: 600;
  color: #FFFFFF;                               /* v8 FLIP: white on red card */
  margin: 0 0 var(--space-3);
  line-height: 1.1;
  position: relative;
  z-index: 2;
  text-wrap: balance;
  /* Cap visual line count by limiting paragraph width */
  max-width: 16ch;
  margin-left: auto;
  margin-right: auto;
  transition: color 1600ms cubic-bezier(0.22, 1, 0.36, 1);
}
.officer-card__honorific {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 16px;
  color: var(--tan-200);                        /* v8 FLIP: warm cream on red card */
  margin: 0 0 var(--space-1);
  position: relative;
  z-index: 2;
  transition: color 1600ms cubic-bezier(0.22, 1, 0.36, 1);
}
/* TITLE — v8.2: pulled down + tightened tracking so the longest
   titles ("DEPUTY DIRECTOR", "MEMBER AT LARGE") land on ONE line in
   the card column. nowrap enforces it. Still reads as a real beat
   below the name, just calibrated to the column width. */
.officer-card__title {
  font-family: var(--font-sans);
  font-size: clamp(14px, 1.25vw, 18px);         /* v8.2: was clamp(18, 1.7, 24) */
  letter-spacing: 0.14em;                       /* v8.2: was 0.20em */
  text-transform: uppercase;
  color: var(--tan-200);                        /* warm cream on wine card */
  font-weight: 700;
  margin: var(--space-3) 0 clamp(28px, 2.8vw, 40px);
  position: relative;
  z-index: 2;
  white-space: nowrap;                          /* v8.2: guarantee one line */
  transition: color 1600ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Icon row — email + LinkedIn */
.officer-card__icons {
  display: inline-flex;
  gap: var(--space-3);
  position: relative;
  z-index: 2;
}
.officer-card__icon {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* v8 FLIP: resting state is cream icons with cream border on red card */
  color: var(--tan-100);
  background: transparent;
  border: 1px solid rgba(245, 229, 201, 0.45);
  transition:
    background 1400ms cubic-bezier(0.22, 1, 0.36, 1),
    color 1400ms cubic-bezier(0.22, 1, 0.36, 1),
    border-color 1400ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
}
.officer-card__icon svg { width: 18px; height: 18px; display: block; }
.officer-card__icon:hover { transform: scale(1.12); }

/* ============================
   v8 HOVER — LIGHT MODE TAKEOVER
   The cream sweep covers the red card; text flips to wine/crimson,
   icons go crimson on cream, glow warms to a tan halo.
   ============================ */
.officer-card:hover .officer-card__name        { color: var(--wine-800); }
.officer-card:hover .officer-card__title       { color: var(--crimson-500); }
.officer-card:hover .officer-card__honorific   { color: var(--tan-400); }
.officer-card:hover .officer-card__glow {
  background: radial-gradient(circle, rgba(212, 150, 88, 0.40) 0%, rgba(212, 150, 88, 0.18) 38%, transparent 70%);
}
.officer-card:hover .officer-card__icon {
  color: var(--crimson-500);
  border-color: rgba(135, 20, 39, 0.30);
}
.officer-card:hover .officer-card__icon:hover {
  color: #FFFFFF;
  background: var(--crimson-500);
  border-color: var(--crimson-500);
}

@media (prefers-reduced-motion: reduce) {
  .officer-card,
  .officer-card__cover,
  .officer-card__ring,
  .officer-card__image,
  .officer-card__glow,
  .officer-card__name,
  .officer-card__title,
  .officer-card__honorific,
  .officer-card__icon {
    transition-duration: 200ms !important;
  }
}

@media (max-width: 900px) {
  .lead-roster__grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-8); }
}
@media (max-width: 600px) {
  .lead-roster__grid { grid-template-columns: 1fr; gap: var(--space-8); }
}

/* Leadership mobile tunings per Diallo 2026-05-31.
   - Two-column grid with balanced 20px spacing on all sides:
     20px outer padding L/R, 20px column gap between cards, 20px
     row gap between rows. Reads as a clean 2×3 grid.
   - Headshots + frame ~10% smaller (90% → 81% portrait width).
   - Skip the wine-deep duotone tint: images render in full color
     from the start. Tap still triggers the existing hover-state
     animations (ring scale-up, image zoom) because :hover fires
     on touch — we just don't have a color reveal to perform. */
@media (max-width: 768px) {
  .lead-roster {
    padding-inline: 0;
    padding-block: 30px;
  }
  /* Multi-word titles ("Member at Large", "Deputy Director") wrap
     onto two tight-spaced lines on the narrow mobile cards. Spans
     render inline on desktop (so titles read naturally on one
     line), block on mobile with tight line-height. The base
     .officer-card__title already has text-transform: uppercase, so
     both lines render in matching uppercase (e.g. "MEMBER" /
     "AT LARGE", "DEPUTY" / "DIRECTOR"). */
  .officer-card__title--stacked .officer-card__title-line {
    display: block;
  }
  .officer-card__title--stacked {
    line-height: 1.05;
  }
  /* Force 2-col at every mobile width (overrides the earlier
     1-col fallback at <=600px). Cards flush to viewport edge with
     10px between cards (both column and row). */
  .lead-roster__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
  }
  .officer-card__portrait {
    width: 81%;
  }
  /* Full-color image from the start (no grayscale base) and no
     overlay tint. Hover transitions still apply if the tap triggers
     :hover, but there's no color shift to do. */
  .officer-card__image {
    filter: none;
  }
  .officer-card__tint {
    opacity: 0;
  }
}


/* ================================================================
   AFFILIATES PAGE
   ================================================================ */

/* ================================================================
   AFFILIATES PAGE — v1 (dark wine, logo-prominent column layout)

   Hero mirrors the leadership pattern with two key differences:
     1. Bright glow peaks on the RIGHT (leadership peaks left)
     2. Torch sits LEFT, horizontally mirrored (leadership sits right)
   Plus a secondary radial glow that adds dimensional texture without
   breaking the wine color story.

   Directory is a DARK wine section with 4 vertical state columns.
   Affiliates are floating logo badges (no card chrome) + city below.
   Asymmetric column heights (California tall, others short) are
   intentional — they communicate real density.
   ================================================================ */

/* Hero — wine palette with layered glow + texture */
.aff-hero {
  padding: 150px 0 75px;
  min-height: 0;
  display: block;
  position: relative;
  overflow: hidden;
  background:
    /* Layer 1 — soft warm crimson highlight (the "gradient glow") */
    radial-gradient(ellipse 50% 65% at 75% 28%, rgba(161, 29, 51, 0.32), transparent 65%),
    /* Layer 2 — deeper wine shadow pocket bottom-left for dimension */
    radial-gradient(ellipse 40% 55% at 14% 82%, rgba(43, 0, 21, 0.55), transparent 60%),
    /* Layer 3 — base wine gradient, peak shifted RIGHT (mirror of lead-hero) */
    radial-gradient(ellipse 85% 110% at 78% 55%, var(--crimson-800) 0%, var(--wine-700) 28%, var(--wine-800) 60%, var(--wine-850) 100%);
}
.aff-hero::after {
  /* Same noise grain texture as leadership for cinematic consistency. */
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  opacity: 0.10;
  mix-blend-mode: overlay;
  pointer-events: none;
}
.aff-hero__inner {
  position: relative;
  z-index: 1;
}

/* Torch — mirror of leadership's position (now LEFT instead of right).
   Horizontal flip (scaleX -1) for variety so the flame leans the other
   direction. Tone-on-tone wine-700 over wine-850 base — low contrast. */
.aff-hero .about-hero__torch {
  top: 0;
  right: auto;
  left: 8%;
  transform: translateY(-4%) scaleX(-1);
  height: 170%;
  width: auto;
  fill: rgba(77, 0, 39, 0.65);
  stroke: rgba(77, 0, 39, 0.65);
  stroke-width: 0.35;
  opacity: 1;
  pointer-events: none;
  z-index: 0;
  filter: drop-shadow(0 0 28px rgba(20, 0, 8, 0.5));
}
@media (max-width: 900px) {
  .aff-hero .about-hero__torch {
    left: -10%;
    height: 130%;
    transform: translateY(-2%) scaleX(-1);
    opacity: 0.85;
  }
}

/* Hero typography — different cadence from leadership: eyebrow first,
   then a two-line title, then a lede paragraph. Right-edge text wins
   spatial real-estate since the gradient peak is also right. */
.aff-hero .aff-hero__inner {
  max-width: 980px;
  margin-left: auto;
  text-align: right;
}
.aff-hero__eyebrow {
  font-family: var(--font-sans);
  font-size: clamp(13px, 1.1vw, 16px);
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--tan-200);
  font-weight: 700;
  margin: 0 0 var(--space-4);
}
.aff-hero__title {
  font-family: var(--font-serif);
  font-size: clamp(44px, 5.6vw, 78px);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -0.016em;
  color: var(--text-primary);
  margin: 0;
}
.aff-hero__title-line { display: block; }
.aff-hero__title-line--accent {
  color: var(--crimson-400);
  font-style: italic;
}
/* Directory — v5: trimmed padding (top -30, bottom -20) so the
   section sits tighter against the hero above and the CTA below. */
.aff-directory {
  padding-top: clamp(50px, 10vh, 110px);
  padding-bottom: clamp(60px, 10vh, 120px);
  background:
    radial-gradient(ellipse 70% 60% at 50% 0%, rgba(232, 180, 120, 0.18) 0%, transparent 60%),
    linear-gradient(180deg, #FFFFFF 0%, var(--tan-25) 60%, var(--tan-50) 100%);
}

/* California featured section — full-width, 2x4 grid below state header */
.aff-state--featured {
  margin-bottom: clamp(64px, 9vh, 110px);
}

.aff-state {
  display: flex;
  flex-direction: column;
  /* Scroll clearance. Combined with html { scroll-padding-top } in
     base.css, this ensures that when ANY scroll operation (anchor
     jump, scrollIntoView, smooth-scroll back to top) lands on a
     state section, the state name sits below where the floating
     site-header would be when it slides in. The value matches the
     header's max height (~84-90px) plus breathing room. */
  scroll-margin-top: 120px;
}
.aff-state__header {
  margin-bottom: clamp(28px, 3.5vh, 44px);
  border-bottom: 1px solid rgba(50, 0, 25, 0.18);
  padding-bottom: var(--space-4);
}
.aff-state__name {
  font-family: var(--font-serif);
  font-size: clamp(28px, 2.8vw, 42px);
  font-weight: 600;
  color: var(--wine-800);
  margin: 0;
  line-height: 1;
  letter-spacing: -0.014em;
}
/* Grid variants — featured = 4-up (CA 2x4), single = 1 card per state column */
.aff-state__grid {
  display: grid;
  gap: clamp(16px, 2vw, 28px);
}
.aff-state__grid--four {
  grid-template-columns: repeat(4, 1fr);
}
.aff-state__grid--single {
  grid-template-columns: 1fr;
}

/* AZ / NV / WA row — 3 columns, each state column has a single card */
.aff-states-row {
  /* v25 per Diallo: 4-column grid to match California's 4-up layout
     above. AZ / NV / WA fill the first three slots; the 4th slot is
     a branded Region IX reach tile. */
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(24px, 3vw, 48px);
  align-items: start;
}
/* The 4th-slot reach tile — wine/crimson gradient with brand language
   anchoring the row. Sits at the same height as the affiliate cards
   beside it so the row reads as one continuous 4-up grid. */
.aff-reach-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 100%;
  padding: clamp(24px, 3vw, 36px);
  border-radius: var(--radius-md);
  background:
    radial-gradient(ellipse at 30% 30%, rgba(212, 150, 88, 0.18), transparent 55%),
    linear-gradient(135deg, var(--crimson-700) 0%, var(--wine-800) 100%);
  color: var(--text-on-authority);
  overflow: hidden;
  isolation: isolate;
}
.aff-reach-tile__eyebrow {
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--tan-100);
  margin: 0 0 var(--space-4);
}
.aff-reach-tile__title {
  font-family: var(--font-serif);
  font-size: clamp(22px, 2.4vw, 30px);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--text-on-authority);
  margin: 0 0 var(--space-3);
}
.aff-reach-tile__title .accent {
  color: var(--tan-200);
  font-style: italic;
}
.aff-reach-tile__body {
  font-family: var(--font-serif);
  font-size: clamp(13px, 1vw, 15px);
  line-height: 1.5;
  color: var(--tan-100);
  margin: 0;
}

/* Affiliate card — v3: unified BOX, NO border / NO heavy shadow.
   Compact logo area (fixed height — not square — for consistent card
   sizing across logos of different proportions). Below the logo: org
   name in Playfair light crimson, city in sans uppercase wine-700.
   Card has a min-height so all 11 cards land at the same height
   whether they sit in the CA 2×4 grid or the AZ/NV/WA 3-col row. */
.affiliate-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  text-decoration: none;
  color: inherit;
  background: #FFFFFF;
  border: none;
  border-radius: var(--radius-lg);
  padding: clamp(22px, 2.2vw, 30px) clamp(16px, 1.8vw, 24px);
  box-shadow: 0 1px 4px -1px rgba(50, 0, 25, 0.025);
  min-height: clamp(220px, 22vw, 280px);
  /* v6: multi-layer hover. Card lift on a long silky curve. */
  transition:
    transform 1400ms cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 1400ms cubic-bezier(0.22, 1, 0.36, 1);
}
.affiliate-card:hover {
  transform: translateY(-8px);
  box-shadow: 0 26px 52px -12px rgba(165, 95, 50, 0.35);
}
.affiliate-card__logo-area {
  width: 100%;
  /* v3: fixed compact height instead of 1:1 aspect — saves ~100px
     vertical space and accommodates logos of varying proportions. */
  height: clamp(72px, 7vw, 96px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(4px, 0.8vw, 8px);
  margin-bottom: clamp(14px, 1.6vw, 20px);
}
.affiliate-card__logo {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
  /* v6: longest curve of the layered set + a spring overshoot so the
     logo "settles" into its hover position a beat behind the card lift. */
  transition: transform 1600ms cubic-bezier(0.34, 1.36, 0.64, 1);
}
.affiliate-card:hover .affiliate-card__logo {
  /* v6: scale + slight Y lift inside the card (logo rises within the
     white space as the card itself rises off the page). */
  transform: scale(1.16) translateY(-3px);
}
/* Organization name — Playfair italic crimson. Animates color AND a
   subtle Y lift on its own timing — distinct from card/logo timings
   so the layers feel choreographed, not synced. */
.affiliate-card__name {
  font-family: var(--font-serif);
  font-size: clamp(15px, 1.25vw, 18px);
  font-weight: 400;
  font-style: italic;
  color: var(--crimson-500);
  margin: 0 0 4px;
  line-height: 1.2;
  letter-spacing: -0.004em;
  text-wrap: balance;
  transition:
    color 1200ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 1200ms cubic-bezier(0.22, 1, 0.36, 1);
}
/* City — sans uppercase. Animates color + letter-spacing widen for a
   subtle "extending" feel. Different timing than name. */
.affiliate-card__city {
  font-family: var(--font-sans);
  font-size: clamp(10px, 0.85vw, 12px);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--wine-700);
  margin: 0;
  line-height: 1.3;
  transition:
    color 1300ms cubic-bezier(0.16, 1, 0.3, 1),
    letter-spacing 1300ms cubic-bezier(0.16, 1, 0.3, 1);
}
.affiliate-card:hover .affiliate-card__name {
  color: var(--crimson-600);
  transform: translateY(-2px);
}
.affiliate-card:hover .affiliate-card__city {
  color: var(--wine-800);
  letter-spacing: 0.28em;
}

/* ACTIVE (clicked) state — visually DISTINCT from hover. Hover lifts
   with warm shadow only; active adds a thin crimson outline ring
   (via inset box-shadow) AND a soft tan gradient bg so the card
   reads "selected" rather than just "hovered." */
.affiliate-card.is-active {
  transform: translateY(-8px);
  background: linear-gradient(180deg, #FFFFFF 0%, var(--tan-25) 100%);
  box-shadow:
    0 26px 52px -12px rgba(165, 95, 50, 0.35),
    inset 0 0 0 1.5px var(--crimson-500);
}
.affiliate-card.is-active .affiliate-card__logo {
  transform: scale(1.16) translateY(-3px);
}
.affiliate-card.is-active .affiliate-card__name {
  color: var(--crimson-600);
  transform: translateY(-2px);
}
.affiliate-card.is-active .affiliate-card__city {
  color: var(--wine-800);
  letter-spacing: 0.28em;
}

/* ============================
   v7 EXPAND PANEL — inline accordion below the row containing the
   clicked card. Lives as a sibling in the grid; grid-column: 1/-1
   spans the full row width when open. Hidden by default. Opens with
   a height + opacity transition for the smooth reveal.
   ============================ */
/* v14: smoother open + close with a dedicated .is-closing state.
   Both open and close animate scaleY (grows/collapses), translateY
   (slides), opacity (fades), and a subtle blur for that "settling"
   feel. Long silky bezier on open; slightly faster ease-in-out on
   close so it doesn't feel sluggish to dismiss.

   CLOSED: display: none — panel doesn't occupy a grid row, so the
   parent grid's gap remains clean (matches the column gap exactly).
   OPENING (.is-open): display: grid + panel-open keyframes.
   CLOSING (.is-closing): display: grid + panel-close keyframes; JS
   removes the class after the animation completes. */
.affiliate-expand {
  grid-column: 1 / -1;
  position: relative;
  background: #FFFFFF;
  border-radius: var(--radius-lg);
  box-shadow: 0 28px 58px -14px rgba(165, 95, 50, 0.32);
  display: none;
  grid-template-columns: minmax(160px, 0.32fr) 1fr;
  gap: clamp(28px, 3.4vw, 56px);
  align-items: center;
  padding: clamp(28px, 3vw, 44px) clamp(28px, 3vw, 48px);
  margin: 0;
  pointer-events: none;
  transform-origin: top center;
}
.affiliate-expand.is-open,
.affiliate-expand.is-closing {
  display: grid;
}
.affiliate-expand.is-open {
  pointer-events: auto;
  animation: panel-open 900ms cubic-bezier(0.22, 1, 0.36, 1) backwards;
}
/* Close — stripped back: no scaleY shrink (which caused the "shrink"
   visual), no intermediate keyframe (which caused the "pause" — it
   held opacity at 0.85 for most of the duration). Just a clean
   opacity + slight translateY + light blur, played short and smooth.
   ease-in-out curve = balanced both ends, no held middle. */
.affiliate-expand.is-closing {
  animation: panel-close 320ms cubic-bezier(0.4, 0, 0.6, 1) forwards;
}
@keyframes panel-open {
  0%   { opacity: 0; transform: translateY(-22px) scaleY(0.82); filter: blur(4px); }
  45%  { opacity: 0.85; filter: blur(0.5px); }
  100% { opacity: 1; transform: translateY(0) scaleY(1); filter: blur(0); }
}
@keyframes panel-close {
  from { opacity: 1; transform: translateY(0);     filter: blur(0); }
  to   { opacity: 0; transform: translateY(-10px); filter: blur(2px); }
}

/* Logo area in the panel is now a link to the affiliate's website.
   Hover scales the logo up with a slow silky curve matching the rest
   of the site's hover language. */
.affiliate-expand__logo-area {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(12px, 1.6vw, 22px);
  text-decoration: none;
  color: inherit;
}
.affiliate-expand__logo {
  max-width: 100%;
  max-height: clamp(120px, 14vw, 180px);
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
  transform: scale(1);
  /* Slow silky transition both directions */
  transition: transform 1400ms cubic-bezier(0.22, 1, 0.36, 1);
}
.affiliate-expand__logo-area:hover .affiliate-expand__logo {
  transform: scale(1.14);
}

.affiliate-expand__content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(10px, 1.2vw, 16px);
}
.affiliate-expand__name {
  font-family: var(--font-serif);
  font-size: clamp(22px, 2.2vw, 32px);
  font-weight: 600;
  font-style: italic;
  color: var(--crimson-500);
  margin: 0;
  line-height: 1.15;
  letter-spacing: -0.008em;
  text-wrap: balance;
}
.affiliate-expand__location {
  font-family: var(--font-sans);
  font-size: clamp(11px, 0.95vw, 13px);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--wine-700);
  margin: 0;
}
.affiliate-expand__summary {
  font-family: var(--font-serif);
  font-size: clamp(15px, 1.1vw, 17px);
  font-weight: 400;
  color: var(--wine-800);
  line-height: 1.55;
  margin: clamp(6px, 0.6vw, 10px) 0 clamp(10px, 1.2vw, 16px);
  text-wrap: pretty;
}
.affiliate-expand__cta {
  margin-top: clamp(4px, 0.5vw, 8px);
}
/* v32 per Diallo: when the active affiliate has no working website,
   hide the Visit Website CTA and disable the logo-area click. The
   logo still displays — just no longer wrapped as a live link. */
.affiliate-expand.has-no-website .affiliate-expand__cta {
  display: none;
}
.affiliate-expand.has-no-website .affiliate-expand__logo-area {
  cursor: default;
  pointer-events: none;
}

/* ============================
   v8 LAYERED ENTRANCE — each content layer animates in on its OWN
   timeline, driven by CSS custom properties that JS sets per-card
   from a preset library. Re-plays whenever the panel switches to a
   new card, so the user sees a creative transition each time they
   click between affiliates.

   Custom properties JS sets per card:
     --logo-x, --logo-y, --logo-scale, --logo-delay
     --name-x, --name-y, --name-delay
     --loc-x, --loc-y, --loc-delay
     --sum-x, --sum-y, --sum-delay
     --btn-x, --btn-y, --btn-delay
   Each defaults to a sensible value if a card omits a preset.
   ============================ */
.affiliate-expand.is-playing .affiliate-expand__logo-area {
  animation: layer-logo 1100ms cubic-bezier(0.22, 1, 0.36, 1) var(--logo-delay, 100ms) both;
}
.affiliate-expand.is-playing .affiliate-expand__name {
  animation: layer-name 1000ms cubic-bezier(0.22, 1, 0.36, 1) var(--name-delay, 280ms) both;
}
.affiliate-expand.is-playing .affiliate-expand__location {
  animation: layer-loc 900ms cubic-bezier(0.22, 1, 0.36, 1) var(--loc-delay, 440ms) both;
}
.affiliate-expand.is-playing .affiliate-expand__summary {
  animation: layer-sum 1000ms cubic-bezier(0.22, 1, 0.36, 1) var(--sum-delay, 600ms) both;
}
.affiliate-expand.is-playing .affiliate-expand__cta {
  animation: layer-btn 900ms cubic-bezier(0.22, 1, 0.36, 1) var(--btn-delay, 800ms) both;
}

@keyframes layer-logo {
  from { opacity: 0; transform: translate(var(--logo-x, 0), var(--logo-y, 20px)) scale(var(--logo-scale, 1)); }
  to   { opacity: 1; transform: translate(0, 0) scale(1); }
}
@keyframes layer-name {
  from { opacity: 0; transform: translate(var(--name-x, 0), var(--name-y, 18px)); }
  to   { opacity: 1; transform: translate(0, 0); }
}
@keyframes layer-loc {
  from { opacity: 0; transform: translate(var(--loc-x, 0), var(--loc-y, 14px)); }
  to   { opacity: 1; transform: translate(0, 0); }
}
@keyframes layer-sum {
  from { opacity: 0; transform: translate(var(--sum-x, 0), var(--sum-y, 16px)); }
  to   { opacity: 1; transform: translate(0, 0); }
}
@keyframes layer-btn {
  from { opacity: 0; transform: translate(var(--btn-x, 0), var(--btn-y, 18px)); }
  to   { opacity: 1; transform: translate(0, 0); }
}

/* ============================
   v8 CLOSE X — crimson by default, more creative hover. The X stays
   crimson at rest, fills to crimson bg on hover with white stroke,
   rotates 180deg and scales 1.08 with a spring overshoot.
   ============================ */
.affiliate-expand__close {
  position: absolute;
  top: clamp(14px, 1.6vw, 22px);
  right: clamp(14px, 1.6vw, 22px);
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  /* v10: ring goes light tan (subtle), X stays crimson — more refined
     resting state. On hover the whole circle fills crimson. */
  border: 1.5px solid var(--tan-200);
  border-radius: 50%;
  color: var(--crimson-500);
  cursor: pointer;
  transition:
    background 600ms cubic-bezier(0.22, 1, 0.36, 1),
    color 600ms cubic-bezier(0.22, 1, 0.36, 1),
    border-color 600ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 900ms cubic-bezier(0.34, 1.36, 0.64, 1);
}
.affiliate-expand__close svg {
  transition: transform 900ms cubic-bezier(0.22, 1, 0.36, 1);
}
.affiliate-expand__close:hover {
  background: var(--crimson-500);
  color: #FFFFFF;
  border-color: var(--crimson-500);
  transform: scale(1.08) rotate(180deg);
}
.affiliate-expand__close:hover svg {
  transform: scale(1.1);
}

@media (max-width: 1100px) {
  .aff-state__grid--four { grid-template-columns: repeat(3, 1fr); }
  .aff-states-row { grid-template-columns: repeat(4, 1fr); gap: var(--space-6); }
}
@media (max-width: 800px) {
  .aff-state__grid--four { grid-template-columns: repeat(2, 1fr); }
  .aff-states-row { grid-template-columns: repeat(2, 1fr); gap: var(--space-6); }
  .affiliate-expand {
    grid-template-columns: 1fr;
    text-align: center;
  }
  .affiliate-expand__content { align-items: center; }
  .affiliate-expand.is-open { max-height: 900px; }
}
@media (max-width: 640px) {
  /* California stays 2-col on mobile per Diallo 2026-05-31 so the
     8-card grid reads as 4 rows of 2 instead of an 8-deep stack.
     The expansion panel is repositioned per-row by JS so it opens
     inline below the clicked card's row. */
  .aff-state__grid--four { grid-template-columns: repeat(2, 1fr); }
  .aff-hero .aff-hero__inner { text-align: left; margin-left: 0; }
}


/* ================================================================
   CONTACT PAGE
   ================================================================ */

.contact-hero {
  padding-block: clamp(80px, 12vh, 140px);
}
.contact-layout {
  padding-block: clamp(40px, 6vh, 80px) clamp(80px, 12vh, 140px);
}
.contact-layout__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: clamp(40px, 6vw, 96px);
}
.contact-form-col__heading,
.contact-info-col__heading {
  font-family: var(--font-serif);
  font-size: clamp(24px, 2.4vw, 32px);
  font-weight: 600;
  color: var(--wine-800);
  margin: 0 0 var(--space-3);
}
.contact-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.contact-form__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.contact-form__label {
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--wine-800);
}
.contact-form input,
.contact-form select,
.contact-form textarea {
  font-family: var(--font-sans);
  font-size: 16px;
  padding: 14px 16px;
  border: 1px solid rgba(50, 0, 25, 0.18);
  border-radius: var(--radius-md);
  background: #FFFFFF;
  color: var(--wine-800);
  transition: border-color 220ms ease, box-shadow 220ms ease;
}
.contact-form input:focus,
.contact-form select:focus,
.contact-form textarea:focus {
  outline: none;
  border-color: var(--crimson-500);
  box-shadow: 0 0 0 3px rgba(161, 29, 51, 0.16);
}
.contact-form textarea { resize: vertical; min-height: 140px; }
.contact-form__submit {
  align-self: flex-start;
  margin-top: var(--space-4);
}

.contact-info-block {
  padding: var(--space-5) 0;
  border-bottom: 1px solid rgba(50, 0, 25, 0.12);
}
.contact-info-block:last-child { border-bottom: none; }
.contact-info-block__label {
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--crimson-500);
  font-weight: 700;
  margin: 0 0 var(--space-2);
}
.contact-info-block__value {
  font-family: var(--font-serif);
  font-size: 19px;
  font-weight: 600;
  color: var(--wine-800);
  margin: 0;
  text-decoration: none;
}
a.contact-info-block__value {
  border-bottom: 1px solid transparent;
  transition: border-color 220ms ease;
}
a.contact-info-block__value:hover {
  border-bottom-color: var(--crimson-500);
}
.contact-info-block__meta {
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.55;
  color: var(--grey-700);
  margin: var(--space-2) 0 0;
}

@media (max-width: 900px) {
  .contact-layout__grid { grid-template-columns: 1fr; gap: var(--space-10); }
}

/* ============================================
   Donation page — coming-soon placeholder in the left column
   The full form is preserved inside a <template> tag in donation.html
   (parsed but not rendered) so it can be restored as-is when Stripe
   ships. This block fills the left column of .donate-form-grid with
   a sectioned coming-soon message that sits next to the donor sidebar.
   ============================================ */
.donate-coming-soon {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-10) var(--space-8);
  background: rgba(255, 240, 220, 0.4);
  border-radius: var(--radius-lg);
  border-left: 4px solid #C44E2D;
}
.donate-coming-soon__eyebrow {
  font-family: var(--font-sans);
  font-size: 15px;          /* bumped per Diallo — was 11px */
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #9E5A1F;
  margin: 0;
}
.donate-coming-soon__heading {
  font-family: var(--font-serif);
  font-size: clamp(32px, 4vw, 48px);
  font-weight: 600;
  line-height: 1.1;
  color: var(--wine-800);
  margin: 0;
}
.donate-coming-soon__heading .accent {
  color: var(--crimson-500);
  font-style: italic;
}
.donate-coming-soon__body {
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.55;
  color: #333333;
  margin: var(--space-4) 0 0;
}
.donate-coming-soon__body a {
  color: var(--crimson-500);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.donate-coming-soon__sub-action {
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.5;
  color: rgba(50, 0, 25, 0.78);
  margin: var(--space-3) 0 0;
}
.donate-coming-soon__sub-action a {
  color: var(--crimson-500);
  text-decoration: underline;
  text-underline-offset: 3px;
  font-weight: 600;
}
.donate-coming-soon__sub {
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  color: rgba(50, 0, 25, 0.55);
  font-style: italic;
  margin: var(--space-2) 0 0;
}

/* ============================================
   Awards roll — used on the "Region IX Honored Across the Legal Community"
   post. Each item shows a presenting org (eyebrow) and the award name
   (heading), preceded by a right-facing crimson triangle that reads as
   a small play/forward marker. Replaces the previous ordered-list
   numbering. Two-line minimum per item, comfortable vertical rhythm.
   ============================================ */
.awards-roll {
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.awards-roll li {
  display: grid;
  grid-template-columns: 14px 1fr;
  align-items: start;
  gap: var(--space-3);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid rgba(50, 0, 25, 0.08);
}
.awards-roll li:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}
/* Right-facing triangle icon — smaller per Diallo. */
.awards-roll li::before {
  content: '';
  display: block;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 5px 0 5px 8px;
  border-color: transparent transparent transparent var(--crimson-400);
  margin-top: 7px;            /* visual alignment with presenter eyebrow */
  transition: border-left-color 320ms var(--ease-in-out), transform 320ms var(--ease-in-out);
}
.awards-roll li:hover::before {
  border-left-color: var(--crimson-700);
  transform: translateX(2px);
}
.awards-roll li > div {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.awards-roll__presenter {
  font-family: var(--font-sans);
  font-size: 15px;             /* +4px per Diallo (was 11px) */
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--crimson-700);
}
.awards-roll__name {
  font-family: var(--font-serif);
  font-size: 23px;             /* +4px per Diallo (was 19px) */
  font-weight: 500;            /* slightly lighter (was 600) */
  line-height: 1.3;
  color: var(--wine-800);
}

/* ============================================
   Post callout block — the 4-level treatment lifted from the donation
   coming-soon pattern and adapted for in-post use. Used for highlighted
   lists, milestone breakdowns, or any block that deserves to stand
   apart from the body prose. Four levels per the design language:
   eyebrow (small caps), heading (serif title), body (intro), then
   either a list or sub-text closer. Crimson left rule + soft warm
   tinted background sets it off without overwhelming the article.
   ============================================ */
.post-callout {
  margin: 0;
  /* Tighter padding to save vertical room. */
  padding: 32px 32px;
  background: rgba(255, 240, 220, 0.45);
  border-radius: 12px;
  border-left: 3px solid var(--crimson-500);
}
/* All selectors below are scoped with .post-callout to win specificity
   against `.post-body__reference p { font-size: 20px }`, which
   otherwise overrides every <p> inside the callout. */
.post-callout .post-callout__eyebrow {
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--crimson-700);
  margin: 0 0 10px;
  line-height: 1.4;
}
.post-callout .post-callout__heading {
  font-family: var(--font-serif);
  font-size: 26px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--wine-800);
  margin: 0;
}
/* Body intro — much smaller per Diallo; separator below stays as a
   hairline divider between intro and list. */
.post-callout .post-callout__body {
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  color: rgba(50, 0, 25, 0.78);
  margin: 18px 0 0;
  padding-bottom: 18px;
  border-bottom: 1px solid rgba(50, 0, 25, 0.12);
}
.post-callout__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Tighter row padding, smaller font, but still spacious enough to read
   as discrete entries. ~22px row height down to ~17px saves ~45px
   across 9 rows. */
.post-callout .post-callout__list li {
  position: relative;
  padding: 11px 0 11px 20px;
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 600;            /* semi-bold per Diallo */
  line-height: 1.45;
  color: var(--crimson-700);   /* dark crimson — visibly red, still deep */
  border-bottom: 1px solid rgba(50, 0, 25, 0.08);
}
.post-callout .post-callout__list li:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}
.post-callout .post-callout__list li:first-child {
  padding-top: 14px;
}
.post-callout__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 18px;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 4px 0 4px 6px;
  border-color: transparent transparent transparent var(--crimson-400);
}
.post-callout__list li:first-child::before { top: 21px; }

/* ================================================================
   MOBILE — HOMEPAGE TUNING + DEFENSIVE OVERFLOW GUARDS
   Scoped to ≤768px (phone + small tablet portrait). All rules below
   only apply on mobile and do not affect desktop. Per Diallo's mobile
   QA pass, 2026-05-30.
   ================================================================ */
@media (max-width: 768px) {
  /* Global guard — kills horizontal page scroll caused by anything
     overflowing its container. Doesn't change layout, just prevents
     the body from being scrollable sideways. */
  html, body { overflow-x: hidden; }

  /* HOME HERO — fit-to-vertical base, shifted ~650px LEFT total
     from center per Diallo (67% → 78% adds another ~250px). Also
     scaled up 10% to push more of the IX glyph into frame. At
     ~393px viewport with ~2297px image overflow, each 1% of
     object-position ≈ 23px of visual shift. */
  .home-hero__bg img {
    object-position: 78% center;
    transform: scale(1.05);
    transform-origin: 50% 50%;
    transition: object-position 60ms linear;
    animation: hero-bg-fade-in 1200ms var(--ease-reveal) forwards !important;
  }
  /* Mobile hero overlay — dark wine mesh sampled from the image's
     own palette (deep wine base ~#1f0010, mid wine ~#2b0015, warm
     crimson ~#78163a from the IX glyph). Multiple radial layers
     create a mesh-y blend that supports text legibility without
     flat-blocking the image texture. Lower alphas in the
     mid-percentages let the underlying photo come through.

     IMPORTANT: this lives on ::before because motion.css owns the
     ::after pseudo-element (noise texture, loaded AFTER pages.css
     so its background-image wins the cascade). Putting the mesh
     on ::before sidesteps that conflict. ::before renders below
     ::after at equal z-index, so noise grain still lays over the
     mesh — exactly the layer order we want.

     Stack (back → front):
       .home-hero__bg img      (the photo, no z-index)
       .home-hero__bg::before  (this mesh, z-index 1)
       .home-hero__bg::after   (noise grain, z-index 1, paints later)
       .home-hero__content     (text/CTA, higher z-index) */
  .home-hero__bg::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    /* Cinematic entrance — mesh starts invisible and ramps up to
       its full target intensity over 3s on page load. Layers in
       gradually over the image so the IX glyph and map texture
       read at first, then the wine mesh settles into place. */
    opacity: 0;
    animation: hero-mesh-fade-in 3000ms var(--ease-reveal) forwards;
    background:
      /* warm crimson bloom upper-right — echoes the IX glyph */
      radial-gradient(ellipse 70% 55% at 82% 18%,
        rgba(120, 22, 58, 0.62), transparent 65%),
      /* deep wine pool lower-left — under the CTA */
      radial-gradient(ellipse 75% 65% at 18% 88%,
        rgba(20, 0, 10, 0.88), transparent 70%),
      /* soft mid-wine wash across the title band */
      radial-gradient(ellipse 110% 60% at 50% 55%,
        rgba(43, 0, 21, 0.68), transparent 75%),
      /* base vertical for overall coverage + slider hand-off */
      linear-gradient(180deg,
        rgba(31, 0, 16, 0.65) 0%,
        rgba(43, 0, 21, 0.60) 40%,
        rgba(31, 0, 16, 0.78) 75%,
        rgba(15, 0, 8, 0.95) 100%);
  }
  /* HERO + SLIDER + ABOUT VERTICAL RHYTHM (mobile)
     Slider straddles the hero/about seam with its vertical middle
     ON the seam — same pattern as desktop. Slider is 425px tall on
     mobile, so half = 212.5px. Hero gets 312px bottom padding
     (212.5 slider half + ~100 breathing room) and About gets the
     same up top. Slider pulled with -212px margins both sides. */
  .home-hero__content { padding-bottom: 297px; }
  .hero-slider-wrap { margin-top: -212px; margin-bottom: -212px; }
  .home-about { padding-top: 297px; }

  /* HERO SLIDER — fixed 425px height on mobile per Diallo. */
  .hero-slider__viewport {
    aspect-ratio: auto;
    height: 425px;
    max-height: 425px;
  }

  /* Slide 3 (affiliates) — swap to the mobile-specific SVG variant
     that has the IX glyph repositioned for the mobile crop. The
     desktop SVG has IX at x=1175 which gets cropped out almost
     entirely at mobile widths. The mobile SVG centers IX at x=800
     so it lands cleanly in the visible window, above the text
     overlay. Same gradient mesh — only the glyph position differs.
     `content: url()` swaps the rendered source without touching
     the HTML or JS. */
  .hero-slide--affiliates .hero-slide__media img {
    content: url('/assets/images/hero/slide-affiliates-mobile.svg');
  }

  /* Slider overlay darker on mobile so the stacked text + button
     content reads cleanly over the bg image. The gradient ramps to
     full coverage faster — wine-tinted, no pure black. Top half
     lifted per Diallo so eyebrow/title get more coverage from
     the first scroll. */
  .hero-slide__overlay {
    background:
      linear-gradient(180deg,
        rgba(43, 0, 21, 0.28) 0%,
        rgba(43, 0, 21, 0.55) 20%,
        rgba(43, 0, 21, 0.85) 45%,
        rgba(43, 0, 21, 0.94) 65%,
        rgba(43, 0, 21, 0.97) 85%,
        rgba(43, 0, 21, 0.99) 100%);
  }

  /* HOME ABOUT — torch anchored flush to the BOTTOM of the
     section, nudged 75px right of center horizontally. JS scroll-
     driven scale (in initTorchParallax) grows it from bottom-
     center upward (1 → 1.7x, smoothstep eased). transform-origin:
     50% 100% pins the scale anchor at the element's bottom-center
     so growth visually rises upward.

     Entrance on mobile: kill the per-path draw-on used on desktop
     (the trace + fill choreography is too much at this size).
     The icon as a whole simply fades in once .is-revealed lands. */
  .home-about__bg-icon {
    top: auto;
    bottom: -300px;
    left: 50%;
    height: 100vh;
    width: auto;
    opacity: 0;
    fill: #42091A;
    stroke: #42091A;
    transform: translateX(calc(-50% + 75px)) scale(1);
    transform-origin: 50% 100%;
    transition: opacity 1200ms var(--ease-reveal);
  }
  /* Paths show filled immediately on mobile (no trace-on). */
  .home-about__bg-icon path {
    fill-opacity: 1;
    stroke-dasharray: none;
    stroke-dashoffset: 0;
  }
  .home-about__bg-icon.is-revealed { opacity: 0.95; }
  .home-about__bg-icon.is-revealed path { animation: none; }

  /* About body paragraphs — 19px on mobile (was 20). Lighter
     weight, comfortable line-height. */
  .home-about__copy p {
    font-size: 19px;
    line-height: 1.55;
    font-weight: 400;
  }
  /* About headline — another couple pixels smaller (28 → 26) +
     20px more breathing room above so it sits clear of the
     eyebrow. */
  .home-about__headline {
    font-size: 30px;       /* 26 → 30 per Diallo */
    font-weight: 500;      /* down a notch from 600 */
    margin-top: 20px;
  }

  /* AT A GLANCE — overflow guards. Marquee container has its own
     overflow:hidden already; this is belt + suspenders for the
     section, the map column, and the SVG. Also explicitly stacks the
     grid items into a flex column so the map column lands below the
     left column instead of trying to share width. */
  .home-glance { overflow-x: hidden; }
  .home-glance__top {
    display: flex;
    flex-direction: column;
    gap: var(--space-10);
  }
  .home-glance__map-col {
    width: 100%;
    max-width: 100%;
    overflow: hidden;
  }
  .region-map { max-width: 100%; }
  .region-map__svg { overflow: hidden; }

  /* FOOTER — center-justify everything on mobile. Columns already
     stack vertically (1-col grid at narrow widths); this centers the
     content within each column. */
  .site-footer { text-align: center; }
  .site-footer__inner { justify-content: center; }
  .site-footer__brand { align-items: center; }
  .site-footer__nav-col { text-align: center; }
  .site-footer__nav-col h3 { text-align: center; }
  .site-footer__nav-col ul { align-items: center; }
  .site-footer__nav-col a { display: inline-block; }
  .site-footer__nba { align-items: center; }
  /* Bottom row stacks vertically and centers everything on mobile.
     The base layout uses flex with space-between to push the
     copyright left and the BQ credit right; on mobile we want them
     stacked + both centered. */
  .site-footer__bottom {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: var(--space-3);
  }
  /* "All rights reserved." on its own line on mobile only. Span
     wrapper added in the HTML; we just block it here. */
  .site-footer__rights { display: block; }

  /* BACK-TO-TOP FAB — fixed circle, bottom-right, clear-glass look
     with an upward triangle. Mobile only (hidden on desktop via
     base rule below). Reveals via .is-visible (toggled by JS once
     the user has scrolled past ~80% of the viewport). Grow on
     :active for tap feedback. No hover state per Diallo. */
  .back-to-top-fab {
    /* display handled by the rule below the mobile block. */
    align-items: center;
    justify-content: center;
    position: fixed;
    /* Sit closer to the bottom edge per Diallo. env() respects the
       iOS home-indicator safe area, so on a notched device it lifts
       just enough; on devices without one it lands at 8px. */
    bottom: calc(8px + env(safe-area-inset-bottom, 0px));
    right: 18px;
    width: 50px;
    height: 50px;
    padding: 0;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.45);
    background: rgba(255, 255, 255, 0.18);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    backdrop-filter: blur(14px) saturate(140%);
    /* Symmetric ambient shadow (0 offset, soft blur) so the FAB
       can sit close to the viewport bottom without the shadow
       getting clipped by the bottom edge. */
    box-shadow: 0 0 14px rgba(20, 0, 10, 0.22);
    cursor: pointer;
    z-index: 90;
    opacity: 0;
    pointer-events: none;
    transform: scale(1);
    transition: opacity 320ms var(--ease-reveal),
                transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1);
    -webkit-tap-highlight-color: transparent;
  }
  .back-to-top-fab.is-visible {
    opacity: 1;
    pointer-events: auto;
  }
  .back-to-top-fab:active {
    transform: scale(1.18);
  }
  .back-to-top-fab svg {
    width: 16px;
    height: 16px;
    /* Default: white arrow — reads against dark / color / image
       backgrounds (hero, About, slider, mosaic, news, footer). */
    fill: rgba(255, 255, 255, 0.95);
    /* Slight optical lift — triangle visually centers a touch high. */
    transform: translateY(-1px);
    transition: fill 320ms ease;
  }
  /* On light section backgrounds, flip the arrow to crimson so it
     still reads even when the glass capsule goes nearly invisible
     against white. JS toggles .is-on-light when a section tagged
     data-fab-theme="light" is in the FAB's vertical band. */
  .back-to-top-fab.is-on-light svg {
    fill: var(--crimson-500);
  }

  /* Hero mesh entrance — 0 → 1 over 3s. Defined inside the mobile
     block since the mesh itself is mobile-only. */
  @keyframes hero-mesh-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
  }
}

/* Hide the FAB on desktop entirely. */
.back-to-top-fab { display: none; }
@media (max-width: 768px) {
  .back-to-top-fab { display: flex; }
}
/* Sub-note — smallest type, separated from the list by a colored rule
   with breathing space above and below it per Diallo. The rule uses
   a soft crimson tint so it ties to the left accent. */
.post-callout .post-callout__sub {
  font-family: var(--font-sans);
  font-size: 10px;
  line-height: 1.55;
  color: rgba(50, 0, 25, 0.6);
  font-style: italic;
  margin: 24px 0 0;
  padding-top: 18px;
  border-top: 1px solid rgba(161, 29, 51, 0.30);
}
