@import url('../fonts/fonts.css');

/* ==========================================================================
   MMwedding
   The website is the invitation continued: embossed letterpress on cream stock.
   Values are measured, see /opt/mmwedding/docs/DESIGN-SYSTEM.md
   ========================================================================== */

:root {
  --paper: #F0EDE8;
  --paper-deep: #EAE6DF;
  --ink: #33302C;
  --ink-soft: #5A554E;
  --gold: #A98C5F;
  --gold-deep: #8B7145;
  --gold-tint: #D8CBB2;

  --serif: 'Cormorant Garamond', Cormorant, Georgia, 'Times New Roman', serif;

  --gutter: clamp(28px, 5vw, 64px);
  --rhythm: clamp(7rem, 14vh, 11rem);
  --measure: 620px;

  --fs-names: clamp(1.5rem, 5.6vw, 3.4rem);
  --fs-title: clamp(1.75rem, 4.2vw, 2.6rem);
  --fs-label: 0.95rem;
  --fs-body: clamp(1.02rem, 1.35vw, 1.18rem);
  --fs-meta: clamp(1rem, 1.1vw, 1.05rem);

  --ease: cubic-bezier(.22, .61, .36, 1);
}

/* --------------------------------------------------------------- reset --- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background-color: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-weight: 400;
  font-size: var(--fs-body);
  line-height: 1.85;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body.is-locked { overflow: hidden; }

h1, h2, h3, p, ul, ol, figure, blockquote {
  margin: 0;
  padding: 0;
}

ul, ol { list-style: none; }

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

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

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

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The skip link was removed on Tom's call. It was parked just above the
   viewport and desktop overscroll dragged it into view, so pulling down at the
   top of any page revealed a stray button on otherwise empty paper. With four
   nav items there is almost nothing for a keyboard user to skip past, so the
   accessibility cost of dropping it is small. */

/* ------------------------------------------------------------- texture --- */

.paper-texture {
  position: fixed;
  top: -20vh;
  left: 0;
  width: 100%;
  height: 140vh;
  z-index: -1;
  pointer-events: none;
  /* Measured on the real stock scan: the tile deviates about 7 levels peak,
     0.76 standard deviation, so at the design system's 0.5 it lands under the
     visible threshold. 0.85 at 400px reads as tooth, never as a pattern. */
  opacity: 0.85;
  background-image: url('../img/paper-texture.png');
  background-image: image-set(url('../img/paper-texture.webp') type('image/webp'),
                              url('../img/paper-texture.png') type('image/png'));
  background-repeat: repeat;
  background-size: 400px 400px;
  will-change: transform;
}

/* ----------------------------------------------------------- ornaments --- */

.rule-diamond {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: min(180px, 60vw);
  margin-inline: auto;
}
.rule-diamond::before,
.rule-diamond::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--gold-tint);
}
.rule-diamond i {
  width: 5px;
  height: 5px;
  background: var(--gold);
  transform: rotate(45deg);
}

.rule-under-title { margin-top: 1.6rem; }

.block-gap { margin-top: clamp(3rem, 7vh, 4.5rem); }

.rule-short {
  width: 48px;
  height: 1px;
  margin: 0 auto;
  background: var(--gold-tint);
  border: 0;
}

.motif { color: var(--gold); }
.motif svg { width: 26px; height: 26px; }

.motif-wide {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  width: min(260px, 70vw);
  margin-inline: auto;
}
.motif-wide::before,
.motif-wide::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--gold-tint);
}
.motif-wide svg { width: 28px; height: 28px; color: var(--gold); }

/* ------------------------------------------------------------ typeface --- */

/* Cormorant defaults to old style figures. The invitation sets its dates,
   times and postcode as lining figures, so those are asked for by name. */
.date,
.agenda-time,
.venue-address,
.account-value {
  font-variant-numeric: lining-nums;
  font-feature-settings: 'lnum' 1;
}

.date {
  font-size: var(--fs-meta);
  letter-spacing: 0.30em;
  text-indent: 0.30em;
  color: var(--ink);
  line-height: 1.4;
}

.intro {
  font-size: var(--fs-meta);
  letter-spacing: 0.22em;
  text-indent: 0.22em;
  color: var(--ink);
  line-height: 1.4;
}

.names {
  font-weight: 300;
  font-size: var(--fs-names);
  line-height: 1.24;
  letter-spacing: 0.10em;
  text-indent: 0.10em;
  text-transform: uppercase;
  color: var(--gold);
  text-wrap: balance;
}
.names .name { display: block; }
.names .amp {
  display: block;
  letter-spacing: 0;
  text-indent: 0;
  font-size: 0.72em;
  line-height: 1.5;
}

.timing {
  font-size: var(--fs-meta);
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  text-transform: uppercase;
  color: var(--ink);
  line-height: 1.4;
}

.page-title,
.section-title {
  font-weight: 300;
  font-size: var(--fs-title);
  line-height: 1.2;
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  text-transform: uppercase;
  color: var(--gold);
}

.label {
  font-weight: 400;
  font-size: var(--fs-label);
  letter-spacing: 0.22em;
  text-indent: 0.22em;
  text-transform: uppercase;
  color: var(--gold-deep);
  line-height: 1.5;
}

.body-italic {
  font-style: italic;
  font-size: var(--fs-body);
  line-height: 1.85;
  color: var(--ink);
  max-width: 58ch;
  margin-inline: auto;
}
.body-italic + .body-italic { margin-top: 0.2em; }
.label + .body-italic { margin-top: 0.85rem; }

/* The place accent is the calligrapher's own stroke, lifted from the
   invitation, not type. It carries its own paper and composites straight onto
   the page. */
.script-mark {
  width: clamp(210px, 26vw, 330px);
  height: auto;
}

.footnote {
  font-size: var(--fs-label);
  letter-spacing: 0.20em;
  text-indent: 0.20em;
  text-transform: uppercase;
  color: var(--gold-deep);
  line-height: 1.6;
}

/* --------------------------------------------------------------- links --- */

a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--gold-deep);
  text-underline-offset: 0.22em;
  transition: text-decoration-thickness 200ms var(--ease);
}
a:hover { text-decoration-thickness: 1.5px; }

.text-button {
  color: var(--ink);
  font-size: var(--fs-meta);
  letter-spacing: 0.10em;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--gold-deep);
  text-underline-offset: 0.22em;
  transition: text-decoration-thickness 200ms var(--ease);
}
.text-button:hover { text-decoration-thickness: 1.5px; }

/* ---------------------------------------------------------- navigation --- */

.masthead {
  padding: clamp(2rem, 5vh, 3.4rem) var(--gutter) 0;
}

.nav-list {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: clamp(1.6rem, 4vw, 3.2rem);
}

.nav-list a {
  display: inline-block;
  padding-bottom: 4px;
  font-size: 0.875rem;
  letter-spacing: 0.20em;
  text-indent: 0.20em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 260ms var(--ease), border-color 260ms var(--ease);
}
.nav-list a:hover { color: var(--ink); }
.nav-list a[aria-current='page'] {
  color: var(--ink);
  border-bottom-color: var(--gold);
}

.menu-toggle {
  display: none;
  position: fixed;
  top: 18px;
  right: 18px;
  z-index: 90;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
}
.menu-toggle i {
  position: absolute;
  left: 11px;
  width: 22px;
  height: 1px;
  background: var(--ink);
  transition: transform 320ms var(--ease), opacity 220ms var(--ease);
}
/* nth-of-type, not nth-child: the button also holds a hidden label span. */
.menu-toggle i:nth-of-type(1) { transform: translateY(-6px); }
.menu-toggle i:nth-of-type(2) { transform: translateY(0); }
.menu-toggle i:nth-of-type(3) { transform: translateY(6px); }

body[data-menu='open'] .menu-toggle i:nth-of-type(1) { transform: rotate(45deg); }
body[data-menu='open'] .menu-toggle i:nth-of-type(2) { opacity: 0; }
body[data-menu='open'] .menu-toggle i:nth-of-type(3) { transform: rotate(-45deg); }

/* --------------------------------------------------------------- shell --- */

.page-main {
  padding-inline: var(--gutter);
}

.section {
  padding-block: var(--rhythm);
}
.section:first-child { padding-top: clamp(5rem, 12vh, 9rem); }

.wrap {
  width: 100%;
  max-width: var(--measure);
  margin-inline: auto;
  text-align: center;
}
.wrap-wide { max-width: 1100px; }

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

.hero {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(1.6rem, 4vh, 3rem);
  padding: clamp(3rem, 7vh, 5rem) var(--gutter);
  text-align: center;
}

/* The whole card face has to sit above the fold on every screen, so the mark
   is bounded by viewport height as well as width. On a short laptop the
   butterfly gives up the room, never the type. */
.hero-mark {
  width: clamp(210px, min(33vw, 40vh), 470px);
}
.hero-mark img { width: 100%; }

.butterfly { will-change: transform; }

.hero-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.9rem, 2.2vh, 1.6rem);
  width: 100%;
  max-width: 900px;
}
.hero-card .names { margin-top: clamp(0.2rem, 1vh, 0.8rem); }
.hero-card .rule-diamond { margin-top: clamp(0.4rem, 1.4vh, 1rem); }
.hero-card .motif { margin-top: clamp(0.6rem, 2vh, 1.4rem); }

/* --------------------------------------------------------- page header --- */

.page-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.4rem, 3vh, 2.2rem);
  text-align: center;
}
.page-head .mark { width: clamp(120px, 16vw, 190px); }

/* --------------------------------------------------------- information --- */

.info-list {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(2.6rem, 6vh, 4rem);
  margin-top: clamp(3rem, 7vh, 4.5rem);
}

.info-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.85rem;
  width: 100%;
}
.info-item .rule-short { margin-top: clamp(2.6rem, 6vh, 4rem); }
.info-item:last-child .rule-short { display: none; }

.info-lines {
  font-style: italic;
  font-size: var(--fs-body);
  line-height: 1.85;
}
.info-lines span { display: block; }

/* -------------------------------------------------------------- agenda --- */

.agenda {
  --time-col: clamp(72px, 8vw, 96px);
  --rail-col: 44px;
  margin-top: clamp(3rem, 7vh, 4.5rem);
  text-align: left;
}

.agenda-item {
  position: relative;
  display: grid;
  grid-template-columns: var(--time-col) var(--rail-col) minmax(0, 1fr);
  grid-template-areas:
    'time rail title'
    'time rail detail'
    'time rail rule';
  column-gap: 0;
  row-gap: 0.25rem;
  padding-bottom: clamp(1.6rem, 3.4vh, 2.4rem);
}
.agenda-item:last-child { padding-bottom: 0; }

.agenda-item::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--time-col) + (var(--rail-col) / 2));
  width: 1px;
  background: var(--gold-tint);
}
.agenda-item:first-child::before { top: 0.72em; }
.agenda-item:last-child::before { bottom: auto; height: 0.72em; }

.agenda-node {
  grid-area: rail;
  align-self: start;
  justify-self: center;
  width: 5px;
  height: 5px;
  margin-top: 0.62em;
  background: var(--gold);
  transform: rotate(45deg);
}

.agenda-time {
  grid-area: time;
  align-self: start;
  font-size: var(--fs-meta);
  letter-spacing: 0.10em;
  color: var(--gold-deep);
  line-height: 1.5;
  text-align: right;
  padding-right: 0.6rem;
}

.agenda-title {
  grid-area: title;
  font-weight: 400;
  font-size: var(--fs-meta);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  line-height: 1.5;
}

.agenda-detail {
  grid-area: detail;
  font-style: italic;
  font-size: var(--fs-body);
  line-height: 1.7;
  color: var(--ink);
  max-width: 46ch;
  margin-top: 0.2rem;
}

.agenda-rule {
  grid-area: rule;
  justify-self: start;
  width: 48px;
  height: 1px;
  margin: clamp(1.1rem, 2.4vh, 1.6rem) 0 0;
  background: var(--gold-tint);
  border: 0;
}
.agenda-item:last-child .agenda-rule { display: none; }

.agenda-foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.4rem;
  margin-top: clamp(3rem, 7vh, 4.5rem);
  text-align: center;
}

/* ------------------------------------------------------------ location --- */

.venue-figure { margin: clamp(3rem, 7vh, 4.5rem) 0 0; }

.venue-drawing { margin-inline: auto; width: 100%; }

.venue-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
  margin-top: clamp(2rem, 5vh, 3.2rem);
  text-align: center;
}

.venue-name {
  font-weight: 400;
  font-size: clamp(1.2rem, 2.2vw, 1.6rem);
  letter-spacing: 0.24em;
  text-indent: 0.24em;
  text-transform: uppercase;
  color: var(--ink);
  line-height: 1.4;
}

.venue-address {
  font-size: var(--fs-meta);
  letter-spacing: 0.20em;
  text-indent: 0.20em;
  text-transform: uppercase;
  color: var(--ink);
  line-height: 1.9;
}
.venue-address span { display: block; }

.directions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(2.4rem, 5vw, 4rem);
  margin-top: clamp(4rem, 9vh, 6rem);
  text-align: center;
}
.directions .body-italic { max-width: 30ch; }

.direction h3 { margin-bottom: 0.7rem; }

.map-frame {
  margin-top: clamp(4rem, 9vh, 6rem);
  border: 1px solid var(--gold-tint);
  border-radius: 0;
  background: var(--paper-deep);
  overflow: hidden;
}
.map-frame iframe {
  display: block;
  width: 100%;
  height: clamp(280px, 38vh, 380px);
  border: 0;
}
.map-frame .map-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: clamp(280px, 38vh, 380px);
  color: var(--ink-soft);
  font-style: italic;
}
.map-link { margin-top: 1.6rem; text-align: center; }

/* The map is a static plate rather than a live embed: Google's iframe paints
   its own rated info card over one corner, and suppressing that needs an API
   key. Same plate as .map-frame above: same hairline, same height budget, no
   radius. LocationPage.maps_embed_url stays on the model so the live embed can
   be switched back on later. */
.venue-map { margin-top: clamp(4rem, 9vh, 6rem); }
.venue-map img {
  display: block;
  width: 100%;
  height: clamp(280px, 38vh, 380px);
  object-fit: cover;
  background: var(--paper-deep);
  border: 1px solid var(--gold-tint);
  border-radius: 0;
}

/* ------------------------------------------------------------ registry --- */

.account {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.7rem;
  margin-top: clamp(3rem, 7vh, 4.5rem);
}
.account + .account { margin-top: clamp(2.4rem, 5vh, 3.4rem); }

.account-value {
  font-size: clamp(1.1rem, 1.9vw, 1.35rem);
  letter-spacing: 0.14em;
  text-indent: 0.14em;
  color: var(--ink);
  line-height: 1.6;
}
.account-value.iban { word-spacing: 0.45em; }

.copy-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  margin-top: clamp(2rem, 4vh, 2.8rem);
  min-height: 3.4rem;
}
.copy-feedback {
  font-size: var(--fs-label);
  letter-spacing: 0.18em;
  text-indent: 0.18em;
  text-transform: uppercase;
  color: var(--gold-deep);
  opacity: 0;
  transition: opacity 400ms var(--ease);
}
.copy-feedback.is-shown { opacity: 1; }

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

.site-foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.8rem, 4vh, 2.6rem);
  padding: clamp(5rem, 11vh, 8rem) var(--gutter) clamp(4rem, 9vh, 6rem);
  text-align: center;
}
.site-foot a {
  font-size: var(--fs-meta);
  letter-spacing: 0.12em;
}

/* ------------------------------------------------------------- reveals --- */

.js .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 900ms var(--ease), transform 900ms var(--ease);
  will-change: opacity, transform;
}
.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* ------------------------------------------------------------- mobile --- */

@media (max-width: 760px) {
  .menu-toggle { display: flex; }

  .masthead {
    position: fixed;
    inset: 0;
    z-index: 80;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 5rem var(--gutter);
    background: var(--paper);
    opacity: 0;
    visibility: hidden;
    transition: opacity 320ms var(--ease), visibility 0s linear 320ms;
  }
  body[data-menu='open'] .masthead {
    opacity: 1;
    visibility: visible;
    transition: opacity 320ms var(--ease), visibility 0s linear 0s;
  }

  .nav-list {
    flex-direction: column;
    gap: clamp(1.8rem, 5vh, 2.8rem);
  }
  .nav-list a {
    font-size: clamp(1.3rem, 6vw, 1.8rem);
    letter-spacing: 0.24em;
    text-indent: 0.24em;
  }

  .directions {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(2.6rem, 6vh, 3.4rem);
  }
  .directions .body-italic { max-width: 42ch; }

  .agenda {
    --time-col: 0px;
    --rail-col: 26px;
  }
  .agenda-item {
    grid-template-columns: var(--rail-col) minmax(0, 1fr);
    grid-template-areas:
      'rail time'
      'rail title'
      'rail detail'
      'rail rule';
  }
  .agenda-item::before { left: calc(var(--rail-col) / 2); }
  .agenda-time {
    text-align: left;
    padding-right: 0;
    padding-bottom: 0.15rem;
  }
  .agenda-detail { max-width: none; }
}

@media (max-width: 480px) {
  /* Both names hold a single line at phone widths, as they do on the card.
     Below 24px the lighter gold no longer counts as large text, so the
     deeper gold carries it. */
  .names {
    font-size: clamp(1.28rem, 5.4vw, 1.5rem);
    letter-spacing: 0.04em;
    text-indent: 0.04em;
    color: var(--gold-deep);
  }
  .page-title,
  .section-title { letter-spacing: 0.18em; text-indent: 0.18em; }
}

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

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

  .js .reveal,
  .js .reveal.is-visible {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .butterfly,
  .paper-texture { transform: none; }

  .menu-toggle i,
  .masthead,
  .copy-feedback,
  a,
  .nav-list a { transition: none; }
}

/* --------------------------------------------------------------- print --- */

@media print {
  .paper-texture,
  .menu-toggle,
  .masthead { display: none; }
}
