/* ==========================================================================
   Azamjon & Mahfuzaxon — mobile wedding invitation
   ========================================================================== */

:root {
  /* palette */
  --backdrop:   #efe7dc;
  --sheet:      #f8f3ec;
  --surface:    #fffdfa;
  --cream:      #fffaf3;
  --ink:        #2c3039;
  --rose:       #c2796d;
  --rose-deep:  #ad675c;
  --blue:       #5c7da6;
  --blue-deep:  #43607f;
  --night:      #2b3038;

  --hair:       rgba(44, 48, 57, .09);
  --hair-strong:rgba(44, 48, 57, .22);

  /* type */
  --serif:  'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  --script: 'Parisienne', 'Cormorant Garamond', Georgia, cursive;
  --sans:   'Jost', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* metrics */
  --col: 480px;
  --ease: cubic-bezier(.22, .61, .36, 1);
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
}

/* Parisienne has no Cyrillic subset — Russian falls back to an italic serif
   that carries the same "handwritten" weight instead of a system default. */
html[lang="ru"] .script {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 500;
  letter-spacing: .01em;
}

* { box-sizing: border-box; }

/* Several components set display on themselves, which would otherwise beat
   the [hidden] attribute we toggle from JS. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--backdrop);
}

body {
  min-height: 100dvh;
  font-family: var(--serif);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior-y: none;
  text-rendering: optimizeLegibility;
}

body.is-locked { overflow: hidden; }

img { max-width: 100%; }
button { font-family: inherit; }
button:focus { outline: none; }
:focus-visible { outline: 2px solid var(--rose); outline-offset: 3px; border-radius: 3px; }

a { color: var(--blue); text-decoration: none; }

/* ── shared type ────────────────────────────────────────────────────────── */

.script {
  font-family: var(--script);
  font-weight: 400;
  margin: 0;
  color: var(--ink);
}
.script--h2 { font-size: 29px; line-height: 1.2; }

.eyebrow {
  margin: 0;
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 400;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: rgba(44, 48, 57, .45);
}
.eyebrow--wide  { letter-spacing: .36em; color: rgba(44, 48, 57, .5); }
.eyebrow--onDark{ color: rgba(255, 247, 239, .8); }

/* ── when: the date-and-time stamp ──────────────────────────────────────────
   The one thing every guest opens the invitation to find, and previously set
   as a 9.5px eyebrow that everyone skimmed past. It earns its attention from
   contrast and framing rather than from size: the hour sits alone inside a
   hairline rule — the same ornament the invitation already uses to mark a
   moment — so it draws the eye while staying clearly subordinate to the
   couple's names above it. */

/* one flex item wherever it lands, so a parent's gap spaces the stamp as a
   whole instead of prising the date away from the time */
.when {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.when__date {
  margin: 0;
  font-family: var(--sans);
  /* the longest wording is Russian ("Суббота · 15 августа 2026"), which at a
     flat size would wrap on a 320px phone — so the whole stamp scales down
     with the viewport instead of breaking */
  font-size: clamp(11px, 3.3vw, 12.5px);
  font-weight: 400;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: rgba(44, 48, 57, .72);
}

/* The hour, flanked by the invitation's hairline rule. The rules do the work
   of drawing the eye, which lets the numerals stay modest. */
.when__time {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 13px;
  margin: 9px 0 0;
  /* fallback wording, shown only when a translation carries no readable time */
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: rgba(44, 48, 57, .6);
  white-space: nowrap;
}

.when__time::before,
.when__time::after {
  content: '';
  display: block;
  width: 30px;
  height: 1px;
  background: var(--hair-strong);
}

.when__clock {
  font-family: var(--serif);
  /* deliberately below .hero__names, which resolves to ~29px at 375px wide —
     the couple stay the headline and the hour reads as the detail it is */
  font-size: 21px;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: none;
  color: var(--ink);
  /* Cormorant defaults to old-style figures, which set 1 and 0 below cap
     height — charming in the countdown, but it makes a clock reading look
     mistyped. Lining figures give the digits one even height. */
  font-variant-numeric: lining-nums;
  font-feature-settings: 'lnum' 1;
  /* the tracking above would otherwise hang as a gap before the right rule */
  margin-right: -.08em;
  line-height: 1;
}

.rule {
  display: flex;
  align-items: center;
  gap: 12px;
}
.rule__line { display: block; width: 44px; height: 1px; background: var(--hair-strong); }
.rule__line--sm { width: 34px; }
.rule__mark { font-size: 12px; color: var(--rose); line-height: 1; }
.rule--onDark .rule__line { background: rgba(255, 247, 239, .5); }
.rule--onDark .rule__mark { color: rgba(255, 247, 239, .8); font-size: 11px; }

/* ── shell ──────────────────────────────────────────────────────────────── */

.stage {
  display: flex;
  justify-content: center;
  min-height: 100dvh;
  background: var(--backdrop);
}

.sheet {
  position: relative;
  width: 100%;
  max-width: var(--col);
  background: var(--sheet);
  box-shadow: 0 0 90px rgba(44, 48, 57, .18);
  overflow: hidden;
}

.main {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 1.25s var(--ease) .35s, transform 1.4s var(--ease) .35s;
  padding-bottom: var(--safe-b);
}
.main.is-in { opacity: 1; transform: translateY(0); }

/* ── hero ───────────────────────────────────────────────────────────────── */

.hero { position: relative; }

.hero__arch {
  /* Full-bleed and flush with the top of the sheet, with no edge of its own.
     The frame matches the banner's own ratio, so the image shows whole — no
     crop, and nothing at its edges gets eaten. Swapping in a portrait photo
     later is a one-line change here. */
  position: relative;
  width: 100%;
  aspect-ratio: 1254 / 730;
  margin: 0;
  overflow: hidden;
  background: var(--sheet);
}

.hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.hero__veil {
  position: absolute;
  inset: 0;
  /* Dissolves the photo's lower edge into the exact sheet colour so the
     image and the copy below read as one surface — no seam, no framing
     line. Held off until 84% so the last Saturday in frame — the 15th —
     stays readable instead of dissolving with the rest of the row. */
  background: linear-gradient(to bottom,
    rgba(248, 243, 236, 0) 84%,
    rgba(248, 243, 236, .55) 93%,
    var(--sheet) 100%);
}

.hero__caption {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  /* sits on the sheet where the photo has already faded out, keeping the
     script clear of the calendar numbers behind it */
  padding: 4px 24px 0;
  text-align: center;
}

.hero__names {
  /* kept to one line like the wireframe: scales with the viewport so the
     full name always fits between the 24px gutters, with headroom for
     fallback-font metrics before Parisienne loads. "Azamjon & Mahfuzaxon"
     is a long pair, so the slope is gentler than the ceiling suggests. */
  font-size: clamp(22px, calc(8vw - 3px), 38px);
  line-height: 1.2;
  color: var(--ink);
  white-space: nowrap;
}

/* ── reveal-on-scroll ───────────────────────────────────────────────────── */

[data-reveal] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 1s ease, transform 1s var(--ease);
}
[data-reveal].is-in { opacity: 1; transform: translateY(0); }

/* ── blocks ─────────────────────────────────────────────────────────────── */

.block {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.block--copy  { gap: 16px; padding: 44px 40px 10px; }
.block--count { gap: 20px; padding: 36px 26px 8px; }
.block--venue { gap: 14px; padding: 48px 40px 0; }
.block--close { gap: 14px; padding: 56px 40px 54px; }

.block--copy .rule { padding-top: 6px; }

/* the card's "Hurmatli ____" line — only rendered when ?to= names a guest */
.guest {
  font-size: 29px;
  line-height: 1.25;
  color: var(--rose);
  margin: -2px 0 -4px;
  overflow-wrap: anywhere;
}

.lede {
  margin: 0;
  font-size: 21px;
  line-height: 1.62;
  font-weight: 300;
  color: rgba(44, 48, 57, .88);
  text-wrap: pretty;
}

/* ── countdown ──────────────────────────────────────────────────────────── */

.count {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  width: 100%;
}

.count__cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  padding: 16px 4px;
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: 4px;
  box-shadow: 0 6px 18px rgba(44, 48, 57, .05);
}

.count__num {
  font-size: 30px;
  font-weight: 400;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
.count__num--accent { color: var(--rose); }

.count__lbl {
  font-family: var(--sans);
  font-size: 8.5px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: rgba(44, 48, 57, .48);
  text-align: center;
}

.count__done {
  margin: 0;
  font-size: 19px;
  font-style: italic;
  font-weight: 300;
  color: var(--rose);
}

/* ── venue ──────────────────────────────────────────────────────────────── */

.venue__name { font-size: 31px; }

/* Street address and landmark, straight off the printed card. Set in the sans
   face rather than the serif so they read as directions to follow, not as
   more of the invitation's prose — and tucked right under the venue's name,
   which is the thing they qualify. */
.venue__where {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: -4px;
}

.venue__addr {
  margin: 0;
  font-family: var(--sans);
  font-size: 13px;
  line-height: 1.55;
  color: rgba(44, 48, 57, .78);
  text-wrap: pretty;
}

.venue__near {
  margin: 0;
  font-family: var(--sans);
  font-size: 11.5px;
  line-height: 1.5;
  color: rgba(44, 48, 57, .5);
}

.map-embed {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid var(--hair);
  background: #e4ddd0;
  box-shadow: 0 6px 18px rgba(44, 48, 57, .05);
}
.map-embed__frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  /* live tiles for a real preview, but not draggable — a pannable map
     inside a scrolling page is a guaranteed thumb-scroll conflict */
  pointer-events: none;
}
.map-embed__tap {
  position: absolute;
  inset: 0;
  -webkit-tap-highlight-color: rgba(194, 121, 109, .18);
}

.btn-ghost {
  margin-top: 10px;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 14px 26px;
  border: 1px solid rgba(92, 125, 166, .45);
  border-radius: 999px;
  font-family: var(--sans);
  font-size: 10.5px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--blue);
  background: var(--surface);
  transition: background .3s ease, color .3s ease, border-color .3s ease;
}
.btn-ghost__pin { font-size: 12px; }
.btn-ghost:active { background: var(--blue); color: var(--surface); border-color: var(--blue); }

/* ── closing ────────────────────────────────────────────────────────────── */

.close__note {
  margin: 0;
  font-size: 20px;
  font-weight: 300;
  font-style: italic;
  line-height: 1.6;
  color: rgba(44, 48, 57, .75);
  text-wrap: pretty;
}
.close__sign { font-size: 27px; }
.close__stamp { font-size: 9px; letter-spacing: .3em; color: rgba(44, 48, 57, .35); }

/* ── cover ──────────────────────────────────────────────────────────────── */

.cover {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  justify-content: center;
  background: var(--night);
  opacity: 1;
  transform: scale(1);
  transition: opacity 1.35s cubic-bezier(.4, 0, .2, 1), transform 1.6s cubic-bezier(.4, 0, .2, 1);
}
.cover.is-open { opacity: 0; transform: scale(1.08); pointer-events: none; }

.cover__inner {
  position: relative;
  width: 100%;
  max-width: var(--col);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.cover__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 55%;
  display: block;
}

.cover__veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
    rgba(24, 29, 38, .56) 0%,
    rgba(22, 27, 36, .5)  30%,
    rgba(20, 25, 34, .58) 55%,
    rgba(18, 22, 30, .8)  100%);
}

.cover__vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(115% 72% at 50% 44%, rgba(16, 20, 28, .34) 0%, rgba(14, 18, 26, .6) 100%);
}

.petals { position: absolute; inset: 0; pointer-events: none; }
.petal {
  position: absolute;
  border-radius: 60% 60% 60% 0;
  background: rgba(255, 246, 238, .46);
  animation: drift 12s ease-in infinite;
  will-change: transform, opacity;
}
.petal--1 { left: 14%; bottom: 120px; width: 9px; height: 9px; background: rgba(255,246,238,.5);  animation-duration: 11s; animation-delay: 1.2s; }
.petal--2 { left: 62%; bottom:  90px; width: 7px; height: 7px; background: rgba(255,246,238,.45); animation-duration: 14s; animation-delay: 3.4s; }
.petal--3 { left: 38%; bottom: 150px; width: 6px; height: 6px; background: rgba(255,246,238,.4);  animation-duration: 13s; animation-delay: 6.1s; }
.petal--4 { left: 82%; bottom: 130px; width: 8px; height: 8px; background: rgba(255,246,238,.42); animation-duration: 12s; animation-delay: 8.3s; }

.cover__top {
  position: relative;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  padding: calc(20px + var(--safe-t)) 20px 0;
}

.cover__mid {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 0 34px;
  text-align: center;
  animation: glowIn 1.6s var(--ease) both;
}

.cover__mid .eyebrow { letter-spacing: .4em; color: rgba(255, 247, 239, .78); }

.cover__names {
  /* "& Mahfuzaxon" is the widest line and would run under the 34px gutters at
     a flat size, so the pair scales with the viewport up to a ceiling that
     the 480px sheet can hold. */
  font-size: clamp(36px, 12vw, 50px);
  line-height: 1.06;
  color: var(--cream);
  text-shadow: 0 4px 30px rgba(20, 24, 32, .55);
}

.cover__bot {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 0 0 calc(48px + var(--safe-b));
}
.cover__bot .eyebrow { letter-spacing: .3em; color: rgba(255, 247, 239, .72); }

.opener {
  position: relative;
  width: 82px;
  height: 82px;
  display: grid;
  place-items: center;
}

.opener__ring {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  border: 1px solid rgba(255, 247, 239, .6);
  animation: ringPulse 2.8s ease-out infinite;
}
.opener__ring--late { border-color: rgba(255, 247, 239, .4); animation-delay: 1.4s; }

.opener__btn {
  position: relative;
  width: 74px;
  height: 74px;
  border-radius: 999px;
  border: 1px solid rgba(255, 247, 239, .55);
  background: rgba(255, 250, 243, .94);
  color: var(--rose);
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
  box-shadow: 0 12px 34px rgba(16, 20, 28, .35);
  animation: beat 2.8s ease-in-out infinite;
  transition: transform .3s ease, background .3s ease;
}
.opener__btn:active { background: var(--cream); transform: scale(1.06); }
.opener__btn svg { width: 34px; height: 34px; display: block; }

/* ── chips / floating bar ───────────────────────────────────────────────── */

.chip {
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  line-height: 1;
  padding: 8px 12px;
  min-height: 30px;
  border-radius: 999px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background .3s ease, color .3s ease, border-color .3s ease;
}

.chip--dark {
  background: rgba(255, 250, 243, .08);
  color: rgba(255, 247, 239, .82);
  border: 1px solid rgba(255, 247, 239, .42);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.chip--dark[aria-pressed="true"] {
  background: rgba(255, 250, 243, .95);
  color: var(--rose);
  border-color: rgba(255, 250, 243, .95);
}

.chip--light {
  background: rgba(255, 253, 250, .92);
  color: rgba(44, 48, 57, .62);
  border: 1px solid rgba(44, 48, 57, .16);
  box-shadow: 0 6px 20px rgba(44, 48, 57, .12);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.chip--light[aria-pressed="true"] {
  background: var(--rose);
  color: var(--surface);
  border-color: var(--rose);
  box-shadow: 0 6px 20px rgba(44, 48, 57, .16);
}

.bar {
  position: fixed;
  z-index: 30;
}
.bar--music {
  /* bottom corner keeps the illustration clear and sits in thumb reach */
  right: max(16px, calc(50% - (var(--col) / 2) + 16px));
  bottom: calc(18px + var(--safe-b));
}
.bar[hidden] { display: none; }

/* ── keyframes ──────────────────────────────────────────────────────────── */

@keyframes ringPulse {
  0%   { transform: scale(1);   opacity: .55; }
  70%  { transform: scale(1.9); opacity: 0; }
  100% { transform: scale(1.9); opacity: 0; }
}

@keyframes beat {
  0%, 100% { transform: scale(1); }
  14% { transform: scale(1.13); }
  28% { transform: scale(1); }
  42% { transform: scale(1.09); }
  56% { transform: scale(1); }
}

@keyframes drift {
  0%   { transform: translate3d(0, 0, 0) scale(1); opacity: 0; }
  12%  { opacity: .55; }
  100% { transform: translate3d(18px, -120px, 0) scale(1.25); opacity: 0; }
}

@keyframes glowIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}


/* ── short phones: keep the cover on one screen ─────────────────────────── */

@media (max-height: 700px) {
  .cover__names { font-size: clamp(32px, 10.5vw, 44px); }
  .cover__mid   { gap: 14px; }
  .cover__bot   { padding-bottom: calc(34px + var(--safe-b)); }
  .opener       { width: 72px; height: 72px; }
  .opener__btn  { width: 64px; height: 64px; }
  .opener__btn svg { width: 30px; height: 30px; }
}

@media (max-width: 360px) {
  .block--copy   { padding-inline: 28px; }
  .block--venue,
  .block--close  { padding-inline: 26px; }
  .lede          { font-size: 19px; }
  .count         { gap: 7px; }
  .count__num    { font-size: 26px; }
}

/* ── accessibility ──────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .petals { display: none; }
  [data-reveal] { opacity: 1; transform: none; }
}

@media print {
  .cover, .bar { display: none !important; }
  .main { opacity: 1 !important; transform: none !important; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
  .sheet { box-shadow: none; }
}
