/* site/assets/css/style.css */

/* The owner's FM family. The files are licensed and deliberately not in git;
   if they are missing the browser falls back to the warm serif stack below. */
@font-face { font-family: 'FM'; font-weight: 300; font-style: normal; font-display: swap; src: url('../fonts/FM-Light.woff2') format('woff2'); }
@font-face { font-family: 'FM'; font-weight: 300; font-style: italic; font-display: swap; src: url('../fonts/FM-LightItalic.woff2') format('woff2'); }
@font-face { font-family: 'FM'; font-weight: 400; font-style: normal; font-display: swap; src: url('../fonts/FM-Regular.woff2') format('woff2'); }
@font-face { font-family: 'FM'; font-weight: 500; font-style: normal; font-display: swap; src: url('../fonts/FM-Medium.woff2') format('woff2'); }
@font-face { font-family: 'FM'; font-weight: 500; font-style: italic; font-display: swap; src: url('../fonts/FM-MediumItalic.woff2') format('woff2'); }
@font-face { font-family: 'FM'; font-weight: 700; font-style: normal; font-display: swap; src: url('../fonts/FM-Bold.woff2') format('woff2'); }

:root {
  /* The owner's palette. */
  --color-white: #ffffff;
  --color-cream: #fdf6eb;
  --color-sand: #d1c2b8;
  /* The original khaki (#c2ba95) and olive (#ab9e76), lightened about 35 percent toward white so
     dark text reads easily on them and the bands sit softly. */
  --color-khaki: #d7d2ba;
  --color-olive: #c8c0a6;
  --color-brown: #744836;
  --color-rule: #424242;

  /* Roles. --color-accent is used for text and links, so it is the brown
     (7.7:1 on white). The active nav item uses a darker olive than the palette
     olive (#ab9e76 is only 2.7:1 on white): #7a6d47 is about 5.1:1. */
  --color-bg: var(--color-white);
  --color-text: #2c2a20;
  --color-muted: #706a50;
  --color-accent: var(--color-brown);
  --color-nav-active: #7a6d47;
  --color-overlay: rgba(253, 246, 235, 0.54);

  /* The accents of the white pass. A rule needs more presence on white than a
     panel fill does, so these are their own tokens and do not follow the khaki
     and olive fills when those are lightened. */
  --color-accent-rule: #b8ae86;
  --color-accent-hair: #cfc8ae;

  --font-display: 'FM', Georgia, 'Times New Roman', serif;
  --font-body: 'FM', Georgia, 'Times New Roman', serif;

  /* Side gutter: wider on desktop so content clears the fixed side texts. */
  --gutter: 24px;
  --header-height: 80px;
}

@media (min-width: 1000px) {
  :root { --gutter: 64px; }
}

* { box-sizing: border-box; }

/* FM's default ligatures turn "st" into a long s (Sebeſtyen); keep letters plain. */
* { font-variant-ligatures: none; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 17px;
  line-height: 1.65;
}

h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 500; }

button, input, select, textarea { font-family: inherit; }

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

:focus-visible { outline: 2px solid var(--color-text); outline-offset: 3px; }

/* Header and nav ------------------------------------------------------- */

.site-header {
  position: relative;
  z-index: 10;
  display: flex;
  justify-content: flex-end;
  align-items: flex-start;
  min-height: var(--header-height);
  padding: 16px var(--gutter) 0;
  background: var(--color-bg);
}

@media (min-width: 1000px) {
  .site-header { padding-right: 80px; }
}

.nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.nav-item {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--color-text);
}

.nav-item:hover { text-decoration: underline; text-underline-offset: 6px; }

/* Header items: 50px tall, a 1px rule between neighbours, like the original. */
.nav .nav-item {
  display: flex;
  align-items: center;
  height: 50px;
}

.nav .nav-item + .nav-item {
  margin-left: 15px;
  padding-left: clamp(16px, 3.4vw, 48px);
  border-left: 1px solid var(--color-text);
}

/* Olive-gold on white is only 2.7:1, so the active item also carries an underline. */
.nav .nav-item.is-active {
  color: var(--color-nav-active);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 6px;
}

.nav-toggle {
  display: none;
  min-height: 44px;
  padding: 0 4px;
  border: 0;
  background: none;
  color: var(--color-text);
  font-weight: 300;
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
}

/* Collapsed menu: only when scripting is on (a tiny inline script in the head adds
   the .js class before first paint), so the nav simply wraps without JavaScript.
   On a phone the header stays with you: a slim bar with the date on the left and a Menu
   button on the right, opening a calm full width panel of large, centred links. */
@media (max-width: 899.98px) {
  .site-header { --header-height: 56px; padding-top: 0; }

  .js .site-header {
    position: sticky;
    top: 0;
    z-index: 40;
    align-items: center;
    justify-content: space-between;
    height: var(--header-height);
    min-height: 0;
    padding: 0 var(--gutter);
    background: rgba(255, 255, 255, 0.96);
    border-bottom: 1px solid rgba(44, 42, 32, 0.12);
  }

  .js .site-header::before {
    content: '09.19.19';
    font-weight: 300;
    font-size: 13px;
    letter-spacing: 0.28em;
    color: var(--color-text);
  }

  .js .site-header .nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 0 4px;
  }

  /* Two short lines that become a cross when the menu is open. */
  .nav-toggle::after {
    content: '';
    width: 18px;
    height: 7px;
    border-top: 1px solid currentColor;
    border-bottom: 1px solid currentColor;
    transition: transform 0.2s ease, height 0.2s ease;
  }

  .nav-toggle[aria-expanded="true"]::after {
    content: '\00d7';
    width: auto;
    height: auto;
    border: 0;
    font-size: 28px;
    font-weight: 300;
    line-height: 1;
  }

  .js .site-header .nav { display: none; }

  .js .site-header .nav.is-open {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    padding: 6px var(--gutter) 22px;
    background: #fff;
    border-bottom: 1px solid rgba(44, 42, 32, 0.12);
    box-shadow: 0 18px 30px rgba(44, 42, 32, 0.12);
    animation: nav-drop 0.18s ease-out;
  }

  .js .site-header .nav .nav-item,
  .js .site-header .nav .nav-item + .nav-item {
    justify-content: center;
    height: auto;
    min-height: 54px;
    margin: 0;
    padding: 14px 0;
    border-left: 0;
    border-top: 1px solid rgba(44, 42, 32, 0.1);
    font-size: 15px;
    letter-spacing: 0.22em;
    text-align: center;
  }

  .js .site-header .nav .nav-item:first-child { border-top: 0; }

  .js .site-header .nav .nav-item.is-active { text-underline-offset: 8px; }
}

@keyframes nav-drop {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .js .site-header .nav.is-open { animation: none; }
  .nav-toggle::after { transition: none; }
}

/* Fixed, decorative side texts, hidden when the page is too narrow for them. */
.side-text {
  display: none;
  position: fixed;
  top: 50%;
  z-index: 1;
  writing-mode: vertical-rl;
  white-space: nowrap;
  font-weight: 300;
  color: var(--color-text);
  pointer-events: none;
}

.side-text-left {
  left: 30px;
  font-size: 14px;
  letter-spacing: 0.2em;
  transform: translateY(-50%) rotate(180deg);
}

.side-text-right {
  right: 32px;
  font-size: 20px;
  transform: translateY(-50%);
}

@media (min-width: 1000px) {
  .side-text { display: block; }
}

/* Shared page pieces --------------------------------------------------- */

.site-footer {
  padding: 34px 24px;
  background: var(--color-cream);
  color: var(--color-text);
  text-align: center;
  font-weight: 300;
  font-style: italic;
  font-size: 14px;
}

/* Inner pages ------------------------------------------------------------
   Every page after Home shares one vocabulary: a framed column inset from
   the page edges, a large italic h1 with a short rule, and colour panels.

   Contrast, text on panel (WCAG 2 ratios, measured in the browser):
     dark #2c2a20 on khaki #c2ba95 7.4:1, on olive #ab9e76 5.4:1,
     on sand #d1c2b8 8.3:1, on cream #fdf6eb 13:1;
     cream #fdf6eb on brown #744836 7.0:1.
   --color-muted (#706a50) is only for white or cream grounds, never on a
   colour panel (2.8:1 on khaki). */

.page-frame { margin-inline: 16px; }

@media (min-width: 700px) {
  .page-frame { margin-inline: 40px; }
}

@media (min-width: 1000px) {
  .page-frame { margin-inline: 80px; }
}

.page { position: relative; padding-bottom: 80px; }

/* The dashed hairlines of the original, just outside the content column and running
   the height of the page. The 80px frame leaves a 28px channel outside it, and the
   fixed side texts reach about 52px in from each edge, so the rules sit at 66px, in
   the middle of that channel. They only appear where there is room. The Gallery
   is left out: its toolbar and grid are busy enough. */
@media (min-width: 1100px) {
  .ceremony::before, .ceremony::after,
  .reception::before, .reception::after,
  .honeymoon::before, .honeymoon::after,
  .media::before, .media::after,
  .details::before, .details::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    width: 0;
    border-left: 1px dashed rgba(66, 66, 66, 0.4);
    pointer-events: none;
  }

  .ceremony::before, .reception::before, .honeymoon::before,
  .media::before, .details::before { left: -14px; }

  .ceremony::after, .reception::after, .honeymoon::after,
  .media::after, .details::after { right: -14px; }
}

/* The page title band, in the hero's language: a wide band inset to the frame with a
   low-contrast ghost of one of the page's own photographs on sand, and a translucent
   cream card floating inside it holding a rule, the title and a second rule.

   Every page sets --page-ghost to its own photograph (usually the same file the page
   already loads, so the band costs no extra bytes); without one the band is plain sand
   and cream, which is what the Gallery takes. */
.page-head {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: clamp(58px, 8.4vw, 126px) clamp(30px, 8vw, 116px);
  margin-bottom: clamp(40px, 5vw, 64px);
  background: #e9e1da;   /* sand lifted toward white so the band reads light */
  text-align: center;
}

.page-head::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  background-image: var(--page-ghost, none);
  background-position: var(--page-ghost-pos, center);
  background-size: cover;
  background-repeat: no-repeat;
  filter: saturate(0.3) contrast(0.7) brightness(1.15);
  opacity: 0.2;
}

/* The vellum card. */
.page-head::after {
  content: '';
  position: absolute;
  inset: clamp(16px, 4.4vw, 64px);
  z-index: -1;
  background: rgba(253, 248, 240, 0.6);
}

.page-title {
  margin: 0;
  font-weight: 500;
  font-style: italic;
  font-size: clamp(44px, 6vw, 84px);
  line-height: 1.05;
  color: #3a382d;
}

/* The rule above the title, the twin of the .page-rule below it. */
.page-title::before {
  content: '';
  display: block;
  width: 304px;
  max-width: 100%;
  height: 3px;
  margin: 0 auto clamp(28px, 3vw, 42px);
  background: var(--color-rule);
}

/* The hero card's rule: 304px wide, 3px thick. */
.page-rule {
  display: block;
  width: 304px;
  max-width: 100%;
  height: 3px;
  margin: clamp(28px, 3vw, 42px) auto 0;
  border: 0;
  background: var(--color-rule);
}

.panel {
  padding: clamp(40px, 6vw, 72px) clamp(20px, 4vw, 56px);
  color: var(--color-text);
}

.panel-khaki { background: var(--color-khaki); }
.panel-cream { background: var(--color-cream); }
.panel-olive { background: var(--color-olive); }
.panel-sand { background: var(--color-sand); }
.panel-brown { background: var(--color-brown); color: var(--color-cream); }

/* Small tracked label, FM Medium capitals: column and section labels. */
.panel-label {
  margin: 0;
  font-weight: 500;
  font-style: normal;
  font-size: 15px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  text-align: center;
}

/* A short vertical rule under a label, as in the original columns. */
.panel-vrule {
  display: block;
  width: 1px;
  height: 90px;
  margin: 26px auto 30px;
  background: currentColor;
  opacity: 0.85;
}

/* Big section heading inside a panel. */
.panel-heading {
  margin: 0;
  font-weight: 500;
  font-style: italic;
  font-size: clamp(34px, 4.4vw, 56px);
  line-height: 1.1;
  text-align: center;
}

.panel a,
.page-intro a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.page-intro {
  max-width: 620px;
  margin: 0 auto;
  padding: 0 0 clamp(40px, 5vw, 56px);
  text-align: center;
  font-size: 19px;
  text-wrap: balance;
}

/* A line under the h1 rule: where and when, in small tracked FM Light capitals. */
.page-subtitle {
  margin: 26px 0 0;
  font-weight: 300;
  font-size: 15px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

/* Until the words arrive: a quiet light italic line, not a box. Sits on a colour panel
   or on cream, so it uses the body text colour (--color-muted is for white grounds only). */
.section-placeholder {
  margin: 24px 0 0;
  font-weight: 300;
  font-style: italic;
  font-size: clamp(22px, 2.6vw, 28px);
  line-height: 1.5;
  text-align: center;
}

/* A quiet row of in-page links under the h1 rule. FM Light small capitals, dark text
   (7:1 or better on white); the underline appears on hover and focus. */
.page-jump {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px 28px;
  margin-top: 26px;
}

.page-jump a {
  padding: 6px 0;
  font-weight: 300;
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text);
  text-decoration: none;
}

.page-jump a:hover { text-decoration: underline; text-underline-offset: 6px; }

/* Reading text and quotations shared by the Ceremony, Reception, Honeymoon and Media pages.
   Everything here is centred in a 640px column, like the vows entries. */

.prose {
  max-width: 640px;
  margin: 0 auto;
  text-align: center;
  font-size: 19px;
  line-height: 1.85;
  text-wrap: pretty;
}

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

.prose a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 3px; }

/* A quotation with its attribution: <figure><blockquote><p>..</p></blockquote><figcaption>..</figcaption></figure> */
.pull-quote {
  max-width: 640px;
  margin: 32px auto 0;
  text-align: center;
}

.pull-quote blockquote { margin: 0; }

.pull-quote blockquote p {
  margin: 0;
  font-weight: 300;
  font-style: italic;
  font-size: clamp(21px, 2.4vw, 26px);
  line-height: 1.6;
  text-wrap: pretty;
}

.pull-quote figcaption,
.credit-line {
  margin-top: 18px;
  font-weight: 300;
  font-size: 13px;
  letter-spacing: 0.2em;
  line-height: 1.7;
  text-transform: uppercase;
}

.credit-line { margin-bottom: 0; text-align: center; }

/* A small tracked label above a run of panels, in the same voice as .panel-label.
   It takes the same short hairline under it, so the motif runs across the site. */
.section-label { margin: clamp(8px, 2vw, 24px) 0 0; }

.section-label + .panel-vrule { margin-bottom: clamp(30px, 4vw, 44px); }

/* Photographs: a tidy grid inside a panel, never wider than 1000px (every source photo is
   at least 1067px wide, so nothing is drawn larger than it really is). The width and height
   attributes on each img reserve the right box before it loads. Each page sets its own
   column layout on .figures. */
.figures {
  display: grid;
  gap: 28px 20px;
  max-width: 1000px;
  margin: 48px auto 0;
}

.figures figure { margin: 0; }

.figures img {
  width: 100%;
  height: auto;
  background: rgba(44, 42, 32, 0.08);
}

.figures figcaption {
  margin-top: 10px;
  font-style: italic;
  font-size: 15px;
  line-height: 1.5;
  text-wrap: pretty;
}

/* Breathing room between a panel heading and the text that follows it. */
.panel-heading + .prose { margin-top: 24px; }

/* Photographs on the content pages ---------------------------------------
   A banner spans the framed column under the page title. The box sets the
   shape and the photograph fills it, so the file on disk is never cropped:
   a phone sees the whole frame, a wide screen sees a band. Each page picks
   its own object-position so no face is cut. */
.page-banner {
  position: relative;
  isolation: isolate;
  margin: 0;
  aspect-ratio: 3 / 2;
  background: rgba(44, 42, 32, 0.08);
}

/* A thin cream veil over the banner, so the full-colour photograph sits in the same
   soft register as the ghosted band above it. */
.page-banner::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(253, 246, 235, 0.3);
  pointer-events: none;
}

/* Straight under the header band the photograph sits at the panel rhythm, not a wide gap. */
.page-head + .page-banner { margin-top: calc(16px - clamp(40px, 5vw, 64px)); }

@media (min-width: 700px) {
  .page-banner { aspect-ratio: 16 / 9; }
}

@media (min-width: 1000px) {
  .page-banner { aspect-ratio: 16 / 7; }
}

.page-banner img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Every photograph on the content pages carries the same gentle treatment: a little
   less saturation and contrast, a little more light. The gallery is not touched. */
.page-banner img { filter: saturate(0.78) contrast(0.86) brightness(1.12); }

.page-inset img,
.figures img,
.media-portrait img,
.details-venues img {
  filter: saturate(0.86) contrast(0.94) brightness(1.06);
}

/* A single photograph on its own inside a panel, set narrower than the text. */
.page-inset {
  max-width: 440px;
  margin: 48px auto 0;
}

.page-inset img {
  width: 100%;
  height: auto;
  background: rgba(44, 42, 32, 0.08);
}

/* The white pass ----------------------------------------------------------
   The Ceremony, Reception, Media and Honeymoon pages no longer stack
   full-width colour blocks. Every section sits on white, separated by air and
   one short hairline, and colour survives as accents only: that hairline, a
   vellum tint behind a quotation or a card, and the two ghosted photograph
   bands (the page header and the Music band). Details keeps its approved
   colour panels; only its invitation section opts in, by taking .page-section
   in place of .panel.

   Contrast on white: text #2c2a20 is 13.7:1, --color-muted #706a50 is 5.4:1,
   and the khaki accents are never asked to carry text. */

.page-section {
  padding: 0;
  color: var(--color-text);
}

.page-section a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* Air between sections, and a short rule so the eye keeps the rhythm the
   colour blocks used to give it. Every section opens the same way, whatever
   comes before it, so the page has one measure all the way down. */
.page-section + .page-section,
.page-section + .music-band,
.music-band + .page-section {
  margin-top: clamp(64px, 8vw, 104px);
}

.page-section::before {
  content: '';
  display: block;
  width: 90px;
  height: 1px;
  margin: 0 auto clamp(36px, 4vw, 48px);
  background: var(--color-accent-hair);
}

/* A touch smaller than the heading inside a colour panel: on white it carries
   more weight, so it needs less size. */
.page-section > .panel-heading { font-size: clamp(34px, 4vw, 52px); }

/* Quotations on the white pages -------------------------------------------
   The section heading carries the page's italic voice, so a quotation is set
   upright in FM Light against a khaki rule, left aligned in a narrow column,
   with its attribution under a short hairline. The quotation marks are drawn
   by CSS, so the words themselves are never touched. */
.ceremony .pull-quote,
.reception .pull-quote,
.honeymoon .pull-quote,
.media .pull-quote,
.details .details-invitation .pull-quote {
  max-width: 620px;
  margin: clamp(32px, 4vw, 44px) auto 0;
  padding-left: clamp(22px, 3vw, 34px);
  border-left: 2px solid var(--color-accent-rule);
  text-align: left;
}

.ceremony .pull-quote blockquote p,
.reception .pull-quote blockquote p,
.honeymoon .pull-quote blockquote p,
.media .pull-quote blockquote p,
.details .details-invitation .pull-quote blockquote p {
  font-weight: 300;
  font-style: normal;
  font-size: clamp(20px, 2.2vw, 26px);
  line-height: 1.7;
}

.ceremony .pull-quote blockquote p:first-of-type::before,
.reception .pull-quote blockquote p:first-of-type::before,
.honeymoon .pull-quote blockquote p:first-of-type::before,
.media .pull-quote blockquote p:first-of-type::before,
.details .details-invitation .pull-quote blockquote p:first-of-type::before {
  content: '\201C';
}

.ceremony .pull-quote blockquote p:last-of-type::after,
.reception .pull-quote blockquote p:last-of-type::after,
.honeymoon .pull-quote blockquote p:last-of-type::after,
.media .pull-quote blockquote p:last-of-type::after,
.details .details-invitation .pull-quote blockquote p:last-of-type::after {
  content: '\201D';
}

.ceremony .pull-quote figcaption,
.reception .pull-quote figcaption,
.honeymoon .pull-quote figcaption,
.media .pull-quote figcaption,
.details .details-invitation .pull-quote figcaption {
  margin-top: 22px;
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.22em;
  line-height: 1.6;
  text-transform: uppercase;
  text-align: left;
  color: var(--color-muted);
}

.ceremony .pull-quote figcaption::before,
.reception .pull-quote figcaption::before,
.honeymoon .pull-quote figcaption::before,
.media .pull-quote figcaption::before,
.details .details-invitation .pull-quote figcaption::before {
  content: '';
  display: block;
  width: 24px;
  height: 1px;
  margin-bottom: 14px;
  background: currentColor;
}

/* Credit lines on the white pages: the same small tracked voice, muted. */
.page-section .credit-line { color: var(--color-muted); font-size: 12px; }

/* Photograph captions: small, upright and muted. The section heading is the
   one italic voice on the page, so captions do not add a second one. */
.page-section .figures figcaption,
.page-section figure > figcaption {
  font-style: normal;
  color: var(--color-muted);
  font-size: 14px;
}

/* A vellum panel: the page's one tint, pale sand over white. Used behind the
   vows, the menu card, the toasts note and the smaller photographs that would
   otherwise float on the page with nothing under them. */
.vellum {
  background: rgba(209, 194, 184, 0.34);
  border: 1px solid rgba(44, 42, 32, 0.12);
}

/* Photographs on the white pages ------------------------------------------
   Two shapes carry almost everything: a wide photograph across the reading
   width, and a row of photographs of equal height. Both are centred on the
   page, so no picture is ever left floating in an empty column. */
.photo-wide {
  max-width: 960px;
  margin: clamp(36px, 4vw, 48px) auto 0;
}

.photo-wide img {
  width: 100%;
  height: auto;
  background: rgba(44, 42, 32, 0.08);
}

/* A single upright photograph, centred like the wide one so it is never left
   floating at one side of an empty column. */
.photo-narrow { max-width: 380px; }

.photo-row {
  display: grid;
  gap: 24px;
  max-width: 960px;
  margin: clamp(36px, 4vw, 48px) auto 0;
}

.photo-row { align-items: start; }

.photo-row figure { margin: 0; }

/* Equal heights: every picture in a row is drawn to the same shape and filled,
   so the row lines up whatever the files behind it are. The shape alone sets
   the height, so the caption below it is never pushed out of its figure. */
.photo-row img {
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: center;
  background: rgba(44, 42, 32, 0.08);
}

.photo-row figcaption,
.photo-wide figcaption {
  margin-top: 10px;
  font-style: normal;
  font-size: 14px;
  line-height: 1.5;
  color: var(--color-muted);
  text-wrap: pretty;
}

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

/* An upright photograph in a row keeps its head in frame when it is cropped
   to the row's shape. */
.photo-row img.crop-upper { object-position: center 32%; }

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

.photo-wide img,
.photo-row img {
  filter: saturate(0.86) contrast(0.94) brightness(1.06);
}

/* The Music band ----------------------------------------------------------
   A ghosted photograph on the right fading out to the left, the words on a
   translucent vellum card on the left, in the same low contrast register as
   the page header. On phones the photograph sits behind the whole card.
   Ceremony and Reception both use it; each sets its own --music-ghost. */
.music-band {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: clamp(28px, 6vw, 72px) clamp(16px, 5vw, 64px);
  background: #e9e1da;
}

.music-band::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  background: var(--music-ghost) 50% 66% / cover no-repeat;
  filter: saturate(0.3) contrast(0.72) brightness(1.18);
  opacity: 0.55;
}

.music-card {
  padding: clamp(36px, 5vw, 64px) clamp(22px, 4vw, 52px);
  background: rgba(253, 248, 240, 0.74);
  text-align: center;
}

.music-card .panel-heading { margin-top: 0; }

/* A band can carry its ghost as a real <img> instead of a CSS background, so
   the photograph keeps its alt text and its lazy loading. It is drawn in
   exactly the same register as the background ghost above. */
.music-ghost-img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 42%;
  filter: saturate(0.3) contrast(0.72) brightness(1.18);
  opacity: 0.55;
}

@media (min-width: 900px) {
  .music-band { min-height: 560px; display: flex; align-items: center; }

  .music-band::before {
    inset: 0 0 0 auto;
    width: 56%;
    background-position: 50% 64%;
    -webkit-mask-image: linear-gradient(to right, transparent, #000 22%);
    mask-image: linear-gradient(to right, transparent, #000 22%);
    opacity: 0.85;
  }

  .music-ghost-img {
    inset: 0 0 0 auto;
    width: 56%;
    -webkit-mask-image: linear-gradient(to right, transparent, #000 22%);
    mask-image: linear-gradient(to right, transparent, #000 22%);
    opacity: 0.85;
  }

  .music-card { width: 54%; margin: 0; }
}

/* Quiet credits: the photographer and caption lines recede so the photographs lead. */
.credit-line,
.page-section .credit-line,
.details-invitation .credit-line {
  font-weight: 300;
  font-size: 11px;
  letter-spacing: 0.22em;
  color: #857f66;
}

.figures figcaption,
.page-section .figures figcaption,
.page-section figure:not(.pull-quote) > figcaption,
figure:not(.pull-quote) > figcaption {
  font-style: normal;
  font-weight: 300;
  font-size: 12.5px;
  line-height: 1.5;
  letter-spacing: 0.02em;
  color: #857f66;
}

/* Jumping to a section lands it below the sticky navigation bar. */
.page-section,
.music-band,
.details-where,
.details-itinerary,
.details-invitation,
.credits-panel,
.thanks-panel { scroll-margin-top: 96px; }

html { scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* The subtitle and the section links are two different voices: the subtitle is a quiet
   sentence in light italic, the links are small tracked capitals set apart under a hairline. */
.page-head .page-subtitle {
  margin-top: 22px;
  font-weight: 300;
  font-style: italic;
  font-size: clamp(18px, 1.6vw, 21px);
  letter-spacing: 0.01em;
  text-transform: none;
  color: #57533f;
}

.page-head .page-jump {
  margin-top: 30px;
  padding-top: 24px;
  border-top: 1px solid rgba(44, 42, 32, 0.28);
  max-width: 820px;
  margin-left: auto;
  margin-right: auto;
  gap: 2px 30px;
}

.page-head .page-jump a {
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.24em;
}

/* Details has no subtitle: its links follow the rule directly. */
.page-head .page-rule + .page-jump { margin-top: 26px; }

/* Phones: a little more margin around the reading sections, so text and photographs
   do not sit tight against the screen edge. */
@media (max-width: 699.98px) {
  .page-section { padding-inline: 14px; }
  .gallery .gallery-section { padding-inline: 4px; }
}

/* Back to top ---------------------------------------------------------------- */
.to-top-row {
  margin: clamp(36px, 5vw, 56px) 0 0;
  text-align: center;
}

.to-top-link {
  display: inline-block;
  padding: 10px 6px;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  text-decoration: none;
  color: #857f66;
}

.to-top-link::before { content: '\2191'; margin-right: 10px; letter-spacing: 0; }
.to-top-link:hover { color: var(--color-text); text-decoration: underline; text-underline-offset: 5px; }

.to-top-float {
  position: fixed;
  right: 16px;
  bottom: 18px;
  z-index: 30;
  width: 44px;
  height: 44px;
  border: 1px solid rgba(44, 42, 32, 0.25);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.94);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
}

.to-top-float.is-visible { opacity: 1; visibility: visible; transform: none; }
.to-top-float:hover { background: #fff; border-color: var(--color-text); }


@media (prefers-reduced-motion: reduce) {
  .to-top-float { transition: none; }
}
