/* ═══════════════════════════════════════════════════════════════════════════
   Grant & Orla - 11 February 2027
   One typeface throughout: Schibsted Grotesk.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ---------------------------------------------------------------------------
   Design tokens.
   These are the FALLBACK defaults. /theme.css is generated from the database and
   loads after this file, so anything saved in Settings > Brand & colours wins. If
   the database is unreachable, theme.css still serves these same defaults, and if
   theme.css itself fails to load the site simply renders as designed. There is no
   state in which the page comes out unstyled.
   Change a colour in Settings, not here.
   --------------------------------------------------------------------------- */

:root {
  /* Brand palette (emerald + gold + cream) */
  --brand-stormy-teal:  #123b2c;   /* Emerald    */
  --brand-pearl-aqua:   #3c5a47;   /* Deep sage  */
  --brand-alice-blue:   #f3edde;   /* Cream      */
  --brand-almond-silk:  #eae1cd;   /* Pale cream */
  --brand-tangerine:    #c6a15b;   /* Gold       */

  /* Light sections */
  --paper:      #f3edde;   /* Warm ivory */
  --paper-2:    #eae1cd;   /* Deeper cream */
  --surface:    #fbf7ec;   /* Warm white card */
  --ink:        #223a2c;   /* deep emerald, so body copy stays readable */
  --muted:      #6c7563;
  --line:       #d9c89a;   /* soft gold hairline */

  /* Invitation card divider rules (colour and thickness, set in Settings > Photos) */
  --invite-rule-color: #c9ac6a;
  --invite-rule-width: 1;

  /* Dark sections (emerald) */
  --d-bg:       #123b2c;
  --d-fg:       #f1ebda;
  --d-muted:    #cbbe93;   /* soft gold, so labels on the emerald read warm */
  --d-line:     #35543f;

  /* Buttons and links */
  --accent:       #1e4d3a;  /* Emerald */
  --accent-hover: #163b2c;
  --btn-fg:       #f4efdd;
  --accent-lit:   #c6a15b;  /* Gold */

  /* Typography (elegant serif) */
  --font-heading:   'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  --font-body:      'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  --invite-names-font: 'WindSong', 'Segoe Script', cursive;   /* the Grant & Orla name (Settings > Brand) */
  --w-heading:      600;
  --track-display:  -0.04em;
  --track-nav:      -0.03em;
  --track-caps:     0.18em;

  /* Hero (set in Settings > Photos) */
  --scrim-opacity:  1;

  /* Not themeable */
  --wrap:       1240px;
  --radius:     14px;
  --ease:       cubic-bezier(0.22, 1, 0.36, 1);
}

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

html {
  scroll-behavior: smooth;
  /* Anchor targets clear the sticky bar. */
  scroll-padding-top: 84px;
  -webkit-text-size-adjust: 100%;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  /* Cormorant Garamond has a small x-height, so body copy sits a touch larger and heavier
     than a sans would, to stay comfortable across long paragraphs. */
  font-weight: 500;
  font-size: clamp(18px, 1.25vw, 21px);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; display: block; }
a { color: inherit; }
code {
  font-family: inherit;
  font-weight: 600;
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  padding: 0.1em 0.38em;
  border-radius: 4px;
  font-size: 0.94em;
}

::selection { background: var(--accent); color: var(--btn-fg); }

:where(a, button, input, select, textarea):focus-visible {
  outline: 2px solid var(--accent-lit);
  outline-offset: 3px;
  border-radius: 3px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: var(--paper);
  padding: 0.8rem 1.2rem;
  font-weight: 600;
}
.skip-link:focus { left: 0; }

/* Placeholder shown when an image file is not there yet. ------------------- */
.media { position: relative; overflow: hidden; }
.media.is-missing {
  background:
    linear-gradient(180deg, #7E9AB8 0%, #D9B98C 44%, #C9832F 68%, #4A3A2C 100%);
}
/* The "Add a photo" affordance on an empty image slot. This IS a link (to Settings),
   so it is allowed to look pressable - the previous version was a CSS-only label that
   looked like a button and did nothing. */
.media__add {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: #fff;
  background: rgba(20, 17, 15, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.34);
  padding: 0.6rem 1.15rem;
  border-radius: 999px;
  white-space: nowrap;
  text-decoration: none;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease), transform 0.2s var(--ease);
}
.media__add::before { content: '+'; font-size: 17px; line-height: 1; }
/* On the Photos tiles the button uploads from the page, so only a signed-in admin sees it. */
.gallery .media__add { font: inherit; font-size: 14px; font-weight: 700; cursor: pointer; }
.gallery .media__add[hidden] { display: none; }
/* Edit photo on a filled tile (an admin only): the pill at the top right, and the panel
   it opens with Replace, Remove, the two position sliders and drag. */
.gedit {
  display: none; position: absolute; top: 10px; right: 10px; z-index: 3;
  font: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer;
  padding: 6px 12px; border-radius: 999px; color: #fff;
  background: rgba(20, 17, 15, 0.62); border: 1px solid rgba(255, 255, 255, 0.34);
}
.gallery__item:not(.is-missing) .gedit { display: inline-flex; }
.gedit:hover, .gallery__item.is-editing-photo .gedit { background: var(--accent); border-color: var(--accent); }
.gtools { display: none; }
.gallery__item.is-editing-photo .gtools {
  display: flex; flex-direction: column; gap: 8px;
  position: absolute; left: 10px; right: 10px; bottom: 10px; z-index: 3;
  padding: 10px 12px; border-radius: 10px; background: rgba(0, 0, 0, 0.62); color: #fff;
  font-family: 'Schibsted Grotesk', system-ui, sans-serif; font-size: 12px;
}
.gtools__row { display: flex; flex-wrap: wrap; gap: 8px; }
.gtools__close { margin-left: auto; }
.gtools .vphoto__slider input { width: 100%; }
.gallery__item.is-editing-photo > button[aria-label] { cursor: grab; }
.gallery__item.is-editing-photo img.is-dragging { cursor: grabbing; }
.media__add:hover {
  background: var(--accent);
  border-color: var(--accent);
  transform: translate(-50%, -50%) scale(1.04);
}

/* ═══════════════════════════════════════════════════════════════════════════
   HERO
   ═══════════════════════════════════════════════════════════════════════════ */

/* The green intro panel: monogram, names and date sit on the emerald; the photograph is in
   its own band beneath (the reference's opening column). .hero-intro also carries
   section--dark, so the emerald background and gold corner brackets come from there. */
.hero-intro {
  text-align: center;
  /* Top padding is half what it was: the logo sat too far down the panel. */
  padding: clamp(30px, 4.5vw, 66px) clamp(24px, 5vw, 60px) clamp(52px, 7vw, 96px);
}
/* Wide enough for "GRANT & ORLA" on one line at its largest; 780px was not. */
.hero-intro__inner { max-width: 1080px; margin: 0 auto; position: relative; z-index: 1; }
.hero-intro__logo {
  width: clamp(72px, 9vw, 118px);
  height: auto;
  margin: 0 auto clamp(20px, 2.6vw, 36px);
}
.hero-intro__kicker {
  margin: 0 0 clamp(16px, 2vw, 28px);
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
  font-weight: 600;
  font-size: clamp(11px, 0.95vw, 13px);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--accent-lit);
}
/* Uploaded ornaments (Settings > Photos) in place of the drawn rules. theme.css sets the
   --orn-*-d / -rule / -w variables only when a slot has an image, so with none uploaded the
   picture is display:none and the drawn rule shows, with nothing to flicker. On a phone the
   width is capped at 70% of the screen whatever the slider says. */
.ornament { display: none; height: auto; margin-inline: auto; }
.ornament--home {
  display: var(--orn-home-d, none);
  width: min(var(--orn-home-w, 220px), 70vw);
  margin: clamp(20px, 2.4vw, 32px) auto clamp(16px, 2vw, 28px);
}
.ornament--invite {
  display: var(--orn-invite-d, none);
  width: min(var(--orn-invite-w, 180px), 70vw);
  margin: 0 auto clamp(26px, 3vw, 42px);
}

.hero-intro__rule {
  display: var(--orn-home-rule, block);
  width: clamp(90px, 12vw, 150px);
  height: 1px;
  margin: clamp(20px, 2.4vw, 32px) auto clamp(16px, 2vw, 28px);
  background: linear-gradient(90deg, transparent, var(--accent-lit) 22%, var(--accent-lit) 78%, transparent);
  position: relative;
}
.hero-intro__rule::before {
  content: '';
  position: absolute; left: 50%; top: 50%;
  width: 7px; height: 7px;
  transform: translate(-50%, -50%) rotate(45deg);
  background: var(--accent-lit);
}

/* The names and date live on the emerald intro panel. */
.hero__names {
  margin: 0;
  font-family: var(--home-names-font, var(--font-heading));
  font-weight: var(--home-names-weight, var(--w-heading));
  /* Sized so the capitals fit one line up to 1920px wide. */
  font-size: clamp(48px, 6.4vw, 118px);
  text-transform: uppercase;   /* elegant spaced serif caps, like the reference */
  letter-spacing: 0.06em;
  line-height: 0.98;
  color: var(--d-fg);
  /* One line, always. As a centred flex line, a size too big for the column overflows
     evenly on both sides instead of wrapping or hanging off to the right. */
  display: flex;
  justify-content: center;
  white-space: nowrap;
}
/* The names sit on one line as one text box. (The stacked names with a separate Allura
   ampersand between them went: at signature sizes the stack was a mess.) */
.hero__meta {
  margin: 0;
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
  font-weight: 600;
  font-size: clamp(12px, 1.1vw, 15px);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--d-fg) 82%, transparent);
}

/* The photograph, its own full-width band under the intro. The crop (object-position) is set
   by dragging in Settings > Photos and comes through theme.css. */
.hero-photo {
  height: clamp(571px, 101vh, 1210px);   /* 60vh originally, +20% (v0.33.2), then +40% more */
  background: var(--d-bg);
  position: relative;
}
.hero__img { width: 100%; height: 100%; object-fit: cover; object-position: 62% 50%; }
/* The photo band is anchored to the TOP of the image (the two-class selector outranks the
   single-class rule the theme emits, so this wins over the Settings crop's vertical). */
/* Always the top-left of the photograph, on every screen; the crop drag in Settings > Photos
   does not move the hero any more. */
.hero-photo .hero__img { object-position: 0% 0%; }

/* Phones: names/date smaller. The photo band is much taller so the couple's faces are not
   cropped (a wide landscape photo in a narrow frame needs the height to show them).
   The rest of the phone type sizing lives in one block near the end of this file, so it
   lands AFTER the component rules it overrides. */
@media (max-width: 600px) {
  .hero__names { font-size: clamp(28px, 9.5vw, 44px); }   /* one line: "GRANT & ORLA" must fit a phone */
  .hero__meta  { font-size: clamp(10px, 2.6vw, 12px); letter-spacing: 0.16em; }
  .hero-photo  { height: clamp(384px, 70vh, 656px); }
}
/* On a phone the wide crop otherwise favours the venue on the right and loses the couple on
   the left, so the photo is anchored left as well as top. */
@media (max-width: 900px) {
  .hero-photo .hero__img { object-position: 0% 0%; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   APP BAR + PAGES + HOME TILES
   ═══════════════════════════════════════════════════════════════════════════ */

/* Persistent top navigation. Solid dark bar so it reads over any page, light or dark. */
.appbar {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: clamp(14px, 3vw, 40px);
  padding: 10px clamp(16px, 3vw, 40px);
  background: var(--d-bg);
  color: var(--d-fg);
}
.appbar__brand { display: inline-flex; flex: 0 0 auto; }
.appbar__brand img { width: 34px; height: 34px; border-radius: 9px; display: block; }
.appbar__nav {
  display: flex;
  gap: clamp(12px, 2.4vw, 32px);
  overflow-x: auto;
  scrollbar-width: none;
}
.appbar__nav::-webkit-scrollbar { display: none; }
.appbar__nav a {
  color: rgba(255, 255, 255, 0.72);
  text-decoration: none;
  font-weight: 600;
  font-size: clamp(14px, 1.05vw, 16px);
  letter-spacing: var(--track-nav);
  white-space: nowrap;
  padding: 5px 1px;
  border-bottom: 2px solid transparent;
}
.appbar__nav a:hover { color: #fff; }
.appbar__nav a.is-active { color: #fff; border-bottom-color: var(--accent-lit); }

/* Harmless now that nothing is hidden; kept so a stray hidden never shows. */
.page[hidden] { display: none; }

/* Home tiles: the main navigation. Big blocks, icon over label, four across on a laptop
   and two on a phone, like an app launcher. */
.section--tiles { padding-block: clamp(28px, 4vw, 60px); }
.tiles {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(14px, 1.8vw, 24px);
}
@media (max-width: 860px) { .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: clamp(12px, 1.6vw, 18px);
  aspect-ratio: 1 / 0.92;
  padding: clamp(18px, 2.4vw, 30px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  /* A soft warm off-white, not stark white, so the tiles sit in the cream palette. */
  background: color-mix(in srgb, #ffffff 60%, var(--paper));
  color: var(--ink);
  text-decoration: none;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.tile:hover,
.tile:focus-visible {
  transform: translateY(-4px);
  border-color: var(--accent);
  box-shadow: 0 26px 54px -34px color-mix(in srgb, var(--ink) 55%, transparent);
}
.tile__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: clamp(52px, 5vw, 64px);
  height: clamp(52px, 5vw, 64px);
  border-radius: 50%;
  /* A gold ring around the icon, the reference's motif. */
  border: 1px solid color-mix(in srgb, var(--accent-lit) 55%, transparent);
  background: color-mix(in srgb, var(--accent-lit) 8%, transparent);
  color: var(--accent);
}
.tile:hover .tile__icon { border-color: var(--accent-lit); }
.tile__icon svg { width: 46%; height: 46%; }
.tile__label {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(22px, 1.8vw, 30px);
  letter-spacing: 0.01em;
}

/* On a phone the tiles are about 25% shorter (0.92 -> 0.69 of their width) so all four fit
   below the banner without scrolling. Padding, gap and icon shrink to match so the icon and
   label still sit centred in the shorter tile. */
@media (max-width: 600px) {
  .tile { aspect-ratio: 1 / 0.69; padding: 14px; gap: 8px; }
  .tile__icon { width: 44px; height: 44px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   STICKY NAV
   ═══════════════════════════════════════════════════════════════════════════ */

.stickynav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: clamp(14px, 2vw, 34px);
  padding: 0 clamp(16px, 2.4vw, 40px);
  height: 66px;
  background: color-mix(in srgb, var(--d-bg) 90%, transparent);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid color-mix(in srgb, var(--d-fg) 12%, transparent);
  color: var(--d-fg);
  transform: translateY(-100%);
  transition: transform 0.4s var(--ease);
}
.stickynav.is-visible { transform: translateY(0); }

.stickynav__brand {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-heading);
  font-weight: var(--w-heading);
  font-size: 19px;
  letter-spacing: var(--track-nav);
  text-decoration: none;
  white-space: nowrap;
}
.stickynav__brand img { width: 30px; height: 30px; border-radius: 8px; display: block; }

.stickynav ol {
  list-style: none;
  display: flex;
  gap: clamp(10px, 1.6vw, 28px);
  margin: 0;
  padding: 0;
  flex: 1;
  overflow-x: auto;
  scrollbar-width: none;
}
.stickynav ol::-webkit-scrollbar { display: none; }

.stickynav ol a {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  text-decoration: none;
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.01em;
  white-space: nowrap;
  color: color-mix(in srgb, var(--d-fg) 64%, transparent);
  padding: 6px 0;
  border-bottom: 2px solid transparent;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.stickynav ol a span {
  font-size: 12px;
  font-weight: 600;
  color: color-mix(in srgb, var(--d-fg) 45%, transparent);
  font-variant-numeric: tabular-nums;
}
.stickynav ol a:hover { color: var(--d-fg); }
.stickynav ol a.is-active { color: var(--d-fg); border-bottom-color: var(--accent-lit); }
.stickynav ol a.is-active span { color: var(--accent-lit); }

.stickynav__cta {
  flex: none;
  text-decoration: none;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: var(--accent);
  color: var(--btn-fg);
  padding: 9px 18px;
  border-radius: 999px;
  transition: background 0.2s var(--ease);
}
.stickynav__cta:hover { background: var(--accent-hover); }

@media (max-width: 720px) {
  .stickynav ol { display: none; }
  .stickynav { justify-content: space-between; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   SECTION FURNITURE
   ═══════════════════════════════════════════════════════════════════════════ */

/* Top padding halved so every page heading sits closer to the navigation bar; bottom
   spacing unchanged. Applies to all content pages, so the headings stay aligned. */
/* Bottom padding halved (it was twice the top): the gap above each divider was too deep. */
/* Top and bottom padding from Settings > Brand & colours ("Space above and below each
   section"), a plain number multiplied into px here: full on a computer, half on a phone. */
.section { padding: calc(var(--section-gap, 74) * 1px) 0; }
@media (max-width: 600px) { .section { padding: calc(var(--section-gap, 74) * 0.5px) 0; } }
.section--dark { background: var(--d-bg); color: var(--d-fg); position: relative; overflow: hidden; }
.section--rsvp { background: var(--paper-2); }

/* Thin gold corner brackets on the emerald panels: a framed, formal feel that stands in for
   the reference's gold-leaf corners until real botanical artwork is added. */
.section--dark::before,
.section--dark::after {
  content: '';
  position: absolute;
  width: clamp(38px, 5vw, 84px);
  height: clamp(38px, 5vw, 84px);
  border: 1px solid color-mix(in srgb, var(--accent-lit) 42%, transparent);
  pointer-events: none;
}
.section--dark::before { top: clamp(18px, 2.4vw, 30px); right: clamp(18px, 2.4vw, 30px); border-left: 0; border-bottom: 0; }
.section--dark::after  { bottom: clamp(18px, 2.4vw, 30px); left: clamp(18px, 2.4vw, 30px); border-right: 0; border-top: 0; }

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 clamp(20px, 3.4vw, 48px);
}
.wrap--narrow { max-width: 820px; }

.eyebrow {
  margin: 0 0 clamp(18px, 2.2vw, 34px);
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;   /* small caps read cleaner in a sans */
  font-weight: 600;
  font-size: clamp(12px, 0.95vw, 14px);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--accent-lit);   /* gold label */
}
.eyebrow__num {
  font-size: inherit;
  font-weight: 600;
  letter-spacing: 0.16em;
  color: var(--accent-lit);
  font-variant-numeric: tabular-nums;
}
/* A short gold rule after the label, the way the mockup sets its section titles. */
.eyebrow::after {
  content: '';
  height: 1px;
  flex: 0 0 clamp(26px, 4vw, 56px);
  background: color-mix(in srgb, var(--accent-lit) 70%, transparent);
}

.h-display {
  margin: 0 0 clamp(14px, 1.6vw, 26px);
  font-family: var(--font-heading);
  font-weight: var(--w-heading);
  font-size: clamp(42px, 6vw, 88px);
  letter-spacing: 0.005em;
  line-height: 1.02;
}

.statement {
  margin: 0 0 clamp(38px, 5vw, 72px);
  max-width: 22ch;
  font-family: var(--font-heading);
  font-weight: var(--w-heading);
  font-size: clamp(30px, 4.4vw, 62px);
  letter-spacing: var(--track-display);
  line-height: 1.08;
  max-width: 18ch;
}
@media (min-width: 760px) { .statement { max-width: 24ch; } }

/* The invitation opener: a warm multi-paragraph message rather than one big line, so it
   is sized as a strong lede in the heading face, with "We are getting married." as the
   emphasised beat. */
.invite-message {
  margin: 0;   /* it is the last thing in the section; the section's own padding is the gap */
  /* rem, not ch: ch measures against this container's small inherited font, so it read far
     narrower than the paragraphs inside. rem fills the wrap and uses the space beside it. */
  max-width: 62rem;
}
.invite-message p {
  margin: 0 0 clamp(15px, 1.5vw, 22px);
  font-family: var(--invite-msg-font, var(--font-heading));
  font-weight: var(--invite-msg-weight, 500);
  /* Sized in vh (a share of screen height), set in Settings > Brand: one value for every screen. */
  font-size: calc(var(--invite-msg-fs, 2.6) * 1vh);
  line-height: 1.36;
  letter-spacing: -0.005em;
  color: var(--ink);
}
.invite-message p:last-child { margin-bottom: 0; }
.invite-message .invite-message__beat {
  margin: clamp(22px, 2.3vw, 34px) 0;
  /* Inherits the message font from the paragraph above; its own weight, and a vh size. */
  font-weight: var(--invite-beat-weight, var(--w-heading));
  font-size: calc(var(--invite-beat-fs, 5.2) * 1vh);
  line-height: 1.06;
  letter-spacing: var(--track-display);
}

.lede {
  margin: 0 0 clamp(34px, 4vw, 56px);
  max-width: 62ch;
  font-size: clamp(17px, 1.35vw, 21px);
  font-weight: 400;
  color: var(--muted);
  line-height: 1.55;
}
.section--dark .lede { color: var(--d-muted); }
.lede strong { color: inherit; font-weight: 600; }

/* Buttons ------------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 14px 30px;
  /* Crisp small-caps sans pills, like the reference "VIEW LOCATION" buttons. */
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
  font-weight: 600;
  font-size: 12.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.2s var(--ease), color 0.2s var(--ease),
              border-color 0.2s var(--ease), transform 0.2s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn--lg { padding: 16px 40px; font-size: 13px; }

.btn--primary { background: var(--accent); color: var(--btn-fg); }
.btn--primary:hover { background: var(--accent-hover); }

/* Gold-outlined pill, the way the reference sets its secondary actions. */
.btn--ghost { background: transparent; color: var(--accent); border-color: color-mix(in srgb, var(--accent-lit) 75%, transparent); }
.btn--ghost:hover { border-color: var(--accent-lit); background: color-mix(in srgb, var(--accent-lit) 10%, transparent); }
.section--dark .btn--ghost { color: var(--accent-lit); border-color: color-mix(in srgb, var(--accent-lit) 60%, transparent); }
.section--dark .btn--ghost:hover { border-color: var(--accent-lit); background: color-mix(in srgb, var(--accent-lit) 12%, transparent); }

/* Self-hosted fonts. Amsterdam Handwriting (Mayofont) is not on Google Fonts, so the file
   lives in public/fonts/ and is declared here; the theme lists it as `hosted` so it is never
   @imported. Every format is listed so whichever file was dropped in is the one used. If none
   exists yet the browser falls back through the stack (Allura), so nothing breaks. */
@font-face {
  font-family: 'Amsterdam Handwriting';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  /* The .ttf is the file that exists, so it comes first: the browser stops at the first
     source that loads, and listing the others ahead of it cost two 404s on every page. */
  src: local('Amsterdam Handwriting'),
       url('/fonts/AmsterdamHandwriting.ttf') format('truetype'),
       url('/fonts/AmsterdamHandwriting.woff2') format('woff2'),
       url('/fonts/AmsterdamHandwriting.woff') format('woff'),
       url('/fonts/AmsterdamHandwriting.otf') format('opentype');
}

/* A small hand-drawn gold heart flourish that sits between sections. Inline SVG so it
   takes the gold brand token (currentColor) and stays crisp at any size, no image upload. */
.divider {
  width: min(360px, 72%);
  margin-inline: auto;
  /* "Space around the dividers" in Settings > Brand & colours; half of it on a phone. */
  margin-block: calc(var(--divider-gap, 40) * 1px);
  color: var(--accent-lit);
}
@media (max-width: 600px) { .divider { margin-block: calc(var(--divider-gap, 40) * 0.5px); } }
.divider svg { display: block; width: 100%; height: auto; overflow: visible; }
.divider__line,
.divider__heart {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* On the dark green photos section the gold still reads well; nothing to change. */

/* ═══════════════════════════════════════════════════════════════════════════
   MUSIC PLAYER - one song, on a dark card pulled up over the photo's bottom edge
   ═══════════════════════════════════════════════════════════════════════════ */
.player {
  position: relative;
  z-index: 2;
  width: min(440px, 88vw);
  margin: calc(-1 * clamp(96px, 12vw, 150px)) auto 0;   /* half over the photo, half on the page */
  text-align: center;
}
.player[hidden] { display: none; }
.player__card {
  background: var(--d-bg);
  color: var(--d-fg);
  border: 1px solid var(--accent-lit);
  border-radius: 18px;
  padding: clamp(20px, 3vw, 30px) clamp(20px, 3vw, 32px) clamp(16px, 2.4vw, 24px);
  box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.6);
}
.player__title {
  margin: 0 0 4px;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: clamp(20px, 2vw, 26px);
  line-height: 1.2;
}
.player__artist {
  margin: 0 0 18px;
  font-family: var(--font-heading);
  font-size: clamp(15px, 1.3vw, 18px);
  color: var(--d-muted);
}
.player__bar {
  position: relative;
  height: 3px;
  margin: 0 4px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--d-fg) 22%, transparent);
  cursor: pointer;
}
.player__fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; border-radius: 2px; background: var(--accent-lit); }
.player__knob {
  position: absolute; top: 50%; left: 0;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--accent-lit);
  transform: translate(-50%, -50%);
}
.player__times {
  display: flex; justify-content: space-between;
  margin: 8px 4px 14px;
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
  font-size: 12px; letter-spacing: 0.04em;
  color: var(--d-muted);
}
.player__controls { display: flex; align-items: center; justify-content: center; gap: clamp(22px, 4vw, 34px); }
.player__btn {
  width: 30px; height: 30px; padding: 0; border: 0;
  background: transparent; color: var(--accent-lit); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.player__btn svg { width: 24px; height: 24px; }
.player__btn:hover { color: var(--d-fg); }
.player__btn[aria-pressed="true"] { color: var(--d-fg); }
.player__btn--play { width: 58px; height: 58px; border-radius: 50%; background: var(--accent-lit); color: var(--d-bg); }
.player__btn--play:hover { color: var(--d-bg); filter: brightness(1.08); }
.player__btn--play svg { width: 26px; height: 26px; }
.player__btn--play .player__ico-pause { display: none; }
.player.is-playing .player__btn--play .player__ico-play { display: none; }
.player.is-playing .player__btn--play .player__ico-pause { display: block; }
.player__note {
  margin: 16px 0 0;
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
  font-size: 12px; font-weight: 600;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--accent-lit);
}
.player__note:empty { display: none; }
@media (max-width: 600px) {
  .player { margin-top: -72px; }
  .player__card { border-radius: 14px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   01 · INVITATION
   ═══════════════════════════════════════════════════════════════════════════ */

/* No boxed container: the wording sits directly on the page background. The padding is
   kept for breathing room and to hold the text to a comfortable measure. */
.invite-card {
  padding: clamp(34px, 5vw, 72px) clamp(24px, 4vw, 64px) clamp(30px, 4vw, 56px);
  text-align: center;
}
/* Optional uploaded image across the WHOLE Invitation page, with the wording laid on top.
   Added by app.js when an image has been uploaded (Settings > Photos). The image itself is
   set inline by app.js (cache-busted); the crop position comes from theme.css, and the
   phone gets its own position, both set by dragging in the admin. */
/* The picture is a layer of its own (::before) rather than the section's background, so
   it can be faded with the Transparency slider without fading the wording, which sits
   above it in the positioned .wrap. The vertical offset is in vw (see inviteBgCss). */
[data-page="invitation"].has-invite-bg { position: relative; }
[data-page="invitation"].has-invite-bg::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: var(--invite-bg-url);
  background-repeat: no-repeat;
  background-position: var(--invite-bg-pos, 50% 0vw);
  background-size: var(--invite-bg-size, 100%) auto;
  opacity: var(--invite-bg-opacity, 1);
}
[data-page="invitation"].has-invite-bg > .wrap { position: relative; }
@media (max-width: 760px) {
  [data-page="invitation"].has-invite-bg::before {
    background-position: var(--invite-bg-pos-m, var(--invite-bg-pos, 50% 0vw));
    background-size: var(--invite-bg-size-m, var(--invite-bg-size, 100%)) auto;
  }
}
/* The details drop their white box so the words sit directly on the artwork, and the top
   padding goes so the block sits up near the eyebrow instead of far below it. */
[data-page="invitation"].has-invite-bg .invite-card {
  background: transparent;
  border: none;
  box-shadow: none;
  padding-top: 0;
}

.invite-card__rule {
  display: var(--orn-invite-rule, block);
  width: clamp(90px, 14vw, 150px);
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent-lit) 22%, var(--accent-lit) 78%, transparent);
  margin: 0 auto clamp(26px, 3vw, 42px);
  position: relative;
}
.invite-card__rule::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 7px;
  height: 7px;
  transform: translate(-50%, -50%) rotate(45deg);
  background: var(--accent-lit);
}

.invite-card__hosts {
  margin: 0 0 clamp(14px, 1.6vw, 22px);
  font-weight: 600;
  font-size: clamp(13px, 1.05vw, 16px);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
}

.invite-card__names {
  /* Room above as well as below, in em so it grows with the glyphs: a signature script (the
     default, Amsterdam Handwriting) throws its capitals about half an em above the line box
     and its tails below it, into the addressee line and the request line at desktop sizes. */
  margin: 0.9em 0 0.6em;
  font-family: var(--invite-names-font, var(--font-heading));
  font-weight: var(--invite-names-weight, var(--w-heading));
  /* Sized in vh (a share of screen height), set in Settings > Brand. One value scales
     proportionally on a computer and a phone, so it need not be tuned twice. */
  font-size: calc(var(--invite-names-fs, 7) * 1vh);
  /* normal tracking and a little line height: a connected script overlaps under the tight
     display tracking and needs room for its tall strokes. */
  letter-spacing: normal;
  line-height: 1.25;
}

/* The addressee line ("Dear Wybrand and Valarie"), only shown on a household's personal
   link. .btn sets display:inline-flex, which would beat the browser's own [hidden] rule,
   so both hidden states are spelled out here. */
.invite-card__to {
  margin: 0 0 clamp(10px, 1.2vw, 16px);
  font-size: clamp(18px, 1.5vw, 24px);
  color: var(--muted);
  line-height: 1.4;
}
.invite-card__to-names { color: var(--ink); font-weight: 600; }
/* In Edit mode the names are clickable too (they open the type bar for the whole line), so
   they get the same dashed hint as a wording block. */
.is-editing .invite-card__to-names {
  outline: 1px dashed color-mix(in srgb, var(--accent-lit) 70%, transparent);
  outline-offset: 4px;
  border-radius: 3px;
  cursor: pointer;
}
/* In Edit mode the line shows stand-in names; say so, quietly, so nobody thinks they are real. */
.is-editing .invite-card__to[data-placeholder] .invite-card__to-names::after {
  content: ' (stand-in names; each guest sees their own)';
  font-size: 0.6em;
  font-weight: 400;
  color: var(--muted);
}
.invite-card__to[hidden],
.invite-card__actions .btn[hidden] { display: none; }

.invite-card__request {
  margin: 0 0 clamp(30px, 4vw, 52px);
  font-size: clamp(17px, 1.35vw, 21px);
  color: var(--muted);
  line-height: 1.5;
}

.invite-card__facts {
  margin: 0 0 clamp(30px, 4vw, 48px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: clamp(20px, 2.6vw, 36px);
  text-align: left;
  border-top: calc(var(--invite-rule-width) * 1px) solid var(--invite-rule-color);
  border-bottom: calc(var(--invite-rule-width) * 1px) solid var(--invite-rule-color);
  padding: clamp(24px, 3vw, 38px) 0;
}
.invite-card__facts dt {
  font-weight: 600;
  font-size: 13px;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 7px;
}
.invite-card__facts dd {
  margin: 0;
  font-weight: 600;
  font-size: clamp(16px, 1.2vw, 19px);
  letter-spacing: -0.015em;
  line-height: 1.35;
}

.invite-card__actions {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}

.invite-card__note {
  margin: clamp(20px, 2.4vw, 30px) 0 0;
  font-size: 15px;
  color: var(--muted);
}
.invite-card__note strong { color: var(--ink); font-weight: 600; }

/* ═══════════════════════════════════════════════════════════════════════════
   02 · THE DAY
   ═══════════════════════════════════════════════════════════════════════════ */

/* On the light background: a dark-green icon circle beside each event, joined by a
   thin green connector line. */
.timeline {
  list-style: none;
  margin: 0;   /* the bottom margin went with the notes that used to follow; the section padding is the gap now */
  padding: 0;
  position: relative;
}
.timeline::before {
  content: '';
  position: absolute;
  left: clamp(22px, 2.5vw, 28px);
  top: clamp(62px, 5.8vw, 78px);      /* the first circle's centre, now on its title row */
  bottom: clamp(56px, 5.4vw, 72px);
  width: 2px;
  transform: translateX(-1px);
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  z-index: 0;
}

.timeline__item {
  position: relative;
  display: grid;
  grid-template-columns: clamp(44px, 5vw, 56px) 1fr;
  grid-template-rows: auto auto auto;
  column-gap: clamp(16px, 2.4vw, 30px); row-gap: 0;
  padding: clamp(15px, 1.9vw, 24px) 0;
  align-items: start;
}
.timeline__marker {
  grid-column: 1; grid-row: 2; align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: clamp(44px, 5vw, 56px);
  height: clamp(44px, 5vw, 56px);
  border-radius: 50%;
  background: var(--d-bg);        /* dark green circle */
  color: var(--accent-lit);       /* gold icon */
  flex: 0 0 auto;
  position: relative;
  z-index: 1;
}
.timeline__marker svg { width: 46%; height: 46%; }

/* The circle sits on the centre line of the TITLE. The body's three lines (time, title,
   note) become rows of the item's grid (display: contents), the circle is placed in the
   title's row and centred in it, and the time sits above on its own row. */
.timeline__body { display: contents; }
.timeline__body .timeline__time {
  margin: 0 0 3px;
  grid-column: 2; grid-row: 1;
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
  font-weight: 700;
  font-size: clamp(13px, 1.1vw, 16px);
  letter-spacing: 0.04em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  max-width: none;
}
.timeline__body h3 {
  grid-column: 2; grid-row: 2; align-self: center;   /* the row is the circle's height; the title sits on its centre line */
  margin: 0 0 5px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(22px, 1.9vw, 30px);
  letter-spacing: 0.005em;
  line-height: 1.14;
  color: var(--ink);
}
.timeline__body p {
  grid-column: 2; grid-row: 3;
  margin: 0;
  color: var(--muted);
  max-width: none;
  min-width: 0;
}

@media (max-width: 620px) {
  .timeline__item { gap: 14px; }
}

/* Practical notes ---------------------------------------------------------- */
.notes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(255px, 1fr));
  gap: clamp(22px, 3vw, 44px);
}
.notes--tight { margin-top: clamp(40px, 5vw, 68px); }

/* The four Getting-there topics on one line, full width under the two cards. */
.notes--row { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 900px) { .notes--row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }   /* tablets: two */
@media (max-width: 600px) { .notes--row { grid-template-columns: 1fr; } }   /* phones: one column */

.note h3 {
  margin: 0 0 9px;
  font-family: var(--font-heading);
  font-weight: var(--w-heading);
  font-size: clamp(17px, 1.35vw, 21px);
  letter-spacing: -0.025em;
  padding-top: 16px;
  border-top: 2px solid var(--accent);
  display: inline-block;
}
.section--dark .note h3 { border-top-color: var(--accent-lit); }
.note p { margin: 0; color: var(--muted); }
/* A single note across the whole row (Getting there): spans every grid column, and carries
   the rule itself since there is no heading to carry it. */
.note--wide { grid-column: 1 / -1; padding-top: 16px; border-top: 2px solid var(--accent); }
/* A wide note WITH a heading (Photos): the heading carries the rule, drawn about four
   times the heading's own width, and the full-width line above is not drawn. */
.note--wide:has(h3) { padding-top: 0; border-top: 0; }
.note--wide h3 { min-width: min(100%, 22em); }
.section--dark .note p { color: var(--d-muted); }

/* ═══════════════════════════════════════════════════════════════════════════
   03 · GETTING THERE
   ═══════════════════════════════════════════════════════════════════════════ */

.cols {
  display: grid;
  grid-template-columns: 1.55fr 1fr;
  gap: clamp(30px, 4vw, 68px);
  align-items: stretch;   /* the venue card and the Staying-over card match height */
}
@media (max-width: 900px) { .cols { grid-template-columns: 1fr; } }

.address-card {
  background: var(--accent);
  color: var(--d-fg);
  border-radius: var(--radius);
  padding: clamp(28px, 3.4vw, 46px);
}
.address-card__label {
  margin: 0 0 12px;
  font-weight: 600;
  font-size: 13px;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--accent-lit);
}
.address-card__name {
  margin: 0 0 14px;
  font-family: var(--font-heading);
  font-weight: var(--w-heading);
  font-size: clamp(30px, 3.4vw, 46px);
  letter-spacing: var(--track-display);
  line-height: 1;
}
.address-card address {
  font-style: normal;
  color: var(--d-muted);
  font-size: clamp(16px, 1.15vw, 18px);
  line-height: 1.6;
  margin-bottom: clamp(22px, 2.6vw, 32px);
}
.address-card__actions { display: flex; gap: 12px; flex-wrap: wrap; align-self: start; }
/* The venue photo: a tall panel on the right of the card, the text in the left column. On
   a phone it drops under the button. With no photo uploaded the image removes itself
   (data-optional) and the dashed placeholder shows in its place. */
.address-card { display: grid; grid-template-columns: 1fr minmax(180px, 38%); grid-template-rows: auto auto auto 1fr; column-gap: clamp(22px, 3vw, 44px); }
.address-card > :not(.address-card__photo) { grid-column: 1; }
.address-card__photo {
  grid-column: 2; grid-row: 1 / span 4;
  position: relative; min-height: 260px;
  border-radius: 14px; overflow: hidden;
  background: color-mix(in srgb, var(--accent) 78%, #000);   /* the drawn map's ground */
  color: var(--accent-lit);
  display: flex; align-items: center; justify-content: center;
}
/* Size, offset, crop and opacity come from theme.css variables (set on the page in Edit mode).
   At size 100 the photo fills the panel and x/y choose the crop; larger zooms in and x/y
   slide it; smaller leaves green around it and x/y place it. */
.address-card__photo img {
  position: absolute;
  width: calc(var(--venue-size, 100) * 1%); height: calc(var(--venue-size, 100) * 1%);
  left: calc((100% - var(--venue-size, 100) * 1%) * var(--venue-x, 50) / 100);
  top: calc((100% - var(--venue-size, 100) * 1%) * var(--venue-y, 50) / 100);
  object-fit: cover; object-position: calc(var(--venue-x, 50) * 1%) calc(var(--venue-y, 50) * 1%);
  max-width: none;   /* the global img cap would stop the zoom growing sideways */
  opacity: var(--venue-opacity, 1);
  user-select: none; -webkit-user-drag: none;
}
/* The Edit-mode tools over the photo: Add/Replace, Remove, Size and Transparency sliders. */
.vphoto__tools { display: none; }
.is-editing .vphoto__tools {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  position: absolute; left: 10px; right: 10px; bottom: 10px; z-index: 2;
  padding: 10px 12px; border-radius: 10px;
  background: rgba(0, 0, 0, 0.6); color: #fff;
  font-family: 'Schibsted Grotesk', system-ui, sans-serif; font-size: 12px;
}
.vphoto__btn {
  display: inline-block; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.5); border-radius: 999px; background: transparent;
  padding: 5px 12px; color: #fff; font: inherit; font-weight: 700; line-height: 1.2;
}
.vphoto__btn:hover { border-color: #fff; }
.vphoto__btn[hidden] { display: none; }
.vphoto__btn[data-armed] { color: #f7b0a8; border-color: #f7b0a8; }
.vphoto__slider { display: flex; flex-direction: column; gap: 2px; font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: rgba(255, 255, 255, 0.8); }
.vphoto__slider input { width: 120px; accent-color: var(--accent-lit); }
.vphoto__hint { flex-basis: 100%; font-size: 11px; color: rgba(255, 255, 255, 0.7); }
.vphoto__msg { font-size: 12px; color: var(--accent-lit); }
.is-editing .address-card__photo img { cursor: grab; }
.is-editing .address-card__photo img.is-dragging { cursor: grabbing; }
.address-card__photo img + .address-card__ph { display: none; }
/* The drawn map that stands in until a photo is uploaded. */
.address-card__map { position: absolute; inset: 0; width: 100%; height: 100%; }
.address-card__map-hole { fill: color-mix(in srgb, var(--accent) 78%, #000); }
@media (max-width: 700px) {
  .address-card { grid-template-columns: 1fr; grid-template-rows: none; }
  .address-card > :not(.address-card__photo) { grid-column: 1; }
  .address-card__photo { grid-column: 1; grid-row: auto; min-height: 200px; margin-top: 22px; }
}
/* On the green card the primary pill's usual green would vanish into the card, so it rests
   in the lighter green (what used to be its hover) and goes gold on hover. */
.address-card .btn--primary { background: var(--accent-hover); }
.address-card .btn--primary:hover { background: var(--accent-lit); color: #14110f; }
.address-card .btn--ghost { color: var(--d-fg); border-color: var(--d-line); }
.address-card .btn--ghost:hover { border-color: var(--d-fg); }

.cols__side { display: grid; gap: clamp(18px, 2.2vw, 26px); }

.side-card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(24px, 2.8vw, 34px);
  background: var(--surface);
}
.side-card h3 {
  margin: 0 0 10px;
  font-family: var(--font-heading);
  font-weight: var(--w-heading);
  font-size: clamp(19px, 1.6vw, 24px);
  letter-spacing: var(--track-nav);
}
.side-card p { margin: 0; color: var(--muted); }
.side-card__intro { margin-bottom: 18px !important; font-size: 15px; }

.side-card--accent {
  background: var(--accent);
  border-color: transparent;
  color: var(--btn-fg);
}
.side-card--accent h3 { color: var(--btn-fg); }
.side-card--accent p { color: color-mix(in srgb, var(--btn-fg) 90%, transparent); }

.stay-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; }
.stay-list li { padding-bottom: 16px; border-bottom: 1px solid var(--line); }
.stay-list li:last-child { padding-bottom: 0; border-bottom: 0; }
.stay-list__name {
  display: block;
  font-weight: 600;
  font-size: 17px;
  letter-spacing: -0.02em;
  margin-bottom: 3px;
}
.stay-list__meta { display: block; font-size: 14px; color: var(--muted); line-height: 1.45; }

/* The "Staying over" card on the main page is one link to the accommodation page. */
.side-card--link { cursor: pointer; transition: border-color 0.2s, box-shadow 0.2s; }
.side-card--link:hover { border-color: var(--accent-lit); box-shadow: 0 18px 40px -30px rgba(0, 0, 0, 0.35); }
.side-card__cta { margin: 18px 0 0; }

/* The Staying over card: a dark green panel with a gold line drawing across the top, a kicker, the
   heading, three facts (places, distance, price) and the button. The card's own padding
   moves to the body so the panel runs edge to edge. */
.stay-promo { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.stay-promo__art { height: clamp(130px, 11vw, 170px); background: var(--accent); color: var(--accent-lit); }   /* the venue card's green */
.stay-promo__art svg { display: block; width: 100%; height: 100%; }
.stay-promo__body { padding: clamp(20px, 2.4vw, 28px) clamp(24px, 2.8vw, 34px) clamp(24px, 2.8vw, 34px); display: flex; flex-direction: column; flex: 1; }
.stay-promo__kicker {
  margin: 0 0 6px !important;
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
  font-size: 12px; font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--accent-lit) !important;   /* gold, like the section eyebrows */
}
.stay-promo .side-card__intro { margin-bottom: 16px !important; }
.stay-promo__facts {
  list-style: none; margin: auto 0 0; padding: 14px 0 0;
  border-top: 1px solid var(--line);
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
}
.stay-promo__facts li { display: flex; flex-direction: column; gap: 2px; }
.stay-promo__facts strong {
  font-family: var(--font-heading); font-weight: var(--w-heading);
  font-size: clamp(22px, 1.8vw, 28px); line-height: 1; letter-spacing: -0.01em;
}
.stay-promo__facts span {
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
  font-size: 12px; color: var(--muted); letter-spacing: 0.02em;
}
.stay-promo .side-card__cta { margin-top: 18px; }

/* The accommodation page: a grid of place cards. */
.stay-grid {
  list-style: none;
  margin: clamp(24px, 3vw, 40px) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: clamp(16px, 2vw, 24px);
}
.stay-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: clamp(20px, 2.4vw, 28px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}
.stay-card__dist {
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
  font-size: 12px; font-weight: 600;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--accent-lit);
}
.stay-card__name {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: var(--w-heading);
  font-size: clamp(20px, 1.6vw, 24px);
  line-height: 1.15;
}
.stay-card__addr { margin: 0; color: var(--muted); line-height: 1.45; }
.stay-card__price {
  margin: 6px 0 0;
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
  font-size: 13.5px; font-weight: 600;
  color: var(--accent);
}
.stay-card__acts { display: flex; gap: 14px; flex-wrap: wrap; margin: auto 0 0; padding-top: 8px; }
.stay-card__acts a {
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
  font-size: 13px; font-weight: 700;
  color: var(--accent); text-decoration: none;
}
.stay-card__acts a:hover { text-decoration: underline; }
.stay-card--clickable { cursor: pointer; transition: border-color 0.2s, box-shadow 0.2s; }
.stay-card--clickable:hover,
.stay-card--clickable:focus-visible { border-color: var(--accent-lit); box-shadow: 0 18px 40px -30px rgba(0, 0, 0, 0.35); outline: none; }
.stay-card__more { margin-left: auto; font-family: 'Schibsted Grotesk', system-ui, sans-serif; font-size: 13px; font-weight: 700; color: var(--accent-lit); }
/* The pop-up's wording lives inside the card, hidden; Edit mode shows it so it can be edited. */
.stay-detail { display: none; }
.is-editing .stay-detail {
  display: block;
  margin-top: 10px; padding-top: 10px;
  border-top: 1px dashed var(--line);
}
.is-editing .stay-detail p { margin: 6px 0 0; font-size: 15px; color: var(--muted); line-height: 1.45; }
.stay-detail__label {
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
  font-size: 11px; font-weight: 600; letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--accent);
}
.is-editing .stay-card--clickable { cursor: text; }
/* The pop-up photo row inside that block: thumbnail, Add photo, Remove photo. */
.stay-photo { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.stay-photo__thumb { width: 64px; height: 48px; object-fit: cover; border-radius: 6px; border: 1px solid var(--line); }
.stay-photo__thumb[hidden] { display: none; }
.stay-photo__btn {
  display: inline-block; cursor: pointer;
  border: 1px solid var(--line); border-radius: 999px; background: transparent;
  padding: 5px 12px;
  font-family: 'Schibsted Grotesk', system-ui, sans-serif; font-size: 12.5px; font-weight: 700;
  color: var(--accent); line-height: 1.2;
}
.stay-photo__btn:hover { border-color: var(--accent); }
.stay-photo__btn[hidden] { display: none; }
.stay-photo__remove[data-armed] { color: #a33; border-color: #a33; }
.stay-photo__msg { font-size: 12.5px; color: var(--muted); }

/* The place detail modal on the accommodation page. */
.stay-modal {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center; padding: 20px;
  background: rgba(18, 59, 44, 0.6);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
.stay-modal[hidden] { display: none; }
.stay-modal__card {
  position: relative;
  width: 100%; max-width: 860px; max-height: calc(100vh - 40px); overflow-y: auto;
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--accent-lit); border-radius: 18px;
  box-shadow: 0 40px 80px -30px rgba(0, 0, 0, 0.55);
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
}
/* The photo (or its placeholder) fills the left column; the wording sits on the right. */
.stay-modal__media {
  position: relative; min-height: 320px;
  background: linear-gradient(160deg, var(--paper-2), color-mix(in srgb, var(--accent-lit) 35%, var(--paper-2)));
  border-radius: 17px 0 0 17px; overflow: hidden;
}
.stay-modal__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.stay-modal__media img[hidden] { display: none; }
.stay-modal__ph {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: 'Schibsted Grotesk', system-ui, sans-serif; font-size: 12px; font-weight: 600;
  letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--accent);
  opacity: 0.7;
}
.stay-modal__ph[hidden] { display: none; }
.stay-modal__body { padding: clamp(24px, 3vw, 36px); display: flex; flex-direction: column; gap: 10px; }
@media (max-width: 700px) {
  .stay-modal__card { grid-template-columns: 1fr; }
  .stay-modal__media { min-height: 200px; border-radius: 17px 17px 0 0; }
}
.stay-modal__close {
  position: absolute; top: 12px; right: 14px; z-index: 1;
  width: 36px; height: 36px; border: 0; border-radius: 50%;
  /* A white disc with a green X: on a phone the button sits over the photo, so it has to
     stand out from whatever is behind it. The shadow keeps it visible on a pale photo. */
  background: #fff; color: var(--ink); font-size: 26px; line-height: 1; cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.28);
}
.stay-modal__close:hover { background: var(--ink); color: #fff; }
.stay-modal__name {
  margin: 0; padding-right: 36px;
  font-family: var(--font-heading); font-weight: var(--w-heading);
  font-size: clamp(26px, 2.4vw, 34px); line-height: 1.1;
}
.stay-modal__about { margin: 6px 0 0; line-height: 1.55; }
.stay-modal__acts { display: flex; flex-wrap: wrap; gap: 10px; margin: 12px 0 0; }

.stay-note { margin: clamp(24px, 3vw, 40px) 0 0; max-width: 70ch; font-size: 15px; color: var(--muted); }

/* ═══════════════════════════════════════════════════════════════════════════
   SEATING PLAN (/seating): one card per table. A round table top in the dark green with
   the number in gold, then the names in the display serif, one under the other.
   ═══════════════════════════════════════════════════════════════════════════ */
.plan-find { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 0 0 clamp(22px, 3vw, 40px); }
.plan-find input {
  width: min(100%, 360px); font: inherit; font-size: 17px; padding: 12px 16px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--ink);
}
.plan-find input:focus { outline: 0; border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent); }
.plan-find__note { font-size: 14px; color: var(--muted); }
.plan-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: clamp(18px, 2.4vw, 30px); }
.plan-table {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: clamp(22px, 2.6vw, 30px) clamp(18px, 2vw, 24px) clamp(24px, 2.8vw, 32px);
  text-align: center;
}
.plan-table[hidden] { display: none; }
.plan-table__top { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-bottom: 16px; }
.plan-table__word {
  font-family: 'Schibsted Grotesk', system-ui, sans-serif; font-size: 12px; font-weight: 600;
  letter-spacing: 0.24em; text-transform: uppercase; color: var(--accent-lit);
}
/* The table top: a green disc with a gold double ring, the number or name inside. */
.plan-table__num {
  display: flex; align-items: center; justify-content: center;
  width: 108px; height: 108px; border-radius: 50%; padding: 8px;
  background: var(--accent); color: var(--accent-lit);
  box-shadow: 0 0 0 3px var(--surface), 0 0 0 4px var(--accent-lit);
  font-family: var(--font-heading); font-weight: var(--w-heading); font-size: 34px; line-height: 1;
  overflow-wrap: anywhere;
}
.plan-table__names { list-style: none; margin: 0; padding: 14px 0 0; border-top: 1px solid var(--line); }
.plan-table__name {
  font-family: var(--font-heading); font-weight: 500; font-size: clamp(18px, 1.5vw, 22px); line-height: 1.35;
  padding: 3px 8px; border-radius: 8px; color: var(--ink);
}
.plan-table__name.is-hit { background: color-mix(in srgb, var(--accent-lit) 30%, transparent); font-weight: 700; }
.plan-table__none, .plan-empty { color: var(--muted); font-size: 15px; margin: 0; }
.plan-empty { grid-column: 1 / -1; font-size: 17px; }
.plan-table__none { padding-top: 14px; border-top: 1px solid var(--line); }
.stay-back { margin: clamp(20px, 2.4vw, 32px) 0 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   04 · PHOTOS
   ═══════════════════════════════════════════════════════════════════════════ */

/* Upload Photos: the guest-upload call to action at the top of the Photos page. Lives on a
   dark section, so the QR sits on a white card and the field uses the on-dark treatment. */
.uploadcta { margin: 0 0 clamp(48px, 6vw, 84px); }
.uploadcta[hidden] { display: none; }
.uploadcta__grid {
  display: flex; flex-wrap: wrap; align-items: center; gap: clamp(20px, 3vw, 40px);
  margin-top: clamp(18px, 2vw, 26px);
}
.uploadcta__qr {
  flex: 0 0 auto; width: clamp(140px, 20vw, 180px); aspect-ratio: 1;
  background: #fff; border-radius: 16px; padding: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.28);
}
.uploadcta__qr svg { display: block; width: 100%; height: 100%; }
.uploadcta__qr:empty { display: none; }
.uploadcta__form { flex: 1 1 260px; max-width: 420px; }
.uploadcta__form label {
  display: block; font-weight: 600; font-size: 14px; margin-bottom: 10px;
  letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--d-muted);
}
.uploadcta__row { display: flex; gap: 10px; flex-wrap: wrap; }
.uploadcta__row input {
  flex: 1 1 160px; min-width: 0; font-family: inherit; font-size: 17px; padding: 13px 16px;
  border: 1px solid color-mix(in srgb, var(--d-fg) 26%, transparent);
  border-radius: 12px; background: color-mix(in srgb, var(--d-fg) 8%, transparent);
  color: var(--d-fg);
}
.uploadcta__row input::placeholder { color: color-mix(in srgb, var(--d-fg) 45%, transparent); }
.uploadcta__row input:focus {
  outline: 0; border-color: var(--accent-lit);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-lit) 28%, transparent);
}
.uploadcta__row button {
  flex: 0 0 auto; border: 0; border-radius: 999px; cursor: pointer;
  background: var(--accent-lit); color: #14110f;
  font-family: inherit; font-weight: 700; font-size: 15px; padding: 13px 26px;
  transition: filter 0.2s var(--ease);
}
.uploadcta__row button:hover { filter: brightness(1.07); }
.uploadcta__row button[disabled] { opacity: 0.6; cursor: progress; }
.uploadcta__err {
  margin: 12px 0 0; font-size: 14px; font-weight: 600; color: #ffd9cc;
}
.uploadcta__err[hidden] { display: none; }

.gallery {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-auto-rows: clamp(180px, 24vw, 420px);
  gap: clamp(10px, 1.2vw, 18px);
}

.gallery__item {
  border-radius: 10px;
  grid-column: span 3;
  min-width: 0;
  min-height: 0;
}
/* Put the remainder first, followed by complete rows of four. */
@media (min-width: 601px) {
  .gallery:has(> :nth-child(4n + 1):last-child) > :first-child { grid-column: span 12; }
  .gallery:has(> :nth-child(4n + 2):last-child) > :nth-child(-n + 2) { grid-column: span 6; }
  .gallery:has(> :nth-child(4n + 3):last-child) > :nth-child(-n + 3) { grid-column: span 4; }
}
@media (max-width: 600px) {
  .gallery { grid-template-columns: repeat(6, minmax(0, 1fr)); grid-auto-rows: 220px; }
  .gallery:has(> :nth-child(2n + 1):last-child) > :first-child { grid-column: span 6; }
}

.gallery__item > button[aria-label] {   /* the enlarge button alone: the one wrapping the photo */
  all: unset;
  display: block;
  width: 100%;
  height: 100%;
  cursor: zoom-in;
}
.gallery__item.is-missing > button[aria-label] { cursor: default; }
.gallery__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s var(--ease), filter 0.4s var(--ease);
}
.gallery__item:hover img { transform: scale(1.045); filter: brightness(1.06); }
.gallery__item > button[aria-label]:focus-visible { outline: 2px solid var(--accent-lit); outline-offset: 3px; }

/* Lightbox ----------------------------------------------------------------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(10, 8, 7, 0.95);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(20px, 5vw, 70px);
}
.lightbox[hidden] { display: none; }
.lightbox__img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 6px;
}
.lightbox__close,
.lightbox__nav {
  position: absolute;
  background: rgba(255, 255, 255, 0.1);
  border: 0;
  color: #fff;
  font-family: inherit;
  cursor: pointer;
  border-radius: 50%;
  width: 52px;
  height: 52px;
  font-size: 30px;
  line-height: 1;
  display: grid;
  place-items: center;
  transition: background 0.2s var(--ease);
}
.lightbox__close:hover,
.lightbox__nav:hover { background: rgba(255, 255, 255, 0.22); }
.lightbox__close { top: 18px; right: 18px; font-size: 26px; }
.lightbox__nav--prev { left: 14px; top: 50%; transform: translateY(-50%); }
.lightbox__nav--next { right: 14px; top: 50%; transform: translateY(-50%); }

/* ═══════════════════════════════════════════════════════════════════════════
   05 · RSVP
   ═══════════════════════════════════════════════════════════════════════════ */

.rsvp { display: grid; gap: clamp(20px, 2.4vw, 28px); }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.field { display: grid; gap: 8px; border: 0; padding: 0; margin: 0; min-width: 0; }

.field > label,
.field legend {
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.005em;
  color: var(--ink);
  padding: 0;
}
.req { color: var(--accent); }

.field__hint { margin: 0; font-size: 13.5px; color: var(--muted); line-height: 1.45; }

.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field select,
.field textarea {
  font-family: inherit;
  font-size: 16.5px;
  font-weight: 500;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 13px 16px;
  width: 100%;
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.field textarea { resize: vertical; line-height: 1.55; }
.field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%237D7168' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  padding-right: 42px;
}
.field :is(input, select, textarea):focus {
  outline: 0;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
}
.field :is(input, textarea)::placeholder { color: color-mix(in srgb, var(--muted) 70%, transparent); }
.field.has-error :is(input, select, textarea) { border-color: #B4402F; }

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(14px, 1.8vw, 22px);
}
@media (max-width: 620px) { .field-row { grid-template-columns: 1fr; } }

/* Attending choice --------------------------------------------------------- */
.choice { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 620px) { .choice { grid-template-columns: 1fr; } }

.choice__opt { cursor: pointer; display: block; }
.choice__opt input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.choice__box {
  display: block;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 16px 18px;
  transition: border-color 0.2s var(--ease), background 0.2s var(--ease),
              box-shadow 0.2s var(--ease);
}
.choice__opt:hover .choice__box { border-color: var(--muted); }
.choice__title {
  display: block;
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.02em;
  margin-bottom: 2px;
}
.choice__sub { display: block; font-size: 14px; color: var(--muted); }

.choice__opt input:checked + .choice__box {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.choice__opt input:focus-visible + .choice__box {
  outline: 2px solid var(--accent-lit);
  outline-offset: 2px;
}

.if-yes { display: grid; gap: clamp(20px, 2.4vw, 28px); }
.if-yes[hidden] { display: none; }

.rsvp__error {
  margin: 0;
  background: rgba(180, 64, 47, 0.1);
  border: 1px solid rgba(180, 64, 47, 0.35);
  color: #8C2F21;
  border-radius: 10px;
  padding: 12px 16px;
  font-size: 15px;
  font-weight: 500;
}
.rsvp__error[hidden] { display: none; }

.rsvp__submit { display: grid; gap: 12px; justify-items: start; }
.rsvp__privacy { margin: 0; font-size: 13.5px; color: var(--muted); }
.btn[disabled] { opacity: 0.55; cursor: progress; }

.rsvp-done {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(34px, 4.6vw, 62px);
  text-align: center;
}
.rsvp-done[hidden] { display: none; }
.rsvp-done__mark {
  margin: 0 auto 20px;
  width: 62px;
  height: 62px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--btn-fg);
  font-size: 30px;
  font-weight: 700;
  display: grid;
  place-items: center;
}
.rsvp-done h3 {
  margin: 0 0 10px;
  font-family: var(--font-heading);
  font-weight: var(--w-heading);
  font-size: clamp(26px, 3vw, 40px);
  letter-spacing: var(--track-display);
}
.rsvp-done p { margin: 0 0 24px; color: var(--muted); max-width: 46ch; margin-inline: auto; }

.rsvp__fallback {
  margin: clamp(28px, 3.4vw, 44px) 0 0;
  font-size: 15px;
  color: var(--muted);
  text-align: center;
}
.rsvp__fallback a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }

/* ═══════════════════════════════════════════════════════════════════════════
   FOOTER
   ═══════════════════════════════════════════════════════════════════════════ */

.footer {
  /* The same dark as the nav bar and the dark sections, so the one "Navigation bar &
     dark panels" control drives every dark panel on the site, the footer included. */
  background: var(--d-bg);
  color: var(--d-fg);
  padding: clamp(52px, 6vw, 88px) 0 clamp(38px, 4vw, 56px);
  text-align: center;
}
/* A small gold diamond above the footer names, echoing the invitation divider. */
.footer .wrap::before {
  content: '';
  display: block;
  width: 7px;
  height: 7px;
  transform: rotate(45deg);
  background: var(--accent-lit);
  margin: 0 auto clamp(22px, 2.6vw, 34px);
}
.footer__names {
  margin: 0 0 12px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(34px, 5vw, 66px);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  line-height: 1;
  color: var(--accent-lit);
}
.footer__meta {
  margin: clamp(18px, 2.4vw, 36px) 0 28px;   /* room above the date, below the names */
  font-weight: 600;
  font-size: clamp(13px, 1.05vw, 16px);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--d-muted);
}
.footer__top { margin: 0; font-size: 14px; }
.footer__top a { color: var(--accent-lit); text-decoration: none; font-weight: 600; }
.footer__top a:hover { text-decoration: underline; }
/* The version readout. Quiet: guests will see it, but it is there for the couple. */
.footer__version { margin: 18px 0 0; font-size: 11.5px; letter-spacing: 0.04em; color: var(--d-muted); opacity: .75; }
/* Signed in, the fixed edit bar sits over the last line of the footer, which is exactly
   this one, for exactly the people who read it. Lift it above the bar. */
body:has(.editbar) .footer__version { margin-bottom: 96px; }

/* ═══════════════════════════════════════════════════════════════════════════
   SETTINGS COG
   Bottom-right, deliberately quiet. Guests will see it, so it must read as
   "site settings", not as something they are meant to press: hence the small
   size, low resting opacity and the tooltip.
   ═══════════════════════════════════════════════════════════════════════════ */

.cog {
  position: fixed;
  right: clamp(14px, 1.6vw, 24px);
  bottom: clamp(14px, 1.6vw, 24px);
  z-index: 60;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--d-bg) 82%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border: 1px solid color-mix(in srgb, var(--d-fg) 22%, transparent);
  color: var(--d-fg);
  text-decoration: none;
  opacity: 0.42;
  transition: opacity 0.25s var(--ease), transform 0.35s var(--ease),
              background 0.25s var(--ease);
}
.cog svg { width: 20px; height: 20px; display: block; }
.cog:hover,
.cog:focus-visible {
  opacity: 1;
  transform: rotate(45deg);
  background: var(--accent);
  border-color: var(--accent);
  color: var(--btn-fg);
}

/* Tooltip, so nobody has to guess what the cog does. */
.cog::after {
  content: 'Settings';
  position: absolute;
  right: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%);
  background: var(--d-bg);
  color: var(--d-fg);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  padding: 6px 11px;
  border-radius: 7px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s var(--ease);
}
.cog:hover::after,
.cog:focus-visible::after { opacity: 1; }

@media print { .cog, .stickynav, .editbar { display: none !important; } }

/* ═══════════════════════════════════════════════════════════════════════════
   ON-PAGE EDITOR
   Only ever built for a signed-in admin. A guest never sees any of this, and
   the page has no idea it exists.
   ═══════════════════════════════════════════════════════════════════════════ */

.editbar {
  position: fixed;
  left: 50%;
  bottom: clamp(14px, 1.6vw, 24px);
  transform: translateX(-50%);
  z-index: 70;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 10px 9px 18px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--d-bg) 94%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border: 1px solid color-mix(in srgb, var(--d-fg) 20%, transparent);
  color: var(--d-fg);
  font-size: 14px;
  box-shadow: 0 18px 40px -24px rgba(0, 0, 0, 0.7);
  max-width: calc(100vw - 28px);
  flex-wrap: wrap;
}
.editbar__what { font-weight: 600; white-space: nowrap; }
.editbar__btn {
  border: 1px solid color-mix(in srgb, var(--d-fg) 26%, transparent);
  background: transparent;
  color: var(--d-fg);
  font-family: inherit;
  font-weight: 700;
  font-size: 13.5px;
  padding: 7px 16px;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
}
.editbar__btn:hover { border-color: var(--d-fg); }
.editbar__btn--go { background: var(--accent-lit); border-color: var(--accent-lit); color: #14110F; }
.editbar__btn--go:hover { filter: brightness(1.08); }
.editbar__btn[hidden] { display: none; }
.editbar__msg { font-size: 13px; color: var(--d-muted); min-width: 0; }
.editbar__msg.is-ok { color: var(--accent-lit); font-weight: 600; }
.editbar__msg.is-err { color: #ffb4a2; font-weight: 600; }
.editbar__link { color: var(--accent-lit); font-weight: 600; text-decoration: none; font-size: 13.5px; white-space: nowrap; }
.editbar__link:hover { text-decoration: underline; }

/* The type bar: under the navigation whenever a text box is focused in Edit mode. */
.typebar {
  position: fixed;
  top: 84px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  max-width: calc(100vw - 20px);
  padding: 8px 12px;
  border-radius: 14px;
  background: color-mix(in srgb, var(--d-bg) 94%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border: 1px solid color-mix(in srgb, var(--d-fg) 20%, transparent);
  color: var(--d-fg);
  font-family: 'Schibsted Grotesk', system-ui, sans-serif;
  font-size: 13px;
  box-shadow: 0 18px 40px -24px rgba(0, 0, 0, 0.7);
}
.typebar[hidden] { display: none; }
.typebar__what { font-weight: 600; white-space: nowrap; margin-right: 4px; }
.typebar__sel,
.typebar__num {
  font: inherit;
  color: var(--d-fg);
  background: color-mix(in srgb, var(--d-fg) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--d-fg) 26%, transparent);
  border-radius: 8px;
  padding: 5px 8px;
}
.typebar__sel option { color: #14110f; }
.typebar__size { display: inline-flex; align-items: center; gap: 4px; }
.typebar__num { width: 62px; text-align: center; }
.typebar__unit { color: var(--d-muted); font-size: 12px; }
.typebar__btn {
  font: inherit;
  font-weight: 700;
  color: var(--d-fg);
  background: transparent;
  cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--d-fg) 26%, transparent);
  border-radius: 8px;
  min-width: 30px;
  padding: 5px 8px;
}
.typebar__btn:hover { border-color: var(--d-fg); }
.typebar__btn[aria-pressed="true"] { background: var(--accent-lit); border-color: var(--accent-lit); color: #14110f; }
.typebar__btn--quiet { font-weight: 600; color: var(--d-muted); }
.typebar__sep { width: 1px; height: 22px; background: color-mix(in srgb, var(--d-fg) 22%, transparent); }
/* Colour: the brand palette as round swatches, "as designed" first, then a picker for anything else. */
.typebar__colors { display: inline-flex; align-items: center; gap: 6px; }
.typebar__swatch {
  width: 22px; height: 22px; padding: 0;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--d-fg) 30%, transparent);
  background: var(--sw, transparent);
  cursor: pointer;
  position: relative;
}
.typebar__swatch:hover { border-color: var(--d-fg); }
.typebar__swatch[aria-pressed="true"] { border-color: var(--accent-lit); box-shadow: 0 0 0 2px var(--d-bg), 0 0 0 4px var(--accent-lit); }
.typebar__swatch--none::after {
  content: ''; position: absolute; left: 3px; right: 3px; top: 50%;
  height: 2px; background: color-mix(in srgb, var(--d-fg) 55%, transparent);
  transform: rotate(-45deg);
}
.typebar__pick {
  width: 26px; height: 26px; padding: 0; border: 0; background: transparent; cursor: pointer;
}
@media (max-width: 600px) {
  .typebar { top: 64px; gap: 6px; padding: 6px 8px; font-size: 12.5px; }
}

/* Editable blocks, only while the mode is on. */
.is-editing [data-edit] {
  outline: 1px dashed color-mix(in srgb, var(--accent-lit) 70%, transparent);
  outline-offset: 4px;
  border-radius: 3px;
  cursor: text;
  transition: outline-color 0.2s var(--ease), background 0.2s var(--ease);
}
.is-editing [data-edit]:hover {
  outline-style: solid;
  outline-color: var(--accent-lit);
  background: color-mix(in srgb, var(--accent-lit) 12%, transparent);
}
.is-editing [data-edit]:focus {
  outline: 2px solid var(--accent-lit);
  background: color-mix(in srgb, var(--accent-lit) 16%, transparent);
}
.is-editing [data-edit].is-saving { opacity: 0.55; }
.is-editing [data-edit].was-saved {
  outline-color: #4CAF7D;
  background: rgba(76, 175, 125, 0.18);
}
/* The hero sits on a photograph, so the dashed hint needs to survive on it. */
.is-editing .hero [data-edit] { outline-color: rgba(255, 255, 255, 0.75); }

/* ═══════════════════════════════════════════════════════════════════════════
   ABOVE FULL HD
   Every size in this stylesheet is clamped to a maximum that lands exactly at
   1920px wide - that is the reference the design was drawn against. On a wider
   screen those maximums stay put while the viewport keeps growing, so a 4K
   monitor renders Full-HD-sized text across twice the width and the whole thing
   reads small and sparse.

   Past 1920 every capped value is restated in vw at the same ratio it has at
   1920 (174px / 1920 = 9.0625vw, and so on), so the page scales proportionally
   instead of freezing. At exactly 1920 these compute to the identical pixel
   values, so nothing at or below Full HD changes.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (min-width: 1921px) {
  html { scroll-padding-top: 4.375vw; }          /* 84px  */
  body { font-size: 0.9375vw; }                  /* 18px  */

  /* Hero */
  .hero__logo    { --sh-unit: 0.0520833vw; }     /* 1px at 1920, 2px at 3840 */
  .hero__inner   { max-width: none; padding: 3.125vw 3.229vw 2.917vw; }  /* 60 / 62 / 56 */
  .hero-nav__num   { font-size: 0.833vw; }       /* 16px  */
  .hero-nav__label { font-size: 1.875vw; }       /* 36px  */
  .hero__meta      { font-size: 1.094vw; }       /* 21px  */
  .hero__names     { font-size: 9.0625vw; }      /* 174px */

  /* Sticky bar */
  .stickynav        { height: 3.4375vw; padding: 0 2.083vw; }  /* 66 / 40 */
  .stickynav__brand { font-size: 0.99vw; }       /* 19px  */
  .stickynav ol a   { font-size: 0.781vw; }      /* 15px  */
  .stickynav ol a span,
  .stickynav__cta   { font-size: 0.729vw; }      /* 14px  */

  /* Section furniture */
  .wrap           { max-width: 64.583vw; }       /* 1240px */
  .wrap--narrow   { max-width: 42.708vw; }       /* 820px  */
  .eyebrow        { font-size: 1.094vw; }        /* 21px   */
  .eyebrow__num   { font-size: 0.833vw; }        /* 16px   */
  .h-display      { font-size: 4.271vw; }        /* 82px   */
  .statement      { font-size: 3.229vw; }        /* 62px   */
  .lede           { font-size: 1.094vw; }        /* 21px   */
  .btn            { font-size: 0.781vw; padding: 0.625vw 1.354vw; }
  .btn--lg        { font-size: 0.885vw; padding: 0.833vw 1.979vw; }

  /* Invitation */
  .invite-card__names   { font-size: 4.792vw; }  /* 92px */
  .invite-card__request { font-size: 1.094vw; }  /* 21px */
  .invite-card__facts dd { font-size: 0.99vw; }  /* 19px */

  /* The day */
  .timeline__time    { font-size: 1.667vw; }     /* 32px */
  .timeline__body h3 { font-size: 1.302vw; }     /* 25px */
  .note h3           { font-size: 1.094vw; }     /* 21px */

  /* Getting there */
  .address-card__name { font-size: 2.396vw; }    /* 46px */
  .side-card h3       { font-size: 1.25vw; }     /* 24px */

  /* Photos */
  .gallery { grid-auto-rows: 21.875vw; }

  /* RSVP */
  .field > label,
  .field legend { font-size: 0.781vw; }          /* 15px */
  .field :is(input[type="text"], input[type="email"], input[type="tel"], select, textarea) {
    font-size: 0.859vw; padding: 0.677vw 0.833vw;
  }
  .choice__title { font-size: 0.885vw; }         /* 17px */
  .rsvp-done h3  { font-size: 2.083vw; }         /* 40px */

  /* Footer + cog */
  .footer__names { font-size: 4.063vw; }         /* 78px */
  .footer__meta  { font-size: 0.833vw; }         /* 16px */
  .cog { width: 2.292vw; height: 2.292vw; }      /* 44px */
  .cog svg { width: 1.042vw; height: 1.042vw; }  /* 20px */
}

/* ═══════════════════════════════════════════════════════════════════════════
   PHONE TYPE SIZES
   Placed last so it overrides the component rules above. On a tall phone the
   vh-based invitation sizes and the large serif headings read far too big, so
   here they are re-based to the screen WIDTH (vw) at comfortable phone sizes.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 600px) {
  body { font-size: 16.5px; }

  .h-display { font-size: clamp(30px, 8.4vw, 44px); }
  .lede { font-size: clamp(15px, 4.2vw, 17.5px); }

  /* Amsterdam Handwriting is wide: 13vw wrapped "Grant & Orla" onto two lines on a phone.
     10vw keeps it to one. The em margins from the base rule give the swashes their room. */
  .invite-card__names   { font-size: clamp(30px, 10vw, 44px); }
  .invite-card__request { font-size: clamp(15px, 4.2vw, 17.5px); }
  .invite-message p { font-size: clamp(15.5px, 4.4vw, 18px); line-height: 1.5; margin-bottom: 14px; }
  .invite-message .invite-message__beat { font-size: clamp(26px, 8vw, 36px); margin: 20px 0; }
  .invite-card__facts dd { font-size: clamp(15px, 4vw, 17px); }

  .timeline__body h3 { font-size: clamp(20px, 5.6vw, 25px); }
  .note h3 { font-size: clamp(17px, 4.8vw, 20px); }
  .side-card h3 { font-size: clamp(18px, 5vw, 22px); }
  .address-card__name { font-size: clamp(28px, 8vw, 38px); }
  .footer__names { font-size: clamp(30px, 10vw, 48px); }
}

/* Signed-in administrators can drop a photo onto an empty gallery tile. */
.gallery__drop-hint { display: none; pointer-events: none; }
.gallery__item.is-missing .gallery__drop-hint {
  display: block; position: absolute; top: 16px; left: 12px; right: 12px;
  text-align: center; color: var(--d-fg); background: var(--d-bg);
  padding: 8px 12px; border-radius: 8px; font-size: 16px;
}
.gallery__item.is-drop-target { outline: 4px solid var(--accent-lit); outline-offset: -4px; }
.gallery__item.is-uploading .media__add { pointer-events: none; opacity: .5; }

/* Small uploaded icons flow with editable text, independent of the typeface. */
[data-edit] img.inline-icon { display: inline-block; height: auto; max-width: 100%; vertical-align: middle; object-fit: contain; margin: 0 .15em; }
[data-edit] img.inline-icon--16 { width: 16px; }
[data-edit] img.inline-icon--24 { width: 24px; }
[data-edit] img.inline-icon--32 { width: 32px; }
[data-edit] img.inline-icon--48 { width: 48px; }
[data-edit] img.inline-icon--64 { width: 64px; }
[data-edit] img.inline-icon--96 { width: 96px; }

/* Selected bold words use a true bold face, even inside light text. */
[data-edit] b, [data-edit] strong { font-weight: 700; }
