/* The page is the invitation: artwork, fonts and gold from the Canva PDF. */
:root {
  --gold: #9d5a00;        /* the invitation's text colour; 4.7:1 on the paper */
  --brown: #5a3a14;       /* help text, typed text */
  --error: #a33a2a;
  --font-caps: "Bellefair", Georgia, serif;
  --font-script: "Great Vibes", cursive;
  --font-amp: "Cormorant Garamond", Georgia, serif;
}

@font-face { font-family: "Bellefair"; font-display: swap; src: url("fonts/bellefair.woff2") format("woff2"); }
@font-face { font-family: "Great Vibes"; font-display: swap; src: url("fonts/great-vibes.woff2") format("woff2"); }
@font-face { font-family: "Cormorant Garamond"; font-display: swap; src: url("fonts/cormorant-garamond.woff2") format("woff2"); }

* { box-sizing: border-box; }
html { font-size: 112.5%; -webkit-text-size-adjust: 100%; }
body { font-synthesis: none; margin: 0; background: #f8f6f1 url("paper.jpg") repeat center top / 1000px auto; color: var(--gold); font-family: var(--font-caps); line-height: 1.45; }
p { margin: 0 0 0.75rem; }
a { color: var(--gold); text-underline-offset: 0.2em; }
:focus-visible { outline: 3px solid var(--brown); outline-offset: 3px; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---------- the invitation (first screen) ---------- */

/* Artwork is placed in the Canva PDF's own units (the card is 360 x 504), scaled so the
   invitation fits the first screen: 1u = the smaller of width/360 and height/504.
   Text uses its own unit, --t, a little larger, so it stays readable on phones.
   The page is one long card: top ornaments at the top, bottom ornaments at the very end. */
.page {
  /* One size for everything you read or tap in the reply section: fields, buttons, messages. */
  --control-text: max(16px, calc(13 * var(--t)));
  --u: min(100vw / 360, 100vh / 504);
  --t: min(100vw / 300, 100vh / 520);
  position: relative;
  overflow: clip;
}
/* Fills the screen, but never stretches past the card's own proportions (no empty paper on tall phones). */
.invite { position: relative; min-height: min(100vh, calc(600 * var(--u))); display: flex; flex-direction: column; justify-content: center; }
@supports (height: 100svh) {
  .page { --u: min(100vw / 360, 100svh / 504); --t: min(100vw / 300, 100svh / 520); }
  .invite { min-height: min(100svh, calc(600 * var(--u))); }
}

.art img, .art svg, .art .line { position: absolute; z-index: 0; height: auto; pointer-events: none; user-select: none; }
.defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.art .line { width: calc(1.5 * var(--u)); background: var(--gold); }
.line.left { left: calc(27.25 * var(--u)); top: calc(157 * var(--u)); bottom: calc(162 * var(--u)); }
.line.right { right: calc(27.25 * var(--u)); top: calc(150 * var(--u)); bottom: calc(164 * var(--u)); }

/* One gold corner (vector, from the PDF) used four times, mirrored. */
.art svg.gold { width: calc(144 * var(--u)); height: calc(144.27 * var(--u)); overflow: visible; }
.gold.tl { left: calc(18.8 * var(--u)); top: calc(12.6 * var(--u)); }
.gold.tr { right: calc(21.4 * var(--u)); top: calc(15.2 * var(--u)); scale: -1 1; }
.gold.bl { left: calc(18.6 * var(--u)); bottom: calc(25.1 * var(--u)); scale: 1 -1; }
.gold.br { right: calc(17.5 * var(--u)); bottom: calc(25.1 * var(--u)); scale: -1 -1; }

.flowers, .bismillah { left: 50%; translate: -50% 0; }
.flowers { width: calc(208 * var(--u)); }
.flowers.top { top: 0; transform-origin: 50% 0; }
.flowers.bottom { bottom: 0; transform-origin: 50% 100%; }
.bismillah { top: calc(73 * var(--u)); width: calc(147 * var(--u)); }

/* Top clusters pivot at the base of their stems (bottom outer corner), where the roots would be. */
.leaves.tl { top: 0; left: 0; width: calc(110 * var(--u)); transform-origin: 0 100%; }
.leaves.tr { top: 0; right: 0; width: calc(110 * var(--u)); transform-origin: 100% 100%; }
.leaves.bl { bottom: 0; left: 0; width: calc(160 * var(--u)); transform-origin: 0 100%; }
.leaves.br { bottom: 0; right: 0; width: calc(160 * var(--u)); transform-origin: 100% 100%; }

/* ---------- entrance ----------
   On load: the Bismillah is written first, on a still page. Then the gold is drawn like ink, the flowers bloom, the side lines and divider are drawn,
   then the leaves unfurl and keep swaying. The bottom ornaments do the same when scrolled to.
   Text never moves. With reduced motion everything is simply shown. */

/* Gold corners: the outline is traced (--draw 1 -> 0), then the gold fills in (--ink 0 -> 1).
   Registered so they can animate and reach the <use> copies; without support the corners just show. */
@property --draw { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --ink { syntax: "<number>"; inherits: true; initial-value: 1; }
#corner path {
  fill: var(--gold);
  fill-opacity: var(--ink);
  stroke: var(--gold);
  stroke-width: 0.5;
  stroke-opacity: calc(1 - var(--ink));
  stroke-dasharray: 1;
  stroke-dashoffset: var(--draw);
}
.gold { animation: ink 2.8s ease-in-out calc(var(--after-bismillah) + 0.1s) both; }
.gold.tr { animation-delay: calc(var(--after-bismillah) + 0.25s); }
.gold.bl, .gold.br { animation-delay: 0.2s; }
@keyframes ink {
  0% { --draw: 1; --ink: 0; }
  70% { --draw: 0; --ink: 0; }
  100% { --draw: 0; --ink: 1; }
}

/* Bismillah is written first, quickly, right to left as Arabic is written: a soft-edged
   reveal sweeps across it. Without @property support it simply shows. Everything else at the
   top starts once it is written. */
.page { --after-bismillah: 1.4s; }
@property --written { syntax: "<percentage>"; inherits: false; initial-value: 100%; }
.bismillah {
  -webkit-mask-image: linear-gradient(to left, #000 var(--written), transparent calc(var(--written) + 12%));
  mask-image: linear-gradient(to left, #000 var(--written), transparent calc(var(--written) + 12%));
  animation: write 1.3s cubic-bezier(0.4, 0, 0.6, 1) 0.15s both;
}
@keyframes write { from { --written: -12%; } to { --written: 100%; } }

/* The invitation text fades in line by line once the Bismillah is written (no movement). */
.invite-text > p, .scroll-hint { animation: fade-in 0.9s ease-out calc(var(--after-bismillah) + var(--line, 0) * 0.15s) both; }
.invite-text > :nth-child(3) { --line: 1; }
.invite-text > :nth-child(4) { --line: 2; }
.invite-text > :nth-child(5) { --line: 3; }
.invite-text > :nth-child(6) { --line: 4; }
.invite-text > :nth-child(7) { --line: 5; }
.invite-text > :nth-child(9) { --line: 7; }
.invite-text > :nth-child(10) { --line: 8; }
.invite-text > :nth-child(11) { --line: 9; }
.scroll-hint { --line: 12; }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

/* Side lines are drawn downward from the top corners; dividers outward from the middle. */
.art .line { transform-origin: 50% 0; animation: draw-down 2.4s ease-out calc(var(--after-bismillah) + 1.6s) both; }
@keyframes draw-down { from { transform: scaleY(0); } to { transform: none; } }
.divider { animation: draw-across 1.4s ease-out calc(var(--after-bismillah) + 0.9s) both; }
main .divider { animation-delay: 0.2s; }
@keyframes draw-across { from { clip-path: inset(0 50%); } to { clip-path: inset(0); } }

/* Flowers bloom from the edge they hang from. */
.flowers { animation: bloom 1.8s cubic-bezier(0.2, 0.7, 0.3, 1) calc(var(--after-bismillah) + 0.4s) both; }
.flowers.bottom { animation-delay: 0.4s; }
@keyframes bloom {
  from { opacity: 0; transform: scale(0.85); }
  to { opacity: 1; transform: none; }
}

/* Leaves: --turn makes each cluster start tucked against the screen edge and unfurl inward.
   The sway starts and ends at rest, so it picks up exactly where the entrance stops. */
.leaves { --turn: 1; --delay: calc(var(--after-bismillah) + 0.9s); animation: grow-in 1.6s cubic-bezier(0.2, 0.7, 0.3, 1) var(--delay) both, sway 8s ease-in-out calc(var(--delay) + 1.6s) infinite; }
.leaves.tr { --turn: -1; --delay: calc(var(--after-bismillah) + 1.1s); }
.leaves.bl { --turn: -1; --delay: 0.8s; }
.leaves.br { --turn: 1; --delay: 1s; }
@keyframes grow-in {
  from { opacity: 0; transform: scale(0.8) rotate(calc(var(--turn) * 8deg)); }
  to { opacity: 1; transform: none; }
}

/* Top leaves: revealed outward from their corner while they swing in, overshoot a little
   and settle, then sway. */
.leaves.tl, .leaves.tr {
  animation: unfurl 2.6s ease-out var(--delay) both, sway 8s ease-in-out calc(var(--delay) + 2.6s) infinite;
}
.leaves.tl { --origin: 0% 100%; --turn: -1; }
.leaves.tr { --origin: 100% 100%; --turn: 1; }
@keyframes unfurl {
  0% { opacity: 0.3; clip-path: circle(0% at var(--origin)); transform: rotate(calc(var(--turn) * 12deg)) scale(0.6); }
  55% { opacity: 1; clip-path: circle(110% at var(--origin)); transform: rotate(calc(var(--turn) * -2deg)) scale(1.01); }
  78% { transform: rotate(calc(var(--turn) * 0.7deg)); }
  100% { opacity: 1; clip-path: circle(150% at var(--origin)); transform: none; }
}
@keyframes sway {
  0%, 100% { transform: rotate(0deg); }
  25% { transform: rotate(calc(var(--turn) * -1.5deg)); }
  75% { transform: rotate(calc(var(--turn) * 1.5deg)); }
}

/* app.js holds each piece until its image has arrived, and the bottom ornaments until they
   are scrolled into view, so no entrance is missed. */
.js .leaves:not(.ready), .js .on-scroll:not(.in-view) { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .art .gold, .art .line, .art img, .art img.leaves, .divider, .invite-text > p, .scroll-hint { animation: none; }
  .bismillah { -webkit-mask-image: none; mask-image: none; }
}

.invite-text {
  position: relative;
  z-index: 1;
  padding: calc(131 * var(--u)) calc(44 * var(--u)) calc(64 * var(--u));
  text-align: center;
}
.invite-text p { margin: 0; }
.caps { text-transform: uppercase; letter-spacing: 0.03em; }
.invite-text .intro { font-size: calc(12 * var(--t)); line-height: 1.4; max-width: max(calc(100vw - 172 * var(--u)), 12em); margin: 0 auto calc(4 * var(--t)); }
.name { font-family: var(--font-script); font-size: calc(30 * var(--t)); line-height: 1.2; }
.parents { font-size: calc(10 * var(--t)); letter-spacing: 0.02em; }
.invite-text .amp { font-family: var(--font-amp); font-size: calc(20 * var(--t)); line-height: 1.1; margin-top: calc(4 * var(--t)); }
.invite-text .divider { display: block; height: auto; width: min(70%, 22rem); margin: calc(10 * var(--t)) auto; }
.when { font-size: calc(13 * var(--t)); line-height: 1.35; }
.when span { white-space: nowrap; }
.invite-text .venue { font-size: calc(11 * var(--t)); margin-top: calc(8 * var(--t)); }
.address { font-size: calc(11 * var(--t)); line-height: 1.35; }
/* The pin and the address are one link to the map: no underline, the pin says "map". */
.address a { display: inline-flex; align-items: center; gap: 0.35em; text-decoration: none; }
.address .pin { width: 1.25em; height: 1.25em; flex: none; }

/* Narrow screens: date and time on separate lines, no bar. */
@media (max-width: 30rem) {
  .when .bar { display: none; }
  .when span { display: block; }
}

.scroll-hint {
  position: absolute;
  z-index: 2;
  left: 50%;
  translate: -50% 0;
  bottom: max(calc(10 * var(--u)), env(safe-area-inset-bottom));
  display: flex; flex-direction: column; align-items: center;
  padding: 0.35rem 1.1rem 0.15rem;
  font-size: 0.95rem; line-height: 1.2; letter-spacing: 0.04em; text-transform: uppercase; text-decoration: none; white-space: nowrap;
  background: rgb(251 249 245 / 0.92);
  border: 1px solid var(--gold);
  border-radius: 2rem;
}
.scroll-hint[hidden] { display: none; }
/* جزاك الله خيرًا calligraphy in the Bismillah's colour, written in right to left each time it appears. */
.calligraphy {
  display: block;
  height: auto;
  margin: 0.25rem auto 0.75rem;
  -webkit-mask-image: linear-gradient(to left, #000 var(--written), transparent calc(var(--written) + 12%));
  mask-image: linear-gradient(to left, #000 var(--written), transparent calc(var(--written) + 12%));
  animation: write 1.1s cubic-bezier(0.4, 0, 0.6, 1) 0.15s both;
}
.calligraphy[hidden] { display: none; }
/* Width in the Bismillah's units (it is 147u wide), chosen so both have about the same
   stroke thickness: measured as 2 x ink area / outline length in each image. */
.jzk { width: calc(123 * var(--u)); }
/* Under the address for a returning guest, in place of "Kindly reply below". */
.invite-text .hero-thanks { margin-top: calc(14 * var(--t)); animation-delay: calc(var(--after-bismillah) + 1.8s); }
@media (prefers-reduced-motion: reduce) { .calligraphy { animation: none; -webkit-mask-image: none; mask-image: none; } }
.page.replied .invite { min-height: 0; }
/* After replying, the invitation flows straight into the reply section: only the divider's own spacing. */
.page.replied .invite-text { padding-bottom: 0; }
.page.replied .hero-thanks { margin-bottom: 0; }
.page.replied main { padding-top: 0; }
.scroll-hint span { font-size: 1.4rem; line-height: 0.8; }

/* ---------- the reply, below the invitation ---------- */

main {
  position: relative;
  z-index: 1;
  max-width: 34rem;
  margin: 0 auto;
  padding: 1rem max(1.25rem, calc(44 * var(--u))) calc(120 * var(--u));
}
main > .divider, .midway > .divider { display: block; width: 70%; height: auto; margin: 1rem auto; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }

/* Halfway flowers: the bottom cluster turned sideways so it grows in from each screen edge,
   level with the divider that starts the reply section. */
.midway { position: relative; }
.mid-flower {
  position: absolute;
  z-index: 0;
  top: 50%;                      /* centred on the divider line */
  width: calc(130 * var(--u));   /* turned sideways: 130u tall, about 62u deep */
  height: auto;
  pointer-events: none;
  translate: 0 -50%;
  animation: bloom-side 1.8s cubic-bezier(0.2, 0.7, 0.3, 1) 0.2s both;
}
/* main is centred, so 50% - 50vw is the screen edge. Turned about its centre, the stem end
   lands on the edge when the box sits 34u past it. */
.mid-flower.left { left: calc(50% - 50vw - 34 * var(--u)); rotate: 90deg; }
.mid-flower.right { right: calc(50% - 50vw - 34 * var(--u)); rotate: -90deg; }
@keyframes bloom-side { from { opacity: 0; scale: 0.6; } to { opacity: 1; scale: 1; } }
@media (prefers-reduced-motion: reduce) { .mid-flower { animation: none; } }

/* ---------- reply ---------- */

.reply { text-align: left; }
/* Same size as the couple's names. */
h2 { font-family: var(--font-script); font-weight: 400; font-size: calc(30 * var(--t)); line-height: 1.2; text-align: center; margin: 0 0 0.75rem; }
.field { margin: 0 0 1.1rem; padding: 0; border: 0; min-width: 0; }
/* Questions are the size of "Please join us…"; help text a touch smaller. */
label, legend { display: block; font-size: calc(12 * var(--t)); line-height: 1.4; text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: 0.25rem; padding: 0; }
/* The Yes/No choices are answers, not questions: normal case. */
.tile { text-transform: none; letter-spacing: 0; }
.help { color: var(--brown); font-size: calc(11 * var(--t)); margin-bottom: 0.4rem; }
.big { font-size: var(--control-text); text-align: center; }
.success, [data-rsvp-already] { font-size: var(--control-text); }
/* Same weight and colour as the text around it: Bellefair has no bold, and a faked one renders unevenly. */
.confirmed { font-weight: 400; }

/* Form controls: a little larger than the questions, never under 16px (iPhones zoom into smaller fields),
   and about 48px tall so they are easy to tap. */
input:not([type=radio]) {
  width: 100%;
  min-height: 2.7rem;
  padding: 0.35rem 0.7rem;
  font: inherit;
  font-size: var(--control-text);
  color: var(--brown);
  background: rgb(255 255 255 / 0.8);
  border: 1.5px solid var(--gold);
  border-radius: 0.3rem;
}
input[aria-invalid=true] { border: 2px solid var(--error); }

.tiles { display: grid; gap: 0.75rem; }
.tile {
  display: flex; align-items: center; gap: 0.75rem;
  min-height: 2.7rem; padding: 0.45rem 0.9rem;
  font-size: var(--control-text);
  background: rgb(255 255 255 / 0.8);
  border: 1.5px solid var(--gold); border-radius: 0.3rem;
  cursor: pointer;
}
.tile input { width: 1.15rem; height: 1.15rem; margin: 0; accent-color: var(--gold); flex: none; }
.tile:has(input:checked) { background: #f5e9d6; box-shadow: inset 0 0 0 1.5px var(--gold); }
.tile:has(input:focus-visible) { outline: 3px solid var(--brown); outline-offset: 3px; }

.stepper { display: grid; grid-template-columns: 2.9rem 1fr 2.9rem; gap: 0.5rem; }
.stepper input { text-align: center; -moz-appearance: textfield; }
.stepper input::-webkit-inner-spin-button, .stepper input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.stepper button { font-size: 1.5rem; line-height: 1; padding: 0; }
.total { font-size: calc(12 * var(--t)); margin: -0.4rem 0 1.1rem; }

button {
  min-height: 2.7rem;
  font: inherit; font-size: var(--control-text);
  text-transform: uppercase; letter-spacing: 0.06em;
  border-radius: 0.3rem;
  cursor: pointer;
}
button.primary { width: 100%; color: #fffdf8; background: var(--gold); border: 1.5px solid var(--gold); }
button.secondary { text-transform: none; letter-spacing: 0; color: var(--gold); background: rgb(255 255 255 / 0.8); border: 1.5px solid var(--gold); }
.actions button { width: 100%; }
button:disabled { opacity: 0.7; cursor: wait; }
.actions { display: grid; gap: 0.75rem; margin-top: 1rem; }

.error {
  color: var(--error); font-size: var(--control-text);
  border: 2px solid var(--error); border-radius: 0.3rem; background: #fbeeea;
  padding: 0.75rem 1rem;
}
.notice, .closed { font-size: var(--control-text); text-align: center; background: rgb(255 255 255 / 0.7); border: 1.5px solid var(--gold); border-radius: 0.3rem; padding: 0.75rem 1rem; }

.success { text-align: center; }
.check {
  width: 3.5rem; height: 3.5rem; margin: 0 auto 1rem;
  display: grid; place-items: center;
  font-size: 2rem; color: #fffdf8; background: var(--gold); border-radius: 50%;
}

.contact { font-size: var(--control-text); line-height: 1.7; text-align: center; margin: 2rem 0 0; }
.contact a { white-space: nowrap; }

/* Shown after "Yes" while the count questions are still below the screen. */
.more-below {
  position: fixed;
  z-index: 10;
  left: 50%;
  translate: -50% 0;
  bottom: max(1rem, env(safe-area-inset-bottom));
  display: flex; flex-direction: column; align-items: center;
  min-height: 0;
  padding: 0.6rem 1.4rem 0.35rem;
  font-size: var(--control-text); line-height: 1.2; letter-spacing: 0.03em; text-transform: none; white-space: nowrap;
  color: #fffdf8; background: var(--gold);
  border: 0; border-radius: 2rem;
  box-shadow: 0 4px 16px rgb(60 40 10 / 0.3);
  animation: fade-in 0.4s ease-out both;
}
.more-below span { font-size: 1.5rem; line-height: 0.8; }
.more-below[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .more-below { animation: none; } }

/* Honeypot: off-screen for people, still in the form for bots. */
.hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
