/* ============================================================================
   gallery.css — the Media page
   ============================================================================
   Loaded AFTER assets/campaign.css, and only for gallery.html. It adds the two
   things the shared sheet genuinely has no class for: a dark page-title band
   (the homepage's only dark opener is the hero, which is a different animal
   entirely — full-bleed, slideshow, 780px tall) and the photo grid.

   Everything else on the page reuses campaign.css. No campaign colour is typed
   as a hex value below: every one is a token from that sheet's CAMPAIGN
   IDENTITY block, so re-skinning the site still re-skins this page.
   ========================================================================= */

/* campaign.js measures the fixed header and writes that height onto
   #site-top-spacer. With JavaScript off it never runs, the spacer stays at
   zero, and the band below would sit underneath the header. The homepage
   survives that because its hero carries its own 120px of top padding; this
   page has no such cushion, so the spacer keeps a floor of the header's
   minimum height. JS still overwrites it with the real measurement when it
   runs, including when the mobile menu makes the header taller. */
#site-top-spacer { min-height: 71px; }

/* The Media entry in the header IS this page. aria-current tells assistive
   tech; this tells everyone else. */
.nav-link[aria-current="page"],
.m-link[aria-current="page"] { color: var(--brand); font-weight: 700; }

/* ----------------------------------------------------------- page title -- */
.page-head { background: var(--brand-deep); color: #FFF; }
.page-head h1 {
  margin: 0 0 12px;
  font-size: clamp(32px, 5vw, 54px);
  line-height: 1.08;
  text-wrap: pretty;
}
.page-head-lead {
  font-size: clamp(16px, 2vw, 19px);
  line-height: 1.6;
  color: var(--on-brand-2);
  max-width: 58ch;
}

/* ---------------------------------------------------------- photo grid -- */
.gal { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 640px)  { .gal { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .gal { grid-template-columns: repeat(3, 1fr); } }

.gal-fig { margin: 0; display: flex; flex-direction: column; }

/* .img-frame (campaign.css) supplies the neutral ground and the clip, so a
   photo that fails to load leaves a plain panel instead of a broken icon. */
.gal-img { aspect-ratio: 4 / 3; border-radius: 12px; }
.gal-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; }
.gal-img:hover img { transform: scale(1.04); }

/* NO TILE CARRIES A CAPTION TODAY. The design's thirteen captions each stated
   where a photograph was taken, who was in it or what the occasion was, and
   none of it had been confirmed, so gallery.html deletes them rather than
   guess. This rule is kept — and only this rule — so that the day someone who
   was there can say what a picture shows, a <figcaption class="gal-cap"> drops
   straight back into that tile and looks right. Delete it if the campaign
   decides the gallery stays wordless. */
.gal-cap { margin: 10px 0 0; font-size: 14px; line-height: 1.5; color: var(--ink-3); }

/* The artboard greys this credit line further than any token goes (#8A938C).
   At 13px that measures about 3.1:1 against the paper ground — under the 4.5:1
   the rest of the site holds itself to — so it keeps --ink-3 and steps down in
   size instead, which carries the same "quieter than the captions" intent. */
.gal-note { margin: 36px 0 0; font-size: 13px; line-height: 1.6; color: var(--ink-3); }
