/* ==========================================================
   Supporters of St. Gianna Pregnancy Resource Center
   Top nav, warm ink on sand, oxblood carrying the dark surfaces.
   Deliberately distinct from giannacenter.org, which is
   centered, pink-dominant, and set in a light didone serif.
   ========================================================== */

:root {
  --ink:        #2e2722;   /* headings, warm near-black */
  --ink-soft:   #564b41;
  --ink-2:      #564b41;
  --muted:      #786b5d;   /* darkened to clear 4.5:1 on every ground */
  --cream:      #fbf6ee;   /* warm sand ground */
  --cream-2:    #f5efe3;
  --paper:      #fffdf9;
  --wine:       #7c3f39;   /* oxblood, carries every dark surface */
  --wine-deep:  #5e2e2a;
  --blush:      #edccb8;   /* warm clay */
  --blush-soft: #fbeee2;
  --band:       #f6e4d4;   /* interior page-head ground */
  --line:       #eae2d4;
  --line-2:     #dbd0bd;

  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --display: "Instrument Serif", Georgia, "Times New Roman", serif;

  --pad: clamp(26px, 4.5vw, 80px);
  --measure: 1200px;
  --r: 4px;
  --r-photo: 18px;
  --ease: cubic-bezier(.22, .61, .36, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.62;
  color: var(--ink-2);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4 {
  font-family: var(--sans);
  color: var(--ink);
  font-weight: 600;
  letter-spacing: -.022em;
  line-height: 1.1;
  margin: 0 0 .55em;
  /* balance headings and pretty-wrap body copy so no line ends up
     carrying a single orphaned word. */
  text-wrap: balance;
}

p, li, dd, blockquote, figcaption, .lead, .hero-sub {
  text-wrap: pretty;
}

h1 { font-size: clamp(2.5rem, 4.6vw, 3.9rem); letter-spacing: -.032em; }
h2 { font-size: clamp(1.85rem, 3vw, 2.6rem); letter-spacing: -.028em; }
h3 { font-size: 1.22rem; }
h4 { font-size: 1rem; }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--wine); text-underline-offset: 3px; }
a:hover { color: var(--ink); }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--ink); color: var(--paper); padding: 12px 20px;
}
.skip:focus { left: 8px; top: 8px; }

/* ---------- top nav ---------- */

.topnav {
  position: sticky; top: 0; z-index: 90;
  background: rgba(255, 254, 251, .94);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
  transition: border-color .3s var(--ease), background-color .3s var(--ease);
}
.topnav.is-stuck { border-bottom-color: var(--line-2); background: rgba(255, 254, 251, .97); }
.topnav-inner {
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  width: 100%; max-width: var(--measure); margin-inline: auto;
  padding: 0 var(--pad); min-height: 74px;
  transition: min-height .32s var(--ease);
}
.topnav.is-stuck .topnav-inner { min-height: 62px; }

.brand { display: block; flex-shrink: 0; }
.brand img { width: 118px; transition: width .32s var(--ease); }
.topnav.is-stuck .brand img { width: 100px; }

.nav { display: flex; align-items: center; gap: clamp(20px, 2.6vw, 40px); }
.nav a {
  position: relative; display: flex; align-items: baseline; gap: 8px;
  font-size: .88rem; font-weight: 500; color: var(--ink-2);
  text-decoration: none; padding: 8px 0; white-space: nowrap;
  transition: color .2s var(--ease);
}
.nav a .idx {
  font-size: .62rem; font-weight: 700; letter-spacing: .1em;
  color: var(--line-2); font-variant-numeric: tabular-nums;
  transition: color .2s var(--ease);
}
.nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1.5px;
  background: var(--wine); transform: scaleX(0); transform-origin: left;
  transition: transform .28s var(--ease);
}
.nav a:hover { color: var(--ink); }
.nav a:hover .idx { color: var(--wine); }
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }
.nav a[aria-current="page"] { color: var(--ink); font-weight: 600; }
.nav a[aria-current="page"] .idx { color: var(--wine); }

.nav-actions { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.nav-actions .btn { width: auto; }
/* Declared after .btn so it wins the display race on desktop. */
.nav .nav-cta { display: none; }

.nav-toggle {
  display: none; align-items: center; gap: 8px;
  background: none; border: 1px solid var(--line-2); border-radius: var(--r);
  padding: 9px 15px; font-family: var(--sans); font-size: .74rem; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink); cursor: pointer;
}

/* Slim strip above the nav keeping a path out for people who need services. */
.helpbar {
  background: var(--blush-soft); color: var(--ink-soft);
  border-bottom: 1px solid var(--line);
  font-size: .78rem; letter-spacing: .01em;
}
.helpbar-inner {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px;
  width: 100%; max-width: var(--measure); margin-inline: auto;
  padding: 8px var(--pad);
}
/* Two versions of one line. The full sentence needs about 384px and a 360px
   phone has 324px, so it would always take two rows and push the bar to three.
   The short one holds a single row down to 320px. */
.helpbar .hb-msg--short { display: none; }
.helpbar a { color: var(--wine); font-weight: 600; text-decoration: none; white-space: nowrap; }
.helpbar a:hover { color: var(--ink); }
.helpbar .dot { opacity: .35; }

/* ---------- containers ---------- */

.wrap {
  width: 100%; max-width: var(--measure);
  padding-inline: var(--pad); margin-inline: auto;
}

.section { padding: clamp(56px, 7vw, 96px) 0; border-bottom: 1px solid var(--line); }
.section--paper { background: var(--paper); }
.section--tint { background: var(--cream-2); }

.section-head { max-width: 640px; margin-bottom: clamp(32px, 4vw, 48px); }

.eyebrow {
  display: flex; align-items: center; gap: 12px;
  font-size: .69rem; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--muted);
  margin: 0 0 22px;
}
.eyebrow::after {
  content: ""; flex: 1; height: 1px; background: var(--line-2); max-width: 120px;
}
.eyebrow .n { color: var(--wine); font-variant-numeric: tabular-nums; }

.lead { font-size: 1.1rem; color: var(--ink-soft); }
.muted { color: var(--muted); }

/* ---------- buttons ---------- */

.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  font-family: var(--sans); font-size: .82rem; font-weight: 600;
  letter-spacing: .09em; text-transform: uppercase;
  padding: 14px 26px; border: 1px solid transparent; border-radius: var(--r);
  text-decoration: none; cursor: pointer;
  /* The hover colour wipes in from the left as a background-image, which leaves
     background-color free to hold the resting state. Variants therefore set
     --btn-fill and must use background-color: the background shorthand would
     reset the gradient and kill the wipe. */
  background-image: linear-gradient(var(--btn-fill, transparent), var(--btn-fill, transparent));
  background-repeat: no-repeat;
  background-position: left center;
  background-size: 0% 100%;
  transition: background-size .34s var(--ease), background-color .22s var(--ease),
              color .2s var(--ease) .06s, border-color .24s var(--ease),
              transform .22s var(--ease);
}
.btn:hover { background-size: 100% 100%; transform: translateY(-2px); }
.btn:active { transform: translateY(0); transition-duration: .07s; }

.btn--primary { background-color: var(--wine); color: var(--paper); --btn-fill: var(--wine-deep); }
.btn--primary:hover { color: var(--paper); }

.btn--ghost { background-color: transparent; border-color: var(--line-2); color: var(--ink); --btn-fill: var(--wine); }
.btn--ghost:hover { border-color: var(--wine); color: var(--paper); }

.btn--light { background-color: var(--blush); color: var(--ink); --btn-fill: var(--paper); }
.btn--light:hover { color: var(--ink); }

.btn--outline-light { background-color: transparent; border-color: rgba(255, 255, 255, .38); color: #fff; --btn-fill: #fff; }
.btn--outline-light:hover { border-color: #fff; color: var(--ink); }

.btn--sm { padding: 11px 18px; font-size: .74rem; }

.actions { display: flex; flex-wrap: wrap; gap: 12px; }

.text-link {
  font-weight: 600; font-size: .88rem; color: var(--ink);
  text-decoration: none; border-bottom: 1px solid var(--blush); padding-bottom: 2px;
  transition: color .22s var(--ease), border-color .22s var(--ease);
}
.text-link:hover { border-color: var(--wine); color: var(--wine); }

/* ---------- hero ---------- */

.hero { padding: clamp(64px, 9vw, 128px) 0 clamp(48px, 6vw, 80px); border-bottom: 1px solid var(--line); }
.hero h1 { max-width: 18ch; margin-bottom: .3em; }
.hero h1 .line { display: block; }
.hero h1 em { font-family: var(--display); font-style: italic; font-weight: 400; letter-spacing: -.01em; }
.hero-sub { font-size: 1.16rem; color: var(--ink-soft); max-width: 46ch; margin-bottom: 2.2em; }
.hero-note { margin-top: 34px; padding-top: 22px; border-top: 1px solid var(--line); font-size: .9rem; color: var(--muted); }
.hero-note strong { color: var(--ink); font-weight: 600; }

/* ---------- photo hero ---------- */

.hero--photo {
  position: relative; overflow: hidden; border-bottom: 0;
  display: grid; align-items: end;
  min-height: clamp(460px, 76vh, 720px);
  padding: 0 0 clamp(40px, 6vw, 76px);
}
.hero--photo .hero-bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 52%;
}
.hero--photo .hero-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(
    180deg,
    rgba(24, 21, 19, .34) 0%,
    rgba(24, 21, 19, .12) 28%,
    rgba(24, 21, 19, .42) 68%,
    rgba(24, 21, 19, .68) 100%);
}
.hero--photo .hero-content {
  position: relative;
  /* carries the contrast the lighter scrim gives up */
  text-shadow: 0 1px 2px rgba(20, 17, 15, .34), 0 2px 26px rgba(20, 17, 15, .46);
}
.hero--photo h1 { color: #fff; max-width: 17ch; text-wrap: balance; }
.hero--photo h1 em { color: var(--blush); }
.hero--photo .hero-sub { color: rgba(255, 255, 255, .88); max-width: 44ch; margin-bottom: 2em; }
.hero--photo .eyebrow { color: rgba(255, 255, 255, .78); }
.hero--photo .eyebrow::after { background: rgba(255, 255, 255, .42); }
.hero--photo .hero-note {
  border-top-color: rgba(255, 255, 255, .26);
  color: rgba(255, 255, 255, .78);
}
.hero--photo .hero-note strong { color: #fff; }
.hero--photo .text-link { color: #fff; border-bottom-color: rgba(255, 255, 255, .5); }
.hero--photo .text-link:hover { color: var(--blush); border-bottom-color: var(--blush); }

/* ---------- quote over photo ---------- */

.photoquote {
  position: relative; overflow: hidden;
  padding: clamp(64px, 9vw, 120px) 0;
  border-bottom: 1px solid var(--line);
}
.photoquote img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 45%;
}
/* The photo is a bright sunset behind a white dress, so the scrim stays
   weighted toward the text side even at this lighter setting. */
.photoquote .scrim {
  position: absolute; inset: 0;
  background: linear-gradient(90deg,
    rgba(20, 17, 15, .72) 0%,
    rgba(20, 17, 15, .58) 38%,
    rgba(20, 17, 15, .34) 70%,
    rgba(20, 17, 15, .18) 100%);
}
.photoquote .wrap {
  position: relative;
  display: grid; grid-template-columns: 1fr auto;
  align-items: end; gap: clamp(26px, 4vw, 60px);
}
/* Shadow on the quote only. On the button it would blur the label against its
   own fill. */
.photoquote .quote {
  text-shadow: 0 1px 2px rgba(20, 17, 15, .4), 0 2px 26px rgba(20, 17, 15, .5);
}
/* Centred against the quote, on a panel of its own so the button reads as a
   deliberate block over the photo rather than a control floating on it. The
   blur keeps the label legible wherever the image happens to be light. */
.photoquote .quote-cta {
  align-self: center;
  padding: clamp(20px, 2.4vw, 30px);
  background: rgba(20, 17, 15, .42);
  border: 1px solid rgba(255, 255, 255, .22);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}
/* Needs .quote in the selector: the generic .quote rules are declared later in
   this file at equal specificity and would otherwise win and render dark text. */
.photoquote .quote blockquote { color: #fff; max-width: 20ch; }
.photoquote .quote cite { color: rgba(255, 255, 255, .72); }

/* ---------- page head ---------- */

/* Interior pages open on a tinted band with the logo's bloom bleeding off the
   right edge, so they read as a hero rather than as another content section. */
.pagehead {
  position: relative; overflow: hidden;
  padding: clamp(70px, 9vw, 124px) 0 clamp(56px, 7vw, 88px);
  /* two-tone ground with a hard seam the headline runs across */
  background: linear-gradient(96deg, var(--band) 0 54%, var(--paper) 54%);
  border-bottom: 1px solid var(--line);
}
.pagehead::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: 54%;
  width: 1px; background: var(--wine); opacity: .28;
  transform: skewX(-6deg); transform-origin: top;
}
/* The bloom motif, not the full logo: this element bleeds off the right edge,
   which crops a wordmark mid-word ("St Giann…"). A symmetric flower survives
   the crop; the logo's lettering does not. */
.pagehead::after {
  content: ""; position: absolute; pointer-events: none;
  right: -7%; top: 50%; transform: translateY(-50%);
  width: clamp(330px, 38vw, 560px); aspect-ratio: 1;
  background:
    url("../assets/img/bloom-outline.svg") center / 60% no-repeat,
    url("../assets/img/bloom.svg") center / contain no-repeat;
  opacity: .5;
}
.pagehead .wrap { position: relative; z-index: 1; }
.pagehead h1 { font-size: clamp(2.6rem, 5vw, 4rem); max-width: 24ch; }
/* no cap: the intro is meant to hold a single line on desktop */
.pagehead p { max-width: none; color: var(--ink-soft); font-size: 1.1rem; }
/* --muted measures 4.18:1 on the band, under 4.5 for text this small */
.pagehead .eyebrow { color: var(--ink-soft); }
/* same display-serif accent the home hero uses, for continuity */
.pagehead h1 em {
  font-family: var(--display); font-style: italic; font-weight: 400;
  color: var(--wine); letter-spacing: -.01em;
}

/* ---------- stats ---------- */

.stats {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--line-2); border-bottom: 1px solid var(--line);
}
.stat { padding: 32px 26px; border-right: 1px solid var(--line); text-align: center; }
.stat:last-child { border-right: 0; }
.stat .fig {
  display: block; font-family: var(--display); font-weight: 400;
  font-size: clamp(3rem, 5.4vw, 4.2rem); line-height: .95; color: var(--ink);
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.stat .lbl {
  display: block; margin-top: 14px;
  font-size: .69rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--wine);
}
.stat .sub { margin-top: 10px; font-size: .92rem; color: var(--muted); }

/* ---------- rows (editorial list) ---------- */

.rows { border-top: 1px solid var(--line-2); }
.row {
  display: grid; grid-template-columns: 44px 1.1fr 1.4fr; gap: 26px;
  /* Inline padding cancelled by an equal negative margin, so the hover tint has
     room to breathe without the text moving when it appears. */
  padding: 26px 18px; margin-inline: -18px;
  border-bottom: 1px solid var(--line); align-items: start;
  transition: background-color .3s var(--ease);
}
.row:hover { background-color: var(--blush-soft); }
.row .idx {
  font-size: .72rem; font-weight: 700; letter-spacing: .1em; color: var(--wine);
  font-variant-numeric: tabular-nums; padding-top: 4px;
}
.row h3 { margin: 0; }
.row p { font-size: .97rem; color: var(--muted); margin: 0; }

/* ---------- cards ---------- */

.grid { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }

.card { background: var(--paper); padding: 30px 28px; }
.card h3 { margin-bottom: .45em; }
.card p { font-size: .96rem; color: var(--muted); }
.card .icon { display: none; }
.card--flat { background: var(--paper); }

/* standalone card outside a .grid */
.panel {
  background: var(--paper); border: 1px solid var(--line);
  padding: clamp(26px, 3.4vw, 40px);
}
.panel--wine { background: var(--wine); border-color: var(--wine); color: rgba(255, 255, 255, .84); }
.panel--wine h2, .panel--wine h3, .panel--wine h4 { color: #fff; }
.panel--wine a { color: #fff; }
.panel--wine .btn--light, .panel--wine .btn--light:hover { color: var(--ink); }
.panel--wine .eyebrow { color: rgba(255, 255, 255, .6); }
.panel--wine .eyebrow .n { color: rgba(255, 255, 255, .82); }
.panel--wine .ticks li::before { border-color: rgba(255, 255, 255, .78); }
.panel--wine .form-note { color: rgba(255, 255, 255, .68); }
.panel--wine .eyebrow::after { background: rgba(255, 255, 255, .25); }

/* ---------- lists ---------- */

.ticks { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
.ticks li { position: relative; padding-left: 24px; font-size: .96rem; color: var(--ink-soft); }
.ticks li::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: 11px; height: 6px; border-left: 1.5px solid var(--wine); border-bottom: 1.5px solid var(--wine);
  transform: rotate(-45deg);
}
.ticks--dark li { color: var(--ink-2); }
.crosses li::before {
  border: 0; width: 10px; height: 10px; top: .5em; transform: none;
  background:
    linear-gradient(45deg, transparent 43%, var(--muted) 43%, var(--muted) 57%, transparent 57%),
    linear-gradient(-45deg, transparent 43%, var(--muted) 43%, var(--muted) 57%, transparent 57%);
}

/* ---------- split ---------- */

.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 4vw, 56px); align-items: start; }
/* Panels sitting side by side match height and align their trailing action,
   so the pair reads as one set of cards rather than two ragged blocks. */
.split > .panel { align-self: stretch; display: flex; flex-direction: column; }
/* Scoped to the trailing action only: a blanket :last-child rule also hit
   bare buttons, stretching them full width with lopsided padding. */
.split > .panel > .actions:last-child { margin-top: auto; padding-top: 24px; }
.split > .panel > .btn:last-child { margin-top: auto; align-self: flex-start; }
.split > .panel > .form-note:last-child { margin-top: auto; padding-top: 26px; }
.split--wide-left { grid-template-columns: 1.25fr .75fr; }
/* A hairline down the gutter, the same device the cards and rows use. The gap
   is dropped to zero and rebuilt as padding on each column, so the rule lands
   centred between them rather than hard against the second one. */
/* stretch so the rule runs the full height of the pair, not just the shorter column */
.split--ruled { gap: 0; align-items: stretch; }
.split--ruled > * { padding-inline: clamp(16px, 2.2vw, 30px); }
.split--ruled > *:first-child { padding-left: 0; }
.split--ruled > *:last-child { padding-right: 0; }
.split--ruled > * + * { border-left: 1px solid var(--line-2); }
/* stretch both columns so the map ends up exactly as tall as the card beside it */
.split--match { align-items: stretch; }

.map-frame {
  margin: 0; display: flex; min-height: 340px;
  border: 1px solid var(--line); border-radius: var(--r-photo); overflow: hidden;
}
.map-frame iframe { flex: 1; width: 100%; border: 0; display: block; }

/* ---------- photo slot ---------- */

.photo-slot {
  position: relative; display: grid; place-items: center;
  background: var(--cream-2); border: 1px solid var(--line);
  overflow: hidden; margin: 0;
}
.photo-slot.wide { aspect-ratio: 16 / 9; }
.photo-slot.tall { aspect-ratio: 4 / 5; }
.photo-slot.square { aspect-ratio: 1; }
.photo-slot .bloom { width: 34%; max-width: 150px; opacity: .75; }
.section--tint .photo-slot { background: var(--paper); }

/* ---------- photography ---------- */

.photo { margin: 0; }
.photo img {
  /* height:auto is required: the width/height attributes set a presentational
     height, which would otherwise beat aspect-ratio and render an uncropped image. */
  width: 100%; height: auto;
  border: 1px solid var(--line); border-radius: var(--r-photo);
  object-fit: cover; display: block;
}
.photo.wide img { aspect-ratio: 16 / 9; }
.photo.tall img { aspect-ratio: 4 / 5; }
.photo figcaption {
  margin-top: 12px; font-size: .78rem; letter-spacing: .1em;
  text-transform: uppercase; font-weight: 600; color: var(--muted);
}

/* Full-bleed image band that escapes the centered .wrap. */
.band { border-bottom: 1px solid var(--line); }
.band img {
  width: 100%; height: clamp(280px, 42vw, 520px);
  object-fit: cover; object-position: center 58%; display: block;
}

/* ---------- quote ---------- */

.quote { max-width: none; }
.quote blockquote {
  margin: 0 0 22px;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.7rem, 2.8vw, 2.4rem); line-height: 1.22;
  letter-spacing: -.015em; color: var(--ink);
}
.quote cite {
  font-family: var(--sans); font-style: normal; font-size: .69rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}

/* ---------- steps ---------- */

.steps { display: grid; gap: 0; border-top: 1px solid var(--line); }
.step {
  display: grid; grid-template-columns: 44px 1fr; gap: 20px;
  padding: 22px 0; border-bottom: 1px solid var(--line);
}
.step .num {
  font-size: .72rem; font-weight: 700; letter-spacing: .1em; color: var(--wine);
  font-variant-numeric: tabular-nums; padding-top: 3px;
}
.step h4 { margin-bottom: .3em; }
.step p { font-size: .95rem; color: var(--muted); }

/* ---------- definition list ---------- */

.deflist { display: grid; gap: 0; margin: 0; }
.deflist div { display: grid; gap: 3px; padding: 15px 0; border-bottom: 1px solid var(--line); }
.deflist div:last-child { border-bottom: 0; }
.deflist dt {
  font-size: .66rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted);
}
.deflist dd { margin: 0; font-size: .98rem; color: var(--ink); }
.deflist dd a { text-decoration: none; font-weight: 500; }
.panel--wine .deflist div { border-color: rgba(255, 255, 255, .16); }
.panel--wine .deflist dt { color: rgba(255, 255, 255, .55); }
.panel--wine .deflist dd { color: #fff; }

/* ---------- hours ---------- */

.hours { list-style: none; margin: 0; padding: 0; }
.hours li {
  display: flex; justify-content: space-between; gap: 20px;
  padding: 13px 0; border-bottom: 1px solid var(--line); font-size: .96rem;
}
.hours li:last-child { border-bottom: 0; }
.hours .day { font-weight: 600; color: var(--ink); }
.hours .time { color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---------- cta band ---------- */

.cta { background: var(--wine); color: rgba(255, 255, 255, .84); padding: clamp(40px, 4.4vw, 62px) 0; }
.cta .wrap { text-align: center; }
/* The whole band is one centred column the width of the photo, so the heading,
   the copy and the buttons line up with the image edges instead of running
   wider than it. --cta-col is also what .cta .photo caps at. */
.cta { --cta-col: 720px; }
.cta .wrap > * { max-width: var(--cta-col); margin-left: auto; margin-right: auto; }
.cta h2 { color: #fff; }
.cta p { font-size: 1.08rem; }
.cta .eyebrow { justify-content: center; }
/* mirrored rule so the centred eyebrow is symmetrical */
.cta .eyebrow::before {
  content: ""; flex: 1; height: 1px; background: rgba(255, 255, 255, .25); max-width: 120px;
}
.cta .eyebrow { color: rgba(255, 255, 255, .55); }
.cta .eyebrow::after { background: rgba(255, 255, 255, .25); }
.cta .eyebrow .n { color: rgba(255, 255, 255, .82); }
/* Each tick is absolutely positioned at the left edge of its own item, so in
   a centred band the ticks scatter, one per line length. The list becomes a
   shrink-to-fit column centred as a whole instead, which gives every item the
   same left edge and lines the ticks up under each other. */
.cta .ticks { width: max-content; max-width: 100%; margin-inline: auto; justify-items: start; }
.cta .ticks li { text-align: left; }
.cta .ticks li::before { border-color: rgba(255, 255, 255, .78); }
.cta .actions { margin-top: 32px; justify-content: center; }
/* a CTA band may lead with an image; it centres like the rest of the band */
.cta .photo { max-width: var(--cta-col); margin: 0 auto clamp(32px, 4vw, 48px); }
/* the default hairline disappears on the wine ground */
.cta .photo img { border-color: rgba(255, 255, 255, .24); }

/* ---------- event ---------- */

.event { display: grid; grid-template-columns: 128px 1fr; gap: clamp(22px, 3vw, 44px); border-top: 1px solid var(--line-2); padding-top: 30px; }
.event + .event { margin-top: 30px; }
.event-date { border-right: 1px solid var(--line); padding-right: 20px; }
.event-date .mon { font-size: .69rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--wine); }
.event-date .day { font-family: var(--display); font-size: 3.6rem; line-height: .9; color: var(--ink); display: block; margin: 6px 0 2px; }
.event-date .yr { font-size: .84rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.event-meta { display: grid; gap: 0; margin: 18px 0 24px; font-size: .95rem; }
/* Direct children only: `.event-meta span` also matched the inner .v wrapper,
   turning every value into its own 78px grid and wrapping it a word at a time. */
.event-meta > span { display: grid; grid-template-columns: 88px 1fr; gap: 16px; padding: 11px 0; border-bottom: 1px solid var(--line); color: var(--muted); }
.event-meta > span:first-child { border-top: 1px solid var(--line); }
.event-meta b { color: var(--ink); font-weight: 600; font-size: .69rem; letter-spacing: .12em; text-transform: uppercase; padding-top: 3px; }
/* Every child element of a grid container is its own grid item, so a bare
   <cite> in one of these rows became a third item and dropped onto an
   implicit row back in the 78px label column. Each value is wrapped in .v so
   a row is always exactly two items and the value reads as one run. */
.event-meta .v { min-width: 0; }
/* The book title is one unit and does not break across lines. */
.event-meta cite { font-style: italic; white-space: nowrap; }
.event .tag {
  display: inline-block; font-size: .66rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--wine); background: var(--blush-soft);
  padding: 5px 11px; margin-bottom: 14px;
}

/* ---------- gallery ---------- */

.gallery {
  display: grid; grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 210px; gap: 14px;
  /* dense so the taller portraits do not leave holes behind them */
  grid-auto-flow: dense;
}
.gallery figure {
  margin: 0; overflow: hidden; border-radius: var(--r-photo);
  border: 1px solid var(--line); background: var(--cream-2);
}
.gallery img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Podium shots frame the speaker high; centring the crop clips the forehead. */
.gallery .up img { object-position: center 26%; }
/* Portraits keep their full height instead of being cropped to a letterbox. */
.gallery .tall { grid-row: span 2; }
.gallery .wide { grid-column: span 2; }
.gallery figcaption {
  margin-top: 10px; font-size: .78rem; color: var(--muted);
}

@media (max-width: 900px) {
  .gallery { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 190px; }
}
@media (max-width: 560px) {
  .gallery { grid-template-columns: 1fr; grid-auto-rows: auto; }
  .gallery figure { aspect-ratio: 4 / 3; }
  .gallery .tall { grid-row: auto; }
  .gallery .tall figure, .gallery figure.is-tall { aspect-ratio: 3 / 4; }
  .gallery .wide { grid-column: auto; }
}

/* ---------- give ---------- */

.give { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.give-card { display: flex; flex-direction: column; background: var(--paper); padding: 30px 28px; }
.give-card h3 { margin-bottom: .45em; }
.give-card p { font-size: .96rem; color: var(--muted); flex: 1; }
.give-card .btn { margin-top: 24px; align-self: flex-start; }

/* ---------- people: this year's speaker and honoree ---------- */

.person-head {
  display: flex; align-items: center; gap: 18px;
  padding-bottom: 20px; margin-bottom: 20px;
  border-bottom: 1px solid var(--line);
}
.person-photo {
  flex: 0 0 auto; width: 88px; height: 88px;
  object-fit: cover; border-radius: var(--r);
  border: 1px solid var(--line-2); background: var(--cream-2);
}
/* A logo is a mark, not a face, so it sits inside its tile instead of
   filling it. The PNGs are knocked out, hence the ground behind them. */
.person-photo--mark {
  object-fit: contain; padding: 9px;
  background: var(--paper); border-color: var(--line);
}
.person-id { min-width: 0; }
/* The eyebrow's trailing rule is drawn for a full-width section head and
   looks like a stray hairline in a name block this narrow. */
.person-id .eyebrow { margin-bottom: 9px; }
.person-id .eyebrow::after { display: none; }
.person-id h3 { margin-bottom: .2em; }
/* The role is one unit: broken after the colon it reads as two unrelated
   lines. Two windows are too narrow to hold it, the paired cards between 640
   and 780 and phones under 400, and there it is allowed to wrap. */
.person-role { font-size: .9rem; color: var(--muted); margin: 0; white-space: nowrap; }
@media (min-width: 641px) and (max-width: 780px), (max-width: 430px) {
  .person-role { white-space: normal; }
}
.person-role cite { font-style: italic; }

.accepting {
  display: flex; align-items: center; gap: 14px;
  margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--line);
}
.accepting img {
  flex: 0 0 auto; width: 54px; height: 54px;
  object-fit: cover; border-radius: var(--r); border: 1px solid var(--line-2);
}
.accepting b {
  display: block; color: var(--ink); font-weight: 600;
  font-size: .69rem; letter-spacing: .12em; text-transform: uppercase;
  margin-bottom: 4px;
}

/* ---------- past honorees and speakers ---------- */

/* Long for a pull quote, so it is set well below .quote's display size and
   carries a rule instead, which keeps it readable at full paragraph length. */
.award-quote {
  margin: 0 0 clamp(28px, 3.5vw, 40px);
  padding-left: clamp(20px, 2.6vw, 32px);
  border-left: 2px solid var(--wine);
  max-width: 62ch;
}
.award-quote blockquote { margin: 0; }
.award-quote blockquote p {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.12rem, 1.5vw, 1.3rem); line-height: 1.45;
  letter-spacing: -.005em; color: var(--ink);
}
.award-quote figcaption {
  margin-top: 16px;
  font-size: .69rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted);
}
.award-quote figcaption cite { font-style: normal; }
.award-intro {
  max-width: 62ch; font-size: 1.05rem; color: var(--ink-soft);
  margin: 0 0 clamp(34px, 4.5vw, 52px);
}

/* The head, the quote and the intro drop their own caps here so the copy runs
   the same width as the roster below it. Capped at 640px and 62ch they sat in
   a narrow column above a full-width grid, and the two read as one block that
   had come apart. The section keeps the site's ordinary measure. */
#life-award .section-head,
#life-award .award-quote,
#life-award .award-intro { max-width: none; }

.roster-title {
  font-size: .69rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted);
  margin: 0 0 24px; padding-bottom: 14px;
  border-bottom: 1px solid var(--line-2);
}
.roster {
  list-style: none; margin: 0 0 clamp(38px, 5vw, 58px); padding: 0;
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: clamp(26px, 3.2vw, 40px) clamp(28px, 4vw, 56px);
}
.roster:last-of-type { margin-bottom: 0; }
.roster-item { display: grid; grid-template-columns: 96px 1fr; gap: 20px; align-items: start; }
.roster-photo {
  width: 96px; height: 96px; object-fit: cover;
  border-radius: var(--r); border: 1px solid var(--line-2);
}
.roster-yr {
  font-size: .69rem; font-weight: 700; letter-spacing: .14em; color: var(--wine);
  font-variant-numeric: tabular-nums; margin: 0 0 6px;
}
.roster-item h4 { margin-bottom: .45em; }
.roster-item p { font-size: .93rem; color: var(--muted); margin: 0; }
.roster-item .roster-note { margin-top: .75em; font-size: .84rem; color: var(--ink-soft); }
.roster-foot { margin-top: clamp(26px, 3vw, 38px); text-align: center; }

/* ---------- sponsor logos ---------- */

/* Sits under Request the Packet in the left column. No rule above it and a
   short gap: the wine panel beside it stretches to this column's height, so
   every pixel here opens a gap under the panel's own copy. */
.sponsors { margin-top: clamp(22px, 2.6vw, 30px); }
.sponsors .eyebrow { margin-bottom: 14px; }
.sponsor-logos {
  list-style: none; margin: 0 0 14px; padding: 0;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: clamp(28px, 5vw, 64px);
}
/* Sized by height so a wordmark and a square shield read at the same weight. */
.sponsor-logos img { height: 56px; width: auto; }
.sponsor-logos img.is-square { height: 74px; }

/* ---------- form ---------- */

.form { display: grid; gap: 18px; max-width: 520px; }
.field { display: grid; gap: 7px; }
.field label { font-size: .69rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--muted); }
.field input, .field textarea, .field select {
  font-family: var(--sans); font-size: 1rem; color: var(--ink);
  padding: 13px 14px; border: 1px solid var(--line-2); border-radius: var(--r);
  background: var(--paper); width: 100%;
}
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none; border-color: var(--ink); box-shadow: 0 0 0 3px var(--blush-soft);
}
.field textarea { resize: vertical; min-height: 130px; }
.form-note { font-size: .85rem; color: var(--muted); }
.form-status { font-size: .93rem; font-weight: 500; }
.form-status.ok { color: #2f6b45; }
.form-status.err { color: #9c3b36; }

/* ---------- footer ---------- */

.footer { background: var(--paper); padding: clamp(44px, 5vw, 68px) 0 0; }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: clamp(26px, 4vw, 48px); padding-bottom: 42px; }
.footer img.mark { width: 128px; margin-bottom: 16px; }
.footer h3 { font-size: .66rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); margin-bottom: 14px; }
.footer p, .footer a { font-size: .9rem; color: var(--muted); }
.footer a { display: block; text-decoration: none; padding: 3px 0; }
.footer a:hover { color: var(--wine); }
.footer-note { max-width: 32ch; }
.footer-bottom {
  border-top: 1px solid var(--line); padding: 20px 0 34px;
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px 26px;
  font-size: .82rem; color: var(--muted);
}
/* the credit holds one line and drops to its own row instead of breaking */
.footer-bottom .credit { white-space: nowrap; flex: 0 0 auto; }
/* .footer a is display:block for the link columns above, which pushed the studio
   name onto its own line here no matter what white-space said. */
.footer-bottom .credit a {
  display: inline; font-size: inherit;
  color: var(--ink-soft); text-decoration: none;
  border-bottom: 1px solid var(--line-2); padding: 0 0 1px;
  transition: color .22s var(--ease), border-color .22s var(--ease);
}
.footer-bottom .credit a:hover { color: var(--wine); border-color: var(--wine); }

/* ---------- motion ---------- */

/* Everything below hides content until it is revealed, so it is scoped to .js,
   which the inline script in <head> sets. If the script never runs the page
   still renders in full, just without the motion. */

/* The page arrives rather than snapping in. Opacity only: a transform on body
   would knock the sticky nav and the fixed mobile panel out of position. */
@keyframes page-in { from { opacity: 0; } to { opacity: 1; } }
.js body { animation: page-in .4s var(--ease) both; }

@keyframes rise-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* Page-head copy sits above the fold, so it enters on load instead of waiting
   for a scroll. Held to well under a second: this is the largest text on the
   page and a long fade would show up as a slower paint. */
.js .hero-content > *,
.js .pagehead .wrap > * { animation: rise-in .58s var(--ease) both; }
.js .hero-content > *:nth-child(1), .js .pagehead .wrap > *:nth-child(1) { animation-delay: .05s; }
.js .hero-content > *:nth-child(2), .js .pagehead .wrap > *:nth-child(2) { animation-delay: .13s; }
.js .hero-content > *:nth-child(3), .js .pagehead .wrap > *:nth-child(3) { animation-delay: .21s; }
.js .hero-content > *:nth-child(4), .js .pagehead .wrap > *:nth-child(4) { animation-delay: .29s; }
.js .hero-content > *:nth-child(n+5), .js .pagehead .wrap > *:nth-child(n+5) { animation-delay: .37s; }

/* Scroll reveal. --d is set in main.js so blocks that cross the fold together
   cascade instead of all landing at once. */
.reveal { transition: opacity .62s var(--ease), transform .62s var(--ease); transition-delay: var(--d, 0s); }
.js .reveal { opacity: 0; transform: translateY(16px); }
.js .reveal.in { opacity: 1; transform: none; }

/* Containers that stagger their own children, for lists long enough that one
   fade would look flat. */
[data-stagger] > * { transition: opacity .55s var(--ease), transform .55s var(--ease); }
.js [data-stagger] > * { opacity: 0; transform: translateY(13px); }
.js [data-stagger].in > * { opacity: 1; transform: none; }
[data-stagger].in > *:nth-child(1) { transition-delay: 0s; }
[data-stagger].in > *:nth-child(2) { transition-delay: .07s; }
[data-stagger].in > *:nth-child(3) { transition-delay: .14s; }
[data-stagger].in > *:nth-child(4) { transition-delay: .21s; }
[data-stagger].in > *:nth-child(5) { transition-delay: .28s; }
[data-stagger].in > *:nth-child(6) { transition-delay: .35s; }
[data-stagger].in > *:nth-child(n+7) { transition-delay: .42s; }

/* Keyboard focus was inheriting the browser default, which is invisible against
   the sand ground on the dark panels. */
:focus-visible { outline: 2px solid var(--wine); outline-offset: 3px; }
.panel--wine :focus-visible,
.hero--photo :focus-visible,
.btn--outline-light:focus-visible { outline-color: var(--blush); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js body,
  .js .hero-content > *,
  .js .pagehead .wrap > * { animation: none; }
  .js .reveal,
  .js [data-stagger] > * { opacity: 1; transform: none; transition: none; }
  .btn, .btn:hover, .btn:active { transition: none; transform: none; }
  .topnav, .topnav-inner, .brand img, .row { transition: none; }
}

/* ---------- responsive ---------- */

@media (max-width: 1080px) {
  .split--wide-left { grid-template-columns: 1fr; }
  /* Two cards side by side leave the name block too narrow to sit beside its
     portrait, so the head stacks well before the grid itself does. Stacking
     here rather than at 900 is also what gives the role line its one line. */
  .person-head { flex-direction: column; align-items: flex-start; gap: 14px; }
}

@media (max-width: 900px) {
  .pagehead { background: linear-gradient(168deg, var(--band) 0%, var(--blush-soft) 100%); }
  .pagehead::before { display: none; }
  /* The mark carries a wordmark, and behind an h1 at this width it reads as a
     smudge rather than as branding. The band stands on its own. */
  .pagehead::after { display: none; }
  .nav-toggle { display: inline-flex; }
  .header-cta { display: none; }
  .nav-cta { display: inline-flex; }

  .nav {
    position: fixed; inset: 0 0 auto; top: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--paper); padding: 92px var(--pad) 30px;
    border-bottom: 1px solid var(--line);
    transform: translateY(-100%); visibility: hidden;
    transition: transform .34s var(--ease), visibility 0s linear .34s;
    max-height: 100dvh; overflow-y: auto;
  }
  .nav.open {
    transform: none; visibility: visible;
    transition: transform .34s var(--ease), visibility 0s;
  }
  .nav a { padding: 14px 0; border-bottom: 1px solid var(--line); font-size: 1rem; }
  .nav a::after { display: none; }
  .nav .btn { margin-top: 20px; }
  /* The open panel is fixed to the top of the viewport and covers the header
     row, so both halves of that row have to be lifted over it. The toggle
     already was; without the same on the brand the logo went under the panel
     and the menu opened with nothing in the top left. */
  .nav-toggle, .brand { position: relative; z-index: 95; }

  .split { grid-template-columns: 1fr; }
  .roster { grid-template-columns: 1fr; }
  /* Stacked, so the gutter rule becomes a rule between the rows. */
  .split--ruled { gap: clamp(24px, 4vw, 34px); }
  .split--ruled > * { padding-inline: 0; }
  .split--ruled > * + * { border-left: 0; border-top: 1px solid var(--line-2); padding-top: clamp(24px, 4vw, 34px); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 640px) {
  body { font-size: 16px; }
  .grid-2, .grid-3, .give { grid-template-columns: 1fr; }
  .stats { grid-template-columns: 1fr; }
  .stat { border-right: 0; border-bottom: 1px solid var(--line); padding-right: 0; }
  .stat:last-child { border-bottom: 0; }
  .row { grid-template-columns: 32px 1fr; gap: 14px; }
  .row p { grid-column: 2; }
  /* The hero crops to a tall, narrow window here, about 43% of the frame. At
     42% that window sat on the sunset and the houses and cut the mother and
     baby off the right edge entirely. At 70% it holds both of them. The type
     runs over them, which the scrim and the text shadow carry. */
  .hero--photo .hero-bg { object-position: 70% 50%; }

  .event { grid-template-columns: 1fr; }
  .roster-item { grid-template-columns: 76px 1fr; gap: 16px; }
  .roster-photo { width: 76px; height: 76px; }
  .sponsor-logos img { height: 46px; }
  .sponsor-logos img.is-square { height: 62px; }
  .event-date { border-right: 0; border-bottom: 1px solid var(--line); padding: 0 0 16px; display: flex; align-items: baseline; gap: 10px; }
  .event-date .day { margin: 0; font-size: 2.4rem; }
  .footer-grid { grid-template-columns: 1fr; }
  .quote { max-width: none; }

  /* The 78px label column eats a quarter of a phone screen, so the label goes
     above its value and the value gets the full width. That is also what lets
     the speaker's book title stay on one line here. */
  .event-meta span { grid-template-columns: 1fr; gap: 3px; }
  .event-meta b { padding-top: 0; }

  /* Centred and tight on a phone. Wrapped, the separator dots strand at the
     ends of lines, so they go, the sentence takes its own row and the two
     links sit centred underneath it. */
  .helpbar-inner {
    justify-content: center; text-align: center;
    padding: 6px 18px; gap: 2px 14px;
  }
  .helpbar { font-size: .75rem; }
  .helpbar .dot { display: none; }
  .helpbar .hb-msg { display: none; }
  .helpbar .hb-msg--short { display: block; flex: 0 0 100%; }
  .helpbar a { padding: 2px 0; }

  /* 3px of padding on a .9rem link is a 22px tap target. */
  .footer a { padding: 8px 0; }
}

@media (max-width: 760px) {
  .photoquote .wrap { grid-template-columns: 1fr; align-items: start; }
  /* Stacked the column is full width, so the panel is pulled back to the
     button it wraps instead of running the width of the quote above it. */
  .photoquote .quote-cta { justify-self: start; }
}

/* ---------- phones: centred, and a shorter footer ---------- */

/* Declared last so it wins over the breakpoint blocks above rather than
   fighting them on specificity. */
@media (max-width: 640px) {
  /* Everything centres except the heroes. A hero is a full-bleed photo or a
     tinted band carrying its own left-aligned editorial column, and centring
     it loses the shape each page opens on. */
  .section, .footer, .photoquote { text-align: center; }
  .hero, .pagehead { text-align: left; }

  /* The sentence and the link ran together on one wrapped line. The link takes
     its own line under it, which also gives it a full-width tap target. */
  .hero-note .text-link { display: inline-block; margin-top: 10px; }
  .hero-note strong { display: block; }

  /* The eyebrow's rule is drawn to trail a left-aligned label, so it gains its
     mirror and centres, the way the CTA band already does. */
  .section .eyebrow, .footer .eyebrow { justify-content: center; }
  .section .eyebrow::before {
    content: ""; flex: 1; height: 1px; background: var(--line-2); max-width: 120px;
  }

  .actions { justify-content: center; }
  .give-card .btn, .split > .panel > .btn:last-child { align-self: center; }
  .section-head, .footer-note, .form, .quote blockquote { margin-inline: auto; }

  /* Blocks whose art sat beside the copy put it above the copy instead, so it
     centres over it rather than stranding a centred paragraph beside a photo. */
  .roster-item { grid-template-columns: 1fr; justify-items: center; gap: 12px; }
  .person-head { align-items: center; }
  .accepting { flex-direction: column; }
  .sponsor-logos { justify-content: center; }
  .event-meta span { justify-items: center; }
  .event-date { justify-content: center; }
  .row { grid-template-columns: 1fr; justify-items: center; gap: 8px; }
  .row p { grid-column: 1; }

  /* A rule down the left of centred text reads as a mistake. */
  .award-quote { border-left: 0; padding-left: 0; }

  /* Same as the CTA band: the list centres as one shrink-to-fit column so the
     ticks line up, rather than each item centring on its own. */
  .ticks { width: max-content; max-width: 100%; margin-inline: auto; justify-items: start; }
  .ticks li { text-align: left; }

  /* Typed input is never centred. */
  .field input, .field textarea, .field select { text-align: left; }

  .photoquote .quote-cta { justify-self: center; }

  /* The two link columns repeat the top nav and the contact page, so on a
     phone the footer is the mark, the one-line note and the legal row. */
  /* img is display:block globally, so text-align never reached the mark. */
  .footer img.mark { margin-inline: auto; }
  .footer-grid > div:nth-child(n+2) { display: none; }
  .footer-grid { padding-bottom: 26px; }
  .footer-bottom { justify-content: center; text-align: center; }
}
