/* ══════════════════════════════════════════════════════════════
   Әнел — Qyz Uzatu
   Макет-эталон: 941 × 1672. Единица --u равна одному пикселю
   макета, поэтому все размеры переносятся из него напрямую.
   ══════════════════════════════════════════════════════════════ */

:root {
  --bg: #f8ebe6;
  --paper: #f9efea;
  --paper-warm: #faf2ee;

  --ink: #a85b5c;          /* заголовки */
  --ink-deep: #96504f;     /* акцентные заголовки */
  --ink-soft: #c0807b;
  --line: #cd9089;         /* орнаментальные линии */
  --line-pale: #e0b3ab;
  --body: #8a6857;         /* основной текст */
  --body-deep: #7a5849;
  --rose: #c4807c;         /* заливка кнопок */
  --rose-deep: #b06d69;
  --gold: #dcb7a6;

  --display: 'Playfair Display', 'Times New Roman', serif;
  --serif: 'Cormorant Garamond', Georgia, serif;
  --script: 'Marck Script', 'Cormorant Garamond', cursive;

  --ease: cubic-bezier(.22, .61, .36, 1);
  --ease-soft: cubic-bezier(.4, 0, .2, 1);
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  font-variant-numeric: lining-nums;
  background: var(--bg);
  color: var(--body);
  font-family: var(--serif);
  overflow-x: hidden;
  transition: background-color 1.1s var(--ease-soft);
}

/* на широком экране колонка читается как лист бумаги */
@media (min-width: 620px) {
  .page {
    box-shadow: 0 0 calc(70 * var(--u)) rgba(176, 116, 106, .13);
  }
}

body.is-sealed { overflow: hidden; height: 100svh; }

img { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

::selection { background: rgba(196,128,124,.25); }

:focus-visible {
  outline: 2px solid var(--rose);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ── колонка приглашения ─────────────────────────────────── */
.page {
  width: min(100vw, 560px);
  margin-inline: auto;
  container-type: inline-size;
  --u: calc(1cqw / 9.41);     /* 1 пиксель макета */
}

/* ══ переключатель языка ══ */
.lang {
  position: fixed;
  top: max(14px, env(safe-area-inset-top));
  right: max(14px, calc(50vw - min(50vw, 280px) + 14px));
  z-index: 90;
  display: flex;
  align-items: center;
  width: 108px;
  height: 34px;
  padding: 3px;
  border-radius: 20px;
  background: rgba(252, 245, 241, .92);
  border: 1px solid rgba(205, 144, 137, .45);
  box-shadow: 0 3px 12px rgba(160, 96, 88, .16);
  /* без backdrop-filter: поверх параллаксной шторы Chrome изредка
     оставлял от него белый отпечаток рядом с переключателем */
}

.lang__pill {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 51px;
  height: 28px;
  border-radius: 16px;
  background: linear-gradient(180deg, #c98b86, #b7736f);
  box-shadow: 0 1px 4px rgba(140, 80, 74, .35);
  transition: translate .42s var(--ease);
  translate: 51px 0;
}
.lang[data-active="kk"] .lang__pill { translate: 0 0; }

.lang__btn {
  position: relative;
  z-index: 1;
  flex: 1;
  align-self: stretch;      /* палец попадает по всей высоте переключателя */
  min-height: 28px;
  font-family: var(--display);
  font-size: 12.5px;
  letter-spacing: .06em;
  color: var(--ink);
  transition: color .35s var(--ease);
}
.lang__btn.is-active { color: #fff8f5; }
/* сам переключатель узкий по макету, поэтому палец ловим шире него */
.lang__btn::after {
  content: '';
  position: absolute;
  inset: -8px -4px;
}

/* ══════════════════════════════════════════════════════════
   ЗАПЕЧАТАННЫЙ КОНВЕРТ
   Створки занимают весь экран и раздвигаются, открывая
   первую секцию: под ними сразу контент, менять нечего.
   ══════════════════════════════════════════════════════════ */
.seal {
  --e: calc(min(100vw, 560px) / 941);   /* 1 px макета — тот же, что --u */
  --bow-y: 61.6%;                       /* центр банта по высоте экрана — как в макете */
  position: fixed;
  inset-block: 0;
  left: 50%;
  translate: -50% 0;
  width: min(100vw, 560px);
  height: 100svh;
  z-index: 80;
  overflow: hidden;
  cursor: pointer;
  /* слой зерна идёт через mix-blend-mode: без изоляции он смешивался
     бы с содержимым страницы под конвертом, и оно просвечивало */
  isolation: isolate;
  transition: visibility 0s 2.6s;
}
.seal.is-open { visibility: hidden; pointer-events: none; }

/* Конверт показывается целиком, а не по деталям.
   Створки, фальц и виньетка нарисованы градиентами — они на месте сразу,
   как только доехали стили. Всё, что нарисовано картинками — уголки,
   бусины, тиснение, бант, — ждёт, пока придут ВСЕ картинки, и появляется
   одним разом: раньше каждая деталь всплывала по мере загрузки, и конверт
   собирался у гостя на глазах. Подсказка «нажмите» ждёт вместе с ними:
   стучать по недособранному конверту незачем.
   Класс вешает main.js, там же подстраховка по времени. */
.seal__vign,
.seal__beads,
.seal__ornament,
.seal__open,
.bow { visibility: hidden; }

.seal.is-dressed .seal__vign,
.seal.is-dressed .seal__beads,
.seal.is-dressed .seal__ornament,
.seal.is-dressed .seal__open,
.seal.is-dressed .bow { visibility: visible; }

/* створки закрывают экран целиком */
.seal__leaf {
  position: absolute;
  top: 0;
  width: 50.2%;
  height: 100%;
  z-index: 2;
  background: linear-gradient(102deg, #fdf7f4 0%, #f9efea 46%, #f5e7e1 100%);
  box-shadow: 0 0 calc(95 * var(--e)) rgba(178, 122, 112, .16);
  transition: transform 1.5s .95s var(--ease), opacity .4s;
}
/* волокно бумаги: одним слоем поверх всей сцены, иначе кромки
   вырезанных деталей выделяются на фоне текстуры */
.seal::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 8;
  background-image: url('../assets/paper.webp?v=6');
  background-size: calc(252 * var(--e)) calc(221 * var(--e));
  mix-blend-mode: overlay;      /* зерно нейтрально-серое: overlay не красит бумагу */
  opacity: .34;
  pointer-events: none;
  transition: opacity .6s;
}
.seal.is-open::after { opacity: 0; }
.seal__leaf--l {
  left: 0;
  transform-origin: right center;
  background-image:
    radial-gradient(120% 80% at 20% 40%, rgba(255,252,250,.7), transparent 62%),
    linear-gradient(102deg, #fdf7f4 0%, #f9efea 46%, #f4e6e0 100%);
}
.seal__leaf--r {
  right: 0;
  transform-origin: left center;
  background-image:
    radial-gradient(120% 80% at 80% 40%, rgba(255,252,250,.62), transparent 62%),
    linear-gradient(-102deg, #fdf8f5 0%, #faf0eb 46%, #f4e6e0 100%);
}

/* фальц: одна створка ложится на другую, поэтому по шву идёт тень */
.seal__fold {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: calc(110 * var(--e));
  translate: -50% 0;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(186, 128, 118, .12) 40%,
    rgba(174, 116, 106, .2) 49%,
    rgba(255, 252, 249, .5) 52%,
    transparent 100%);
  transition: opacity .5s;
}
.seal.is-open .seal__fold { opacity: 0; }

/* мягкое затемнение к краям экрана — конверт перестаёт быть плоским */
.seal__vignette {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background:
    radial-gradient(130% 90% at 50% 42%, transparent 52%, rgba(176, 118, 106, .13) 100%);
  transition: opacity .6s;
}
.seal.is-open .seal__vignette { opacity: 0; }

/* рамка на створках сходится по центру закрытого конверта */
.seal__leaf::after {
  content: '';
  position: absolute;
  inset: calc(41 * var(--e));
  border: 1px solid rgba(206, 146, 132, .5);
  box-shadow:
    0 1px 0 rgba(255, 253, 251, .7),
    inset 0 1px 0 rgba(255, 253, 251, .55);
}
.seal__leaf--l::after { border-right: 0; }
.seal__leaf--r::after { border-left: 0; }

.seal.is-open .seal__leaf--l { transform: translateX(-101%) rotateY(16deg); }
.seal.is-open .seal__leaf--r { transform: translateX(101%)  rotateY(-16deg); }

.seal__vign {
  position: absolute;
  width: calc(80 * var(--e));
  opacity: .95;
  filter:
    drop-shadow(0 1px 0 rgba(255, 253, 251, .8))
    drop-shadow(0 -1px 0 rgba(168, 112, 102, .22));
}
.seal__vign--tl { top: calc(36 * var(--e));    left: calc(36 * var(--e)); }
.seal__vign--bl { bottom: calc(36 * var(--e)); left: calc(36 * var(--e)); scale: 1 -1; }
.seal__vign--tr { top: calc(36 * var(--e));    right: calc(36 * var(--e)); scale: -1 1; }
.seal__vign--br { bottom: calc(36 * var(--e)); right: calc(36 * var(--e)); scale: -1 -1; }

.seal__seam {
  position: absolute;
  top: 4%;
  bottom: 4%;
  left: 50%;
  width: 1px;
  z-index: 3;
  background: linear-gradient(180deg, transparent, rgba(200,140,128,.55) 12%, rgba(200,140,128,.55) 88%, transparent);
}
/* Тиснение и бусины висят над бантом на тех же расстояниях, что в макете
   (все три отсчитываются от центра банта). Экран телефона выше макета,
   лишняя высота уходит в поля сверху и снизу, а связка не разъезжается.
   max() удерживает их на экране в альбомной ориентации. */
.seal__ornament {
  filter:
    drop-shadow(0 1px 0 rgba(255, 253, 251, .85))
    drop-shadow(0 -1px 0 rgba(168, 112, 102, .28));
  position: absolute;
  top: max(9%, calc(var(--bow-y) - 570 * var(--e)));
  left: 50%;
  translate: -50% 0;
  width: calc(190 * var(--e));
  z-index: 3;
}
.seal__beads {
  filter:
    drop-shadow(0 1px 0 rgba(255, 253, 251, .8))
    drop-shadow(0 -1px 0 rgba(168, 112, 102, .24));
  position: absolute;
  top: max(3%, calc(var(--bow-y) - 800 * var(--e)));
  left: 50%;
  translate: -50% 0;
  width: calc(42 * var(--e));
  z-index: 3;
}
.seal__seam,
.seal__ornament,
.seal__beads { transition: opacity .5s; }
.seal.is-open .seal__seam,
.seal.is-open .seal__ornament,
.seal.is-open .seal__beads { opacity: 0; }

/* ── бант ──────────────────────────────────────────────────
   Настоящая лента из макета, разрезанная по складкам на обвязку,
   петли, хвосты и печать. Габарит банта в макете — 941 × 396 от
   точки (0, 832), доли ниже посчитаны прямо из него.

   Правые половины — зеркальные копии левых (их и режет
   tools/extract_v2.py), а печать стоит по центру: бант в макете
   нарисован от руки и слегка кривой, при переносе один в один
   правая сторона садилась ближе к центру и это было заметно.
   Холсты половин обрезать нельзя — координаты считаются от них. */
.bow {
  position: absolute;
  left: 0;
  top: var(--bow-y);
  width: 100%;
  aspect-ratio: 941 / 396;
  translate: 0 -50%;
  z-index: 7;
  pointer-events: none;
}
.bow__p { position: absolute; }
.bow__knot-grp { position: absolute; inset: 0; }

.bow__band--l   { left: 0;        top: 7.58%;  width: 15.94%; }
.bow__band--r   { right: 0;       top: 7.58%;  width: 15.94%; }
.bow__tail--l   { left: 19.34%;   top: 58.59%; width: 26.99%; transform-origin: 94% 13%; }
.bow__tail--r   { right: 19.34%;  top: 58.59%; width: 26.99%; transform-origin: 6% 13%; }
.bow__loop--l   { left: 11.05%;   top: 0;      width: 42.51%; transform-origin: 92% 55%; }
.bow__loop--r   { right: 11.05%;  top: 0;      width: 42.51%; transform-origin: 8% 55%; }
.bow__seal      { left: 39.11%;   top: 15.15%; width: 21.79%; transform-origin: 50% 46%; }

.bow__seal { animation: knot-breathe 5.5s 1.6s ease-in-out infinite; }

/* ── развязывание ─────────────────────────────────────────
   Лента перетекает: петли втягиваются через узел, и ровно на
   столько же удлиняются хвосты. Затем распущенная лента
   соскальзывает вниз целиком, а обвязка расходится. */
.seal.is-open .bow__loop--l   { animation: loop-in-l 1.05s .06s cubic-bezier(.4,.02,.55,1) forwards; }
.seal.is-open .bow__loop--r   { animation: loop-in-r 1.05s .06s cubic-bezier(.4,.02,.55,1) forwards; }
.seal.is-open .bow__tail--l   { animation: tail-grow-l 1.05s .06s cubic-bezier(.4,.02,.55,1) forwards; }
.seal.is-open .bow__tail--r   { animation: tail-grow-r 1.05s .06s cubic-bezier(.4,.02,.55,1) forwards; }
.seal.is-open .bow__seal      { animation: knot-slip 1.05s .06s cubic-bezier(.4,.02,.55,1) forwards; }
.seal.is-open .bow__knot-grp  { animation: ribbon-fall 1.15s .78s cubic-bezier(.5,.02,.85,.9) forwards; }
.seal.is-open .bow__band--l   { animation: band-slide-l 1.1s .62s var(--ease) forwards; }
.seal.is-open .bow__band--r   { animation: band-slide-r 1.1s .6s  var(--ease) forwards; }

@keyframes knot-breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.018); }
}
/* петля затягивается в узел — лента уходит на хвост */
@keyframes loop-in-l {
  0%   { transform: scaleX(1) scaleY(1); }
  22%  { transform: scaleX(1.05) scaleY(.99) rotate(-1deg); }
  100% { transform: scaleX(.05) scaleY(.74) rotate(-3deg); }
}
@keyframes loop-in-r {
  0%   { transform: scaleX(1) scaleY(1); }
  22%  { transform: scaleX(1.05) scaleY(.99) rotate(1deg); }
  100% { transform: scaleX(.05) scaleY(.74) rotate(3deg); }
}
/* хвост принимает ленту из петли и вытягивается */
@keyframes tail-grow-l {
  0%   { transform: scaleY(1) skewX(0deg); }
  100% { transform: scaleY(1.7) skewX(4deg) translateX(3%); }
}
@keyframes tail-grow-r {
  0%   { transform: scaleY(1) skewX(0deg); }
  100% { transform: scaleY(1.7) skewX(-4deg) translateX(-3%); }
}
/* печать ослабевает и оседает */
@keyframes knot-slip {
  0%   { transform: none; }
  25%  { transform: scale(1.08) rotate(-4deg); }
  100% { transform: translateY(14%) scale(.88) rotate(9deg); }
}
/* распущенная лента соскальзывает вниз целиком */
@keyframes ribbon-fall {
  0%   { transform: none; opacity: 1; }
  100% { transform: translateY(112svh) rotate(7deg); opacity: 0; }
}
@keyframes band-slide-l {
  0%   { transform: none; opacity: 1; }
  100% { transform: translateX(-140%) rotate(-4deg); opacity: 0; }
}
@keyframes band-slide-r {
  0%   { transform: none; opacity: 1; }
  100% { transform: translateX(140%) rotate(4deg); opacity: 0; }
}

/* Конверт не собирается при зрителе: створки, тиснение и бант просто
   уже лежат на месте. Появление проигрывалось до готовности картинок и
   читалось как сборка из деталей. */

/* конверт отзывается на касание */
.seal:not(.is-open):hover .bow,
.seal:not(.is-open):active .bow {
  transform: scale(1.012);
}
.bow { transition: transform .5s var(--ease); }
.seal:not(.is-open):active .seal__leaf--l { transform: translateX(-.4%); }
.seal:not(.is-open):active .seal__leaf--r { transform: translateX(.4%); }

.seal__open {
  position: absolute;
  left: 50%;
  translate: -50% 0;
  bottom: max(9%, calc(58px + env(safe-area-inset-bottom)));
  z-index: 9;
  font-family: var(--display);
  font-size: calc(47 * var(--e));
  white-space: nowrap;
  color: var(--ink);
  animation: hint-pulse 2.6s 1.2s ease-in-out infinite;
  transition: opacity .4s;
}
.seal.is-open .seal__open { opacity: 0; animation: none; transition-duration: .25s; }

/* ══════════════════════════════════════════════════════════
   СЕКЦИИ
   ══════════════════════════════════════════════════════════ */
.page { position: relative; z-index: 1; }

.sec {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  /* Поля сверху и снизу разные: так центр блока садится туда же, где он
     стоит в макете, а лишняя высота экрана делится в той же пропорции. */
  padding-block: calc(228 * var(--u)) calc(52 * var(--u));
}
.sec--address { padding-block: calc(178 * var(--u)) calc(102 * var(--u)); }
.sec--date    { padding-block: calc(139 * var(--u)) calc(101 * var(--u)); }
.sec--venue   { padding-block: calc(160 * var(--u)) calc(121 * var(--u)); }
.sec--final   { padding-block: calc(98 * var(--u))  calc(182 * var(--u)); }

.sec__body {
  position: relative;
  z-index: 5;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

/* Цветочные углы. Кроп каждого прижат к своему краю макета, поэтому в
   CSS остаются только ширина и отступ от края — координаты переносятся
   из макета один в один. Экран телефона выше макета, лишняя высота
   уходит в пустую середину секции, где в макете тоже ничего нет. */
.flowers {
  position: absolute;
  z-index: 4;
  pointer-events: none;
  will-change: transform;
}
.flowers--tl { top: 0; left: 0; }
.flowers--tr { top: 0; right: 0; }
.flowers--bl { bottom: 0; left: 0; }
.flowers--br { bottom: 0; right: 0; }

.sec--title .flowers--tl   { top: calc(34 * var(--u));   width: calc(268 * var(--u)); }
.sec--title .flowers--tr   { top: calc(34 * var(--u));   width: calc(269 * var(--u)); }
.sec--title .flowers--bl   { width: calc(396 * var(--u)); }
.sec--title .flowers--br   { width: calc(405 * var(--u)); }

.sec--address .flowers--tl { width: calc(420 * var(--u)); }
.sec--address .flowers--tr { width: calc(345 * var(--u)); }
.sec--address .flowers--bl { width: calc(356 * var(--u)); }
.sec--address .flowers--br { width: calc(353 * var(--u)); }

/* календарь: в макете это сплошные колонки по бокам, а не букеты в углах */
.sec--date .flowers--bl    { width: calc(345 * var(--u)); }
.sec--date .flowers--br    { width: calc(345 * var(--u)); }

.sec--venue .flowers--tl   { width: calc(315 * var(--u)); }
.sec--venue .flowers--bl   { width: calc(315 * var(--u)); }
.sec--venue .flowers--br   { width: calc(326 * var(--u)); }

.sec--rsvp .flowers--bl    { width: calc(185 * var(--u)); }
.sec--rsvp .flowers--br    { width: calc(191 * var(--u)); }

.sec--final .flowers--bl   { width: calc(400 * var(--u)); }
.sec--final .flowers--br   { width: calc(411 * var(--u)); }

/* цветы едва заметно дышат. Параллакс пишет в transform из скрипта,
   поэтому покачивание живёт в отдельных свойствах translate и rotate */
.flowers {
  animation: drift 19s var(--ease-soft) infinite alternate;
}
.flowers--br, .flowers--tr { animation-duration: 24s; animation-delay: -7s; }
@keyframes drift {
  from { translate: 0 0; rotate: -.3deg; }
  to   { translate: calc(5 * var(--u)) calc(-8 * var(--u)); rotate: .45deg; }
}

/* ── орнаментальные разделители ───────────────────────────── */
.div { pointer-events: none; }
.div--long      { width: calc(550 * var(--u)); margin-block: calc(22 * var(--u)); }
.div--mid       { width: calc(346 * var(--u)); margin-block: calc(20 * var(--u)); }
.div--knot      { width: calc(320 * var(--u)); margin-block: calc(18 * var(--u)); }
.div--flourish  { width: calc(358 * var(--u)); margin-block: calc(16 * var(--u)); }
.div--dots      { width: calc(285 * var(--u)); margin-block: calc(12 * var(--u)); }
.div--flower    { width: calc(107 * var(--u)); margin-block: calc(10 * var(--u)); }
.div--heart     { width: calc(143 * var(--u)); margin-block: calc(10 * var(--u)); }
.div--top5      { width: calc(161 * var(--u)); margin-bottom: calc(14 * var(--u)); }
.div--heartswirl{ width: calc(155 * var(--u)); margin-block: calc(18 * var(--u)); }
/* один и тот же завиток в макетах стоит в разном размере */
.sec--date .div--flourish  { width: calc(279 * var(--u)); }
.sec--date .div--flower    { width: calc(96 * var(--u)); }
.sec--rsvp .div--knot      { width: calc(293 * var(--u)); }
.sec--rsvp .div--flourish  { width: calc(290 * var(--u)); margin-block: calc(10 * var(--u)); }
/* завиток под шторой: в макете он висит сразу под подолом */
.sec--rsvp .div--rsvptop   { width: calc(240 * var(--u)); margin-block: 0 calc(4 * var(--u)); }
.sec--final .div--long     { width: calc(533 * var(--u)); }
.sec--final .div--mid      { width: calc(400 * var(--u)); }
.div--bottom4 {
  position: absolute;
  bottom: calc(30 * var(--u));
  left: 50%;
  translate: -50% 0;
  width: calc(345 * var(--u));
  z-index: 5;
}

/* ── типографика ──────────────────────────────────────────── */
.name {
  font-family: var(--display);
  font-weight: 400;
  font-size: calc(150 * var(--u));
  line-height: .96;
  color: var(--ink-deep);
  letter-spacing: .01em;
}
.name--lg { font-size: calc(200 * var(--u)); }

.name__sub {
  font-family: var(--serif);
  font-weight: 400;
  font-size: calc(48 * var(--u));
  letter-spacing: .3em;
  text-indent: .3em;
  color: var(--ink-soft);
  margin-top: calc(6 * var(--u));
  white-space: nowrap;
}

.eyebrow {
  font-family: var(--display);
  font-weight: 500;
  font-size: calc(44 * var(--u));
  letter-spacing: .12em;
  text-indent: .12em;
  color: var(--ink-deep);
}
.eyebrow--lg { font-size: calc(48 * var(--u)); letter-spacing: .1em; }

.calligraphy {
  font-family: var(--script);
  font-size: calc(76 * var(--u));
  line-height: 1.25;
  color: var(--ink);
  padding-inline: calc(40 * var(--u));
}
html[lang="kk"] .calligraphy {
  font-family: var(--serif);
  font-style: italic;
  font-size: calc(64 * var(--u));
}

.prose {
  font-size: calc(40 * var(--u));
  line-height: 1.62;
  color: var(--body);
  padding-inline: calc(96 * var(--u));
  max-width: 100%;
}

/* подсказка «прокрутите вниз» */
.scroll-cue {
  position: absolute;
  /* на айфонах с полоской-индикатором стрелка иначе попадает под неё */
  bottom: calc(56 * var(--u) + env(safe-area-inset-bottom) * .6);
  left: 50%;
  translate: -50% 0;
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(10 * var(--u));
  text-decoration: none;
  color: var(--ink);
  font-family: var(--serif);
  font-size: calc(34 * var(--u));
}
.scroll-cue img {
  width: calc(82 * var(--u));
  animation: nudge 2.4s ease-in-out infinite;
}
/* стрелка мелкая, поэтому область нажатия расширена вокруг неё */
.scroll-cue::after {
  content: '';
  position: absolute;
  inset: calc(-14 * var(--u)) calc(-26 * var(--u));
}
.scroll-cue--sm img { width: calc(64 * var(--u)); }

/* ══ 2. ГЛАВНАЯ: имя и дата ══ */
.sec--title .name--lg { font-size: calc(199 * var(--u)); }
.sec--title .name__sub { font-size: calc(49 * var(--u)); }

.title__date {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(2 * var(--u));
  margin-top: calc(10 * var(--u));
}
.title__day {
  font-family: var(--display);
  font-size: calc(132 * var(--u));
  line-height: .96;
  color: var(--ink);
  background: linear-gradient(168deg, #c07f7d 10%, #a85b5c 54%, #bb7472);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.title__month {
  font-family: var(--display);
  font-size: calc(40 * var(--u));
  letter-spacing: .14em;
  text-indent: .14em;
  color: var(--ink-soft);
}
.sec--title .div--flower { margin-top: calc(16 * var(--u)); }

/* ══ 3. ОБРАЩЕНИЕ ══ */
.sec--address .div--flourish { margin-bottom: calc(30 * var(--u)); width: calc(340 * var(--u)); }
.sec--address .calligraphy { font-size: calc(77 * var(--u)); padding-inline: calc(20 * var(--u)); }
.sec--address .prose { font-size: calc(42 * var(--u)); line-height: 1.67; }

/* Рамка секции: в макетах она двойная — внешняя линия на 22 px от края
   и внутренняя на 31. Угловой завиток лежит на обеих сразу, поэтому в
   его ассете полосы оставлены и сходятся с этими линиями. */
.frame {
  position: absolute;
  inset: calc(22 * var(--u));
  z-index: 2;
  border: 1px solid rgba(205, 144, 137, .5);
  pointer-events: none;
}
.frame::after {
  content: '';
  position: absolute;
  inset: calc(8 * var(--u));
  border: 1px solid rgba(205, 144, 137, .38);
}
.frame__c { position: absolute; width: calc(120 * var(--u)); }
.frame__c--tl { top: calc(-12 * var(--u)); left: calc(-12 * var(--u)); }
.frame__c--tr { top: calc(-12 * var(--u)); right: calc(-12 * var(--u)); scale: -1 1; }
.frame__c--bl { bottom: calc(-12 * var(--u)); left: calc(-12 * var(--u)); scale: 1 -1; }
.frame__c--br { bottom: calc(-12 * var(--u)); right: calc(-12 * var(--u)); scale: -1 -1; }

.swallows {
  width: calc(549 * var(--u));
  display: flex;
  justify-content: space-between;
  /* отступ отрицательный: у ассетов ласточек есть собственные поля,
     а расстояние до имени взято из макета */
  margin-bottom: calc(-4 * var(--u));
}
.swallows__l,
.swallows__r { width: calc(275 * var(--u)); }
.swallows--sm { width: calc(485 * var(--u)); margin-bottom: calc(4 * var(--u)); }
.swallows--sm .swallows__l,
.swallows--sm .swallows__r { width: calc(243 * var(--u)); }
.swallows--xs { width: calc(454 * var(--u)); margin-block: calc(20 * var(--u)) calc(-44 * var(--u)); }
.swallows--xs .swallows__l,
.swallows--xs .swallows__r { width: calc(227 * var(--u)); }
.swallows--fin { width: calc(533 * var(--u)); margin-bottom: calc(19 * var(--u)); }
.swallows--fin .swallows__l,
.swallows--fin .swallows__r { width: calc(248 * var(--u)); }

/* ══ 3. МЕСТО ПРОВЕДЕНИЯ ══ */
.venue__pic {
  width: calc(894 * var(--u));
  margin-block: calc(-30 * var(--u)) calc(8 * var(--u));
}
.venue__name {
  font-family: var(--display);
  font-size: calc(73 * var(--u));
  color: var(--ink-deep);
  line-height: 1.1;
}
.venue__city {
  font-family: var(--display);
  font-size: calc(29 * var(--u));
  letter-spacing: .24em;
  text-indent: .24em;
  color: var(--body);
}

/* кнопки */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: calc(14 * var(--u));
  min-height: calc(74 * var(--u));
  padding: 0 calc(32 * var(--u));
  border-radius: calc(37 * var(--u));
  font-family: var(--display);
  font-size: calc(24 * var(--u));
  letter-spacing: .1em;
  text-indent: .1em;
  text-decoration: none;
  transition: translate .3s var(--ease), scale .3s var(--ease),
              box-shadow .3s var(--ease), background-color .3s;
  overflow: hidden;
}
.btn--solid {
  background: linear-gradient(180deg, #cb8783, #b7716d);
  color: #fdf6f3;
  box-shadow: 0 calc(6*var(--u)) calc(18*var(--u)) rgba(160, 95, 88, .3);
}
.btn--ghost {
  border: 1px solid var(--rose);
  color: var(--ink-deep);
  background: rgba(253, 246, 243, .5);
}
/* Отклик на касание идёт через translate и scale, а не transform:
   у появившейся кнопки transform обнулён правилом [data-rv].is-in
   с той же специфичностью, и нажатие переставало быть заметным. */
.btn:hover  { translate: 0 calc(-2 * var(--u)); scale: 1.03; }
.btn:active { translate: 0 calc(1 * var(--u));  scale: .98; }
.btn--wide  { width: 100%; min-height: calc(74 * var(--u)); font-size: calc(29 * var(--u)); border-radius: calc(15 * var(--u)); }
.btn__pin { width: calc(30 * var(--u)); height: calc(30 * var(--u)); fill: currentColor; }
.btn::after {                      /* мягкий блик по нажатию */
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at var(--rx, 50%) var(--ry, 50%), rgba(255,255,255,.5), transparent 55%);
  opacity: 0;
  transition: opacity .5s;
}
.btn:active::after { opacity: 1; transition: none; }

.timebox {
  position: relative;
  margin-top: calc(16 * var(--u));
  width: calc(365 * var(--u));
  padding: calc(24 * var(--u)) calc(16 * var(--u)) calc(27 * var(--u));
  border: 1px solid rgba(214, 163, 152, .6);
  border-radius: calc(8 * var(--u));
}
.timebox::before,
.timebox::after {
  content: '';
  position: absolute;
  left: 50%;
  translate: -50% 0;
  width: calc(60 * var(--u));
  height: calc(10 * var(--u));
  background: var(--bg);
  transition: background-color 1.1s var(--ease-soft);
}
.timebox::before { top: calc(-5 * var(--u)); }
.timebox::after  { bottom: calc(-5 * var(--u)); }
.timebox__label { font-size: calc(33 * var(--u)); color: var(--body); }
.timebox__value {
  font-family: var(--display);
  font-size: calc(75 * var(--u));
  color: var(--ink-deep);
  line-height: 1.05;
}

/* ══ 4. ДАТА ══ */
.arch {
  position: absolute;
  top: calc(84 * var(--u));
  left: calc(58 * var(--u));
  width: calc(830 * var(--u));
  height: calc(1440 * var(--u));
  border: calc(9 * var(--u)) solid #fbf1ed;
  border-bottom: 0;
  border-radius: calc(415 * var(--u)) calc(415 * var(--u)) 0 0;
  background: linear-gradient(180deg, rgba(253,246,243,.6), rgba(250,235,230,.25));
  box-shadow: 0 calc(4*var(--u)) calc(30*var(--u)) rgba(184,132,122,.12);
  z-index: 2;
  /* высота арки задана в единицах макета, а секция тянется по экрану:
     без растворения её нижний край читается линией поперёк календаря */
  -webkit-mask: linear-gradient(#000 62%, transparent 92%);
          mask: linear-gradient(#000 62%, transparent 92%);
}
.arch__inner {
  position: absolute;
  inset: calc(22 * var(--u));
  border: 1px dashed rgba(203, 141, 132, .4);
  border-bottom: 0;
  border-radius: calc(392 * var(--u)) calc(392 * var(--u)) 0 0;
  mask: linear-gradient(#000 82%, transparent);
}

.date__day {
  font-family: var(--display);
  font-size: calc(354 * var(--u));
  /* обрезка фона идёт по строке, поэтому ей нужен запас под глиф */
  line-height: 1;
  padding-bottom: calc(10 * var(--u));
  margin-block: calc(-34 * var(--u)) calc(-26 * var(--u));
  color: var(--ink);
  background: linear-gradient(168deg, #c07f7d 12%, #a85b5c 55%, #bb7472);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.date__month {
  font-family: var(--display);
  font-size: calc(65 * var(--u));
  letter-spacing: .06em;
  text-indent: .06em;
  color: var(--ink);
}

.cal {
  position: relative;
  width: calc(690 * var(--u));
  margin-top: calc(4 * var(--u));
  padding: calc(46 * var(--u)) calc(67 * var(--u)) calc(34 * var(--u));
  background: linear-gradient(170deg, #fdf7f4, #f9ece7);
  border-radius: calc(26 * var(--u));
  box-shadow:
    0 calc(10 * var(--u)) calc(34 * var(--u)) rgba(178, 122, 112, .18),
    inset 0 0 0 1px rgba(214, 163, 152, .5);
}
.cal::after {
  content: '';
  position: absolute;
  inset: calc(12 * var(--u));
  border: 1px dashed rgba(214, 163, 152, .5);
  border-radius: calc(18 * var(--u));
  pointer-events: none;
}
.cal__c { position: absolute; width: calc(100 * var(--u)); opacity: .85; }
.cal__c--tl { top: calc(6 * var(--u)); left: calc(6 * var(--u)); }
.cal__c--tr { top: calc(6 * var(--u)); right: calc(6 * var(--u)); scale: -1 1; }
.cal__title {
  font-family: var(--display);
  font-size: calc(40 * var(--u));
  color: var(--body-deep);
  letter-spacing: .04em;
}
.cal__div { width: calc(46 * var(--u)); margin: calc(-4 * var(--u)) auto calc(6 * var(--u)); }

.cal__grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: calc(6 * var(--u)) 0;
  font-size: calc(36 * var(--u));
  color: var(--body-deep);
}
.cal__wd {
  font-family: var(--display);
  /* подписи мельче 11px на узком телефоне уже не читаются */
  font-size: max(11px, calc(23 * var(--u)));
  letter-spacing: .04em;
  color: var(--body);
  padding-bottom: calc(4 * var(--u));
}
.cal__wd--we { color: var(--ink-soft); }
/* Клетка не квадратная: в макете шаг строк заметно плотнее ширины колонки */
.cal__d {
  position: relative;
  height: calc(59 * var(--u));
  display: grid;
  place-items: center;
  opacity: 0;
  translate: 0 calc(6 * var(--u));
  transition: opacity .5s var(--ease), translate .5s var(--ease);
}
.cal.is-in .cal__d { opacity: 1; translate: 0 0; }
.cal__d--we { color: var(--ink-soft); }
.cal__d--mark { color: #fff8f6; font-weight: 500; }
.cal__d--mark::before {
  content: '';
  position: absolute;
  inset: calc(-2 * var(--u)) calc(16 * var(--u));
  background: linear-gradient(180deg, #eda9a8, #e0918f);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 30'%3E%3Cpath d='M16 29S1 18.5 1 9.5A8.5 8.5 0 0 1 16 4 8.5 8.5 0 0 1 31 9.5C31 18.5 16 29 16 29z'/%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 32 30'%3E%3Cpath d='M16 29S1 18.5 1 9.5A8.5 8.5 0 0 1 16 4 8.5 8.5 0 0 1 31 9.5C31 18.5 16 29 16 29z'/%3E%3C/svg%3E") center/contain no-repeat;
  z-index: -1;
  animation: heart-beat 2.8s 1s ease-in-out infinite;
}

/* ══ 5. ТАЙМЕР + RSVP ══ */
.sec--rsvp { padding-block: calc(304 * var(--u)) calc(32 * var(--u)); }
/* штора висит у самого верха секции во всю ширину колонки */
.drape {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 3;
  pointer-events: none;
  will-change: transform;
}

.count {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: calc(18 * var(--u));
  width: calc(700 * var(--u));
  margin-block: calc(17 * var(--u)) calc(9 * var(--u));
}
.count__cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: calc(22 * var(--u)) 0 calc(19 * var(--u));
  background: linear-gradient(170deg, #fdf7f4, #f8eae5);
  border-radius: calc(22 * var(--u));
  box-shadow:
    0 calc(6 * var(--u)) calc(18 * var(--u)) rgba(178, 122, 112, .16),
    inset 0 0 0 1px rgba(214, 163, 152, .45);
}
.count__d { width: calc(32 * var(--u)); opacity: .7; }
.count__cell b {
  font-family: var(--display);
  font-weight: 400;
  font-size: calc(92 * var(--u));
  line-height: 1.06;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.count__cell b.is-tick { animation: tick .45s var(--ease); }
.count__cell i {
  font-style: normal;
  font-family: var(--display);
  font-size: max(11px, calc(24 * var(--u)));
  letter-spacing: .08em;
  text-indent: .08em;
  color: var(--body);
  margin-top: calc(2 * var(--u));
}

.rsvp {
  width: calc(641 * var(--u));
  display: flex;
  flex-direction: column;
  gap: calc(12 * var(--u));
  margin-top: calc(14 * var(--u));
}
.field { position: relative; display: block; }
.field input {
  width: 100%;
  height: calc(79 * var(--u));
  padding: 0 calc(90 * var(--u)) 0 calc(40 * var(--u));
  font-family: var(--serif);
  /* не меньше 16px: при меньшем размере Safari на iPhone приближает
     страницу, как только палец попадает в поле, и обратно не отдаёт */
  font-size: max(16px, calc(34 * var(--u)));
  color: var(--body-deep);
  background: linear-gradient(170deg, #fdf8f5, #f8ece7);
  border: 1px solid rgba(214, 163, 152, .5);
  border-radius: calc(16 * var(--u));
  box-shadow: inset 0 calc(2*var(--u)) calc(6*var(--u)) rgba(178,122,112,.08);
  transition: border-color .3s, box-shadow .3s;
  -moz-appearance: textfield;
}
.field input::-webkit-outer-spin-button,
.field input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.field input::placeholder { color: var(--ink-soft); opacity: .85; }
.field input:focus {
  outline: none;
  border-color: var(--rose);
  box-shadow: 0 0 0 calc(4*var(--u)) rgba(196,128,124,.12);
}
.field input.is-bad { border-color: #c0625c; animation: shake .4s; }
.field img {
  position: absolute;
  right: calc(18 * var(--u));
  top: 50%;
  translate: 0 -50%;
  width: calc(55 * var(--u));
  opacity: .8;
  pointer-events: none;
}

.rsvp__done {
  font-size: calc(34 * var(--u));
  line-height: 1.5;
  color: var(--ink-deep);
  padding: calc(16 * var(--u));
}

.bow-seal {
  width: calc(660 * var(--u));
  margin-top: calc(20 * var(--u));
  filter: drop-shadow(0 calc(5*var(--u)) calc(12*var(--u)) rgba(160,100,92,.24));
}
/* подпись под лентой: расстояние до завитка взято из макета */
.sec--rsvp .div--rsvpfoot { width: calc(306 * var(--u)); margin-block: calc(-16 * var(--u)) calc(-48 * var(--u)); }
.rsvp__foot {
  font-size: calc(52 * var(--u));
  color: var(--ink);
  margin-top: calc(9 * var(--u));
}

/* ══ 6. ФИНАЛ ══ */
.final__title {
  font-family: var(--display);
  font-weight: 400;
  font-size: calc(96 * var(--u));
  line-height: 1.24;
  color: var(--ink-deep);
  padding-inline: calc(80 * var(--u));
}
.final__from {
  font-size: calc(44 * var(--u));
  line-height: 1.5;
  color: var(--body);
}
.final__quote {
  font-size: calc(36 * var(--u));
  font-style: italic;
  color: var(--ink-soft);
  margin-top: calc(6 * var(--u));
}

/* ══════════════════════════════════════════════════════════
   ПОЯВЛЕНИЕ ПРИ ПРОКРУТКЕ
   ══════════════════════════════════════════════════════════ */
/* Появление идёт только через opacity и transform: blur и clip-path
   тянут за собой перерисовку слоя и роняют кадры на слабых телефонах. */
[data-rv] {
  --d: calc(var(--rv-d, 0) * 80ms);
  opacity: 0;
  transition:
    opacity .6s var(--ease) var(--d),
    transform .6s var(--ease) var(--d);
}
[data-rv="rise"]      { transform: translateY(calc(38 * var(--u))); }
[data-rv="hero"]      { transform: scale(.96); transition-duration: .7s, .7s; }
[data-rv="fade-down"] { transform: translateY(calc(-34 * var(--u))); }
[data-rv="pop"]       { transform: scale(.8); }
[data-rv="stamp"]     { transform: scale(1.4) rotate(-11deg); }
[data-rv="wipe"]      { transform: scaleX(.04); }
[data-rv="wings"]     { transform: scale(.94); }
/* «вырастает»: имя, крупная дата, карточка времени */
[data-rv="grow"]      { transform: scale(.88); transition-duration: .8s, .8s; }
[data-rv="frame"]     { transform: scale(.975); transition-duration: .9s, .9s; }
/* Штора опускается сверху. Двигаем её свойством translate, а не
   transform: в transform пишет параллакс из скрипта. */
[data-rv="fall"] {
  translate: 0 -46%;
  transition: opacity .9s var(--ease) var(--d), translate .9s var(--ease) var(--d);
}
[data-rv="fall"].is-in { translate: 0 0; }

/* Цветы вырастают из своего угла. Им нельзя трогать transform — там
   сидит параллакс из скрипта, а translate/rotate заняты покачиванием,
   поэтому появление идёт отдельным свойством scale. */
[data-rv="corner-l"],
[data-rv="corner-r"],
[data-rv="corner-tl"],
[data-rv="corner-tr"] {
  scale: .84;
  transition: opacity .8s var(--ease) var(--d), scale .8s var(--ease) var(--d);
}
[data-rv="corner-l"]  { transform-origin: 0 100%; }
[data-rv="corner-r"]  { transform-origin: 100% 100%; }
[data-rv="corner-tl"] { transform-origin: 0 0; }
[data-rv="corner-tr"] { transform-origin: 100% 0; }
[data-rv="corner-l"].is-in,
[data-rv="corner-r"].is-in,
[data-rv="corner-tl"].is-in,
[data-rv="corner-tr"].is-in { scale: 1; }

/* текст приглашения проявляется построчно */
[data-rv="lines"] { opacity: 1; }
[data-rv="lines"] .w {
  display: inline-block;
  opacity: 0;
  transform: translateY(calc(16 * var(--u)));
  transition:
    opacity .55s var(--ease) calc(var(--ln, 0) * 110ms),
    transform .55s var(--ease) calc(var(--ln, 0) * 110ms);
}
[data-rv="lines"].is-in .w { opacity: 1; transform: none; }
[data-rv="wings"] .swallows__l { transform: translateX(calc(-70 * var(--u))) rotate(-8deg); transition: transform .8s var(--ease); }
[data-rv="wings"] .swallows__r { transform: translateX(calc(70 * var(--u))) rotate(8deg);  transition: transform .8s var(--ease); }

[data-rv].is-in {
  opacity: 1;
  transform: none;
}
[data-rv="wings"].is-in .swallows__l,
[data-rv="wings"].is-in .swallows__r { transform: none; }

/* здание рисуется слева направо, как штрих карандашом */
[data-rv="draw"] {
  clip-path: inset(0 100% 0 0);
  transition:
    opacity .35s var(--ease) var(--d),
    clip-path 1.15s var(--ease) var(--d);
}
[data-rv="draw"].is-in { clip-path: inset(0 0 0 0); }

/* ласточки покачиваются после появления */
.swallows.is-in .swallows__l { animation: hover-l 7s 1.2s ease-in-out infinite; }
.swallows.is-in .swallows__r { animation: hover-r 7s 1.2s ease-in-out infinite; }

/* ══ фоновая жизнь ══ */
.ambient {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 82;
  pointer-events: none;
}

/* ласточка, изредка пересекающая экран */
.flyby-layer {
  position: fixed;
  inset: 0;
  z-index: 59;
  overflow: hidden;
  pointer-events: none;
}
.flyby {
  position: absolute;
  top: var(--top, 24%);
  left: 0;
  width: var(--size, 12%);
  opacity: .3;
  animation: flyby var(--dur, 16s) linear forwards;
}
.flyby--rev { animation-name: flyby-rev; }

@keyframes flyby {
  0%   { transform: translate(-24vw, 0) rotate(-3deg); opacity: 0; }
  12%  { opacity: .32; }
  50%  { transform: translate(50vw, var(--lift, 4vh)) rotate(2deg); }
  88%  { opacity: .28; }
  100% { transform: translate(124vw, 0) rotate(-2deg); opacity: 0; }
}
@keyframes flyby-rev {
  0%   { transform: translate(124vw, 0) rotate(3deg); opacity: 0; }
  12%  { opacity: .32; }
  50%  { transform: translate(50vw, var(--lift, 4vh)) rotate(-2deg); }
  88%  { opacity: .28; }
  100% { transform: translate(-24vw, 0) rotate(2deg); opacity: 0; }
}

/* очень медленное дыхание света на фоне страницы */
body::before {
  content: '';
  position: fixed;
  inset: -20%;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(38% 30% at 28% 22%, rgba(255, 249, 244, .55), transparent 70%),
    radial-gradient(42% 34% at 76% 72%, rgba(238, 200, 194, .3), transparent 72%);
  animation: light-drift 34s ease-in-out infinite alternate;
}
@keyframes light-drift {
  0%   { transform: translate3d(-2%, -1%, 0) scale(1); opacity: .75; }
  50%  { opacity: 1; }
  100% { transform: translate3d(3%, 2.5%, 0) scale(1.08); opacity: .8; }
}

/* отблеск, скользящий по атласу завязанного банта */
.bow::after {
  content: '';
  position: absolute;
  inset: 24% -10% 30%;
  pointer-events: none;
  background: linear-gradient(102deg,
    transparent 34%,
    rgba(255, 250, 246, .5) 46%,
    rgba(255, 252, 250, .72) 50%,
    rgba(255, 250, 246, .45) 54%,
    transparent 66%);
  mix-blend-mode: soft-light;
  /* блик по атласу отключён: белёсая полоса, проезжающая по банту,
     читалась как оверлей, а не как отблеск */
  display: none;
}
.seal.is-open .bow::after { animation: none; opacity: 0; }

@keyframes satin-sheen {
  0%, 100% { transform: translateX(-58%); opacity: 0; }
  38%      { opacity: .9; }
  62%      { opacity: .9; }
  100%     { transform: translateX(58%); opacity: 0; }
}

/* ══════════════════════════════════════════════════════════
   КЛЮЧЕВЫЕ КАДРЫ
   ══════════════════════════════════════════════════════════ */
@keyframes drape-in {
  from { transform: translateY(-46%); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@keyframes env-in {
  from { opacity: 0; transform: translateY(4%) scale(.94); }
  to   { opacity: 1; transform: none; }
}
@keyframes soft-in  { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; } }
@keyframes bloom    { from { opacity: 0; transform: translateY(12%) scale(.96); } to { opacity: 1; } }
@keyframes hint-pulse {
  0%, 100% { opacity: .5; transform: translateY(0); }
  50%      { opacity: 1;  transform: translateY(calc(-5 * var(--u))); }
}
@keyframes bow-breathe {
  0%, 100% { transform: scale(1) rotate(0deg); }
  50%      { transform: scale(1.018) rotate(-.5deg); }
}
@keyframes fly-l {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50%      { transform: translate(-.9cqw, -1.6cqw) rotate(-2deg); }
}
@keyframes fly-r {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50%      { transform: translate(.9cqw, -1.6cqw) rotate(2deg); }
}
@keyframes hover-l {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50%      { transform: translate(calc(-10 * var(--u)), calc(-16 * var(--u))) rotate(-2.5deg); }
}
@keyframes hover-r {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50%      { transform: translate(calc(10 * var(--u)), calc(-16 * var(--u))) rotate(2.5deg); }
}
@keyframes nudge {
  0%, 100% { transform: translateY(0); opacity: .75; }
  50%      { transform: translateY(calc(12 * var(--u))); opacity: 1; }
}
@keyframes heart-beat {
  0%, 100%  { transform: scale(1); }
  12%       { transform: scale(1.13); }
  24%       { transform: scale(1); }
  36%       { transform: scale(1.08); }
  48%       { transform: scale(1); }
}
@keyframes tick {
  from { opacity: .35; transform: translateY(calc(-14 * var(--u))) scale(.94); }
  to   { opacity: 1; transform: none; }
}
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(calc(-8 * var(--u))); }
  75%      { transform: translateX(calc(8 * var(--u))); }
}
@keyframes petal-fall {
  0%   { opacity: 0; transform: translate3d(0, 0, 0) rotate(0deg); }
  10%  { opacity: .5; }
  90%  { opacity: .25; }
  100% { opacity: 0; transform: translate3d(var(--dx, 40px), 108vh, 0) rotate(var(--spin, 420deg)); }
}

/* ══ адаптация ══ */
@media (max-width: 360px) {
  .prose { padding-inline: calc(70 * var(--u)); }
}

/* невысокий экран: подтягиваем крупные блоки, чтобы секция помещалась целиком.
   Блоки идут от большего порога к меньшему: они перекрываются, и при равной
   специфичности выигрывает последний — иначе правила для самых низких
   экранов молча перебивались бы более общими */
@media (max-height: 730px) {
  .sec { padding-block: calc(92 * var(--u)) calc(104 * var(--u)); }
  .sec--title { padding-block: calc(150 * var(--u)) calc(110 * var(--u)); }
  .sec--rsvp { padding-block: calc(280 * var(--u)) calc(96 * var(--u)); }
  .swallows { margin-bottom: calc(26 * var(--u)); }
  .date__day { font-size: calc(300 * var(--u)); }
  .date__month { font-size: calc(62 * var(--u)); }
  .cal { padding: calc(32 * var(--u)) calc(26 * var(--u)) calc(28 * var(--u)); }
  .cal__grid { font-size: calc(32 * var(--u)); gap: 0; }
  .cal__title { font-size: calc(44 * var(--u)); }
  .arch { height: calc(1240 * var(--u)); }
  .name--lg { font-size: calc(168 * var(--u)); }
  .venue__pic { width: calc(760 * var(--u)); margin-block: calc(14 * var(--u)); }
  .count__cell b { font-size: calc(92 * var(--u)); }
  .final__title { font-size: calc(92 * var(--u)); }
  .div--long { margin-block: calc(18 * var(--u)); }
}

@media (max-height: 620px) {
  .sec--date { padding-block: calc(60 * var(--u)) calc(60 * var(--u)); }
  .sec--date .swallows { margin-bottom: calc(10 * var(--u)); }
  .date__day { font-size: calc(250 * var(--u)); }
  .cal__grid { font-size: calc(30 * var(--u)); }
  .div--flourish, .div--dots { margin-block: calc(8 * var(--u)); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .18s !important;
  }
  [data-rv] { --d: 0ms; }          /* без ожидания очереди появления */
  [data-rv="lines"] .w { transition-delay: 0s !important; }
  /* задержки — не длительность, их media query выше не трогает:
     без этого конверт висел на экране ещё пару секунд после нажатия */
  .seal, .seal__leaf { transition-delay: 0s !important; }
  .petals { display: none; }
}
