/* ---------------------------------------------------------------
   Brendan & Valeria, save the date
   Sage, white and blush. Change the colors here and everything follows.
---------------------------------------------------------------- */

@font-face {
  font-family: "Bodoni Moda";
  src: url("assets/fonts/bodoni-moda-400-italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "Gloock";
  src: url("assets/fonts/gloock.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Cormorant Garamond";
  src: url("assets/fonts/cormorant-garamond-300.woff2") format("woff2");
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Cormorant Garamond";
  src: url("assets/fonts/cormorant-garamond-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Cormorant Garamond";
  src: url("assets/fonts/cormorant-garamond-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}

/* Korean and Chinese: Noto Serif cut down to just the characters on this page */
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part0.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+3002;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part1.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+4E0A,U+FF01;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part2.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+540E;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part3.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+5949;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part4.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+5F0F;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part5.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+611F;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part6.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+67EC;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part7.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+6B63;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part8.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+AC00,U+AE30,U+B2E4,U+B85C,U+B9AC,U+C0AC,U+C2DC,U+C774,U+C778,U+C9C0,U+D558;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part9.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+AC10,U+AD6D,U+AE00,U+B0A8,U+B144,U+B354,U+B418,U+B798,U+BCF5,U+C2DD,U+C6D4,U+C784,U+C800,U+CCAD,U+CD94,U+D50C,U+D568,U+D6C4;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part10.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+AC8C,U+ACFC,U+AD6C,U+B0B4,U+B294,U+B2C8,U+B3C4,U+B3D9,U+B4DC,U+B77C,U+B85D,U+B97C,U+BA54,U+BA74,U+BCF4,U+C11C,U+C131,U+C138,U+C18C,U+C218,U+C2B5,U+C544,U+C548,U+C5B4,U+C5D0,U+C624,U+C694,U+C740,U+C744,U+C77C,U+C788,U+C791,U+C7A5,U+C804,U+C815,U+C8FC,U+C911,U+CE74,U+D2B8,U+D3EC,U+D55C,U+D569,U+D574;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part11.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+ACA0,U+ACB0,U+AE38,U+B108,U+B9B0,U+C1A1,U+C54A,U+C560,U+C628,U+CC3E;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part12.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+ACA8,U+C558,U+CD95,U+D63C,U+D76C;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part13.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+B9B4,U+C154;
}
@font-face {
  font-family: "BV Serif KR";
  src: url("assets/fonts/noto-serif-kr-400-part14.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+CCA9,U+CE98;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part0.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+3002,U+4E00,U+4E2D,U+65E5,U+6708,U+7684,U+7F51,U+FF0C;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part1.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+4E0A,U+4E0B,U+4E0E,U+4EEC,U+5206,U+5230,U+52A0,U+53EF,U+540C,U+540D,U+540E,U+56FD,U+5728,U+5B89,U+5E74,U+5F0F,U+60A8,U+60C5,U+6210,U+6211,U+63D0,U+6587,U+6B21,U+6B63,U+7247,U+7528,U+770B,U+7AD9,U+7EBF,U+7F8E,U+8981,U+8BF7,U+8FD9,U+FF01;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part2.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+4EA4,U+4EAB,U+4F7F,U+5373,U+5BFC,U+5C06,U+611F,U+661F,U+671F,U+6D77,U+7ED3,U+8DEF,U+90AE;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part3.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+4EFD,U+793C,U+8BE6,U+8C22,U+968F;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part4.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+518D,U+529F,U+5361,U+5386,U+559C,U+5DDE,U+672A,U+7559,U+7BB1,U+822A,U+8BD5;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part5.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+5566,U+5A5A,U+7EB3,U+8BDA;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part6.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+5949;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part7.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+59C6,U+60A6;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part8.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+59D3;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part9.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+631A,U+67EC;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part10.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+6DFB;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part11.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+9080;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part12.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+AC00,U+AC10,U+AC8C,U+ACA0;
}
@font-face {
  font-family: "BV Serif SC";
  src: url("assets/fonts/noto-serif-sc-400-part13.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+C5B4;
}

:root {
  --vh: 1vh;             /* 1% of the screen height; newer phones use the steadier svh below */
  --sage: #C9CCBC;        /* behind the envelope: grey sage */
  --page: #F7F6F1;        /* the details page: warm white */
  --card: #F8F7F4;        /* the card inside the envelope */
  --ink: #2D3228;         /* text: deep olive black */
  --moss: #737A64;        /* quieter text: olive sage */
  --line: #D8D5CA;        /* hairlines */
  --rose: #B8908F;        /* dusty rose accents */
  --blush: #EDD9D8;       /* soft blush */
  --sage-soft: #E3E5D9;   /* pale sage panels */
  --leaf: #6E7E52;        /* green accents on the details page */

  --italic: "Bodoni Moda", "Bodoni 72", "Didot", Georgia, serif;   /* elegant italic, used where a script would go */
  --didone: "Gloock", "Bodoni 72", "Didot", Georgia, serif;
  --serif: "Cormorant Garamond", "Iowan Old Style", Georgia, serif;

  /* the envelope is drawn in units of 1/1000 of its width */
  --ew: min(90vw, 600px, calc((calc(100 * var(--vh)) - 150px) * .855));
  --u: calc(var(--ew) / 1000);
  --noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .2 0 0 0 0 .28 0 0 0 0 .2 0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

@supports (height: 1svh) { :root { --vh: 1svh; } }

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--page);
}
/* The page itself never scrolls: the envelope fills the screen, and the
   details arrive as a sheet that slides up over it and scrolls on its own.
   Everything here is plain CSS, so it moves the same with or without scripts. */
/* Before opening there's nothing to scroll. Once open, the details are a normal
   page that scrolls like any website, which every phone viewer handles. */
body { overflow-x: hidden; }

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.125rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
p, h1, figure { margin: 0; }
img { display: block; max-width: 100%; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------------------------------------------------------------
   Hero: the envelope on sage
---------------------------------------------------------------- */

.opener {
  position: fixed;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}

.hero {
  position: fixed;
  inset: 0;
  min-height: calc(100 * var(--vh));
  display: grid;
  place-items: center;
  overflow: hidden;
  background:
    radial-gradient(90% 70% at 50% 45%, rgba(255, 255, 255, .28), rgba(255, 255, 255, 0) 70%),
    var(--noise),
    var(--sage);
}

.stage {
  display: block;
  padding: 24px 0 40px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* once open, the envelope can't be tapped shut again */
.opener:checked ~ .hero .stage { cursor: default; pointer-events: none; }
.hero-tap {
  position: absolute;
  inset: 0;
  z-index: 7;
  display: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.opener:checked ~ .peek:checked ~ .hero .hero-tap { display: block; }
.opener:focus-visible ~ .hero .stage { outline: 2px solid var(--ink); outline-offset: 8px; }

/* the composition box: open flap on top (0 to 470), envelope below (470 to 1170) */
.comp {
  position: relative;
  display: block;
  width: calc(1000 * var(--u));
  height: calc(1170 * var(--u));
  transform: translateY(calc(-235 * var(--u)));
}

.env-back,
.pocket {
  position: absolute;
  left: calc(-60 * var(--u));
  top: calc(410 * var(--u));
  width: calc(1120 * var(--u));
  max-width: none;
}
.env-back { z-index: 1; }
.pocket { z-index: 4; pointer-events: none; }

.flap {
  position: absolute;
  z-index: 5;
  left: 0;
  top: calc(470 * var(--u));
  width: calc(1000 * var(--u));
  height: calc(470 * var(--u));
  transform-origin: 50% 0;
  transform-style: preserve-3d;
  transform: perspective(2200px) rotateX(0deg);
}
.flap-face {
  position: absolute;
  left: calc(-60 * var(--u));
  top: calc(-60 * var(--u));
  width: calc(1120 * var(--u));
  max-width: none;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.flap-face--back { transform: rotateX(180deg); }

.bouquet {
  position: absolute;
  z-index: 6;
  left: calc(-190 * var(--u));
  top: calc(380 * var(--u));
  width: calc(520 * var(--u));
  max-width: none;
  transform: rotate(-9deg);
  transform-origin: 50% 100%;
  pointer-events: none;
}
/* on a phone the envelope is a little narrower so the flowers stay on screen */
@media (max-width: 600px) {
  :root { --ew: min(80vw, calc((calc(100 * var(--vh)) - 150px) * .855)); }
  .bouquet { left: calc(-84 * var(--u)); top: calc(580 * var(--u)); width: calc(400 * var(--u)); transform: rotate(-9deg); }
}

/* the card: real text, so it stays sharp */
.card {
  position: absolute;
  z-index: 3;
  left: calc(120 * var(--u));
  top: calc(510 * var(--u));
  width: calc(760 * var(--u));
  height: calc(640 * var(--u));
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: calc(70 * var(--u));
  background:
    linear-gradient(170deg, rgba(255, 255, 255, .7), rgba(255, 255, 255, 0) 55%),
    var(--noise),
    var(--card);
  box-shadow: 0 calc(2 * var(--u)) calc(6 * var(--u)) rgba(60, 40, 45, .1);
  color: var(--ink);
  text-align: center;
}
/* the card is drawn as paper lace: a scalloped edge with little punched holes
   that the envelope shows through. It's a plain border image, which every browser draws. */
.card { background: none; box-shadow: none; }
.card::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  border: calc(66 * var(--u)) solid transparent;
  border-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='60' height='60' viewBox='0 0 60 60'><defs><mask id='k'><rect width='60' height='60' fill='black'/><g fill='white'><g transform='rotate(0 30 30)'><rect x='20' y='8' width='20' height='12'/><circle cx='25' cy='8' r='5'/><circle cx='35' cy='8' r='5'/><circle cx='9' cy='9' r='7'/><rect x='9' y='8' width='11' height='12'/><rect x='8' y='9' width='12' height='11'/></g><g transform='rotate(90 30 30)'><rect x='20' y='8' width='20' height='12'/><circle cx='25' cy='8' r='5'/><circle cx='35' cy='8' r='5'/><circle cx='9' cy='9' r='7'/><rect x='9' y='8' width='11' height='12'/><rect x='8' y='9' width='12' height='11'/></g><g transform='rotate(180 30 30)'><rect x='20' y='8' width='20' height='12'/><circle cx='25' cy='8' r='5'/><circle cx='35' cy='8' r='5'/><circle cx='9' cy='9' r='7'/><rect x='9' y='8' width='11' height='12'/><rect x='8' y='9' width='12' height='11'/></g><g transform='rotate(270 30 30)'><rect x='20' y='8' width='20' height='12'/><circle cx='25' cy='8' r='5'/><circle cx='35' cy='8' r='5'/><circle cx='9' cy='9' r='7'/><rect x='9' y='8' width='11' height='12'/><rect x='8' y='9' width='12' height='11'/></g><rect x='18' y='18' width='24' height='24'/></g><g fill='black'><g transform='rotate(0 30 30)'><circle cx='25' cy='8.5' r='1.7'/><circle cx='35' cy='8.5' r='1.7'/><circle cx='22.5' cy='15' r='.9'/><circle cx='27.5' cy='15' r='.9'/><circle cx='32.5' cy='15' r='.9'/><circle cx='37.5' cy='15' r='.9'/><circle cx='9' cy='9' r='2.6'/><circle cx='15.5' cy='15.5' r='.9'/></g><g transform='rotate(90 30 30)'><circle cx='25' cy='8.5' r='1.7'/><circle cx='35' cy='8.5' r='1.7'/><circle cx='22.5' cy='15' r='.9'/><circle cx='27.5' cy='15' r='.9'/><circle cx='32.5' cy='15' r='.9'/><circle cx='37.5' cy='15' r='.9'/><circle cx='9' cy='9' r='2.6'/><circle cx='15.5' cy='15.5' r='.9'/></g><g transform='rotate(180 30 30)'><circle cx='25' cy='8.5' r='1.7'/><circle cx='35' cy='8.5' r='1.7'/><circle cx='22.5' cy='15' r='.9'/><circle cx='27.5' cy='15' r='.9'/><circle cx='32.5' cy='15' r='.9'/><circle cx='37.5' cy='15' r='.9'/><circle cx='9' cy='9' r='2.6'/><circle cx='15.5' cy='15.5' r='.9'/></g><g transform='rotate(270 30 30)'><circle cx='25' cy='8.5' r='1.7'/><circle cx='35' cy='8.5' r='1.7'/><circle cx='22.5' cy='15' r='.9'/><circle cx='27.5' cy='15' r='.9'/><circle cx='32.5' cy='15' r='.9'/><circle cx='37.5' cy='15' r='.9'/><circle cx='9' cy='9' r='2.6'/><circle cx='15.5' cy='15.5' r='.9'/></g></g></mask></defs><rect width='60' height='60' fill='%23FAF9F6' mask='url(%23k)'/></svg>") 20 fill round;
  filter: drop-shadow(0 calc(2 * var(--u)) calc(4 * var(--u)) rgba(60, 40, 45, .12));
  pointer-events: none;
}
.card__save {
  display: block;
  font-family: var(--italic);
  font-style: italic;
  font-size: calc(210 * var(--u));
  line-height: 1;
  margin-bottom: calc(-10 * var(--u));
}
.card__the-date {
  display: block;
  font-family: var(--didone);
  font-size: calc(106 * var(--u));
  line-height: 1;
  letter-spacing: -.005em;
  text-transform: uppercase;
  font-variant-ligatures: none;
  font-feature-settings: "liga" 0, "dlig" 0;
  white-space: nowrap;
}
.card__numbers {
  display: block;
  margin-top: calc(30 * var(--u));
  font-family: var(--italic);
  font-style: italic;
  font-size: calc(74 * var(--u));
  line-height: 1;
}
.card__names {
  display: block;
  margin: calc(22 * var(--u)) calc(-.32em) 0 0;
  font-family: var(--serif);
  font-weight: 500;
  font-size: max(calc(25 * var(--u)), 8.5px);
  letter-spacing: .32em;
  text-transform: uppercase;
  white-space: nowrap;
}
@media (max-width: 600px) {
  .card__names { letter-spacing: .16em; margin-right: -.16em; }
}

.hint {
  position: absolute;
  left: 50%;
  top: calc(1170 * var(--u) + clamp(26px, calc(5 * var(--vh)), 46px));
  display: block;
  white-space: nowrap;
  transform: translateX(-50%);
  color: #3F5143;
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .32em;
  text-transform: uppercase;
}
.hint__click { display: none; }
@media (hover: hover) and (pointer: fine) {
  .hint__tap { display: none; }
  .hint__click { display: inline; }
}
.hint { margin-left: .16em; }

.to-details {
  position: absolute;
  z-index: 8;
  left: 50%;
  bottom: max(26px, env(safe-area-inset-bottom, 0px));
  padding: 12px 10px;
  margin-right: -.3em;
  transform: translateX(-50%);
  white-space: nowrap;
  color: #3F5143;
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .3em;
  text-transform: uppercase;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .6em;
  text-decoration-color: rgba(63, 81, 67, .35);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition: opacity .5s ease, visibility 0s .5s;
}
.opener:checked ~ .peek:checked ~ .hero .to-details {
  opacity: 1;
  visibility: visible;
  transition: opacity .6s ease .5s, visibility 0s .5s;
}
.peek {
  position: fixed;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}

/* the sheet: arrives once (animation), then slides down and up on request (transition).
   It starts as the back of the card, the same size and spot as the card in the
   envelope, flips over and grows to fill the screen. --s is the card's width as a
   share of the screen and --ct is the card's top edge; script.js measures both
   exactly, these are close values for when scripts don't run. */
:root { --s: .33; --ct: calc(calc(50 * var(--vh)) - 8px - 460 * var(--u)); }
@media (max-width: 600px) { :root { --s: .608; } }
.sheet {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: calc(100 * var(--vh));
  overflow: hidden;
  z-index: 20;
  pointer-events: none;
  transform-origin: 50% 0;
  visibility: hidden;
}
.opener:checked ~ .sheet { height: auto; overflow: visible; animation: sheet-in 1.55s 3.15s both; }
@keyframes sheet-in {
  0% {
    visibility: visible;
    transform: translate3d(0, var(--ct), 0) perspective(1400px) rotateY(-90deg) scale(var(--s));
    clip-path: inset(0 0 calc(100% - 640 * var(--u) / var(--s)) 0);
    animation-timing-function: cubic-bezier(.2, .6, .35, 1);
  }
  22% {
    transform: translate3d(0, var(--ct), 0) perspective(1400px) rotateY(0deg) scale(var(--s));
    clip-path: inset(0 0 calc(100% - 640 * var(--u) / var(--s)) 0);
    animation-timing-function: cubic-bezier(.55, 0, .2, 1);
  }
  99.5% { clip-path: inset(0 0 0 0); }
  100% {
    visibility: visible;
    transform: none;
    clip-path: none;
  }
}
.page {
  position: relative;
  min-height: calc(100 * var(--vh));
  pointer-events: auto;
  box-shadow: 0 -20px 40px -24px rgba(31, 38, 33, .35);
  transition: transform .95s cubic-bezier(.6, 0, .2, 1), visibility 0s;
}
.opener:checked ~ .peek:checked ~ .sheet .page {
  transform: translate3d(0, 105%, 0);
  visibility: hidden;
  transition: transform .95s cubic-bezier(.6, 0, .2, 1), visibility 0s .95s;
}

.to-card,
.to-details { -webkit-tap-highlight-color: transparent; }
.to-card {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin: 0 -.3em 6px 0;
  padding: 0 8px 4px;
  color: var(--moss);
  font-size: .6875rem;
  font-weight: 500;
  letter-spacing: .3em;
  text-transform: uppercase;
  cursor: pointer;
}
.to-card__bar {
  width: 38px;
  height: 3px;
  border-radius: 3px;
  background: rgba(31, 38, 33, .2);
}

/* ---------------------------------------------------------------
   Opening: the envelope rises to center, the flap swings open,
   and the card slides up out of it. Transform and opacity only.
---------------------------------------------------------------- */

.opener:checked ~ .hero .comp,
.opener:checked ~ .hero .flap,
.opener:checked ~ .hero .card { will-change: transform; }

.opener:checked ~ .hero .comp { animation: comp-up 1.7s cubic-bezier(.45, 0, .2, 1) .1s both; }
.opener:checked ~ .hero .flap { animation: flap-open 1s cubic-bezier(.45, 0, .3, 1) .05s forwards, env-away 2.75s 2.1s; }
.opener:checked ~ .hero .card { animation: card-out 1.25s cubic-bezier(.35, 0, .15, 1) .75s forwards, card-flip 1.95s 2.85s; }
.opener:checked ~ .hero .hint { animation: fade-out .3s ease forwards; }
/* once the card is out, the envelope drops away and the card turns over.
   These don't hold their end state: by the time they finish the details cover
   the screen, so "See the card again" finds the open envelope underneath. */
.opener:checked ~ .hero .env-back,
.opener:checked ~ .hero .pocket,
.opener:checked ~ .hero .bouquet { animation: env-away 2.75s 2.1s; }
@keyframes env-away {
  0% { translate: 0 0; animation-timing-function: cubic-bezier(.55, 0, .8, .3); }
  30%, 100% { translate: 0 calc(115 * var(--vh)); }
}
@keyframes card-flip {
  0% { transform: translateY(calc(-385 * var(--u))) perspective(1400px) rotateY(0deg); animation-timing-function: cubic-bezier(.5, 0, .9, .45); }
  15.4%, 100% { transform: translateY(calc(-385 * var(--u))) perspective(1400px) rotateY(90deg); }
}

@keyframes comp-up {
  from { transform: translateY(calc(-235 * var(--u))); }
  to { transform: translateY(0); }
}
@keyframes flap-open {
  0% { transform: perspective(2200px) rotateX(0deg); z-index: 5; }
  49.9% { z-index: 5; }
  50% { z-index: 2; }
  100% { transform: perspective(2200px) rotateX(180deg); z-index: 2; }
}
@keyframes card-out {
  from { transform: translateY(0); }
  to { transform: translateY(calc(-385 * var(--u))); }
}
@keyframes fade-out { to { opacity: 0; visibility: hidden; } }
@keyframes fade-in { to { opacity: 1; } }
@keyframes cue {
  from { transform: translateY(-100%); }
  to { transform: translateY(250%); }
}

/* ---------------------------------------------------------------
   The page below
---------------------------------------------------------------- */

.page {
  padding: max(16px, env(safe-area-inset-top, 0px)) 20px max(40px, calc(env(safe-area-inset-bottom, 0px) + 28px));
  text-align: center;
  background:
    radial-gradient(110% 50% at 50% 0%, rgba(237, 217, 216, .55), rgba(237, 217, 216, 0) 70%),
    var(--noise),
    var(--page);
  overflow-x: hidden;
}

.headline {
  margin: 4px 0 0;
  font-family: var(--italic);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(2rem, 1.5rem + 3vw, 3.4rem);
  line-height: 1.1;
  letter-spacing: -.01em;
}

/* painted callas tucked into two corners */
.page { isolation: isolate; display: flex; flex-direction: column; }
.page > .to-card { align-self: center; }
.page > .row { width: 100%; }
.page > .row--b { margin-bottom: 0; }
.page > .sprays-end { margin-top: 0; }
/* the details page uses green for its colored text */
.page { --rose: var(--leaf); }
/* the flowers sit behind the photos and are trimmed at the page edges,
   so they never add extra scrolling */
.sprays {
  position: absolute;
  z-index: 0;
  inset: 0;
  min-height: 100%;
  overflow: hidden;
  pointer-events: none;
}
.spray {
  position: absolute;
  width: clamp(110px, 30vw, 190px);
  max-width: none;
  pointer-events: none;
}
.spray--top { top: -48px; right: -50px; transform: rotate(204deg); }
/* a small spray tucked behind the links, between the two rows */
/* the top row sits above this one, so the spray tucks under the video */
.page > .row.row--b:not(.sprays) { z-index: 0; }
.spray--mid {
  z-index: -1;
  left: -34px;
  top: -22px;
  width: clamp(84px, 22vw, 140px);
  transform: rotate(64deg);
  opacity: .95;
}
/* the bottom flowers hang from the very end of the page, so they follow the
   last section on any screen size */
.sprays-end { position: relative; z-index: 0; flex: none; height: 0; margin-top: auto; }
.page > :not(.sprays):not(.sprays-end) { position: relative; z-index: 1; }
.sprays-end__box {
  position: absolute;
  left: -20px;
  bottom: calc(-1 * max(40px, calc(env(safe-area-inset-bottom, 0px) + 28px)));
  width: 260px;
  height: 300px;
  overflow: hidden;
}
.spray--bottom { bottom: -64px; left: -30px; transform: rotate(58deg); }

/* the headline sits beside the video, above the date */
.info .headline {
  margin: 0 0 14px;
  font-size: clamp(2.15rem, 1.4rem + 3.4vw, 3.8rem);
  line-height: 1.08;
  text-align: left;
}
.info .headline [lang] { font-size: .7em; line-height: 1.3; }
.info .headline [lang="zh-Hans"] { font-size: .6em; white-space: nowrap; }
.row--b { margin-top: clamp(30px, 7vw, 56px); }
/* on a tall phone screen, share the spare room above and between the two rows */
.page > .row--a, .page > .row--b { margin-top: auto; padding-top: clamp(22px, 5vw, 40px); }
.page > .row--b { margin-bottom: auto; }

/* rows that alternate the video or the photo with the information */
.row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(16px, 5vw, 48px);
  max-width: 720px;
  margin: clamp(22px, 5vw, 44px) auto 0;
}
.row--a, .row--c { text-align: left; }
.row--b { text-align: right; }

.media {
  margin: 0;
  padding: clamp(5px, 1.2vw, 8px);
  background: #FFFFFF;
  box-shadow: 0 1px 2px rgba(60, 50, 45, .1), 0 16px 30px -18px rgba(60, 50, 45, .5);
}
.media img,
.media picture {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  height: auto;
}
.media picture img { aspect-ratio: auto; height: 100%; }
.media img {
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
}
.media--tilt-l { transform: rotate(-4deg); margin-left: -4px; }
.media--tilt-r { transform: rotate(3deg); margin-right: -4px; }
/* two photos laid on top of each other, like prints on a table */
.stack { display: grid; }
.stack > .media { grid-area: 1 / 1; align-self: start; }
.stack__back { width: 76%; justify-self: end; transform: rotate(4deg); margin-right: -4px; }
.stack__front { position: relative; width: 70%; justify-self: start; margin-top: 74%; transform: rotate(-4deg); }
.media--tilt-l2 { transform: rotate(-2.5deg); margin-left: 6px; width: 86%; }

.info__day {
  font-family: var(--italic);
  font-style: italic;
  font-size: clamp(1.2rem, 1rem + 1vw, 1.6rem);
  line-height: 1.1;
  color: var(--rose);
}
.info__date {
  margin-top: 4px;
  font-family: var(--didone);
  font-size: clamp(1.45rem, 1.1rem + 2vw, 2.4rem);
  line-height: 1.02;
  text-transform: uppercase;
  font-variant-ligatures: none;
}
.info__venue {
  margin-top: 12px;
  font-size: clamp(.68rem, .62rem + .3vw, .82rem);
  font-weight: 500;
  letter-spacing: .2em;
  line-height: 1.55;
  text-transform: uppercase;
}
.info__town {
  margin-top: 2px;
  font-style: italic;
  font-size: clamp(.86rem, .8rem + .3vw, 1rem);
  color: var(--moss);
}
.info--links {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 14px;
}
.info--links .info__note { margin-top: 14px; }
.info--links .info__names { margin-top: -8px; }
.info__note {
  font-size: .68rem;
  font-weight: 500;
  letter-spacing: .18em;
  line-height: 1.7;
  text-transform: uppercase;
  color: var(--moss);
}
.info__names {
  margin-top: 6px;
  font-family: var(--italic);
  font-style: italic;
  font-size: clamp(1.3rem, 1.05rem + 1.4vw, 1.9rem);
  line-height: 1.15;
}

.link {
  padding: 3px 0;
  text-align: right;
  margin-right: -.2em;
  font-size: .7rem;
  font-weight: 500;
  letter-spacing: .2em;
  line-height: 2.2;
  text-transform: uppercase;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .55em;
  text-decoration-color: var(--rose);
}

/* sections drift in as they scroll into view (only when scripts run) */
.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 1s ease, transform 1.2s cubic-bezier(.22, 1, .36, 1);
}
.js .reveal.is-in { opacity: 1; transform: none; }

/* ---------------------------------------------------------------
   Reduced motion: everything simply appears
---------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .opener:checked ~ .hero .comp { animation: none; transform: none; }
  .opener:checked ~ .hero .flap { animation: none; transform: perspective(2200px) rotateX(180deg); z-index: 2; }
  .opener:checked ~ .hero .card { animation: none; transform: translateY(calc(-385 * var(--u))); }
  .opener:checked ~ .sheet { animation: none; visibility: visible; transform: none; transition: visibility 0s 1s; }
  .opener:checked ~ .hero .env-back, .opener:checked ~ .hero .pocket, .opener:checked ~ .hero .bouquet { animation: none; }
  .page, .to-details { transition: none !important; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
}

/* ---------------------------------------------------------------
   Languages: English, Korean and Chinese. The tabs are radio buttons,
   so switching works with or without JavaScript. English is the default.
---------------------------------------------------------------- */

.lang {
  position: fixed;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}
.l-ko, .l-zh { display: none; }
#lang-ko:checked ~ * .l-en,
#lang-zh:checked ~ * .l-en { display: none; }
#lang-ko:checked ~ * .l-ko,
#lang-zh:checked ~ * .l-zh { display: inline; }

[lang="ko"] { font-family: "BV Serif KR", var(--serif); font-style: normal; word-break: keep-all; }
[lang="zh-Hans"] { font-family: "BV Serif SC", var(--serif); font-style: normal; }
.link [lang], .info__note [lang], .info__venue [lang], .to-card [lang], .to-details [lang] { letter-spacing: .1em; }
.headline [lang] { letter-spacing: .02em; font-size: .86em; }
.info__date [lang] { font-family: var(--didone); font-size: .74em; white-space: nowrap; letter-spacing: 0; }
.info__date [lang="ko"] { font-family: "BV Serif KR", var(--didone); }
.info__date [lang="zh-Hans"] { font-family: "BV Serif SC", var(--didone); }

.langs {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin: 10px 0 2px;
}
.langs__tab {
  padding: 5px 10px 6px;
  border-bottom: 1px solid transparent;
  color: var(--moss);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .14em;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color .3s ease, border-color .3s ease;
}
.langs__tab--en { text-transform: uppercase; font-size: .66rem; letter-spacing: .22em; }
#lang-en:checked ~ .sheet .langs__tab--en,
#lang-ko:checked ~ .sheet .langs__tab--ko,
#lang-zh:checked ~ .sheet .langs__tab--zh { color: var(--ink); border-bottom-color: var(--leaf); }
#lang-en:focus-visible ~ .sheet .langs__tab--en,
#lang-ko:focus-visible ~ .sheet .langs__tab--ko,
#lang-zh:focus-visible ~ .sheet .langs__tab--zh { outline: 2px solid var(--ink); outline-offset: 2px; }

/* ---------------------------------------------------------------
   Email sign-up for the formal invitation
---------------------------------------------------------------- */

.page > .invite { width: 100%; }
.invite {
  max-width: 460px;
  margin: clamp(40px, 9vw, 64px) auto 96px;
  padding: 26px 22px 24px;
  border-top: 1px solid var(--line);
  text-align: center;
}
.invite__title {
  margin: 0;
  font-family: var(--italic);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.5rem, 1.2rem + 1.6vw, 2.1rem);
  line-height: 1.15;
}
.invite__title [lang] { font-size: .8em; }
.invite__lead {
  margin: 10px auto 0;
  max-width: 36ch;
  font-size: 1.02rem;
  line-height: 1.55;
  color: var(--moss);
}
.invite__lead [lang] { font-size: .9em; line-height: 1.8; }
.invite__form { margin-top: 18px; display: grid; gap: 16px; text-align: left; }
.invite__field { display: grid; gap: 4px; }
.invite__label {
  font-size: .64rem;
  font-weight: 500;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--rose);
}
.invite__input {
  width: 100%;
  padding: 8px 2px 7px;
  border: 0;
  border-bottom: 1px solid #BFC3B0;
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 1.1rem;
  -webkit-appearance: none;
  appearance: none;
}
.invite__input:focus { outline: none; border-bottom-color: var(--leaf); box-shadow: 0 1px 0 var(--leaf); }
.invite__send {
  justify-self: center;
  margin-top: 6px;
  padding: 12px 34px 11px;
  border: 1px solid var(--leaf);
  border-radius: 0;
  background: var(--leaf);
  color: #FBFAF6;
  font: inherit;
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .26em;
  text-transform: uppercase;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background .3s ease, color .3s ease;
}
.invite__send:hover { background: transparent; color: var(--leaf); }
.invite__send:disabled { opacity: .6; cursor: default; }
.invite__status { margin: 0; min-height: 1.4em; text-align: center; font-size: .95rem; color: var(--moss); }
.invite__trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.invite__done { margin-top: 16px; font-size: 1.1rem; line-height: 1.6; }
