/* Self-hosted so the card reads the same everywhere, offline-friendly and
   with no request to a third party. PT Serif/PT Sans are one family drawn
   together for Cyrillic, which is why Russian sets so much more evenly in
   them than in a Latin face with Cyrillic bolted on. Each weight/style is
   split into a cyrillic and a latin file — the browser only fetches the
   one it actually needs for the characters on the page. */
@font-face {
  font-family: "PT Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/pt-serif-normal-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "PT Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/pt-serif-normal-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: "PT Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/pt-serif-italic-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "PT Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/pt-serif-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: "PT Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/pt-sans-400-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "PT Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/pt-sans-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: "PT Sans";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/pt-sans-700-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "PT Sans";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/pt-sans-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+20AC, U+2122;
}

:root {
  color-scheme: dark;
  --ink-deep: #120a17;
  --ink: #1b1023;
  --ink-soft: #2a1830;
  --ink-line: #3c2745;
  --gold: #e3b158;
  --gold-soft: #f2cf8e;
  --rose: #e0899d;
  --cream: #f6ecdd;
  --muted: #a68fae;
  --font-display: "PT Serif", Georgia, "Times New Roman", serif;
  --font-body: "PT Sans", -apple-system, "Segoe UI", Roboto, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
}

body {
  background: var(--ink-deep);
  color: var(--cream);
  font-family: var(--font-body);
  -webkit-tap-highlight-color: transparent;
  overflow-x: hidden;
  overscroll-behavior-y: none;
}

.frame {
  max-width: 460px;
  margin: 0 auto;
  min-height: 100dvh;
  position: relative;
  background: radial-gradient(120% 90% at 50% -10%, var(--ink-soft), var(--ink) 55%, var(--ink-deep) 100%);
  box-shadow: 0 0 80px rgba(0, 0, 0, 0.6);
  overflow: hidden;
}

/* ---------- shared screen mechanics ---------- */
.screen {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  transition: opacity 0.7s ease, transform 0.7s ease, visibility 0.7s;
}
.screen.leaving {
  opacity: 0;
  transform: translateY(-14px) scale(0.98);
  pointer-events: none;
  visibility: hidden;
}
.screen.hidden-init {
  opacity: 0;
  transform: translateY(18px);
  pointer-events: none;
  visibility: hidden;
}
.screen.entering {
  opacity: 1;
  transform: none;
  visibility: visible;
}

/* ---------- GATE ---------- */
#gate {
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 12dvh 32px 6dvh;
  gap: 28px;
}

.card-icon {
  filter: drop-shadow(0 8px 18px rgba(227, 177, 88, 0.22));
  animation: card-float 3.4s ease-in-out infinite;
}
@keyframes card-float {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50% { transform: translateY(-5px) rotate(-1.5deg); }
}

.eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.22em;
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
}

h1.gate-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(26px, 7vw, 32px);
  line-height: 1.3;
  margin: 0;
  color: var(--cream);
  text-wrap: balance;
}

.gate-sub {
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  color: var(--muted);
  font-size: 16px;
  line-height: 1.55;
  max-width: 32ch;
}

form#gate-form {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  width: 100%;
}

.date-field {
  width: 100%;
  max-width: 260px;
  padding: 14px 16px;
  border-radius: 14px;
  border: 1px solid var(--ink-line);
  background: rgba(255, 255, 255, 0.03);
  color: var(--cream);
  font-family: var(--font-body);
  font-size: 16px;
  text-align: center;
}
.date-field:focus {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-color: var(--gold);
}

.seal-btn {
  appearance: none;
  border: none;
  cursor: pointer;
  width: 84px;
  height: 84px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, var(--gold-soft), var(--gold) 60%, #b6853a 100%);
  color: var(--ink-deep);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  box-shadow: 0 10px 30px rgba(227, 177, 88, 0.28), inset 0 -4px 8px rgba(0, 0, 0, 0.18);
  transition: transform 0.2s ease;
}
.seal-btn:active { transform: scale(0.94); }

.gate-feedback {
  min-height: 20px;
  font-size: 13px;
  color: var(--rose);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.gate-feedback.show { opacity: 1; }
.gate-hint {
  font-size: 12px;
  color: var(--muted);
  opacity: 0;
  max-width: 30ch;
  transition: opacity 0.5s ease;
}
.gate-hint.show { opacity: 1; }

.shake { animation: shake 0.5s ease; }
@keyframes shake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(4px); }
  30%, 50%, 70% { transform: translateX(-7px); }
  40%, 60% { transform: translateX(7px); }
}

/* ---------- REELS ---------- */
/* Paging is hand-rolled (pointer events + transform), not native
   scroll-snap: native momentum scrolling can carry a hard flick past more
   than one snap point, which is exactly what a reel/story feed must never
   do. See createPager() in script.js — one gesture always moves exactly
   one step, on both axes. */
#reels {
  inset: 0;
}
.track {
  position: relative;
  height: 100%;
  overflow: hidden;
  touch-action: none;
  overscroll-behavior: contain;
}
.track-inner {
  display: flex;
  flex-direction: column;
  height: 100%;
  transition: transform 0.32s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: transform;
}
.track-inner.dragging { transition: none; }

.slide {
  position: relative;
  flex: 0 0 100%;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
}
/* horizontal carousel inside a vertical slide — multi-photo posts */
.carousel {
  position: absolute;
  inset: 0;
  overflow: hidden;
  touch-action: none;
  background: var(--ink-soft);
}
.carousel-inner {
  display: flex;
  height: 100%;
  transition: transform 0.28s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: transform;
}
.carousel-inner.dragging { transition: none; }
.carousel-item {
  position: relative;
  flex: 0 0 100%;
  height: 100%;
  overflow: hidden;
}
/* blurred, cropped copy of the same photo fills the frame behind it */
.carousel-item .media-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: blur(34px) brightness(0.55) saturate(1.15);
  transform: scale(1.15);
}
/* the real photo/video always shown whole — never cropped */
.carousel-item .media-fg, .carousel-item video {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.carousel-dots {
  position: absolute;
  top: 16px;
  left: 16px;
  right: 16px;
  z-index: 4;
  display: flex;
  gap: 5px;
}
.carousel-dots .dot {
  flex: 1;
  max-width: 40px;
  height: 3px;
  border-radius: 2px;
  background: rgba(246, 236, 221, 0.28);
  transition: background 0.3s ease;
}
.carousel-dots .dot.active { background: var(--gold-soft); }

.slide-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgba(18, 10, 23, 0.05) 0%, rgba(18, 10, 23, 0.05) 45%, rgba(18, 10, 23, 0.85) 100%);
  pointer-events: none;
}
.slide-content {
  position: relative;
  z-index: 2;
  padding: 0 60px 44px 22px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.slide-caption {
  font-family: var(--font-display);
  font-size: 19px;
  line-height: 1.4;
  color: var(--cream);
  text-wrap: balance;
  max-width: 30ch;
  white-space: pre-line; /* the "\n" line (hashtags, etc.) in manifest.json breaks onto its own line */
}

/* single, binary like per post — no counter, just on/off */
.like-btn {
  position: absolute;
  z-index: 3;
  right: 10px;
  bottom: 46px;
  width: 46px;
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  appearance: none;
  border: none;
  border-radius: 50%;
  background: rgba(18, 10, 23, 0.4);
  box-shadow: inset 0 0 0 1px rgba(246, 236, 221, 0.22);
  backdrop-filter: blur(3px);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.like-btn svg { width: 23px; height: 23px; overflow: visible; }
.like-btn .heart-fill {
  opacity: 0;
  transform-origin: 12px 12px;
  transform: scale(0.6);
  transition: opacity 0.15s ease, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.like-btn.liked .heart-fill { opacity: 1; transform: scale(1); }
.like-btn.liked .heart-outline { opacity: 0; }
.like-btn.pop svg { animation: like-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes like-pop {
  0% { transform: scale(1); }
  45% { transform: scale(1.3); }
  100% { transform: scale(1); }
}

.play-glyph {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgba(246, 236, 221, 0.14);
  border: 1px solid rgba(246, 236, 221, 0.35);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.play-glyph.show { opacity: 1; }
.play-glyph::after {
  content: "";
  border-style: solid;
  border-width: 9px 0 9px 14px;
  border-color: transparent transparent transparent var(--cream);
  margin-left: 3px;
}

/* empty-state slide, shown before any media has been added */
.slide-empty {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0 40px;
}
.slide-empty p {
  font-family: var(--font-display);
  font-size: 18px;
  color: var(--muted);
  line-height: 1.6;
  max-width: 26ch;
}

/* candle-tally progress rail */
.rail {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 10px;
  width: 14px;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
}
.tick {
  width: 3px;
  height: 16px;
  border-radius: 2px;
  background: rgba(246, 236, 221, 0.22);
  transition: background 0.4s ease, transform 0.4s ease;
}
.tick.done { background: var(--gold); }
.tick.now { background: var(--gold-soft); transform: scaleY(1.35); }

.finale {
  align-items: center;
  justify-content: center;
  justify-content: safe center; /* if the message is long, scroll instead of clipping it */
  overflow-y: auto;
  touch-action: pan-y; /* let this one slide scroll natively if the message overflows it — see script.js shouldIgnore() */
  text-align: center;
  padding: 48px 36px;
}
.finale-inner {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
}
/* the personalised greeting ("Марина, с днём рождения") is the emotional
   payoff of the whole card, so it leads as the biggest line, not a kicker */
.finale-eyebrow {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(30px, 9vw, 38px);
  line-height: 1.2;
  color: var(--rose);
  margin: 0;
  text-wrap: balance;
}
.finale-title {
  font-family: var(--font-display);
  font-size: clamp(22px, 6.5vw, 28px);
  line-height: 1.3;
  color: var(--gold-soft);
  margin: 0;
  text-wrap: balance;
}
.finale-line {
  font-family: var(--font-body);
  color: var(--cream);
  font-size: 18px;
  max-width: 34ch;
  line-height: 1.65;
}
canvas#confetti {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .card-icon, .shake { animation: none !important; }
  .screen { transition: opacity 0.3s ease !important; transform: none !important; }
}
