/* Shared by index.html, site.html and valaszok.html. The look follows Szandi's invitation: ivory paper,
   ink-black Art Nouveau silhouettes (her frame, traced, is img/invite-frame.svg) and
   saffron lettering. Tokens, the sheet, the margin plant's colours, reveals, controls,
   the bar, the opening, section headings, the reply card's stock and the footer.
   Page-specific styles stay inline in each page. */
:root {
  interpolate-size: allow-keywords;
  /* surfaces: an ivory sheet on a slightly deeper ivory ground, so the margin plant can
     grow past the sheet's edge without being cut */
  --table: #F1EADB;
  --paper: #FBF7EE;
  --paper-2: #F2ECDD;
  --card: #FFFDF8;         /* reply card stock */
  /* text: the black of the invitation */
  --ink: #15130F;
  --ink-soft: #5A554B;
  /* the plant: solid silhouettes, their inner lines cut out in paper */
  --plant-ink: #15130F;
  --plant-aged: color-mix(in srgb, var(--plant-ink) 34%, var(--paper));
  --mali-petal: #F2B8C4; --mali-petal-dark: #E494A8; --mali-face: #F3CDCB; --mali-snout: #F2B1B5; --mali-ear: #EBA3AE; --mali-blush: #E0919F; --mali-nostril: #B42A3C; --mali-eye: #151515;
  /* the saffron of the invitation's lettering: display lettering and ornament only
     (too light for small text; --gold-ink is its readable shade) */
  --gold: #F5B149;
  --gold-ink: #96590A;
  /* actions: ink on paper */
  --action: #15130F;
  --on-action: #FBF7EE;
  /* errors only */
  --eosin: #A3293A;
  --line: rgba(21, 19, 15, .17);
  --ok: #2F6B3F;
  /* sealing wax on the reply (saffron); the pink rubber-stamp ink of Mali's hide-and-seek */
  --wax: #E39A26; --wax-hi: #F9C96F; --wax-lo: #A8680E;
  --stamp: #B4506A;
  /* film grain laid over every photograph (overlay blend, so it works on both papers) */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 .5'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  /* torn (deckled) edges of the reply card, one strip per side */
  --deckle-t: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='8'%3E%3Cpath d='M0 8L0 2.6L5 3.0L10 4.3L15 2.7L20 2.8L25 3.1L30 1.7L35 2.8L40 3.3L45 3.9L50 1.3L55 2.1L60 1.3L65 3.9L70 3.5L75 1.2L80 4.5L85 4.5L90 3.4L95 3.2L100 1.6L105 1.1L110 2.9L115 1.2L120 1.7L125 1.9L130 1.1L135 2.7L140 2.6L145 4.0L150 2.9L155 3.3L160 2.6L160 8Z'/%3E%3C/svg%3E");
  --deckle-b: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='8'%3E%3Cpath d='M0 0L0 5.4L5 5.0L10 3.7L15 5.3L20 5.2L25 4.9L30 6.3L35 5.2L40 4.7L45 4.1L50 6.7L55 5.9L60 6.7L65 4.1L70 4.5L75 6.8L80 3.5L85 3.5L90 4.6L95 4.8L100 6.4L105 6.9L110 5.1L115 6.8L120 6.3L125 6.1L130 6.9L135 5.3L140 5.4L145 4.0L150 5.1L155 4.7L160 5.4L160 0Z'/%3E%3C/svg%3E");
  --deckle-l: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='160'%3E%3Cpath d='M8 0L2.6 0L3.0 5L4.3 10L2.7 15L2.8 20L3.1 25L1.7 30L2.8 35L3.3 40L3.9 45L1.3 50L2.1 55L1.3 60L3.9 65L3.5 70L1.2 75L4.5 80L4.5 85L3.4 90L3.2 95L1.6 100L1.1 105L2.9 110L1.2 115L1.7 120L1.9 125L1.1 130L2.7 135L2.6 140L4.0 145L2.9 150L3.3 155L2.6 160L8 160Z'/%3E%3C/svg%3E");
  --deckle-r: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='160'%3E%3Cpath d='M0 0L5.4 0L5.0 5L3.7 10L5.3 15L5.2 20L4.9 25L6.3 30L5.2 35L4.7 40L4.1 45L6.7 50L5.9 55L6.7 60L4.1 65L4.5 70L6.8 75L3.5 80L3.5 85L4.6 90L4.8 95L6.4 100L6.9 105L5.1 110L6.8 115L6.3 120L6.1 125L6.9 130L5.3 135L5.4 140L4.0 145L5.1 150L4.7 155L5.4 160L0 160Z'/%3E%3C/svg%3E");
  /* a saffron flourish with a heart, between sections (the invitation's swash) */
  --flourish: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 150 24'%3E%3Cg fill='none' stroke='%23F5B149' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath id='a' d='M62 12C48 12 42 19 30 19C18 19 13 11 18 6.5C21 4 25.5 6 24.5 10M36 9C28 3 14 4 5 12'/%3E%3Cuse href='%23a' transform='matrix(-1 0 0 1 150 0)'/%3E%3C/g%3E%3Cpath d='M75 19C67 13.5 66 7 70.5 5.6C73 4.9 75 7.4 75 8.8C75 7.4 77 4.9 79.5 5.6C84 7 83 13.5 75 19Z' fill='%23F5B149'/%3E%3C/svg%3E");
  /* the yellow of the M1 Millennium Underground, on the map */
  --m1: #F5B149;
  /* photographs: one finish so the prints belong to the same album */
  --photo: saturate(1.04) contrast(1.02);

  --radius: 2px;
  --s1: 8px; --s2: 16px; --s3: 24px; --s4: 32px; --s5: 48px; --s6: 64px; --s7: 96px; --s8: 128px;
  --measure: 62ch;
  --bar-h: 64px;

  --display: "Rakkas", "Hoefler Text", Georgia, serif;   /* the invitation's flared lettering */
  --body: "Libre Caslon Text", "Iowan Old Style", Georgia, serif;
}
/* night: the invitation inverted, ivory silhouettes on black, the saffron unchanged */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --table: #0B0A08; --paper: #14120F; --paper-2: #1E1B16; --card: #1B1814;
    --ink: #F4EEDF; --ink-soft: #B9B2A2; --plant-ink: #F4EEDF;
    --gold-ink: #F5B149; --action: #F5B149; --on-action: #15130F;
    --eosin: #EE8E9B; --line: rgba(244, 238, 223, .17); --ok: #8CCB9A;
    --wax: #D89022; --wax-hi: #F6C267; --wax-lo: #8F560A; --stamp: #E48DA3;
    --photo: saturate(.9) contrast(1) brightness(.92);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --table: #0B0A08; --paper: #14120F; --paper-2: #1E1B16; --card: #1B1814;
  --ink: #F4EEDF; --ink-soft: #B9B2A2; --plant-ink: #F4EEDF;
  --gold-ink: #F5B149; --action: #F5B149; --on-action: #15130F;
  --eosin: #EE8E9B; --line: rgba(244, 238, 223, .17); --ok: #8CCB9A;
  --wax: #D89022; --wax-hi: #F6C267; --wax-lo: #8F560A; --stamp: #E48DA3;
  --photo: saturate(.9) contrast(1) brightness(.92);
  color-scheme: dark;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { scroll-behavior: smooth; scroll-padding-top: calc(var(--bar-h) + var(--s2)); -webkit-text-size-adjust: 100%; scrollbar-color: var(--line) transparent; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  margin: 0; background: var(--table); color: var(--ink);
  font: 400 1.0625rem/1.7 var(--body);
  font-variant-numeric: lining-nums;
  caret-color: var(--action); accent-color: var(--action);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
@media (min-width: 768px) {
  body { padding: clamp(18px, 2.4vw, 32px) clamp(14px, 2.2vw, 32px); }
}
::selection { background: var(--gold); color: #15130F; }
img { display: block; max-width: 100%; }
p { margin: 0; }
a { color: var(--action); text-decoration-line: underline; text-decoration-color: var(--gold); text-decoration-thickness: 1.5px; text-underline-offset: .22em; transition: text-decoration-thickness .15s ease-out; }
a:hover { text-decoration-thickness: 2.5px; }
:focus-visible { outline: 2px solid var(--action); outline-offset: 2px; border-radius: var(--radius); }
.num { font-variant-numeric: lining-nums tabular-nums; }
.wrap { max-width: 1120px; margin: 0 auto; padding-inline: max(var(--s2), env(safe-area-inset-left, 0px)) max(var(--s2), env(safe-area-inset-right, 0px)); }
@media (min-width: 768px) { .wrap { padding-inline: var(--s4); } }
.skip { position: absolute; left: var(--s2); top: -80px; background: var(--action); color: var(--on-action); padding: var(--s1) var(--s2); border-radius: var(--radius); z-index: 20; }
.skip:focus { top: var(--s2); }

/* ---------- the sheet ---------- */
/* the sheet is ruled like the invitation's card (ink line, a gap, a saffron hairline);
   nothing clips it, so the plant grows over its edge onto the ground */
.sheet {
  position: relative; max-width: 1320px; margin: 0 auto;
  background-color: var(--paper);
  box-shadow: 0 0 0 1.5px var(--ink), 0 0 0 6px var(--table), 0 0 0 7.2px var(--gold);
}
@media (max-width: 767px) { .sheet { box-shadow: none; } }
.sheet > main, .sheet > footer { position: relative; z-index: 1; }
.vines { position: absolute; inset: 0 auto auto 0; z-index: 0; pointer-events: none; overflow: visible; }
.sheet[data-vine="narrow"] .wrap { padding-left: max(48px, env(safe-area-inset-left, 0px)); }
@media (min-width: 768px) { .sheet[data-vine="narrow"] .wrap { padding-left: 60px; } }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* the plant, in the manner of the invitation: solid ink silhouettes whose inner lines
   and overlaps are cut out in the paper's colour (classes, so ageing can transition) */
.v-stem-b, .v-ped-b, .v-tendril { fill: none; stroke: var(--plant-ink); stroke-linecap: round; }
.v-stem-b { stroke-width: 5.5; } .v-ped-b { stroke-width: 2.8; }
.v-stem-f, .v-ped-f { display: none; }
.sheet[data-vine="narrow"] .v-stem-b { stroke-width: 4.5; }
.v-tendril { stroke-width: 2.4; stroke-dasharray: 1 1; stroke-dashoffset: 1; }
.v-ink, .v-leaf, .v-std, .v-fall, .v-peri, .v-berry, .v-bell {
  fill: var(--plant-ink); stroke: var(--paper); stroke-width: .9; stroke-linejoin: round; transition: fill 1.8s ease-out;
}
.v-cut, .v-vein { fill: none; stroke: var(--paper); stroke-width: 1; stroke-linecap: round; }
.v-line, .v-seed { fill: none; stroke: var(--plant-ink); stroke-width: 1.1; stroke-linecap: round; }
.v-dot, .v-core { fill: var(--gold); }
.v-beard { fill: none; stroke: var(--gold); stroke-width: 2.4; stroke-linecap: round; }
.v-eye, .v-shine { fill: var(--paper); }
.aged .v-ink, .aged .v-std, .aged .v-fall, .aged .v-peri { fill: var(--plant-aged); }
.v-mali-petal { fill: var(--mali-petal); stroke: var(--plant-ink); stroke-width: 1; stroke-linejoin: round; } .v-mali-petal.dark { fill: var(--mali-petal-dark); }
.v-mali-face { fill: var(--mali-face); stroke: var(--plant-ink); stroke-width: 1; stroke-linejoin: round; }
.v-mali-ear { fill: var(--mali-ear); } .v-mali-snout { fill: var(--mali-snout); stroke: var(--plant-ink); stroke-width: .8; }
.v-mali-blush { fill: var(--mali-blush); opacity: .7; } .v-mali-nostril { fill: var(--mali-nostril); } .v-mali-eye { fill: var(--mali-eye); }
/* flowers near the reader move a little in the air; pivot is where the stalk leaves the stem */
.v-sway { transform-box: view-box; transform-origin: 0 0; }
.v-sway.on { animation: sway 5s ease-in-out infinite alternate; }
@keyframes sway { from { transform: rotate(-4deg); } to { transform: rotate(4deg); } }
.petals { position: fixed; inset: 0; z-index: 5; pointer-events: none; overflow: hidden; }
.petals svg { position: absolute; left: 0; top: 0; }
@media (prefers-reduced-motion: reduce) { .v-sway.on { animation: none; } }

/* things reveal as the scroll unrolls: headings unroll top-down, photographs are unveiled
   from below while settling, prints are laid down on the page, the rest rises softly */
.js .rv { opacity: 0; translate: 0 28px; transition: opacity 1s cubic-bezier(.16, 1, .3, 1), translate 1.2s cubic-bezier(.16, 1, .3, 1); transition-delay: calc(var(--i, 0) * 90ms); }
.js .rv.in { opacity: 1; translate: none; }
/* headings and years unroll with a mask (an observer ignores fully clipped elements, not masked ones) */
.js h2.rv, .js .year.rv, .js .frame.rv {
  opacity: 1; translate: none;
  -webkit-mask: linear-gradient(#000, #000) top / 100% 0% no-repeat; mask: linear-gradient(#000, #000) top / 100% 0% no-repeat;
  transition: -webkit-mask-size 1.3s cubic-bezier(.65, 0, .25, 1), mask-size 1.3s cubic-bezier(.65, 0, .25, 1);
}
.js .frame.rv { -webkit-mask-position: bottom; mask-position: bottom; transition-duration: 1.5s; }
.js .frame.rv > img { scale: 1.14; transition: scale 2.2s cubic-bezier(.16, 1, .3, 1); }
.js .frame.rv.in > img { scale: 1.06; }
.js h2.rv.in, .js .year.rv.in, .js .frame.rv.in { -webkit-mask-size: 100% 100%; mask-size: 100% 100%; }
.js .print.rv { translate: 0 60px; rotate: calc(var(--tilt, 0deg) + 7deg); scale: .96; transition-property: opacity, translate, rotate, scale; transition-duration: .9s, 1.3s, 1.3s, 1.3s; transition-timing-function: cubic-bezier(.16, 1, .3, 1); }
.js .print.rv.in { opacity: 1; translate: none; rotate: var(--tilt, 0deg); scale: 1; }
/* the opening arrives once: the frame grows up from its foot, the lettering follows */
.js .opening .invite::before { clip-path: inset(100% 0 0 0); transition: clip-path 2.4s cubic-bezier(.5, 0, .2, 1) .1s; }
.js .opening .invite-in > *, .js .opening .window > * {
  opacity: 0; translate: 0 .6em; transition: opacity 1.1s cubic-bezier(.16, 1, .3, 1), translate 1.3s cubic-bezier(.16, 1, .3, 1);
  transition-delay: calc(.5s + var(--o, 0) * .16s);
}
.js.ready .opening .invite::before { clip-path: inset(0); }
.js.ready .opening .invite-in > *, .js.ready .opening .window > * { opacity: 1; translate: none; }
/* photographs drift slightly inside their frames as they pass */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .frame > img { animation: drift linear both; animation-timeline: view(); }
    @keyframes drift { from { translate: 0 -4%; } to { translate: 0 4%; } }
  }
}
@media (prefers-reduced-motion: reduce) {
  .js .rv, .js h2.rv, .js .year.rv, .js .frame.rv, .js .print.rv { opacity: 1 !important; translate: none !important; scale: none !important; -webkit-mask: none !important; mask: none !important; transition: none !important; }
  .js .opening *, .js .opening .invite::before { clip-path: none !important; opacity: 1 !important; translate: none !important; transition: none !important; }
  .js .print.rv { rotate: var(--tilt, 0deg) !important; }
}
/* smooth scrolling (Lenis) */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: clip; }

/* ---------- controls ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s1);
  min-height: 44px; padding: 0 var(--s3);
  font: 400 1.1875rem/1 var(--display); letter-spacing: .01em; text-decoration: none; white-space: nowrap;
  color: var(--on-action); background: var(--action); border: 1px solid var(--action); border-radius: var(--radius);
  cursor: pointer; transition: background-color .15s ease-out, border-color .15s ease-out;
}
.btn:hover { background: var(--gold); border-color: var(--gold); color: #15130F; text-decoration: none; }
.btn:active { background: color-mix(in srgb, var(--gold) 86%, #000); border-color: transparent; color: #15130F; }
.btn[disabled] { opacity: .5; cursor: progress; }
.btn.outline { color: var(--ink); background: transparent; border-color: var(--line); }
.btn.outline:hover { border-color: var(--ink-soft); background: transparent; }
.btn.outline:active { background: var(--paper-2); }
.link {
  font: inherit; color: var(--action); background: none; border: 0; padding: 0; min-height: 44px; cursor: pointer;
  text-decoration: underline; text-decoration-color: var(--gold); text-decoration-thickness: 1.5px; text-underline-offset: .22em;
}
.link:hover { text-decoration-thickness: 2.5px; }
.link:active { color: var(--ink); }
.square {
  width: 44px; height: 44px; display: grid; place-items: center; padding: 0;
  color: var(--ink); background: transparent; border: 1px solid var(--line); border-radius: var(--radius); cursor: pointer;
  transition: border-color .15s ease-out, background-color .15s ease-out;
}
.square:hover { border-color: var(--ink-soft); }
.square:active { background: var(--paper-2); }
.square[disabled] { opacity: .35; cursor: default; }
.square svg { width: 16px; height: 16px; }

/* ---------- bar ---------- */
.bar {
  position: sticky; top: 0; z-index: 10; min-height: var(--bar-h);
  background-color: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 1px 0 var(--line);
}
.bar .wrap { min-height: var(--bar-h); display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; }
/* the A over M of the invitation (img/invite-monogram.svg), tinted through a mask */
.monogram {
  display: inline-block; flex: none; width: 27px; aspect-ratio: 96 / 136; background: var(--ink);
  -webkit-mask: url(../img/invite-monogram.svg) center / contain no-repeat; mask: url(../img/invite-monogram.svg) center / contain no-repeat;
  transition: background-color .15s ease-out;
}
.monogram:hover { background: var(--gold-ink); }
.nav { display: flex; gap: var(--s3); margin-left: auto; }
.nav a { color: var(--ink-soft); text-decoration: none; font-size: 1rem; padding-block: var(--s1); white-space: nowrap; }
.nav a:hover, .nav a[aria-current="true"] { color: var(--ink); text-decoration: underline; text-decoration-color: var(--gold); text-decoration-thickness: 2px; text-underline-offset: .3em; }
.bar-end { display: flex; align-items: center; gap: var(--s3); }
.lang { display: flex; align-items: center; gap: 6px; font-size: 1rem; color: var(--ink-soft); }
.lang button {
  font: inherit; color: var(--ink-soft); background: none; border: 0; padding: 0; min-height: 44px; cursor: pointer;
  text-decoration: none; text-underline-offset: .22em;
}
.lang button:hover { color: var(--ink); }
.lang button[aria-pressed="true"] { color: var(--ink); text-decoration: underline; text-decoration-color: var(--gold); text-decoration-thickness: 2px; }
.bar-rsvp { font-size: 1rem; font-weight: 500; }
@media (max-width: 899px) {
  :root { --bar-h: 88px; }
  .bar .wrap { padding-block: 4px 6px; row-gap: 0; }
  .bar-end { margin-left: auto; }
  .nav { order: 3; width: 100%; justify-content: flex-start; gap: var(--s3); border-top: 1px solid var(--line); padding-top: 2px; overflow-x: auto; scrollbar-width: none; }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { font-size: .9375rem; padding-block: 6px; }
}
@media (max-width: 599px) {
  .bar .wrap { gap: 4px 12px; }
  .bar-end { gap: 12px; }
  .lang, .bar-rsvp { font-size: .9375rem; }
  .monogram { width: 23px; }
  .nav { gap: 18px; }
}

/* ---------- opening: the invitation itself ----------
   Szandi's oval frame (traced from the invitation) holds the monogram, her lettering of
   the names, the date and the place; the engagement photograph sits beside it as an oval
   cameo. Everything inside the frame is sized in cqw, so it scales with the frame. */
.opening { position: relative; padding-block: clamp(20px, 3vw, 40px) var(--s6); }
.opening .wrap { position: relative; z-index: 1; display: grid; grid-template-columns: auto minmax(240px, 320px); justify-content: center; align-items: center; gap: clamp(32px, 7vw, 104px); }
.invite {
  position: relative; container-type: inline-size; aspect-ratio: 833 / 1202;
  width: clamp(300px, calc((100svh - var(--bar-h) - 108px) * .693), 560px); max-width: 100%;
}
.invite::before {
  content: ""; position: absolute; inset: 0; background: var(--plant-ink);
  -webkit-mask: url(../img/invite-frame.svg) center / 100% 100% no-repeat; mask: url(../img/invite-frame.svg) center / 100% 100% no-repeat;
}
.invite-in { position: absolute; inset: 9.5% 19% 14.5%; display: flex; flex-direction: column; align-items: center; justify-content: space-between; text-align: center; }
.invite-mono { --o: 0; width: 11.5cqw; aspect-ratio: 96 / 136; background: var(--gold); -webkit-mask: url(../img/invite-monogram.svg) center / contain no-repeat; mask: url(../img/invite-monogram.svg) center / contain no-repeat; }
.names { --o: 1; margin: 0; width: 58cqw; aspect-ratio: 468 / 320; background: var(--gold); -webkit-mask: url(../img/invite-names.svg) center / contain no-repeat; mask: url(../img/invite-names.svg) center / contain no-repeat; }
/* all the lettering inside the frame is saffron, as on the invitation */
.invite-in { color: var(--gold); }
.lede { --o: 2; font: 400 5.6cqw/1.15 var(--display); max-width: 56cqw; text-wrap: balance; }
.wedding-date { --o: 4; display: grid; justify-items: center; font: 400 10.5cqw/.92 var(--display); font-variant-numeric: lining-nums; }
.wedding-date .month { font-size: .5em; line-height: 1.25; letter-spacing: .05em; text-transform: uppercase; }
.wedding-place { --o: 3; font: 400 5.6cqw/1.1 var(--display); }
@media (forced-colors: active) { .invite::before, .invite-mono, .names, .monogram { background: CanvasText; } }

.window { margin: 0; display: flex; flex-direction: column; align-items: center; text-align: center; }
/* the cameo: an oval portrait inside an ink ring with a saffron hairline */
.cameo { --o: 5; position: relative; width: min(100%, 300px); padding: 9px; border: 2.5px solid var(--plant-ink); border-radius: 50%; }
.cameo::before { content: ""; position: absolute; inset: 3px; border: 1px solid var(--gold); border-radius: 50%; pointer-events: none; }
.arch { position: relative; aspect-ratio: 4 / 5; overflow: hidden; border-radius: 50%; background: var(--paper-2); }
.arch img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 40%; filter: var(--photo); }
.window figcaption { --o: 6; margin: 14px auto 0; max-width: 30ch; color: var(--ink-soft); font-size: .9375rem; font-style: italic; }
.opening-actions { --o: 7; display: flex; flex-direction: column; align-items: center; gap: var(--s1); margin-top: var(--s4); }
.count { color: var(--ink-soft); font-size: 1rem; font-style: italic; }
@media (max-width: 859px) {
  .opening { padding-block: var(--s2) var(--s6); }
  .opening .wrap { display: flex; flex-direction: column; gap: var(--s4); }
  .invite { width: min(100%, 520px); margin-inline: auto; }
  .opening-actions { order: -1; margin: 0 0 var(--s5); }
  .cameo { width: min(64vw, 250px); }
}
/* the plant keeps to the edge beside the invitation on small screens */
@media (max-width: 599px) { .opening .wrap { padding-inline: var(--s2) !important; } }

/* ---------- sections ---------- */
.sec > .wrap { position: relative; border-top: 1px solid var(--line); padding-block: clamp(64px, 8vw, 104px); }
.sec > .wrap::before {
  content: ""; position: absolute; top: -12px; left: 50%; width: 186px; height: 24px; translate: -50% 0;
  background: var(--flourish) center / 150px 24px no-repeat var(--paper);
  pointer-events: none;
}
h2 { font: 400 clamp(2.375rem, 4.8vw, 3.75rem)/1.04 var(--display); letter-spacing: 0; margin: 0 0 var(--s2); text-wrap: balance; }
h3 { font: 400 1.5rem/1.25 var(--display); margin: 0 0 var(--s1); }
.intro { color: var(--ink-soft); max-width: var(--measure); text-wrap: pretty; }

/* ---------- reply card ----------
   A loose cream card with torn (deckled) edges and a printed double rule inside.
   The card stock lives on ::before, so the deckle mask doesn't clip Mali peeking
   over the top or the wax seal. */
.card {
  position: relative; isolation: isolate; max-width: 640px; margin: 0 auto;
  padding: var(--s6) clamp(var(--s3), 6vw, var(--s6)) var(--s5);
}
.card::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--card);
  -webkit-mask: linear-gradient(#000, #000) center / calc(100% - 14px) calc(100% - 14px) no-repeat,
    var(--deckle-t) left top / 160px 8px repeat-x, var(--deckle-b) left bottom / 160px 8px repeat-x,
    var(--deckle-l) left top / 8px 160px repeat-y, var(--deckle-r) right top / 8px 160px repeat-y;
  mask: linear-gradient(#000, #000) center / calc(100% - 14px) calc(100% - 14px) no-repeat,
    var(--deckle-t) left top / 160px 8px repeat-x, var(--deckle-b) left bottom / 160px 8px repeat-x,
    var(--deckle-l) left top / 8px 160px repeat-y, var(--deckle-r) right top / 8px 160px repeat-y;
}
/* the printed rule: an ink line with a saffron hairline inside it */
.card::after {
  content: ""; position: absolute; inset: 18px; z-index: -1; pointer-events: none;
  border: 1.5px solid var(--ink);
  box-shadow: inset 0 0 0 3px var(--card), inset 0 0 0 4.2px var(--gold);
}
.card h2 { text-align: center; }
.card .lead { text-align: center; color: var(--ink-soft); max-width: 40ch; margin: 0 auto var(--s5); }

/* ---------- footer ---------- */
footer > .wrap { border-top: 1px solid var(--line); padding-block: var(--s6) calc(var(--s6) + env(safe-area-inset-bottom, 0px)); text-align: center; color: var(--ink-soft); }
footer .monogram { width: 44px; background: var(--gold); margin-bottom: var(--s2); }
/* the foot of the invitation's frame closes the page, fading out towards the top */
.frame-foot {
  display: block; width: min(340px, 78vw); aspect-ratio: 833 / 290; margin: 0 auto var(--s3); background: var(--plant-ink);
  -webkit-mask: url(../img/invite-frame.svg) center bottom / 100% auto no-repeat, linear-gradient(transparent, #000 55%);
  -webkit-mask-composite: source-in;
  mask: url(../img/invite-frame.svg) center bottom / 100% auto no-repeat, linear-gradient(transparent, #000 55%);
  mask-composite: intersect;
}
/* headings on an arch (js/arc.js) */
.arc-w { display: inline-block; white-space: nowrap; }
.arc-w > span { display: inline-block; }
@media (forced-colors: active) { .frame-foot { background: CanvasText; } }
footer .credit { margin-top: var(--s4); font-size: .875rem; font-style: italic; }

.lbl { font-size: .9375rem; font-style: italic; color: var(--ink-soft); }
