/* ==========================================================================
   Undangan pernikahan - layout mirrors a fixed 484 unit wide canvas.

   Every position the generator emits is `calc(<n> * var(--u))`, so changing
   --u rescales the whole invitation without a transform, which keeps text
   rendering at native resolution on small screens.
   ========================================================================== */

:root{
  --canvas: 484;
  --u: calc(min(100vw, 484px) / 484);
  --maroon:#330000;
  --wine:#6e2237;
  --cream:#fffaf3;
  --sand:#f3efe8;
  --ink:#333;
  --line:rgba(53,58,64,.18);
  --shadow:0 10px 30px rgba(51,0,0,.16);
}

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

html{-webkit-text-size-adjust:100%}

body{
  margin:0;
  background:#efe7dd;
  color:var(--ink);
  font-family:'Source Sans 3',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-size:calc(16 * var(--u));
  line-height:1.5;
  overflow-x:hidden;
}

body.locked{overflow:hidden;height:100dvh}

img{max-width:none;border:0}
button{font:inherit;color:inherit}

/* --- canvas -------------------------------------------------------------- */

.canvas{
  position:relative;
  width:calc(484 * var(--u));
  margin:0 auto;
  background:#fff;
  overflow:hidden;
  box-shadow:0 0 60px rgba(51,0,0,.18);
}

.sec{
  position:relative;
  width:100%;
  overflow:hidden;
  /* Each section declares its own contain-intrinsic-size, so the browser can
     skip painting the 12 000 px that are off screen without the scrollbar
     jumping. */
  content-visibility:auto;
}

.el{position:absolute}

img.ph{display:block;object-fit:cover}

.clip{overflow:hidden}
.clip>img{position:absolute;display:block;object-fit:cover}

/* Rich text keeps the source theme's inline colours and sizes. */
.tx{z-index:4}
.tx p,.tx h1,.tx h2,.tx h3,.tx h4{margin:0;font-weight:inherit;line-height:1.5}
.tx h2{font-family:'Playfair Display',serif}
.tx strong{font-weight:700}
.tx em{font-style:italic}

.wg{z-index:5}

/* A slow bob for artwork that should feel alive rather than pasted on. */
.float-y{animation:floatY 4.2s ease-in-out infinite}
@keyframes floatY{
  0%,100%{transform:translateY(0)}
  50%{transform:translateY(calc(-15 * var(--u)))}
}
@media (prefers-reduced-motion:reduce){.float-y{animation:none}}

/* Legibility over photography. The theme paints text straight onto busy
   artwork; a shadow on the glyphs plus a soft plate behind the block keeps
   every line readable without changing the layout. */
.scrim{z-index:3;pointer-events:none}
.scrim-dark{
  background:linear-gradient(180deg,
    rgba(24,12,8,0) 0%, rgba(24,12,8,.5) 16%,
    rgba(24,12,8,.5) 84%, rgba(24,12,8,0) 100%);
}
.scrim-light{
  background:linear-gradient(180deg,
    rgba(255,250,243,0) 0%, rgba(255,250,243,.82) 16%,
    rgba(255,250,243,.82) 84%, rgba(255,250,243,0) 100%);
}
.tx-light{text-shadow:0 1px 2px rgba(0,0,0,.55), 0 2px 16px rgba(0,0,0,.45)}
.tx-dark{text-shadow:0 1px 1px rgba(255,250,243,.9), 0 0 14px rgba(255,250,243,.95)}

/* --- reveal animations --------------------------------------------------- */

[data-anim]{
  opacity:0;
  will-change:transform,opacity;
  transition:opacity var(--ad,1s) ease var(--adl,0s), transform var(--ad,1s) cubic-bezier(.22,.61,.36,1) var(--adl,0s);
}
[data-anim^="rise-up"]{transform:translateY(calc(28 * var(--u)))}
[data-anim^="rise-down"]{transform:translateY(calc(-28 * var(--u)))}
[data-anim^="pan-left"]{transform:translateX(calc(40 * var(--u)))}
[data-anim^="pan-right"]{transform:translateX(calc(-40 * var(--u)))}
[data-anim^="pop"]{transform:scale(.86)}
[data-anim^="breathe"]{transform:scale(1.06)}
[data-anim^="fade"]{transform:none}
[data-anim].in{opacity:1;transform:none}

/* Flipped or rotated artwork carries its own transform; animating it would
   fight the layout, so those elements only fade. */
.el[style*="scale(-1"][data-anim].in,
.el[style*="rotate"][data-anim].in{transition:opacity var(--ad,1s) ease var(--adl,0s)}

@media (prefers-reduced-motion:reduce){
  [data-anim]{opacity:1!important;transform:none!important;transition:none!important}
}

/* --- cover / notice ------------------------------------------------------
   Laid out in the same canvas units as the invitation, so the two scale
   together and nothing reflows into an awkward shape between breakpoints. */

.cover{
  position:fixed;
  inset:0;
  z-index:60;
  display:flex;
  align-items:center;
  justify-content:center;
  overflow:hidden;
  background:#1d1410;
  transition:opacity .7s ease, visibility .7s;
}
.cover.gone{opacity:0;visibility:hidden;pointer-events:none}
.cover-static{position:absolute;min-height:100dvh}

.cover-bg{
  position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:cover;
  object-position:50% 52%;
  transform:scale(1.06);
  animation:coverDrift 22s ease-in-out infinite alternate;
}
@keyframes coverDrift{to{transform:scale(1.13) translateY(-1.5%)}}

.cover-veil{
  position:absolute;inset:0;
  background:
    radial-gradient(118% 58% at 50% 40%, rgba(29,20,16,.06), rgba(29,20,16,.62) 74%),
    linear-gradient(180deg, rgba(29,20,16,.6), rgba(29,20,16,.2) 34%, rgba(29,20,16,.88));
}

/* Fixed-width stage: ornaments are pinned to it, never to the viewport. */
.cover-stage{
  position:relative;
  z-index:2;
  width:calc(484 * var(--u));
  min-height:100dvh;
  display:flex;
  align-items:center;
  justify-content:center;
}

.cover-orn{position:absolute;pointer-events:none;user-select:none}
.cover-lace{
  top:calc(-18 * var(--u));
  left:50%;
  width:calc(500 * var(--u));
  transform:translateX(-50%);
  opacity:.92;
}
.cover-flower-l{left:calc(-96 * var(--u));bottom:calc(-52 * var(--u));width:calc(210 * var(--u));opacity:.85}
.cover-flower-r{right:calc(-96 * var(--u));bottom:calc(-52 * var(--u));width:calc(210 * var(--u));transform:scaleX(-1);opacity:.85}


.cover-inner{
  position:relative;
  z-index:2;
  width:100%;
  padding:calc(70 * var(--u)) calc(34 * var(--u)) calc(96 * var(--u));
  text-align:center;
  color:var(--cream);
  text-shadow:0 1px 3px rgba(0,0,0,.45);
}

.cover-kicker{
  margin:0;
  font-size:calc(12 * var(--u));
  letter-spacing:.36em;
  text-indent:.36em;
  text-transform:uppercase;
  opacity:.86;
}

.cover-names{
  margin:calc(10 * var(--u)) 0 0;
  display:flex;
  flex-direction:column;
  align-items:center;
  font-family:'Playfair Display',serif;
  font-weight:500;
  line-height:1;
}
.cover-name{font-size:calc(52 * var(--u))}
.cover-amp{
  font-size:calc(30 * var(--u));
  font-style:italic;
  opacity:.82;
  margin:calc(2 * var(--u)) 0;
}

.cover-full{
  margin:calc(12 * var(--u)) auto 0;
  max-width:calc(360 * var(--u));
  font-size:calc(11.5 * var(--u));
  letter-spacing:.05em;
  opacity:.78;
  line-height:1.55;
}

.cover-rule{
  display:block;
  width:calc(74 * var(--u));
  height:1px;
  margin:calc(16 * var(--u)) auto calc(14 * var(--u));
  background:linear-gradient(90deg,transparent,rgba(255,250,243,.75),transparent);
}

.cover-date{
  margin:0;
  font-size:calc(12.5 * var(--u));
  letter-spacing:.2em;
  text-transform:uppercase;
  opacity:.9;
}

.cover-guest{
  margin:calc(26 * var(--u)) auto 0;
  padding:calc(14 * var(--u)) calc(18 * var(--u));
  max-width:calc(330 * var(--u));
  border:1px solid rgba(255,250,243,.28);
  border-radius:calc(14 * var(--u));
  background:rgba(29,20,16,.42);
  backdrop-filter:blur(3px);
}
.cover-guest-label{display:block;font-size:calc(11.5 * var(--u));letter-spacing:.08em;opacity:.8}
.cover-guest-name{
  display:block;
  margin:calc(4 * var(--u)) 0;
  font-family:'Playfair Display',serif;
  font-weight:600;
  font-size:calc(24 * var(--u));
  line-height:1.25;
}
.cover-guest-note{display:block;font-size:calc(11.5 * var(--u));opacity:.72}

.cover-btn{
  display:inline-flex;
  align-items:center;
  gap:calc(8 * var(--u));
  margin-top:calc(24 * var(--u));
  padding:calc(13 * var(--u)) calc(26 * var(--u));
  border:0;
  border-radius:999px;
  background:var(--maroon);
  color:var(--cream);
  font-family:'Source Sans 3',sans-serif;
  font-size:calc(14 * var(--u));
  font-weight:500;
  letter-spacing:.06em;
  cursor:pointer;
  text-shadow:none;
  box-shadow:0 calc(10 * var(--u)) calc(24 * var(--u)) rgba(0,0,0,.45);
  transition:transform .18s ease, background .18s ease;
}
.cover-btn:hover{transform:translateY(calc(-2 * var(--u)));background:#4a0d0d}
.cover-btn svg{width:calc(17 * var(--u));height:calc(17 * var(--u));fill:currentColor}

.cover-hint{
  margin:calc(16 * var(--u)) auto 0;
  max-width:calc(320 * var(--u));
  font-size:calc(11 * var(--u));
  line-height:1.55;
  opacity:.62;
}

/* Notice shown to anyone without a personal link. */
body.plain{min-height:100dvh}
.notice-card{max-width:calc(350 * var(--u));text-align:center}
.notice-icon{display:block;margin:0 auto calc(6 * var(--u))}
.notice-icon svg{width:calc(22 * var(--u));height:calc(22 * var(--u));fill:rgba(255,250,243,.85)}
.notice-title{
  display:block;
  font-family:'Playfair Display',serif;
  font-weight:600;
  font-size:calc(19 * var(--u));
  line-height:1.3;
}
.notice-body{
  margin:calc(6 * var(--u)) 0 calc(10 * var(--u));
  font-size:calc(12.5 * var(--u));
  line-height:1.55;
  opacity:.85;
}
.notice-sample{
  display:inline-block;
  padding:calc(5 * var(--u)) calc(12 * var(--u));
  border-radius:999px;
  background:rgba(255,250,243,.12);
  border:1px solid rgba(255,250,243,.22);
  font-size:calc(11.5 * var(--u));
  letter-spacing:.04em;
}
.notice-code{color:#f0c98a;font-weight:600}

/* Short screens: keep the standing couple from creeping into the card. */
@media (max-height:760px){
  .cover-inner{padding-top:calc(48 * var(--u));padding-bottom:calc(120 * var(--u))}
  .cover-name{font-size:calc(46 * var(--u))}
  .cover-flower-l,.cover-flower-r{width:calc(170 * var(--u))}
}

/* --- shared controls ----------------------------------------------------- */

.pill{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:calc(8 * var(--u));
  padding:calc(13 * var(--u)) calc(22 * var(--u));
  border:0;
  border-radius:999px;
  background:var(--maroon);
  color:var(--cream);
  font-family:'Source Sans 3',sans-serif;
  font-size:calc(13 * var(--u));
  font-weight:500;
  letter-spacing:.08em;
  text-decoration:none;
  cursor:pointer;
  transition:transform .18s ease, box-shadow .18s ease, opacity .18s ease;
  box-shadow:0 calc(6 * var(--u)) calc(16 * var(--u)) rgba(51,0,0,.28);
}
.pill:hover{transform:translateY(calc(-2 * var(--u)))}
.pill:active{transform:translateY(0)}
.pill svg{width:calc(16 * var(--u));height:calc(16 * var(--u));fill:currentColor}
.pill-block{width:100%}
.pill-ghost{
  background:transparent;
  color:var(--maroon);
  border:1px solid rgba(51,0,0,.35);
  box-shadow:none;
}

.fld{display:block;margin-bottom:calc(10 * var(--u))}
.fld-lbl{
  display:block;
  margin-bottom:calc(4 * var(--u));
  font-size:calc(12 * var(--u));
  font-weight:600;
  letter-spacing:.03em;
  color:rgba(51,0,0,.72);
}
.fld-lbl em{font-style:normal;font-weight:400;opacity:.65}
.fld-in{
  width:100%;
  padding:calc(11 * var(--u)) calc(13 * var(--u));
  border:1px solid var(--line);
  border-radius:calc(10 * var(--u));
  background:rgba(255,255,255,.9);
  color:#222;
  font-family:inherit;
  font-size:calc(14 * var(--u));
  line-height:1.35;
  outline:0;
  transition:border-color .18s ease, box-shadow .18s ease;
}
.fld-in:focus{border-color:var(--wine);box-shadow:0 0 0 calc(3 * var(--u)) rgba(110,34,55,.14)}
.fld-area{resize:vertical;min-height:calc(58 * var(--u))}
.fld-row{display:flex;gap:calc(10 * var(--u))}
.fld-row .fld{flex:1}
.fld-narrow{max-width:calc(110 * var(--u))}
.fld-check{border:0;margin:0 0 calc(10 * var(--u));padding:0}
.chk{
  display:inline-flex;
  align-items:center;
  gap:calc(6 * var(--u));
  margin-right:calc(14 * var(--u));
  font-size:calc(13 * var(--u));
}
.chk input{width:calc(15 * var(--u));height:calc(15 * var(--u));accent-color:var(--wine)}

.live-dot{
  width:calc(8 * var(--u));height:calc(8 * var(--u));
  border-radius:50%;
  background:#38a169;
  box-shadow:0 0 0 0 rgba(56,161,105,.6);
  animation:livePulse 2s infinite;
  flex:none;
}
@keyframes livePulse{
  70%{box-shadow:0 0 0 calc(8 * var(--u)) rgba(56,161,105,0)}
  100%{box-shadow:0 0 0 0 rgba(56,161,105,0)}
}

/* --- countdown ----------------------------------------------------------- */

.cd{text-align:center;color:var(--cream)}
.cd-grid{display:flex;justify-content:center;gap:calc(6 * var(--u))}
.cd-cell{
  flex:1 1 0;
  max-width:calc(104 * var(--u));
  padding:calc(8 * var(--u)) 0;
}
.cd-num{
  display:block;
  font-family:'Playfair Display',serif;
  font-size:calc(46 * var(--u));
  font-weight:500;
  line-height:1.1;
  color:var(--cream);
  text-shadow:0 calc(2 * var(--u)) calc(10 * var(--u)) rgba(0,0,0,.35);
  font-variant-numeric:tabular-nums;
}
.cd-lbl{
  display:block;
  font-size:calc(15 * var(--u));
  letter-spacing:.04em;
  color:var(--cream);
  opacity:.92;
}
.cd-btn{margin-top:calc(12 * var(--u))}
.cd-note{
  margin:calc(8 * var(--u)) 0 0;
  font-size:calc(11 * var(--u));
  color:rgba(255,250,243,.75);
}

/* --- our story ----------------------------------------------------------- */

.story{list-style:none;margin:0;padding:0;text-align:left}
.story-item{
  display:flex;
  gap:calc(10 * var(--u));
  margin-bottom:calc(12 * var(--u));
}
.story-dot{
  flex:none;
  width:calc(24 * var(--u));height:calc(24 * var(--u));
  display:grid;place-items:center;
  border-radius:50%;
  border:1px solid rgba(255,250,243,.55);
  color:var(--cream);
  font-size:calc(12 * var(--u));
  font-family:'Playfair Display',serif;
}
.story-title{
  margin:0 0 calc(2 * var(--u));
  font-family:'Playfair Display',serif;
  font-size:calc(16 * var(--u));
  font-weight:500;
  color:var(--cream);
}
.story-body{
  margin:0;
  font-size:calc(13 * var(--u));
  line-height:1.45;
  color:rgba(255,250,243,.88);
}

/* --- RSVP ---------------------------------------------------------------- */

.rsvp,.rsvp-done{
  padding:calc(16 * var(--u));
  border-radius:calc(16 * var(--u));
  background:rgba(255,255,255,.82);
  border:1px solid rgba(51,0,0,.08);
  box-shadow:var(--shadow);
  backdrop-filter:blur(6px);
}
.rsvp-err{
  margin:calc(8 * var(--u)) 0 0;
  color:#a02020;
  font-size:calc(12 * var(--u));
  text-align:center;
}
.rsvp-done{text-align:center}
.rsvp-check{
  width:calc(46 * var(--u));height:calc(46 * var(--u));
  margin:0 auto calc(8 * var(--u));
  display:grid;place-items:center;
  border-radius:50%;
  background:var(--maroon);
}
.rsvp-check svg{width:calc(26 * var(--u));height:calc(26 * var(--u));fill:var(--cream)}
.rsvp-done-title{
  margin:0 0 calc(4 * var(--u));
  font-family:'Playfair Display',serif;
  font-size:calc(21 * var(--u));
  font-weight:500;
  color:var(--maroon);
}
.rsvp-done-body{
  margin:0 0 calc(12 * var(--u));
  font-size:calc(13.5 * var(--u));
  line-height:1.5;
}
/* --- wishes board: a paper panel whose notes drift past ------------------ */

.notes{
  display:flex;
  flex-direction:column;
  height:100%;
  padding:calc(14 * var(--u));
  border-radius:calc(16 * var(--u));
  background:
    linear-gradient(rgba(255,253,248,.55), rgba(255,253,248,.55)),
    url('../img/paper-cream.webp') center/cover;
  border:1px solid rgba(51,0,0,.12);
  box-shadow:var(--shadow);
}
.notes-head{
  display:flex;
  align-items:center;
  gap:calc(8 * var(--u));
  margin-bottom:calc(10 * var(--u));
}
.notes-title{
  margin:0;
  flex:1;
  font-family:'Playfair Display',serif;
  font-size:calc(18 * var(--u));
  font-weight:500;
  color:var(--maroon);
}
.notes-board{
  position:relative;
  height:calc(152 * var(--u));
  margin-bottom:calc(12 * var(--u));
  overflow:hidden;
  /* Cards fade out at both ends so the loop never shows a hard cut. */
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
}
.notes-track{display:flex;width:max-content;gap:calc(10 * var(--u))}
.notes-track.rolling{animation:noteRollX var(--roll,32s) linear infinite}
@keyframes noteRollX{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){
  .notes-track.rolling{animation:none}
  .notes-board{overflow-x:auto}
}

.notes-list{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  gap:calc(10 * var(--u));
}

.note{
  flex:none;
  width:calc(232 * var(--u));
  height:calc(152 * var(--u));
  padding:calc(12 * var(--u));
  border-radius:calc(12 * var(--u));
  background:rgba(255,255,255,.86);
  border-top:calc(3 * var(--u)) solid var(--wine);
  box-shadow:0 calc(3 * var(--u)) calc(10 * var(--u)) rgba(51,0,0,.1);
  display:flex;
  flex-direction:column;
}
.note.tone-1{background:rgba(250,242,231,.92);border-top-color:#a9713f}
.note.tone-2{background:rgba(240,245,238,.92);border-top-color:#5b7c56}
.note.tone-3{background:rgba(247,240,246,.92);border-top-color:#7a5470}
.note.tone-4{background:rgba(238,242,248,.92);border-top-color:#4f6488}
.note-top{display:flex;align-items:center;gap:calc(7 * var(--u))}
.note-avatar{
  flex:none;
  width:calc(22 * var(--u));height:calc(22 * var(--u));
  display:grid;place-items:center;
  border-radius:50%;
  background:var(--wine);
  color:var(--cream);
  font-size:calc(10.5 * var(--u));
  font-weight:700;
}
.note-name{font-weight:700;font-size:calc(13 * var(--u));color:var(--maroon)}
.note-time{margin-left:auto;font-size:calc(10.5 * var(--u));color:rgba(51,0,0,.45)}
.note-body{
  margin:calc(6 * var(--u)) 0 0;
  font-size:calc(12.5 * var(--u));
  line-height:1.45;
  word-break:break-word;
  overflow:hidden;
  display:-webkit-box;
  -webkit-line-clamp:4;
  -webkit-box-orient:vertical;
}
.notes-empty[hidden]{display:none}
.notes-empty{
  position:absolute;
  inset:0;
  margin:0;
  display:grid;
  place-items:center;
  padding:calc(16 * var(--u));
  text-align:center;
  font-size:calc(13 * var(--u));
  color:rgba(51,0,0,.5);
}
.notes-form{display:grid;gap:calc(8 * var(--u));margin-top:auto}

/* Sender identity comes from the invitation link, so it is shown, not typed. */
.fld-fixed{
  display:inline-flex;
  align-items:center;
  gap:calc(7 * var(--u));
  padding:calc(9 * var(--u)) calc(13 * var(--u));
  border-radius:999px;
  background:rgba(110,34,55,.09);
  border:1px solid rgba(110,34,55,.16);
  color:var(--maroon);
  font-size:calc(13 * var(--u));
  font-weight:600;
  line-height:1.2;
}
.fld-fixed svg{
  width:calc(14 * var(--u));height:calc(14 * var(--u));
  fill:currentColor;opacity:.65;flex:none;
}
.fld-fixed-block{display:flex;width:100%}
.fld-fixed-sm{
  display:flex;
  width:100%;
  margin-bottom:calc(6 * var(--u));
  padding:calc(6 * var(--u)) calc(11 * var(--u));
  font-size:calc(12 * var(--u));
}

/* Sign-off at the foot of the canvas. */
.signoff{z-index:4;text-align:center}
.signoff-names{
  margin:0;
  font-family:'Playfair Display',serif;
  font-size:calc(28 * var(--u));
  font-weight:500;
  color:var(--cream);
  text-shadow:0 1px 2px rgba(0,0,0,.5);
}
.signoff-tag{
  margin:calc(5 * var(--u)) 0 0;
  font-size:calc(11.5 * var(--u));
  letter-spacing:.2em;
  text-transform:uppercase;
  color:rgba(255,250,243,.8);
  text-shadow:0 1px 2px rgba(0,0,0,.45);
}

/* --- live chat ----------------------------------------------------------- */

.chat{
  display:flex;
  flex-direction:column;
  height:calc(430 * var(--u));
  border-radius:calc(16 * var(--u));
  overflow:hidden;
  background:rgba(255,250,243,.94);
  border:1px solid rgba(51,0,0,.1);
  box-shadow:var(--shadow);
}
.chat-head{
  display:flex;
  align-items:center;
  gap:calc(8 * var(--u));
  padding:calc(10 * var(--u)) calc(14 * var(--u));
  background:var(--maroon);
  color:var(--cream);
}
.chat-title{flex:1;font-size:calc(14 * var(--u));font-weight:600;letter-spacing:.02em}
.chat-online{font-size:calc(12 * var(--u));opacity:.85}
.chat-log{
  flex:1;
  padding:calc(12 * var(--u));
  overflow-y:auto;
  overscroll-behavior:contain;
  display:flex;
  flex-direction:column;
  gap:calc(8 * var(--u));
  background:
    linear-gradient(rgba(255,255,255,.6),rgba(255,255,255,.6)),
    url('../img/lace_no_bg_0-1.webp') center/140% no-repeat;
}
.chat-empty{margin:auto;font-size:calc(13 * var(--u));color:rgba(51,0,0,.45);text-align:center}
.msg{max-width:82%;animation:noteIn .28s ease}
.msg-meta{
  display:flex;gap:calc(6 * var(--u));align-items:baseline;
  margin-bottom:calc(2 * var(--u));
  font-size:calc(11 * var(--u));
  color:rgba(51,0,0,.55);
}
.msg-name{font-weight:700;color:var(--wine)}
.msg-bubble{
  padding:calc(8 * var(--u)) calc(11 * var(--u));
  border-radius:calc(14 * var(--u));
  border-top-left-radius:calc(4 * var(--u));
  background:#fff;
  border:1px solid rgba(51,0,0,.08);
  font-size:calc(13.5 * var(--u));
  line-height:1.45;
  word-break:break-word;
}
.msg.mine{align-self:flex-end}
.msg.mine .msg-meta{justify-content:flex-end}
.msg.mine .msg-bubble{
  background:var(--wine);
  color:var(--cream);
  border-color:transparent;
  border-top-left-radius:calc(14 * var(--u));
  border-top-right-radius:calc(4 * var(--u));
}
.chat-form{padding:calc(10 * var(--u));background:rgba(255,255,255,.9);border-top:1px solid rgba(51,0,0,.08)}
.chat-name{
  width:100%;
  margin-bottom:calc(6 * var(--u));
  padding:calc(7 * var(--u)) calc(10 * var(--u));
  border:1px solid var(--line);
  border-radius:calc(999 * var(--u));
  font-family:inherit;
  font-size:calc(12.5 * var(--u));
  outline:0;
}
.chat-row{display:flex;gap:calc(8 * var(--u))}
.chat-input{
  flex:1;
  padding:calc(10 * var(--u)) calc(14 * var(--u));
  border:1px solid var(--line);
  border-radius:999px;
  font-family:inherit;
  font-size:calc(13.5 * var(--u));
  outline:0;
}
.chat-input:focus,.chat-name:focus{border-color:var(--wine)}
.chat-send{
  flex:none;
  width:calc(42 * var(--u));height:calc(42 * var(--u));
  border:0;border-radius:50%;
  background:var(--maroon);
  color:var(--cream);
  display:grid;place-items:center;
  cursor:pointer;
  transition:transform .16s ease;
}
.chat-send:hover{transform:scale(1.06)}
.chat-send svg{width:calc(18 * var(--u));height:calc(18 * var(--u));fill:currentColor}

/* --- digital envelope ---------------------------------------------------- */

.gift{display:grid;gap:calc(12 * var(--u))}
.gift-card{
  padding:calc(14 * var(--u));
  border-radius:calc(16 * var(--u));
  background:linear-gradient(150deg,#fffdf9,#f4ece2);
  border:1px solid rgba(51,0,0,.1);
  box-shadow:var(--shadow);
}
.gift-top{display:flex;align-items:center;gap:calc(10 * var(--u));margin-bottom:calc(8 * var(--u))}
.gift-logo{height:calc(22 * var(--u));width:auto}
.gift-tag{
  margin-left:auto;
  padding:calc(3 * var(--u)) calc(9 * var(--u));
  border-radius:999px;
  background:rgba(51,0,0,.08);
  font-size:calc(11 * var(--u));
  letter-spacing:.04em;
  color:var(--maroon);
}
.gift-num{
  display:flex;
  align-items:center;
  gap:calc(8 * var(--u));
  width:100%;
  padding:0;
  border:0;
  background:none;
  cursor:pointer;
  font-family:'Playfair Display',serif;
  font-size:calc(23 * var(--u));
  letter-spacing:.06em;
  color:var(--maroon);
}
.gift-num svg{width:calc(15 * var(--u));height:calc(15 * var(--u));fill:rgba(51,0,0,.45)}
.gift-holder{margin:calc(2 * var(--u)) 0 calc(10 * var(--u));font-size:calc(12.5 * var(--u));color:rgba(51,0,0,.7)}
.gift-note{margin:0;text-align:center;font-size:calc(12 * var(--u));color:rgba(255,250,243,.85)}

/* --- music button: a little record player -------------------------------- */

.music-fab,.top-fab{
  position:fixed;
  bottom:calc(16px + env(safe-area-inset-bottom));
  z-index:50;
  padding:0;border:0;
  background:none;
  cursor:pointer;
}
.music-fab{
  left:max(calc(12px + env(safe-area-inset-left)), calc(50vw - 232px));
  width:56px;height:56px;
  filter:drop-shadow(0 6px 16px rgba(0,0,0,.5));
}

/* Back to top, wearing the couple's cat. */
.top-fab{
  right:max(calc(12px + env(safe-area-inset-right)), calc(50vw - 236px));
  width:60px;height:62px;
  filter:drop-shadow(0 6px 14px rgba(0,0,0,.42));
  transition:opacity .3s ease, transform .3s ease;
}
.top-fab[hidden]{display:none}
.top-fab img{display:block;width:100%;height:100%;object-fit:contain}
.top-fab:hover{transform:translateY(-3px)}
/* A small nudge left and right, so it reads as "tap me". */
.top-fab img{animation:catShake 2.6s ease-in-out infinite}
@keyframes catShake{
  0%,62%,100%{transform:translateX(0) rotate(0)}
  68%{transform:translateX(-3px) rotate(-6deg)}
  74%{transform:translateX(3px) rotate(6deg)}
  80%{transform:translateX(-2px) rotate(-4deg)}
  86%{transform:translateX(2px) rotate(4deg)}
  92%{transform:translateX(0) rotate(0)}
}
@media (prefers-reduced-motion:reduce){.top-fab img{animation:none}}

.vinyl{
  display:block;
  width:56px;height:56px;
  border-radius:50%;
  position:relative;
  background:
    repeating-radial-gradient(circle at 50% 50%,
      #1a1a1a 0 1.5px, #242424 1.5px 3px),
    #101010;
}
.vinyl::before{
  content:'';
  position:absolute;inset:0;
  border-radius:50%;
  background:linear-gradient(118deg,
    rgba(255,255,255,.26) 0 10%, rgba(255,255,255,0) 26% 72%,
    rgba(255,255,255,.14) 90% 100%);
}
.vinyl-label{
  position:absolute;inset:32%;
  border-radius:50%;
  display:grid;place-items:center;
  background:radial-gradient(circle at 34% 28%, #fff3df, #c9995a 68%, #8c6532);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.28);
}
.vinyl-label::after{
  content:'';
  width:5px;height:5px;
  border-radius:50%;
  background:#12100e;
}
.music-fab.playing .vinyl{animation:spin 3.4s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

@media (prefers-reduced-motion:reduce){
  .music-fab.playing .vinyl{animation:none}
}

#ytHost{position:fixed;width:1px;height:1px;opacity:0;pointer-events:none;left:-9999px;top:0}

/* --- modal --------------------------------------------------------------- */

.modal{
  position:fixed;inset:0;z-index:70;
  display:grid;place-items:center;
  padding:16px;
  background:rgba(20,12,10,.6);
  backdrop-filter:blur(3px);
}
.modal[hidden]{display:none}
.modal-card{
  width:min(96vw,430px);
  max-height:88dvh;
  overflow-y:auto;
  padding:18px;
  border-radius:18px;
  background:var(--cream);
  box-shadow:0 24px 60px rgba(0,0,0,.4);
  position:relative;
}
.modal-close{
  position:absolute;top:8px;right:10px;
  width:32px;height:32px;
  border:0;border-radius:50%;
  background:rgba(51,0,0,.08);
  font-size:20px;line-height:1;
  cursor:pointer;
}
.modal-title{
  margin:0 30px 8px 0;
  font-family:'Playfair Display',serif;
  font-size:20px;font-weight:500;
  color:var(--maroon);
}
.modal-photo img{width:100%;height:auto;border-radius:12px;display:block;margin-bottom:10px}
.modal-addr{margin:0 0 12px;font-size:13.5px;line-height:1.5;color:rgba(51,0,0,.8)}
.modal-map{border-radius:12px;overflow:hidden;margin-bottom:12px;background:#e8e2d9}
.modal-map iframe{display:block;width:100%;height:210px;border:0}
.modal-map .modal-map-empty{padding:26px 14px;text-align:center;font-size:13px;color:rgba(51,0,0,.6)}
.modal-btn{
  display:block;
  padding:12px;
  border-radius:999px;
  background:var(--maroon);
  color:var(--cream);
  text-align:center;
  text-decoration:none;
  font-size:13px;
  letter-spacing:.06em;
}
.modal-btn[hidden]{display:none}

/* --- toast --------------------------------------------------------------- */

.toast{
  position:fixed;
  left:50%;bottom:76px;
  z-index:80;
  transform:translateX(-50%) translateY(10px);
  padding:10px 18px;
  border-radius:999px;
  background:rgba(51,0,0,.92);
  color:var(--cream);
  font-size:13px;
  opacity:0;
  transition:opacity .22s ease, transform .22s ease;
  pointer-events:none;
}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

/* --- desktop framing ----------------------------------------------------- */

@media (min-width:520px){
  body{
    background:
      linear-gradient(rgba(29,20,16,.55),rgba(29,20,16,.72)),
      url('../img/meina-yin-bph-hj1f09k-unsplash-1.webp') center/cover fixed no-repeat;
  }
  .canvas{border-radius:6px}
}

/* --- inserted venue section ---------------------------------------------- */

.venue{z-index:4;text-align:center}
.venue-title{
  margin:0 0 calc(14 * var(--u));
  font-family:'Playfair Display',serif;
  font-size:calc(34 * var(--u));
  font-weight:500;
  color:var(--maroon);
}

/* Photo, address and map share one card so the block reads as a single unit. */
.venue-card{
  padding:calc(10 * var(--u));
  border-radius:calc(14 * var(--u));
  background:#fff;
  box-shadow:0 calc(10 * var(--u)) calc(26 * var(--u)) rgba(51,0,0,.2);
}
.venue-photo{margin:0}
.venue-photo img{
  display:block;
  width:100%;
  height:calc(228 * var(--u));
  object-fit:cover;
  border-radius:calc(9 * var(--u));
}
.venue-photo figcaption{
  padding:calc(8 * var(--u)) calc(4 * var(--u)) calc(6 * var(--u));
  font-family:'Playfair Display',serif;
  font-size:calc(14.5 * var(--u));
  color:var(--maroon);
  line-height:1.3;
}
.venue-addr{
  display:flex;
  gap:calc(6 * var(--u));
  margin:0 0 calc(10 * var(--u));
  padding:0 calc(4 * var(--u));
  text-align:left;
  font-size:calc(12.5 * var(--u));
  line-height:1.45;
  color:rgba(51,0,0,.72);
}
.venue-addr svg{
  width:calc(14 * var(--u));height:calc(14 * var(--u));
  fill:var(--wine);flex:none;margin-top:calc(2 * var(--u));
}
.venue-map{
  border-radius:calc(9 * var(--u));
  overflow:hidden;
  background:#e8e2d9;
  box-shadow:inset 0 0 0 1px rgba(51,0,0,.1);
}
.venue-map iframe{display:block;width:100%;height:calc(210 * var(--u));border:0}
.venue-btn{margin-top:calc(14 * var(--u))}
