/* style.css: all styles for wedding template Pro-11 (index.html). Mobile-first,
   min-width queries only (481 / 769). Class names are shared with script.js,
   which drives the stop-motion actors by writing their transforms each tick.
   Stop-motion rule of the whole page: motion holds poses and snaps between them
   (steps(), 12fps), never glides. That is what makes it read as handmade. */

@font-face {
  font-family: 'Zviadi';
  src: url('fonts/zviadi.woff2') format('woff2');
  font-weight: 400;
  font-display: block;   /* safe only because the loader covers the block period */
}
/* Secondary face: a light calligraphic serif. Its stroke contrast reads as
   "formal invitation" beside the casual pen hand of Zviadi, so the two set
   each other off. Used for dates, event names and supporting lines; BPG Nino
   stays for the functional UI (form, buttons, links). */
@font-face {
  font-family: 'Irubaqidze';
  src: url('fonts/irubaqidze.woff2') format('woff2');
  font-weight: 400;
  font-display: block;
}
@font-face {
  font-family: 'Nino';
  src: url('fonts/nino.woff2') format('woff2');
  font-weight: 500;
  font-display: block;
}

/* Every colour is sampled from the hero painting: --paper is its exact bottom
   edge (the hero melts into the countdown), --sky its sky, --lav the spire
   shadows, --gold the crosses. */
:root {
  --vh: 1vh;                       /* JS off = original value */
  --paper: #f0f1f6;
  --sky: #e4f0f2;
  --card: #fffdf8;
  --ink: #3a425c;
  --ink-soft: #626a86;
  --lav: #9c98c4;
  --lav-pale: #d9d8ea;
  --accent: #625e9a;               /* buttons + focus; white text on it passes AA */
  --gold: #d6b26a;
  --blush: #e9b4b8;
  --sage: #b5c99a;
  --shadow: rgba(78, 80, 128, 0.16);
  --serif: 'Irubaqidze', 'Nino', serif;
}

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

html, body { overscroll-behavior-y: none; }
html {
  background-color: var(--paper);
  -webkit-text-size-adjust: 100%;
  /* scrollbar starts invisible during the intro, fades in once scrolling unlocks */
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
  transition: scrollbar-color 0.8s ease;
}
html.can-scroll { scrollbar-color: var(--lav) var(--paper); }
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background-color: var(--paper); }
::-webkit-scrollbar-thumb { background-color: transparent; border-radius: 6px; transition: background-color 0.8s ease; }
html.can-scroll ::-webkit-scrollbar-thumb { background-color: var(--lav); }

body {
  font-family: 'Nino', 'Noto Sans Georgian', sans-serif;
  font-weight: 500;
  color: var(--ink);
  background-color: var(--paper);
  line-height: 1.6;
  overflow-x: hidden;
}

/* Intro lock: JS traps the gesture. Never position:fixed / overflow:hidden on the
   document, Chrome iOS from a chat app then freezes its viewport short. */
html.is-locked, body.is-locked { overscroll-behavior: none; touch-action: none; }

img { display: block; max-width: 100%; height: auto; }

/* Stamps, sliding tickets and the lane cars all poke past the sides on
   purpose. clip (not hidden) trims that sideways spill without making <main> a
   scroll container, so the torn-paper seams and the hearts still draw above
   their sections. */
main { overflow-x: clip; }
a { color: inherit; }
button, input { font: inherit; color: inherit; }

/* ===== Loader ===== */
.loader {
  position: fixed;
  inset: 0;
  z-index: 20000;                  /* above every overlay on the page */
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #ecf6f7;
  transition: opacity 0.7s ease;
}
.loader.is-done { opacity: 0; pointer-events: none; }
.loader.is-gone { display: none; }
.loader__ring {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 3px solid var(--lav-pale);
  border-top-color: var(--ink);
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Display script (DM Zviadi): a thin monoline hand, so a stroke in the text's
   own colour thickens it to the weight of the brush-lettered save-the-date. */
.hero__names, .clock__num, .ticket__time, .rsvp__thanks-text, .footer__name {
  -webkit-text-stroke: 0.6px currentColor;
}

/* ===== Stop-motion helpers ===== */
/* Boil: a still drawing re-traced every few frames never sits perfectly still.
   Animates `transform` only, so it stacks with .reveal (which uses `translate`). */
@keyframes boil {
  0%   { transform: translate(0, 0) rotate(0deg); }
  33%  { transform: translate(0.6px, -0.5px) rotate(-0.5deg); }
  66%  { transform: translate(-0.5px, 0.5px) rotate(0.4deg); }
}
.boil { animation: boil 0.75s steps(1) infinite; }

/* Pop-in on 12fps frames: small, overshoot, settle. */
@keyframes pop {
  0%   { transform: scale(0.3); }
  25%  { transform: scale(1.18); }
  50%  { transform: scale(0.92); }
  75%  { transform: scale(1.03); }
  100% { transform: scale(1); }
}

/* Scroll reveal, stepped like everything else (4 frames instead of a glide). */
.reveal {
  opacity: 0;
  translate: 0 18px;
  transition: opacity 0.5s steps(4) var(--d, 0s), translate 0.5s steps(4) var(--d, 0s);
}
.reveal.is-in { opacity: 1; translate: 0 0; }

/* ===== Hero ===== */
.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  overflow: hidden;
  background-color: #ecf6f7;
}
.vh-lock .hero { min-height: calc(var(--vh) * 100); }

/* The painting's aspect box, covering the hero and anchored to its bottom so the
   plaza (where the car parks) never crops. Tall phones crop the sides, wide
   screens crop the sky. */
.stage {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: max(100%, 56.28vh);
  aspect-ratio: 941 / 1672;
  transform: translateX(-50%);
}
.vh-lock .stage { width: max(100%, calc(var(--vh) * 56.28)); }
.stage__bg { position: absolute; inset: 0; width: 100%; height: 100%; }

/* Positions below are % of the painting: the door is at x 50.4%, its sill at
   y 80.7%; the plaza runs from ~82% down. */
.std {
  position: absolute;
  left: 50%;
  top: 8.2%;
  width: 26.5%;
  aspect-ratio: 520 / 787;
  transform: translateX(-50%) rotate(-3deg);
  z-index: 1;
}
.car {
  position: absolute;
  left: 24%;
  bottom: 6.6%;
  width: 52%;
  aspect-ratio: 960 / 355;
  z-index: 3;                      /* above the couple: they climb in from behind it */
  transform-origin: 50% 100%;
  visibility: hidden;
}
.car img { position: absolute; inset: 0; width: 100%; height: 100%; }
.car__full, .car.is-full .car__empty { visibility: hidden; }
.car.is-full .car__full { visibility: visible; }

.couple {
  position: absolute;
  left: 0;
  top: 0;
  width: 9.3%;
  aspect-ratio: 300 / 369;
  z-index: 2;
  background-image: url('img/couple.webp');
  background-size: 400% 100%;
  background-repeat: no-repeat;
  transform-origin: 50% 100%;
  visibility: hidden;
}
.couple[data-f="1"] { background-position: 33.333% 0; }
.couple[data-f="2"] { background-position: 66.667% 0; }
.couple[data-f="3"] { background-position: 100% 0; }

.hero__text {
  position: absolute;
  left: 0;
  right: 0;
  top: 84.5%;
  z-index: 4;
  text-align: center;
  padding: 0 16px;
}
.hero__names {
  font-family: 'Zviadi', 'Nino', sans-serif;
  font-weight: 400;
  font-size: 38px;
  line-height: 1.25;
  color: var(--ink);
}
.hero__names .ch { display: inline-block; visibility: hidden; }
.hero__names .ch.is-on { visibility: visible; animation: pop 0.42s steps(1) both; }
.hero__names .ch--space { width: 0.28em; }
.hero__date {
  margin-top: 4px;
  font-family: var(--serif);
  font-size: 18px;
  color: #535b78;
  opacity: 0;
  transition: opacity 0.5s steps(4);
}
.hero__date.is-on { opacity: 1; }
.hero.is-still .hero__names .ch { visibility: visible; }
.hero.is-still .hero__date { opacity: 1; }

.fx {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 5;
  pointer-events: none;
}

.hero__hint {
  position: absolute;
  left: 50%;
  bottom: calc(10px + env(safe-area-inset-bottom));
  z-index: 6;
  width: 40px;
  height: 40px;
  margin-left: -20px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background-color: rgba(255, 253, 248, 0.75);
  box-shadow: 0 4px 12px var(--shadow);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s steps(3);
}
.hero__hint svg { width: 20px; height: 20px; fill: var(--ink); }
.hero__hint.is-on { opacity: 1; pointer-events: auto; animation: bob 1.2s steps(1) infinite; }
@keyframes bob {
  0%  { transform: translateY(0); }
  25% { transform: translateY(3px); }
  50% { transform: translateY(5px); }
  75% { transform: translateY(2px); }
}

/* ===== Sections ===== */
.section {
  position: relative;
  padding: 64px 20px 72px;
  text-align: center;
}
/* Section titles use the serif, so the script stays special: it belongs to
   the couple's names and the numbers only. */
.title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 32px;
  letter-spacing: 0.02em;
  line-height: 1.3;
  color: var(--ink);
}

/* Torn-paper seam: the next section's colour tears up over the previous one,
   with a lavender shadow line along the rip, like a cut-out sheet laid on top. */
.plan::before, .plan::after,
.rsvp::before, .rsvp::after,
.footer::before, .footer::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  height: 26px;
  pointer-events: none;
  -webkit-mask: url('img/edge.svg') 0 0 / 600px 26px repeat-x;
  mask: url('img/edge.svg') 0 0 / 600px 26px repeat-x;
}
.plan::before, .rsvp::before, .footer::before { top: -24px; z-index: 1; }
.plan::after, .rsvp::after, .footer::after { top: -27px; z-index: 0; background-color: rgba(98, 94, 154, 0.22); }
.plan::before { background-color: var(--sky); }
.rsvp::before { background-color: var(--paper); -webkit-mask-position: 230px 0; mask-position: 230px 0; }
.rsvp::after { -webkit-mask-position: 230px 0; mask-position: 230px 0; }
.footer::before { background-color: var(--ink); -webkit-mask-position: 410px 0; mask-position: 410px 0; }
.footer::after { -webkit-mask-position: 410px 0; mask-position: 410px 0; }

/* ===== Countdown ===== */
.count { background-color: var(--paper); padding-top: 40px; padding-bottom: 36px; }
/* The countdown ticket reuses .ticket (wrapper shadow, slide-in, stamp slam,
   jolt). Only the paper differs: four equal stubs with a perforation and a
   pair of punched notches at every tear line. */
.ticket--count { max-width: 360px; margin: 40px auto 0; }
.ticket--count .ticket__paper {
  grid-template-columns: repeat(4, 1fr);
  min-height: 118px;
  -webkit-mask:
    radial-gradient(circle 9px at 25% 0, transparent 8.5px, #000 9px),
    radial-gradient(circle 9px at 25% 100%, transparent 8.5px, #000 9px),
    radial-gradient(circle 9px at 50% 0, transparent 8.5px, #000 9px),
    radial-gradient(circle 9px at 50% 100%, transparent 8.5px, #000 9px),
    radial-gradient(circle 9px at 75% 0, transparent 8.5px, #000 9px),
    radial-gradient(circle 9px at 75% 100%, transparent 8.5px, #000 9px);
  -webkit-mask-composite: source-in;
  mask:
    radial-gradient(circle 9px at 25% 0, transparent 8.5px, #000 9px),
    radial-gradient(circle 9px at 25% 100%, transparent 8.5px, #000 9px),
    radial-gradient(circle 9px at 50% 0, transparent 8.5px, #000 9px),
    radial-gradient(circle 9px at 50% 100%, transparent 8.5px, #000 9px),
    radial-gradient(circle 9px at 75% 0, transparent 8.5px, #000 9px),
    radial-gradient(circle 9px at 75% 100%, transparent 8.5px, #000 9px);
  mask-composite: intersect;
}
.ticket--count .ticket__stamp { right: -6px; top: -40px; width: 64px; height: 64px; }
.clock__cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 14px 2px 12px;
  border-right: 2px dashed #cfcde6;       /* the perforation */
}
.clock__cell:first-child { background-color: #ecebf6; }   /* the days stub, tinted like the timetable stubs */
.clock__cell:last-child { border-right: 0; }
.clock__num {
  font-family: 'Zviadi', 'Nino', sans-serif;
  font-size: 34px;
  line-height: 1.1;
  color: var(--accent);
}
/* The tick: up, stretch, squash, settle, on held 12fps frames. */
.clock__num.is-hop { animation: hop 0.42s steps(1); }
@keyframes hop {
  0%   { transform: translateY(0); }
  20%  { transform: translateY(-8px) scaleY(1.06); }
  40%  { transform: translateY(-4px); }
  60%  { transform: translateY(1px) scaleY(0.92); }
  80%  { transform: translateY(0) scaleY(1.03); }
  100% { transform: translateY(0); }
}
.clock__lbl { margin-top: 6px; font-family: var(--serif); font-size: 15px; color: #535b78; }
.count__date { margin-top: 22px; font-family: var(--serif); font-size: 18px; color: var(--ink); }
.count__text {
  max-width: 300px;
  margin: 10px auto 0;
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.55;
  color: #535b78;
}

/* ===== Drive-by lanes =====
   A strip with a painted ground line; script.js drives the couple across it,
   left to right, whenever the lane is on screen (then again every so often). */
.lane {
  position: relative;
  height: 124px;                   /* 78px of road + 46px of headroom for the heart */
  margin: -20px -20px 0;           /* the headroom overlaps the content above, so layout spacing is unchanged */
  overflow: hidden;                /* hides the car while it waits off either edge */
  pointer-events: none;
}
.lane--top { margin: -70px -20px 18px; }
.lane__ground {
  position: absolute;
  left: 8%;
  right: 8%;
  bottom: 10px;
  height: 7px;
  background-color: #d6d5e8;
  -webkit-mask: url('img/edge.svg') 0 0 / 260px 7px repeat-x;
  mask: url('img/edge.svg') 0 0 / 260px 7px repeat-x;
}
.lane__car {
  position: absolute;
  left: 0;
  bottom: 12px;
  width: 136px;
  visibility: hidden;
  filter: drop-shadow(0 3px 3px rgba(78, 80, 128, 0.18));
}
.lane__car.is-on { visibility: visible; }
.lane__car img { width: 100%; }
.lane--rtl .lane__car img { transform: scaleX(-1); }          /* the art faces right */
.lane__heart {
  position: absolute;
  left: 44%;
  top: -12px;
  width: 16px;
  height: 14px;
  background-color: #e8a3ab;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 22'%3E%3Cpath d='M12 21.5C5 16.2 0 11.9 0 6.9 0 3 3 0 6.7 0c2.2 0 4.2 1.1 5.3 2.8C13.1 1.1 15.1 0 17.3 0 21 0 24 3 24 6.9c0 5-5 9.3-12 14.6z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 22'%3E%3Cpath d='M12 21.5C5 16.2 0 11.9 0 6.9 0 3 3 0 6.7 0c2.2 0 4.2 1.1 5.3 2.8C13.1 1.1 15.1 0 17.3 0 21 0 24 3 24 6.9c0 5-5 9.3-12 14.6z'/%3E%3C/svg%3E") center / contain no-repeat;
  visibility: hidden;
}
.lane__heart.is-on { visibility: visible; animation: heart-up 1s steps(1) both; }
@keyframes heart-up {
  0%   { transform: translateY(6px) scale(0.4); opacity: 1; }
  17%  { transform: translateY(0) scale(1.15); }
  33%  { transform: translateY(-8px) scale(1) rotate(-8deg); }
  50%  { transform: translateY(-16px) scale(1) rotate(6deg); }
  67%  { transform: translateY(-24px) scale(0.95) rotate(-6deg); opacity: 0.8; }
  83%  { transform: translateY(-31px) scale(0.9) rotate(4deg); opacity: 0.45; }
  100% { transform: translateY(-36px) scale(0.85); opacity: 0; }
}

/* ===== Timetable ===== */
.plan { background-color: var(--sky); padding-bottom: 80px; }
.sr-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.tickets {
  display: grid;
  justify-items: center;
  gap: 34px;
  max-width: 360px;
  margin: 40px auto 0;
}
/* The wrapper carries the shadow (a drop-shadow, so it follows the punched
   notches) and the slide-in; the paper inside takes the jolt. */
.ticket {
  position: relative;
  width: 100%;
  transform: rotate(var(--r));
  filter: drop-shadow(0 8px 12px rgba(78, 80, 128, 0.16));
  visibility: hidden;
}
.ticket.is-placed { visibility: visible; animation: slide-in 0.5s steps(1) both; }
@keyframes slide-in {
  0%   { transform: translateX(calc(var(--from) * 70px)) rotate(calc(var(--r) + var(--from) * 8deg)); opacity: 0; }
  17%  { transform: translateX(calc(var(--from) * 44px)) rotate(calc(var(--r) + var(--from) * 5deg)); opacity: 1; }
  33%  { transform: translateX(calc(var(--from) * 20px)) rotate(calc(var(--r) + var(--from) * 2deg)); }
  50%  { transform: translateX(calc(var(--from) * -6px)) rotate(calc(var(--r) - var(--from) * 1deg)); }
  67%  { transform: translateX(calc(var(--from) * 3px)) rotate(var(--r)); }
  100% { transform: rotate(var(--r)); }
}
/* Two notches punched where the stub tears off: masks intersected, so the cut
   is real (the section shows through) and the shadow follows it. */
.ticket__paper {
  --cut: 92px;
  display: grid;
  grid-template-columns: var(--cut) 1fr;
  min-height: 108px;
  border-radius: 10px;
  background-color: var(--card);
  background-image: radial-gradient(ellipse at 80% 20%, rgba(255, 255, 255, 0.9), transparent 60%);
  -webkit-mask:
    radial-gradient(circle 10px at var(--cut) 0, transparent 9.5px, #000 10px),
    radial-gradient(circle 10px at var(--cut) 100%, transparent 9.5px, #000 10px);
  -webkit-mask-composite: source-in;
  mask:
    radial-gradient(circle 10px at var(--cut) 0, transparent 9.5px, #000 10px),
    radial-gradient(circle 10px at var(--cut) 100%, transparent 9.5px, #000 10px);
  mask-composite: intersect;
}
.ticket.is-placed .ticket__paper { animation: jolt 0.34s steps(1) 0.66s; }
@keyframes jolt {
  0%   { transform: translateY(0); }
  25%  { transform: translateY(4px) scale(1.01, 0.97); }
  50%  { transform: translateY(-1px); }
  75%  { transform: translateY(1px); }
}
.ticket__stub {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #ecebf6;
  border-right: 2px dashed #cfcde6;       /* the perforation */
}
.ticket__time {
  font-family: 'Zviadi', 'Nino', sans-serif;
  font-size: 30px;
  line-height: 1;
  color: var(--accent);
}
.ticket__main {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 16px 52px 16px 18px;           /* right padding leaves room under the stamp */
  text-align: left;
}
.ticket__name { font-family: var(--serif); font-size: 20px; line-height: 1.3; color: var(--ink); }
.ticket__place {
  display: inline-flex;
  align-items: flex-start;
  gap: 4px;
  margin-top: 6px;
  font-size: 13px;
  line-height: 1.35;
  color: var(--ink-soft);
  text-decoration: underline;
  text-decoration-color: var(--lav);
  text-underline-offset: 3px;
}
.ticket__place svg { flex: 0 0 auto; width: 14px; height: 14px; margin-top: 2px; fill: var(--accent); }
/* The ink stamp: multiply so it soaks into the paper like real ink. Slams in
   from above the page on held frames, right after the ticket lands. */
.ticket__stamp {
  position: absolute;
  right: -4px;
  top: -16px;
  width: 74px;
  height: 74px;
  color: #b0697a;
  opacity: 0;
  mix-blend-mode: multiply;
  transform: rotate(var(--sr));
  pointer-events: none;
}
.ticket__stamp text { font-family: var(--serif); }
.ticket.is-placed .ticket__stamp { animation: slam 0.42s steps(1) 0.58s both; }
@keyframes slam {
  0%   { opacity: 0; transform: rotate(calc(var(--sr) - 24deg)) scale(1.9); }
  20%  { opacity: 0.85; transform: rotate(calc(var(--sr) - 6deg)) scale(1.18); }
  40%  { opacity: 0.85; transform: rotate(var(--sr)) scale(0.9); }
  60%  { opacity: 0.85; transform: rotate(var(--sr)) scale(1.04); }
  80%  { opacity: 0.85; transform: rotate(var(--sr)) scale(0.99); }
  100% { opacity: 0.85; transform: rotate(var(--sr)) scale(1); }
}

/* ===== RSVP ===== */
.rsvp { background-color: var(--paper); padding-bottom: 80px; }
.rsvp .fx { z-index: 4; }
.rsvp__deadline { margin-top: 8px; font-family: var(--serif); font-size: 18px; color: #535b78; }
.rsvp__form {
  position: relative;
  z-index: 2;
  max-width: 420px;
  margin: 26px auto 0;
  padding: 24px 18px;
  border-radius: 18px;
  background-color: var(--card);
  box-shadow: 0 12px 28px var(--shadow);
  text-align: left;
}
.field { border: 0; margin-bottom: 18px; min-width: 0; }
.field__label { display: block; margin-bottom: 6px; font-size: 14px; color: var(--ink); }
.field__input {
  width: 100%;
  height: 48px;
  padding: 0 14px;
  border: 1.5px solid #c9cbe0;
  border-radius: 12px;
  background-color: #fff;
  font-size: 16px;                 /* 16px+ stops iOS zooming on focus */
  transition: border-color 0.2s ease;
}
.field__input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(98, 94, 154, 0.18); }
.field__input.is-invalid { border-color: #b4505a; }
.choice { display: grid; gap: 10px; }
.choice__card, .pill { position: relative; cursor: pointer; }
.choice__card input, .pill input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.choice__card span {
  display: block;
  padding: 13px 14px;
  border: 1.5px solid #c9cbe0;
  border-radius: 12px;
  font-size: 15px;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}
.choice__card input:checked + span { border-color: var(--accent); background-color: #efeef8; }
.choice__card input:focus-visible + span, .pill input:focus-visible + span { box-shadow: 0 0 0 3px rgba(98, 94, 154, 0.3); }
.rsvp__count { display: none; }
.rsvp__count.is-open { display: block; }
.pills { display: flex; gap: 8px; }
.pill span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1.5px solid #c9cbe0;
  border-radius: 50%;
  font-size: 16px;
  transition: border-color 0.2s ease, background-color 0.2s ease, color 0.2s ease;
}
.pill input:checked + span { border-color: var(--accent); background-color: var(--accent); color: #fff; }
.rsvp__error { min-height: 22px; margin-bottom: 8px; font-size: 14px; color: #a2434d; }
.btn {
  display: block;
  width: 100%;
  height: 52px;
  border: 0;
  border-radius: 999px;
  background-color: var(--accent);
  color: #fff;
  font-size: 16px;
  cursor: pointer;
  box-shadow: 0 6px 14px rgba(98, 94, 154, 0.3);
  transition: transform 0.1s ease, background-color 0.2s ease;
}
.btn:active { transform: translateY(1px) scale(0.98); }
.btn:focus-visible { outline: 3px solid rgba(98, 94, 154, 0.35); outline-offset: 3px; }
.rsvp__thanks { display: none; max-width: 340px; margin: 30px auto 0; }
.rsvp.is-sent .rsvp__form { display: none; }
.rsvp.is-sent .rsvp__thanks { display: block; animation: pop 0.42s steps(1) both; }
.rsvp__thanks-text { font-family: 'Zviadi', 'Nino', sans-serif; font-size: 26px; line-height: 1.45; }
.rsvp__closed { display: none; margin-top: 26px; font-size: 17px; }
.rsvp.is-closed .rsvp__form { display: none; }
.rsvp.is-closed .rsvp__closed { display: block; }

/* ===== Footer ===== */
.footer {
  position: relative;
  padding: 46px 20px calc(30px + env(safe-area-inset-bottom));
  background-color: var(--ink);
  color: #eceef6;
  text-align: center;
}
.footer__name { font-family: 'Zviadi', 'Nino', sans-serif; font-size: 28px; }
.footer__credit {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 18px;
  font-size: 12px;
  text-decoration: none;
  opacity: 0.3;
  transition: opacity 0.3s ease;
}
.footer__credit:hover, .footer__credit:focus-visible { opacity: 0.9; }
.footer__logo { width: 18px; height: 18px; }

/* ===== Desktop notice ===== */
.desktop-notice { display: none; }

@media (min-width: 481px) {
  .hero__names { font-size: 46px; }
  .hero__date { font-size: 20px; }
  .title { font-size: 38px; }
  .clock__num { font-size: 38px; }
  .lane__car { width: 160px; }
}

@media (min-width: 769px) {
  .desktop-notice {
    position: fixed;
    inset: 0;
    z-index: 30000;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background-color: #ecf6f7;
    text-align: center;
  }
  .desktop-notice p { font-size: 15px; line-height: 1.9; color: var(--ink); }
  .desktop-notice__logo { width: 52px; height: auto; opacity: 0.8; margin-bottom: 18px; }
  .desktop-notice__sub { margin-top: 6px; font-size: 13px; color: var(--ink-soft) !important; }
}

@media (prefers-reduced-motion: reduce) {
  .boil, .hero__hint.is-on { animation: none; }
  .reveal { opacity: 1; translate: none; transition: none; }
  .clock__num.is-hop, .hero__names .ch.is-on, .rsvp.is-sent .rsvp__thanks { animation: none; }
  .ticket, .ticket.is-placed { visibility: visible; animation: none; }
  .ticket.is-placed .ticket__paper { animation: none; }
  .ticket__stamp, .ticket.is-placed .ticket__stamp { opacity: 0.85; animation: none; }
}
