/*
 * Structural styles for the base template: body defaults, container,
 * sticky site header, primary nav, footer. Sits on top of tokens.css
 * (custom properties) and fonts.css (@font-face for Poppins).
 *
 * Section-specific styles (hero, intro band, cards, news strip, etc.)
 * live in their own files alongside this one.
 */

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

html {
  -webkit-text-size-adjust: 100%;

  /* Anchor scrolling: glide instead of snap, and offset the target
     so it lands below the sticky header instead of being hidden by
     it. Affects every fragment link (e.g. /about/#andre-beck from
     the sermons table). */
  scroll-behavior: smooth;
  scroll-padding-top: 96px;

  /* Reserve scrollbar space so page width does not jump between
     short and long pages or when modals/overlays appear. */
  scrollbar-gutter: stable;

  /* Standard CSS scrollbar styling (Firefox always, Chrome 121+,
     Safari 18.2+). The thumb is a brand-tinted translucent fill via
     color-mix so it reads as branded without competing with content;
     the track stays transparent. */
  scrollbar-width: thin;
  scrollbar-color: color-mix(in oklab, var(--color-brand) 38%, transparent) transparent;
}

/* Honour user preference for reduced motion (accessibility). */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* Tint native form controls (the /sermons/ search input, any
   future checkboxes / radios) to the brand colour. */
:root {
  accent-color: var(--color-brand);
}

/* Chromium-only fallback for the hover transition that the
   standard scrollbar-color spec cannot express. Matches the standard
   styling above so the visual result is identical at rest; on hover
   the thumb tints to full brand red. */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  background: color-mix(in oklab, var(--color-brand) 38%, transparent);
  border: 2px solid transparent;
  background-clip: padding-box;
  border-radius: 999px;
  transition: background-color 0.18s ease-out;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--color-brand);
  background-clip: padding-box;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-weight: var(--weight-regular);
  font-size: var(--size-body);
  line-height: var(--line-body);
  color: var(--color-text);
  background: #fff;
}

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

a {
  color: var(--color-brand);
}

/* Focus ring for keyboard users (mouse clicks suppress it via
   :focus-visible). The default UA outline varies a lot; ours is a
   solid brand-red ring with offset for legibility on any background. */
:focus-visible {
  outline: 2px solid var(--color-brand);
  outline-offset: 2px;
  border-radius: 2px;
}

.btn:focus-visible,
.btn--brand:focus-visible {
  outline-color: #fff;
  outline-offset: -4px;
}

.hero__inner :focus-visible {
  outline-color: #fff;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-weight: var(--weight-bold);
  color: var(--color-heading);
}

/* Container: shared inner-bound for header, footer, and content
   sections. 1200 / 1024 / 767 caps lifted from the live site's
   Elementor kit (reference/design-notes.md). */
.container {
  width: 100%;
  max-width: var(--container-desktop);
  margin: 0 auto;
  padding: 0 24px;
}

@media (max-width: 1024px) {
  .container {
    max-width: var(--container-tablet);
  }
}

@media (max-width: 767px) {
  .container {
    max-width: var(--container-mobile);
    padding: 0 16px;
  }
}

/* ----- Skip to content (keyboard accessibility) ----- */
.skip-link {
  position: absolute;
  left: 0;
  top: 0;
  padding: 8px 16px;
  background: var(--color-brand);
  color: var(--color-on-brand);
  text-decoration: none;
  font-weight: var(--weight-semibold);
  z-index: 200;
  transform: translateY(-110%);
  transition: transform 0.15s ease-out;
}

.skip-link:focus {
  transform: translateY(0);
  outline: 2px solid var(--color-brand-bright);
  outline-offset: 2px;
}

/* ----- Site header ----- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: #fff;
  border-bottom: 1px solid var(--color-rule);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 80px;
  flex-wrap: wrap;
}

/* On desktop, swap to a 3-column grid so the nav block sits in the
   visually-centred middle column with the logo anchored to the left.
   The side columns are fixed-width so they reliably hold the logo
   (178px wide) and balance it on the right; the centre column flexes
   to the remaining width, which keeps both nav rows centred relative
   to the container.
   Threshold = 1100px because below that the row 1 items (~592px)
   don't fit in the remaining nav column, which would force "About
   Us" onto a third row. At narrower viewports the hamburger menu
   takes over instead. */
@media (min-width: 1100px) {
  .site-header__inner {
    display: grid;
    grid-template-columns: 200px 1fr 200px;
    align-items: center;
  }

  .site-header__brand {
    grid-column: 1;
    justify-self: start;
  }

  .site-nav {
    grid-column: 2;
  }
}

/* Mobile menu toggle. Hidden on desktop; on narrow viewports it
   appears as a hamburger that toggles `aria-expanded`, which then
   shows/hides the primary nav. A small inline script in `base.html`
   wires up the click. */
.site-menu-btn {
  display: none;
  cursor: pointer;
  align-items: center;
  gap: 8px;
  background: transparent;
  border: 1px solid var(--color-brand);
  border-radius: 3px;
  color: var(--color-brand);
  padding: 8px 14px;
  font-family: var(--font-sans);
  font-weight: var(--weight-semibold);
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.site-header__brand {
  display: inline-flex;
  align-items: center;
}

.site-header__brand img {
  display: block;
  height: 50px;
  width: auto;
}

/* ----- Primary nav ----- */
.site-nav__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  /* Centred so the shorter second row (3 items) sits under the
     centre of row 1 rather than hanging off to the left. Wrap is
     forced by the .site-nav__break li between item 5 and item 6.
     Row gap is small: line-height already provides visual breathing. */
  justify-content: center;
  gap: 4px 24px;
}

/* Zero-height full-width item that forces a flex wrap. Lives in the
   markup between "About Us" and "News & Updates" so the desktop nav
   splits 5/3 across two rows. */
.site-nav__break {
  flex-basis: 100%;
  height: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav a {
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  color: var(--color-brand);
  text-decoration: none;
  font-size: 14px;
  letter-spacing: 0.5px;
}

.site-nav a:hover,
.site-nav a:focus {
  text-decoration: underline;
}

.site-nav .is-active a {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}

/* Hamburger menu kicks in below 1100px (the threshold where the
   desktop 2-row nav stops fitting): the wrapper becomes a block,
   the menu button is visible, and opening it lays the nav out as a
   full-width stack below the brand row. */
@media (max-width: 1099px) {
  .site-menu-btn {
    display: inline-flex;
  }

  .site-nav {
    display: none;
    flex-basis: 100%;
  }

  .site-menu-btn[aria-expanded="true"] + .site-nav {
    display: block;
    padding-bottom: 12px;
  }

  .site-nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
  }

  .site-nav__break {
    display: none;
  }

  .site-nav__list li {
    border-bottom: 1px solid var(--color-rule);
  }

  .site-nav__list a {
    display: block;
    padding: 12px 4px;
    font-size: 15px;
  }
}

/* ----- Site footer ----- */
.site-footer {
  margin-top: 64px;
  padding: 40px 0;
  border-top: 1px solid var(--color-rule);
  font-size: 14px;
}

.site-footer__inner {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: start;
  gap: 24px;
}

.site-footer__address {
  font-style: normal;
}

.site-footer__contact a {
  color: var(--color-brand);
}

.site-footer__meta {
  color: #666;
  margin: 0;
  grid-column: 1 / -1;
}

.site-footer__socials {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 12px;
}

.site-footer__socials a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--color-brand);
  color: var(--color-on-brand);
  text-decoration: none;
  transition: background 0.15s ease-out;
}

.site-footer__socials a:hover,
.site-footer__socials a:focus {
  background: #9b1010;
}

.social-icon {
  width: 18px;
  height: 18px;
  display: block;
}

@media (max-width: 767px) {
  .site-footer__inner {
    grid-template-columns: 1fr;
  }
}

/* ----- Page (static prose) ----- */
.page {
  max-width: 720px;
  margin: 56px auto 80px;
  padding: 0 24px;
}

.page__header {
  margin-bottom: 32px;
}

.page__title {
  font-size: clamp(2rem, 5vw, 2.5rem);
  line-height: 1.1;
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--color-heading);
  margin: 0;
  /* Shrink to text width so the ::after bar below scales with the
     title rather than always sitting at the same absolute size. */
  width: fit-content;
  max-width: 100%;
}

/* Brand-red rule under every page title. Width tracks the title so
   short headings ("CALENDAR") get a proportional bar and long ones
   ("WHAT'S ON EACH WEEK") get something more substantial; min/max
   keeps it sensible at the extremes. */
.page__title::after {
  content: '';
  display: block;
  width: clamp(56px, 35%, 160px);
  height: 3px;
  background: var(--color-brand);
  margin-top: 18px;
  border-radius: 2px;
}

/* Markdown-rendered body. .prose is the wrapper class on the rendered
   page content; styling targets the elements Zola emits. */
.prose > * + * {
  margin-top: 16px;
}

.prose h2 {
  font-size: 24px;
  line-height: 1.3;
  margin-top: 32px;
  margin-bottom: 12px;
}

.prose h3 {
  font-size: 20px;
  line-height: 1.3;
  margin-top: 24px;
  margin-bottom: 8px;
}

.prose p {
  margin: 0 0 16px;
}

.prose ul,
.prose ol {
  margin: 0 0 16px;
  padding-left: 24px;
}

.prose li + li {
  margin-top: 4px;
}

.prose a {
  color: var(--color-brand);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

/* Scripture reference links, emitted by the `scripture` shortcode and
   macro (e.g. "Luke 15:4" opening the full passage on Bible Gateway).
   Treated as a quiet citation, not a call to action: brand red (from the
   base `a` rule) with a dotted underline that turns solid on hover and
   focus, and kept on one line so a reference never breaks awkwardly. The
   .prose-scoped selector is there to override the solid underline that
   .prose a would otherwise apply. */
.scripture-ref,
.prose a.scripture-ref {
  text-decoration-line: underline;
  text-decoration-style: dotted;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  white-space: nowrap;
}

.scripture-ref:hover,
.scripture-ref:focus-visible,
.prose a.scripture-ref:hover,
.prose a.scripture-ref:focus-visible {
  text-decoration-style: solid;
}

.prose strong {
  font-weight: var(--weight-bold);
}

.prose blockquote {
  margin: 16px 0;
  padding: 8px 16px;
  border-left: 3px solid var(--color-brand);
  color: #555;
}

/* Pull quote: emphasis treatment for declarations like the mission
   statement and the Mark 1:1 quote on About. Use:
     <blockquote class="pullquote">
     ...statement...
     <cite>Optional attribution</cite>
     </blockquote>
   Bigger and bolder than a default blockquote on purpose. */
.prose blockquote.pullquote {
  margin: 28px 0;
  padding: 14px 22px;
  border-left: 4px solid var(--color-brand);
  font-size: 19px;
  font-style: italic;
  line-height: 1.55;
  color: inherit;
}

.prose blockquote.pullquote p {
  margin: 0;
}

.prose blockquote.pullquote p + p {
  margin-top: 12px;
}

.prose blockquote.pullquote cite {
  display: block;
  margin-top: 8px;
  font-size: 15px;
  font-style: normal;
  color: #555;
}

.prose img {
  display: block;
  margin: 24px auto;
}

.prose table {
  width: 100%;
  border-collapse: collapse;
  margin: 16px 0;
  font-size: 15px;
}

.prose thead th {
  text-align: left;
  padding: 12px 14px;
  background: #fafafa;
  border-bottom: 2px solid var(--color-brand);
  font-size: 13px;
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-heading);
}

.prose tbody td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--color-rule);
  vertical-align: top;
}

.prose tbody tr:hover {
  background: rgba(188, 20, 20, 0.03);
}

/* Sermons filter (on /sermons/). Search box above the sermon card grid;
   the JS in /js/sermons.js toggles card visibility (and drives the video
   lightbox). The grid and lightbox themselves are styled in sermons.css. */
.sermons-filter {
  margin: 20px 0 12px;
}

.sermons-filter__label {
  display: block;
  font-size: 12px;
  font-weight: var(--weight-bold);
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--color-heading);
}

.sermons-filter input[type='search'] {
  width: 100%;
  max-width: 480px;
  padding: 10px 14px;
  border: 1px solid var(--color-rule);
  border-radius: 4px;
  font: inherit;
  font-size: 15px;
  background: #fff;
  color: var(--color-text);
}

.sermons-filter input[type='search']:focus-visible {
  outline: 2px solid var(--color-brand);
  outline-offset: 2px;
  border-color: var(--color-brand);
}

.sermons-filter__count {
  margin: 8px 0 0;
  font-size: 13px;
  color: #666;
  min-height: 1.2em;
}

.sermons-filter__empty {
  margin: 16px 0 0;
  font-size: 14px;
  color: #666;
  font-style: italic;
}

/* "All sermons →" link below the trimmed table on /resources/. */
.more-sermons {
  margin: 18px 0 0;
  text-align: right;
}

/* Wrap a wide table in `.table-scroll` to allow horizontal scrolling
   on small screens without breaking layout. */
.table-scroll {
  overflow-x: auto;
  margin: 16px 0;
  -webkit-overflow-scrolling: touch;
}

.table-scroll table {
  min-width: 540px;
  margin: 0;
}

/* Below ~640px the sermons table cannot breathe inside a phone
   viewport. Reflow each row to a stacked card: the video thumbnail on
   top, the title as a heading, then passage / speaker / date as
   labelled meta lines below. thead is visually hidden but kept in the
   DOM for screen readers. NB: the first cell is the play thumbnail
   (added for click-to-play), so the title is the second cell and the
   passage/speaker/date labels start at the third. */
@media (max-width: 640px) {
  .table-scroll {
    overflow-x: visible;
  }
  .table-scroll table {
    min-width: 0;
    display: block;
    font-size: 14px;
  }
  .table-scroll thead {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
  .table-scroll tbody,
  .table-scroll tbody tr,
  .table-scroll tbody td {
    display: block;
    width: 100%;
  }
  .table-scroll tbody tr {
    padding: 14px 16px;
    margin-bottom: 12px;
    border: 1px solid var(--color-rule);
    border-radius: 4px;
    background: #fff;
  }
  .table-scroll tbody tr:hover {
    background: #fff;
  }
  .table-scroll tbody td {
    padding: 2px 0;
    border: none;
  }
  /* Thumbnail sits on top of the stacked card and grows from the fixed
     desktop size to fill the card width (capped). width:auto releases
     the 132px column width lightbox.css gives the desktop table. */
  .sermons-table tbody td.sermons-table__thumb {
    width: auto;
    margin-bottom: 10px;
  }
  .sermons-table tbody td.sermons-table__thumb .sermon-thumb {
    width: 100%;
    max-width: 320px;
  }
  /* Title = second cell. */
  .sermons-table tbody td:nth-child(2) {
    font-size: 16px;
    font-weight: var(--weight-bold);
    margin-bottom: 6px;
    line-height: 1.3;
  }
  .sermons-table tbody td:nth-child(2) a {
    color: var(--color-heading);
    text-decoration: none;
  }
  .sermons-table tbody td:nth-child(2) a:hover,
  .sermons-table tbody td:nth-child(2) a:focus-visible {
    color: var(--color-brand);
    text-decoration: underline;
  }
  /* Passage / speaker / date = labelled meta lines (cells 3-5). */
  .sermons-table tbody td:nth-child(n+3) {
    font-size: 13px;
    color: #555;
  }
  .sermons-table tbody td:nth-child(3)::before { content: 'Passage: '; }
  .sermons-table tbody td:nth-child(4)::before { content: 'Speaker: '; }
  .sermons-table tbody td:nth-child(5)::before { content: 'Date: '; }
  .sermons-table tbody td:nth-child(n+3)::before {
    font-weight: var(--weight-semibold);
    color: var(--color-heading);
  }
  .table-scroll tbody td:empty {
    display: none;
  }
}

/* Brand-coloured external links (YouTube, Spotify). Used inside
   `.prose` next to the corresponding section. */
.brand-links {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 20px 0;
}

.brand-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  border-radius: 4px;
  color: #fff !important;
  text-decoration: none !important;
  font-weight: var(--weight-semibold);
  font-size: 14px;
  letter-spacing: 0.2px;
  transition: filter 0.15s ease-out, transform 0.15s ease-out;
}

.brand-link:hover,
.brand-link:focus-visible {
  filter: brightness(1.1);
  transform: translateY(-1px);
}

.brand-link--youtube     { background: #FF0000; }
.brand-link--spotify     { background: #1DB954; }
.brand-link--ytmusic     { background: #FF0033; }
.brand-link--applemusic  { background: #FA243C; }
.brand-link--gcal        { background: #1A73E8; }
.brand-link--apple-cal   { background: #000; }
.brand-link--outlook     { background: #0078D4; }
.brand-link--ical        { background: var(--color-brand); }

/* `.is-pending` is used on the YouTube Music and Apple Podcasts
   placeholders. Keep the original translucent brand look (the bg
   mutes via rgba alpha so the badge inside is free to stay vivid),
   render them as `<span>` (not `<a>`), so they read as visible but
   not yet linked. */
.brand-link.is-pending {
  cursor: not-allowed;
  filter: grayscale(0.15);
}

.brand-link--ytmusic.is-pending {
  background: rgba(255, 0, 51, 0.55);
}

.brand-link--applemusic.is-pending {
  background: rgba(250, 36, 60, 0.55);
}

.brand-link.is-pending .brand-link__icon,
.brand-link.is-pending .brand-link__label {
  opacity: 0.85;
}

.brand-link.is-pending:hover,
.brand-link.is-pending:focus-visible {
  filter: grayscale(0.15);
  transform: none;
}

/* Solid dark pill so "Coming soon" pops against the muted button. */
.brand-link__badge {
  margin-left: 4px;
  padding: 2px 9px;
  border-radius: 999px;
  background: #111;
  color: #fff;
  font-size: 10px;
  font-weight: var(--weight-bold);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  line-height: 1.4;
}

/* On the resources page the four buttons should sit in a 2x2 (or 4
   across on wide screens) responsive grid. */
.brand-links--grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}

.brand-links--grid .brand-link {
  justify-content: flex-start;
}

.brand-link__icon {
  flex: none;
  width: 20px;
  height: 20px;
}

/* Weekly schedule on the whats-on-each-week page. The `.schedule-grid`
   is a quick "at a glance" anchor list at the top; each `.schedule-item`
   jumps to the detailed `.event` section further down. */
.schedule-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  margin: 16px 0 24px;
}

.schedule-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 16px;
  border: 1px solid var(--color-rule);
  border-top: 3px solid var(--color-brand);
  border-radius: 4px;
  color: var(--color-heading);
  text-decoration: none;
  transition: background 0.15s ease-out, transform 0.15s ease-out;
}

.schedule-item:hover,
.schedule-item:focus-visible {
  background: rgba(188, 20, 20, 0.04);
  transform: translateY(-1px);
}

.schedule-item__day {
  font-size: 11px;
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--color-brand);
}

.schedule-item__time {
  font-size: 16px;
  font-weight: var(--weight-bold);
  line-height: 1.2;
}

.schedule-item__name {
  font-size: 14px;
  color: var(--color-text);
  margin-top: 2px;
}

/* Detailed event sections lower on the page. Each block has a small
   day badge in its header, the event name as a regular h2, and the
   body underneath. */
.event {
  margin: 32px 0;
  padding: 24px 24px 8px;
  border: 1px solid var(--color-rule);
  border-top: 3px solid var(--color-brand);
  border-radius: 4px;
  background: #fff;
  scroll-margin-top: 96px;
}

.event__header {
  margin-bottom: 12px;
}

.event__when {
  margin: 0 0 4px;
  font-size: 14px;
  font-weight: var(--weight-semibold);
  color: var(--color-text);
}

.event__day-badge {
  display: inline-block;
  padding: 2px 10px;
  margin-right: 8px;
  background: var(--color-brand);
  color: var(--color-on-brand);
  border-radius: 999px;
  font-size: 11px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  vertical-align: 1px;
}

.event h2 {
  margin: 0;
  font-size: 24px;
  line-height: 1.2;
}

.event img {
  border-radius: 4px;
  margin: 12px 0 16px;
}

/* Values grid on the what-we-believe page. Each card has a brand-red
   top accent, the value name in brand red, an italic tagline, then
   the body paragraph. */
.values-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
  margin: 20px 0 8px;
}

.value-card {
  padding: 20px 22px;
  border: 1px solid var(--color-rule);
  border-top: 3px solid var(--color-brand);
  border-radius: 4px;
  background: #fff;
  scroll-margin-top: 96px;
}

.value-card__name {
  margin: 0 0 6px;
  font-size: 22px;
  line-height: 1.2;
  color: var(--color-brand);
}

.value-card__tagline {
  margin: 0 0 12px;
  font-style: italic;
  color: #555;
  font-size: 15px;
  line-height: 1.4;
}

.value-card > p:last-child {
  margin-bottom: 0;
}

/* Statement-of-faith style: tighten the spacing under each doctrine
   heading so the bond between heading and paragraph feels tight,
   and add a small brand-red top-rule for visual rhythm. The
   `.prose h3` rule from above sets the type sizes; we only override
   the surrounding ornamentation. */
.prose h3 {
  scroll-margin-top: 96px;
}

/* Leadership photo grids on the about page. Real names + bios are
   Each figure has the photo plus a figcaption with the leader's
   name. */
.people-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 20px;
  margin: 20px 0 32px;
}

.people-grid--single {
  grid-template-columns: minmax(180px, 240px);
}

.person {
  margin: 0;
}

.person img {
  width: 100%;
  height: auto;
  border-radius: 4px;
  display: block;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.person figcaption {
  margin-top: 8px;
  font-size: 14px;
  line-height: 1.35;
  color: var(--color-heading);
}

.person__name {
  font-weight: var(--weight-bold);
}

/* ----- News card + grid (shared by home-page news strip and the
   news index). Each card has an optional featured image at the top,
   then a body with date / title / description / Read More. ----- */
.news-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-rule);
  border-radius: 6px;
  background: #fff;
  overflow: hidden;
  transition: transform 0.15s ease-out, box-shadow 0.15s ease-out;
}

.news-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
  border-color: rgba(188, 20, 20, 0.25);
}

.news-card__media {
  display: block;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: #f5f5f5;
}

.news-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.4s ease-out;
}

.news-card:hover .news-card__media img {
  transform: scale(1.04);
}

.news-card__body {
  padding: 16px 18px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex-grow: 1;
  border-top: 3px solid var(--color-brand);
}

/* When there is no featured image, the body's top accent IS the card
   accent. */
.news-card:not(:has(.news-card__media)) .news-card__body {
  padding-top: 18px;
}

.news-card__date {
  margin: 0;
  font-size: 13px;
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-brand);
}

.news-card__title {
  margin: 0;
  font-size: 20px;
  line-height: 1.3;
  font-weight: var(--weight-bold);
}

.news-card__title a {
  color: var(--color-heading);
  text-decoration: none;
}

.news-card__title a:hover,
.news-card__title a:focus {
  color: var(--color-brand);
  text-decoration: underline;
}

.news-card__cta {
  margin: auto 0 0;
  padding-top: 4px;
}

.news-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  text-align: left;
}

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

.news-card__summary {
  margin: 0;
  font-size: 15px;
  color: #555;
  line-height: 1.5;
}

.news-index {
  margin: 40px auto 64px;
}

.news-index__header {
  margin-bottom: 32px;
}

/* Photo gallery inside news posts. Wrap a cluster of `![](...)` or
   `[![](thumb)](full)` images in `<div class="post-gallery">` to lay
   them out as a uniform grid of clickable thumbnails. */
.post-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 6px;
  margin: 24px 0;
}

/* Markdown wraps consecutive image lines in a single `<p>`, which
   becomes one grid item and squashes the layout. `display: contents`
   makes the `<p>` transparent so the inline `<a>`s become direct grid
   items. */
.post-gallery p {
  display: contents;
  margin: 0;
}

.post-gallery a {
  display: block;
  overflow: hidden;
  border-radius: 3px;
}

.post-gallery img {
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
  margin: 0;
  transition: transform 0.3s ease-out;
}

.post-gallery a:hover img,
.post-gallery a:focus-visible img {
  transform: scale(1.05);
}

/* Calendar / map / generic embed wrappers used inside .prose. */
.calendar-embed,
.map-embed {
  margin: 24px 0;
  width: 100%;
  border-radius: 4px;
  overflow: hidden;
}

.calendar-embed {
  /* Scale with viewport rather than the container's width: a 4:3 box
     was a tiny rectangle on phones and showed only 2-3 agenda events.
     The clamp gives a sensible minimum (~6-8 events visible), grows
     to 80% of viewport height, and caps so it does not become absurd
     on tall monitors. */
  height: clamp(480px, 80vh, 900px);
}


.map-embed {
  aspect-ratio: 16 / 9;
  max-height: 420px;
}

.calendar-embed iframe,
.map-embed iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* ----- News post-specific bits on top of .page ----- */
.post__back {
  margin: 0 0 12px;
  font-size: 14px;
}

.post__back a {
  color: var(--color-brand);
  text-decoration: none;
  text-transform: uppercase;
  font-weight: var(--weight-semibold);
  letter-spacing: 0.5px;
}

.post__back a:hover,
.post__back a:focus {
  text-decoration: underline;
}

.post__meta {
  margin: 8px 0 0;
  color: #666;
  font-size: 14px;
}

@media (max-width: 767px) {
  .page {
    padding: 0 16px;
    margin: 32px auto 48px;
  }
}
