/* ---------- Fonts (self-hosted) ---------- */
@font-face { font-family: 'Playfair Display SC'; src: url('../assets/fonts/playfair-display-sc-400.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Lora'; src: url('../assets/fonts/lora-400-500.woff2') format('woff2'); font-weight: 400 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Lora'; src: url('../assets/fonts/lora-italic-400.woff2') format('woff2'); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: 'Amiri'; src: url('../assets/fonts/amiri-subset.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }

/* ---------- Tokens ---------- */
:root {
  color-scheme: light;
  --paper: #E7DECB;
  --envelope: #DCD0B8;
  --ink: #64584A;          /* all normal text: 5.17:1 on paper */
  --ink-display: #7A6D5C;  /* text >= 24px only: 3.77:1 */
  --seal: #A8916B;         /* ornaments only, never text */
  --leaf: #9DB08A;
  --blush: #D8B7AB;
  --card: #FBF8F2;
  --font-display: 'Playfair Display SC', 'Times New Roman', serif;
  --font-body: 'Lora', Georgia, serif;
  --font-arabic: 'Amiri', 'Geeza Pro', 'Traditional Arabic', serif;
  --gutter: 20px;
  --column: 430px;
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .39 0 0 0 0 .35 0 0 0 0 .29 0 0 0 .08 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 17px/1.6 var(--font-body);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; height: auto; }
p { margin: 0; }
h1, h2 { margin: 0; font-weight: 400; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}
.js-only { display: none !important; }
.js .no-js-only { display: none; }
.js .js-only { display: revert !important; }
.js .btn.js-only { display: inline-flex !important; }
.js .countdown__grid.js-only { display: grid !important; }

/* ---------- Page column ---------- */
.page {
  position: relative;
  max-width: var(--column);
  margin-inline: auto;
  background: var(--paper);
  overflow-x: hidden;       /* fallback: Safari < 16, older webviews */
  overflow-x: clip;
  outline: none;
  isolation: isolate;        /* florals (z-index:-1) multiply onto the paper, under the text */
}
.page::after {               /* paper grain over the whole column */
  content: "";
  position: absolute; inset: 0;
  background-image: var(--grain);
  mix-blend-mode: multiply;
  pointer-events: none;
}

.section {
  position: relative;
  min-height: 100vh;        /* fallback for browsers without svh */
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: max(64px, env(safe-area-inset-top)) max(var(--gutter), env(safe-area-inset-right)) 64px max(var(--gutter), env(safe-area-inset-left));
  text-align: center;
}
.measure { max-width: 60ch; }
.stack {                     /* a group inside a section, laid out like the section itself */
  display: flex; flex-direction: column; align-items: center; gap: 12px;
}

/* ---------- Type ---------- */
.display {
  font-family: var(--font-display);
  color: var(--ink-display);
  line-height: 1.15;
}
.display-sm {               /* 20px small-caps lines: hosts, venue, closing names */
  font-family: var(--font-display);
  font-size: 20px;
  line-height: 1.3;
  color: var(--ink);
}
.family { font-size: 15px; line-height: 1.55; max-width: 34ch; }
.divider { width: 180px; margin-block: 12px; }

/* 1 · Intro */
.intro { padding-top: max(calc(min(100vw, var(--column)) * .55), env(safe-area-inset-top)); } /* clear the vine */
.bismillah__img { width: min(300px, 80vw); margin-inline: auto; }
.bismillah__text { font-family: var(--font-arabic); font-size: 30px; line-height: 1.8; }
.bismillah__en { font-style: italic; font-size: 15px; max-width: 30ch; }
.wording { font-style: italic; max-width: 30ch; }

/* 2 · Couple */
.couple { padding-bottom: max(64px, calc(min(100vw, var(--column)) * .47)); } /* clear the bouquet */
.couple__name { font-size: 34px; }
.couple__with { font-size: 24px; letter-spacing: .3em; margin-block: 8px; }

/* 3 · Date + venue */
.date { display: flex; align-items: center; justify-content: center; gap: 14px; }
.date__side { font-size: 24px; border-block: 1px solid currentColor; padding: 2px 10px; white-space: nowrap; }
.date__day { font-size: 72px; line-height: 1; }
@media (max-width: 359px) {
  .date { gap: 6px; }
  .date__side { padding: 2px 4px; }
  .date__day { font-size: 56px; }
}
.date__month { font-size: 24px; letter-spacing: .12em; margin-bottom: 12px; }
.venue__at { font-style: italic; }

/* 4 · Countdown + closing */
.countdown__title { font-style: italic; font-size: 20px; }
.countdown__grid { grid-template-columns: repeat(4, minmax(56px, 1fr)); gap: 8px; width: 100%; max-width: 340px; }
.countdown__cell { display: flex; flex-direction: column; align-items: center; }
.countdown__num {
  font-family: var(--font-display);
  font-size: 34px;
  line-height: 1.1;
  color: var(--ink-display);
  font-variant-numeric: tabular-nums lining-nums;
}
.countdown__label { font-size: 13px; letter-spacing: .08em; text-transform: uppercase; }
@media (max-width: 359px) {
  .countdown__grid { gap: 4px; }
  .countdown__label { font-size: 12px; letter-spacing: .04em; }
}
.countdown__done { font-style: italic; font-size: 20px; }
.inshallah { font-family: var(--font-arabic); font-size: 26px; line-height: 1.8; margin-top: 12px; }
.closing__line { font-style: italic; max-width: 30ch; }
.closing__label { font-size: 15px; letter-spacing: .08em; text-transform: uppercase; margin-top: 8px; }

/* 5 · Summary card */
.summary { min-height: auto; padding-bottom: max(96px, calc(64px + env(safe-area-inset-bottom))); }
.summary__card {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  width: 100%;
  padding: 24px 20px 28px;
  border: 1px solid rgba(100, 88, 74, .35);
  border-radius: 6px;
  background: rgba(251, 248, 242, .45);
}
.summary__name { font-size: 28px; }
.summary__with { font-size: 16px; letter-spacing: .3em; color: var(--ink); }
.summary__date { margin-top: 12px; font-weight: 500; }
.summary__venue { font-size: 15px; }
.summary__qr { width: 160px; margin-top: 12px; border-radius: 4px; }
.summary__qr-label { font-size: 13px; letter-spacing: .08em; text-transform: uppercase; margin-bottom: 8px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; min-width: 44px;
  margin-top: 8px;
  padding: 0 24px;
  border: 1px solid var(--ink);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  font: 500 15px/1 var(--font-body);
  letter-spacing: .02em;
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
  transition: background-color .18s ease-out, color .18s ease-out, transform .15s ease-out;
}
.btn:active { transform: scale(.97); }
@media (hover: hover) { .btn:hover { background: var(--ink); color: var(--paper); } }
.btn--block { width: 100%; }

/* ---------- Florals ---------- */
.floral { position: absolute; z-index: -1; mix-blend-mode: multiply; pointer-events: none; }
.floral--vine {
  top: 0; right: -36px; width: 46%;
  -webkit-mask-image: linear-gradient(to bottom, #000 70%, transparent);
  mask-image: linear-gradient(to bottom, #000 70%, transparent);
}
.floral--bouquet {            /* landscape artwork (480x364) */
  bottom: 0; left: -40px; width: 62%;
  -webkit-mask-image: linear-gradient(to bottom, #000 80%, transparent);
  mask-image: linear-gradient(to bottom, #000 80%, transparent);
}

/* ---------- Desktop ---------- */
.backdrop { display: none; }
@media (min-width: 600px) {
  body { background: #DDD3BE; }
  .backdrop {
    display: block;
    position: fixed; inset: -40px;
    background:
      url('../assets/img/vine.webp') right 4% top 0 / 360px auto no-repeat,
      url('../assets/img/bouquet.webp') left 4% bottom 0 / 440px auto no-repeat;
    filter: blur(14px);
    opacity: .5;
    mix-blend-mode: multiply;
  }
  .page { box-shadow: 0 0 60px rgba(100, 88, 74, .18); }
}

/* ---------- Landscape phones: don't force full-height sections ---------- */
@media (orientation: landscape) and (max-height: 500px) {
  .section { min-height: auto; }
  .section:not(.intro):not(.couple):not(.summary) { padding-block: 48px; }
  .scroll-hint { background: none; padding-top: 0; }
}

/* ---------- Envelope ---------- */
/* Follows the reference site: seal pops (0.5 s), the closed envelope holds until 1.5 s,
   then the base fades (0.3 s) and the four flaps slide off-screen (1.5 s). invite.js
   removes the envelope at 3 s (FLAP_DELAY_MS + FLAP_MS). */
.envelope { display: none; }
.sealed, .sealed body { overflow: hidden; }
.sealed .envelope {
  position: fixed; inset: 0; z-index: 40;
  display: block;
  overflow: hidden;
  overscroll-behavior: contain; touch-action: none;
}
.envelope::before {          /* base fill, shows through nothing until the flaps part */
  content: "";
  position: absolute; inset: 0;
  background: var(--envelope);
}
.envelope__flap {
  position: absolute; inset: 0;
  transition: transform 1.5s cubic-bezier(.42, 0, .58, 1) 1.5s; /* ease-in-out, after the hold */
}
.envelope__flap--left   { background: #D6CAB0; clip-path: polygon(0 0, 0 100%, 52% 50%); }
.envelope__flap--right  { background: #D6CAB0; clip-path: polygon(100% 0, 100% 100%, 48% 50%); }
/* The top flap's V (apex 60% down) overlaps the bottom one (apex 35% down), as on the reference. */
.envelope__flap--bottom { background: #E0D5BF; clip-path: polygon(-50% 100%, 150% 100%, 50% 35%); }
.envelope__flap--top    { background: var(--envelope); clip-path: polygon(-50% 0, 150% 0, 50% 60%);
                          filter: drop-shadow(0 2px 0 rgba(100, 88, 74, .12)); }
.envelope__seal {
  position: absolute; z-index: 2;
  top: calc(60% - 2rem - 60px);  /* centred just above the top flap's apex */
  left: calc(50% - 60px);
  width: 120px; height: 120px;
  padding: 0; border: 0; border-radius: 50%;
  background: none;
  cursor: pointer;
  filter: drop-shadow(0 4px 6px rgba(100, 88, 74, .35));
  transition: transform .2s ease-out;
}
@media (hover: hover) { .envelope__seal:hover { transform: scale(1.05); } }
.envelope__seal:active { transform: scale(.95); }
.envelope__seal svg { width: 100%; height: 100%; }
.envelope__hint {
  position: absolute; z-index: 2;
  bottom: calc(40px + env(safe-area-inset-bottom));
  left: 0; right: 0;
  text-align: center;
  font-style: italic;
}
.envelope.is-opening { pointer-events: none; }
.envelope.is-opening::before { opacity: 0; transition: opacity .3s ease 1.5s; }
.envelope.is-opening .envelope__seal { opacity: 0; transform: scale(1.5); transition: transform .5s ease-in, opacity .5s ease-in; }
.envelope.is-opening .envelope__hint { opacity: 0; transition: opacity .3s ease-in; }
.envelope.is-opening .envelope__flap--left   { transform: translateX(-100%); }
.envelope.is-opening .envelope__flap--right  { transform: translateX(100%); }
.envelope.is-opening .envelope__flap--top    { transform: translateY(-100%); }
.envelope.is-opening .envelope__flap--bottom { transform: translateY(100%); }

/* ---------- Section reveal ---------- */
/* As on the reference site: each section rises, unblurs and fades in once, when ~35% of it
   is in view (invite.js adds .is-visible). Sections are isolated on their own paper so the
   multiply-blended florals look the same while the section is translucent or blurred; the
   clip (a no-op once settled: .page already clips at the same edges) keeps their white
   backgrounds from showing past a scaled-down section's edge. */
.reveal { isolation: isolate; background: var(--paper); overflow: hidden; overflow: clip; }
.js .reveal {
  opacity: 0;
  transform: translateY(80px) scale(.96);
  filter: blur(10px);
  transition: opacity .95s cubic-bezier(.22, 1, .36, 1), transform .95s cubic-bezier(.22, 1, .36, 1), filter .95s cubic-bezier(.22, 1, .36, 1);
}
.js .reveal.is-visible { opacity: 1; transform: none; filter: none; }
.js .reveal.is-revealing { will-change: transform, opacity, filter; } /* only while it animates */

/* Inner reveals, stacked on the section's: data-reveal="up|scale|fade", optional --d delay. */
.js [data-reveal] {
  opacity: 0;
  transition: opacity var(--dur, .8s) var(--ease, ease) var(--d, 0s), transform var(--dur, .8s) var(--ease, ease) var(--d, 0s);
}
.js [data-reveal="up"]    { transform: translateY(var(--y, 30px)); }
.js [data-reveal="scale"] { transform: scale(var(--s, .9)); }
.js .is-visible [data-reveal] { opacity: 1; transform: none; }
.intro__inner    { --dur: 1s; }
.couple__inner   { --y: 40px; }
.countdown__cell { --s: .8; --dur: .5s; }
.countdown__title { --dur: .8s; }
.inshallah       { --dur: 1s; }
.closing__lines  { --y: 15px; --dur: 1s; }
.floral--bouquet { --s: .8; --dur: 1.2s; --ease: ease-out; }

/* Couple names: bride, "with", groom, 150 ms apart. */
.js .stagger { opacity: 0; transition: opacity .5s ease-out; }
.js .is-visible .stagger { opacity: 1; }
.js .is-visible .couple__with { transition-delay: 150ms; }
.js .is-visible .couple__name ~ .couple__name { transition-delay: 300ms; }

/* ---------- Glow ---------- */
/* Slow warm-gold pulse on the date "28" and the couple "with" (reference: glowPulse 5.5 s). */
.glow { animation: glow 5.5s ease-in-out infinite; }
.js .reveal:not(.is-visible) .glow { animation-play-state: paused; }
@keyframes glow {
  0%, 100% { filter: drop-shadow(0 0 0 rgba(168, 145, 107, 0)) drop-shadow(0 0 22px rgba(168, 145, 107, .08)); }
  50%      { filter: drop-shadow(0 0 12px rgba(168, 145, 107, .45)) drop-shadow(0 0 30px rgba(216, 183, 171, .3)); }
}

/* ---------- Scroll hint ---------- */
.scroll-hint {
  position: fixed; z-index: 20;
  left: 0; right: 0; bottom: 0;
  max-width: var(--column);
  margin-inline: auto;
  background: linear-gradient(to top, var(--paper) 45%, transparent);
  padding-top: 12px;
  padding-bottom: calc(16px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; align-items: center;
  font-size: 14px; font-style: italic; letter-spacing: .04em;
  opacity: 0;
  pointer-events: none;
  transition: opacity 1s ease-out .5s;     /* reference: fade 1 s after a 0.5 s delay */
}
.scroll-hint.is-shown { opacity: 1; }
.scroll-hint:not(.is-shown) * { animation-play-state: paused; }
.scroll-hint__text {                      /* gold shimmer sweeping across the ink */
  background: linear-gradient(90deg, var(--ink), var(--seal), var(--ink)) 0 50% / 200% auto;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: shimmer 3s ease-in-out infinite;
}
@keyframes shimmer { from { background-position: -200% 50%; } to { background-position: 200% 50%; } }
.scroll-hint__arrow { font-style: normal; font-size: 20px; line-height: 1; animation: bob 2s ease-in-out infinite; }
@keyframes bob { 50% { transform: translateY(6px); } }

/* ---------- Calendar dialog (bottom sheet) ---------- */
.sheet {
  width: min(100%, var(--column));
  max-width: none;
  margin: auto auto 0;
  padding: 0;
  border: 0;
  border-radius: 16px 16px 0 0;
  background: var(--card);
  color: var(--ink);
}
.sheet::backdrop { background: rgba(60, 52, 42, .45); }
.sheet[open] { animation: sheet-in .25s ease-out; }
.sheet[open]::backdrop { animation: fade-in .25s ease-out; }
@keyframes sheet-in { from { transform: translateY(100%); } }
@keyframes sheet-in-centred { from { opacity: 0; transform: translateY(16px); } }
@keyframes fade-in { from { opacity: 0; } }
.sheet__body {
  display: flex; flex-direction: column; gap: 12px;
  padding: 24px var(--gutter) calc(20px + env(safe-area-inset-bottom));
}
.sheet__title { font-family: var(--font-display); font-size: 22px; text-align: center; margin-bottom: 4px; }
.sheet__close {
  min-height: 44px;
  border: 0; background: none;
  color: var(--ink);
  font: italic 15px var(--font-body);
  text-decoration: underline;
  cursor: pointer;
}
@media (min-width: 600px) {
  .sheet { margin: auto; border-radius: 16px; width: 360px; }
  .sheet[open] { animation-name: sheet-in-centred; }
}

/* ---------- Petals ---------- */
/* 8 petals falling through the viewport forever (reference keyframes): y -100px -> 100vh,
   x through [0, sway, drift, -0.6 sway, 0], one extra turn, scale [.9 1 .95 1], opacity
   [0 .75 .85 0]. Each channel is its own property, so its stops interpolate independently. */
.petals { position: fixed; inset: 0; z-index: 30; overflow: hidden; pointer-events: none; }
.petal {
  position: absolute;
  top: -50px;
  left: var(--x);
  width: var(--size);
  height: var(--size);
  fill-opacity: .85;
  opacity: 0;
  animation: petal-fall var(--dur) linear var(--delay) infinite both;
}
.petals.is-paused .petal { animation-play-state: paused; }
@keyframes petal-fall {
  0%      { translate: 0 -100px;                                       rotate: var(--r0); scale: .9;  opacity: 0; }
  25%     { translate: var(--sway) calc((100vh + 100px) * .25 - 100px); }
  33.333% {                                                                               scale: 1;   opacity: .75; }
  50%     { translate: var(--drift) calc((100vh + 100px) * .5 - 100px); }
  66.667% {                                                                               scale: .95; opacity: .85; }
  75%     { translate: calc(var(--sway) * -.6) calc((100vh + 100px) * .75 - 100px); }
  100%    { translate: 0 100vh;                rotate: calc(var(--r0) + 360deg);  scale: 1;   opacity: 0; }
}

/* ---------- Print / PDF ---------- */
@media print {
  .js .reveal, .js [data-reveal], .js .stagger { opacity: 1 !important; transform: none !important; filter: none !important; transition: none !important; }
  .petals, .scroll-hint, .envelope { display: none !important; }
  .sealed, .sealed body { overflow: visible !important; }
}

/* ---------- Reduced motion ---------- */
/* Last, so it overrides every animation above. */
@media (prefers-reduced-motion: reduce) {
  .js .reveal, .js [data-reveal], .js .stagger { opacity: 1; transform: none; filter: none; transition: none; }
  .scroll-hint__arrow, .scroll-hint__text, .glow { animation: none; }
  .scroll-hint__text { background: none; color: inherit; -webkit-text-fill-color: currentColor; }
  .scroll-hint { transition: none; }
  .petals { display: none; }
  .sheet[open], .sheet[open]::backdrop { animation: none; }
}
