/* ============================================
   Palette · typography · base
   ============================================ */
:root {
  --cream:        #fdf6ec;
  --cream-warm:   #f7ebd6;
  --cream-deep:   #efddc1;
  --paper:        #fbf3e3;
  --paper-deep:   #f0e3c8;

  --rose:         #d4a5a5;
  --rose-deep:    #b87f7f;
  --rose-dark:    #8d4a4a;
  --rose-soft:    #ead4cf;

  --peach:        #f3c9a1;
  --peach-deep:   #e8a878;

  --gold:         #c9a96e;
  --gold-deep:    #a48652;
  --gold-soft:    #e6d3a6;
  --gold-light:   #f0d2a0;

  --burgundy:     #6b2e3d;
  --burgundy-deep:#4a1f2b;

  --ink:          #5a4636;
  --ink-soft:     #8a7460;
  --ink-faint:    #b5a18a;

  --shadow-soft:  0 10px 30px -12px rgba(120, 80, 50, 0.18);
  --shadow-card:  0 22px 48px -22px rgba(120, 80, 50, 0.42),
                  0 6px 14px -6px rgba(120, 80, 50, 0.18);

  --serif:        'Cormorant Garamond', 'Playfair Display', Georgia, serif;
  --hand:         'Dancing Script', cursive;
}

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

html { scroll-behavior: smooth; overflow-x: hidden; }

/* ============================================
   Lock screen — passcode gate
   ============================================ */
body.is-locked { overflow: hidden; }

.lock {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: grid;
  place-items: center;
  overflow: hidden;
  opacity: 1;
  transition: opacity 0.6s ease, visibility 0.6s ease;
}
.lock.is-unlocked {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.lock__bg {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(900px 700px at 20% 10%, rgba(243, 201, 161, 0.55), transparent 60%),
    radial-gradient(800px 700px at 85% 90%, rgba(212, 165, 165, 0.5), transparent 60%),
    linear-gradient(180deg, var(--cream) 0%, var(--cream-warm) 45%, var(--cream) 100%);
}

.lock__card {
  position: relative;
  width: min(340px, calc(100vw - 40px));
  max-height: min(calc(100dvh - 24px), 92dvh);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding:
    clamp(16px, 4.5dvh, 40px)
    clamp(22px, 5vw, 34px)
    clamp(16px, 4dvh, 34px);
  text-align: center;
  border-radius: 22px;
  background: linear-gradient(180deg, #fffaf0 0%, var(--paper) 100%);
  border: 1px solid rgba(201, 169, 110, 0.28);
  box-shadow:
    0 30px 60px -22px rgba(120, 80, 50, 0.45),
    0 8px 18px -8px rgba(120, 80, 50, 0.2),
    inset 0 0 0 1px rgba(255, 255, 255, 0.5);
}
.lock__card.is-error { animation: lock-shake 0.5s cubic-bezier(.36,.07,.19,.97); }
@keyframes lock-shake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(4px); }
  30%, 50%, 70% { transform: translateX(-8px); }
  40%, 60% { transform: translateX(8px); }
}

.lock__icon {
  width: clamp(32px, 6dvh, 48px);
  height: clamp(32px, 6dvh, 48px);
  margin: 0 auto clamp(6px, 1.6dvh, 16px);
  color: var(--rose-deep);
  filter: drop-shadow(0 6px 12px rgba(184, 127, 127, 0.35));
  animation: heart-beat 1.8s ease-in-out infinite;
}
.lock__icon svg { width: 100%; height: 100%; fill: currentColor; }

.lock__title {
  font-family: var(--serif);
  font-size: 1.2rem;
  color: var(--ink);
  margin-bottom: 4px;
}
.lock__hint {
  font-family: var(--hand);
  font-size: 1.25rem;
  color: var(--rose-deep);
  margin-bottom: clamp(10px, 3dvh, 22px);
}

.lock__dots {
  display: flex;
  justify-content: center;
  gap: 14px;
  margin-bottom: clamp(12px, 3dvh, 26px);
}
.lock__dot {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 1.5px solid var(--gold-deep);
  background: transparent;
  transition: transform 0.2s ease, background 0.2s ease, border-color 0.2s ease;
}
.lock__dot.is-filled {
  background: var(--rose-deep);
  border-color: var(--rose-deep);
  transform: scale(1.18);
}
.lock__card.is-error .lock__dot {
  border-color: var(--rose-dark);
  background: var(--rose-dark);
}

.lock__pad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(6px, 2vh, 16px);
  /* Each key is a square whose size comes from the column width, so on short
     screens the pad must shrink by height (vh), not just width, or the 4 rows
     of round keys would push the card past the viewport and force scrolling. */
  max-width: min(260px, 56dvh);
  margin: 0 auto;
}
.lock__key {
  aspect-ratio: 1 / 1;
  border: none;
  border-radius: 50%;
  background: rgba(255, 250, 240, 0.7);
  box-shadow:
    0 4px 10px -4px rgba(120, 80, 50, 0.28),
    inset 0 0 0 1px rgba(201, 169, 110, 0.3);
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(1.4rem, 4.5vw, 1.7rem);
  color: var(--ink);
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.12s ease, background 0.2s ease, box-shadow 0.2s ease;
}
.lock__key:active {
  transform: scale(0.92);
  background: var(--gold-soft);
  box-shadow: inset 0 2px 6px rgba(120, 80, 50, 0.25);
}
.lock__key--empty {
  background: none;
  box-shadow: none;
  cursor: default;
}
.lock__key--del {
  font-size: clamp(1.2rem, 4vw, 1.5rem);
  color: var(--rose-deep);
  background: none;
  box-shadow: none;
}
.lock__key--del:active { background: rgba(212, 165, 165, 0.18); box-shadow: none; }

@media (hover: hover) {
  .lock__key:not(.lock__key--empty):hover {
    background: var(--gold-soft);
    transform: translateY(-1px);
  }
}

body {
  font-family: var(--serif);
  font-weight: 400;
  color: var(--ink);
  background: var(--cream);
  min-height: 100vh;
  overflow-x: hidden;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Fixed backdrop layer instead of `background-attachment: fixed`, which
   jitters / drifts while scrolling on mobile browsers (iOS Safari especially).
   A truly fixed pseudo-element stays put on every device. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(1200px 800px at 15% -10%, rgba(243, 201, 161, 0.35), transparent 60%),
    radial-gradient(900px  700px at 110% 30%, rgba(212, 165, 165, 0.30), transparent 60%),
    radial-gradient(1100px 900px at 50% 120%, rgba(230, 211, 166, 0.35), transparent 60%),
    linear-gradient(180deg, var(--cream) 0%, var(--cream-warm) 40%, var(--cream) 100%);
}

/* ============================================
   Paper noise overlay
   ============================================ */
.noise {
  pointer-events: none;
  position: fixed;
  inset: 0;
  z-index: 1;
  opacity: 0.35;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.55  0 0 0 0 0.42  0 0 0 0 0.30  0 0 0 0.18 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

/* ============================================
   Floating petals
   ============================================ */
.petals {
  pointer-events: none;
  position: fixed;
  inset: 0;
  z-index: 2;
  overflow: hidden;
}

.petal {
  position: absolute;
  top: -40px;
  width: 22px;
  height: 22px;
  color: var(--rose);
  opacity: 0;
  will-change: transform, opacity;
  animation:
    petal-fall linear infinite,
    petal-fade ease-in-out infinite;
}

.petal svg { width: 100%; height: 100%; display: block; }

@keyframes petal-fall {
  0%   { transform: translate3d(0, -10vh, 0) rotate(0deg); }
  100% { transform: translate3d(var(--drift, 80px), 110vh, 0) rotate(360deg); }
}

@keyframes petal-fade {
  0%, 100% { opacity: 0; }
  10%, 90% { opacity: var(--max-opacity, 0.7); }
}

/* ============================================
   Corner ornaments
   ============================================ */
.corner-ornament {
  position: fixed;
  width: 100px;
  height: 100px;
  color: var(--gold);
  opacity: 0.55;
  z-index: 3;
  pointer-events: none;
}
.corner-ornament--tl { top: 18px; left: 18px; }
.corner-ornament--tr { top: 18px; right: 18px; transform: scaleX(-1); }

@media (max-width: 640px) {
  .corner-ornament { width: 60px; height: 60px; opacity: 0.45; }
}

/* ============================================
   Reveal animation
   ============================================ */
[data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity 1.1s cubic-bezier(.2,.7,.2,1),
    transform 1.1s cubic-bezier(.2,.7,.2,1);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}
[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ============================================
   Section base
   ============================================ */
section {
  position: relative;
  z-index: 5;
  max-width: 1180px;
  margin: 0 auto;
  padding: clamp(80px, 12vh, 140px) clamp(16px, 5vw, 80px);
  text-align: center;
}

.section__eyebrow {
  font-family: var(--hand);
  font-size: clamp(1.15rem, 1.6vw, 1.4rem);
  color: var(--gold-deep);
  letter-spacing: 0.04em;
  margin-bottom: 14px;
}

.section__title {
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(2.4rem, 5.5vw, 4.2rem);
  letter-spacing: -0.01em;
  line-height: 1.05;
  color: var(--ink);
  margin-bottom: 16px;
}
.section__title em {
  font-family: var(--hand);
  font-weight: 600;
  font-style: normal;
  color: var(--rose-deep);
  padding: 0 0.05em;
}

.section__subtitle {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  color: var(--ink-soft);
  margin-bottom: 56px;
}

.hand { font-family: var(--hand); }

/* ============================================
   Hero
   ============================================ */
.hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  padding: clamp(80px, 14vh, 160px) clamp(20px, 5vw, 80px);
  text-align: center;
  overflow: hidden;
  z-index: 5;
}

.hero__bg {
  position: absolute;
  inset: -10% -10%;
  z-index: -1;
  background:
    radial-gradient(600px 400px at 20% 30%, rgba(243, 201, 161, 0.5), transparent 60%),
    radial-gradient(500px 400px at 80% 70%, rgba(212, 165, 165, 0.45), transparent 60%);
  opacity: 0.9;
  will-change: transform;
}

.hero__inner { position: relative; max-width: 900px; }

.hero__eyebrow {
  font-family: var(--hand);
  font-size: clamp(1.2rem, 1.8vw, 1.5rem);
  color: var(--gold-deep);
  letter-spacing: 0.06em;
  margin-bottom: clamp(24px, 4vh, 40px);
}

.hero__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.6rem, 6vw, 5rem);
  line-height: 1.02;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin-bottom: clamp(20px, 3vh, 32px);
  display: flex;
  flex-direction: column;
  gap: 0.05em;
}
.hero__title span { display: inline-block; }

.hero__name-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(16px, 3vw, 36px);
  margin-bottom: clamp(20px, 3vh, 28px);
}

.hero__name {
  font-family: var(--serif);
  font-weight: 600;
  font-style: italic;
  font-size: clamp(4rem, 11vw, 8rem);
  line-height: 1;
  letter-spacing: -0.02em;
  background: linear-gradient(135deg, var(--rose-deep) 0%, var(--gold-deep) 60%, var(--rose-deep) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: 0 2px 24px rgba(184, 127, 127, 0.15);
}

.hero__flourish {
  font-size: clamp(1.5rem, 3vw, 2.4rem);
  color: var(--gold);
  opacity: 0.7;
}

.hero__subtitle {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.1rem, 1.7vw, 1.4rem);
  color: var(--ink-soft);
  letter-spacing: 0.02em;
  margin-bottom: clamp(28px, 4vh, 44px);
}

.hero__heart {
  width: clamp(46px, 5vw, 64px);
  height: clamp(46px, 5vw, 64px);
  margin: 0 auto clamp(20px, 3vh, 28px);
  color: var(--rose-deep);
  filter: drop-shadow(0 6px 14px rgba(184, 127, 127, 0.35));
  animation: heart-beat 1.8s ease-in-out infinite;
}
.hero__heart svg { width: 100%; height: 100%; fill: currentColor; }

@keyframes heart-beat {
  0%, 100% { transform: scale(1); }
  20%      { transform: scale(1.12); }
  40%      { transform: scale(0.98); }
  60%      { transform: scale(1.08); }
}

.hero__signature {
  font-family: var(--hand);
  font-size: clamp(1.3rem, 2vw, 1.8rem);
  color: var(--rose-deep);
}

.hero__scroll {
  position: absolute;
  bottom: clamp(24px, 4vh, 48px);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  font-family: var(--hand);
  font-size: 0.95rem;
  color: var(--ink-faint);
  letter-spacing: 0.08em;
  opacity: 0.85;
  animation: scroll-bob 2.4s ease-in-out infinite;
}
.hero__scroll-arrow { font-size: 1.2rem; }

@keyframes scroll-bob {
  0%, 100% { transform: translate(-50%, 0); opacity: 0.85; }
  50%      { transform: translate(-50%, 8px); opacity: 1; }
}

/* ============================================
   Divider
   ============================================ */
.divider {
  position: relative;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  max-width: 520px;
  margin: 0 auto;
  padding: 0 24px;
  color: var(--gold);
}
.divider span {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, currentColor, transparent);
  opacity: 0.55;
}
.divider svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
  opacity: 0.7;
}

/* ============================================
   Love is — flip cards (no frame)
   ============================================ */
.love-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: clamp(28px, 4vw, 48px);
  max-width: 1000px;
  margin: 0 auto;
  padding: 20px 0 10px;
  perspective: 1400px;
}

.love-card {
  position: relative;
  aspect-ratio: 3 / 4;
  cursor: pointer;
  background: transparent;
  transition:
    transform 0.55s cubic-bezier(.2,.7,.2,1),
    filter 0.55s ease;
  will-change: transform;
}

.love-card:hover {
  transform: translateY(-10px);
  filter: drop-shadow(0 22px 30px rgba(120, 80, 50, 0.25));
}

.love-card__inner {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 1.1s cubic-bezier(.4, .05, .15, 1);
  will-change: transform;
}

.love-card.is-flipped .love-card__inner {
  transform: rotateY(180deg);
}

.love-card__face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  border-radius: 14px;
  overflow: hidden;
  box-shadow:
    0 22px 40px -18px rgba(120, 80, 50, 0.40),
    0 6px 12px -4px rgba(120, 80, 50, 0.18);
  /* Hard-swap visibility at the flip's mid-point so the decorative back
     (heart + hint) can't bleed through onto the photo. The heart's filter +
     animation otherwise create a compositing layer that ignores
     backface-visibility in some browsers. */
  transition: opacity 0.12s linear 0.5s;
}

/* Only the face currently turned toward the viewer stays opaque */
.love-card:not(.is-flipped) .love-card__face--front { opacity: 0; }
.love-card.is-flipped .love-card__face--back { opacity: 0; }

/* BACK FACE — decorative, default visible */
.love-card__face--back {
  background:
    radial-gradient(circle at 30% 20%, rgba(255, 240, 220, 0.45), transparent 55%),
    radial-gradient(circle at 80% 90%, rgba(232, 168, 120, 0.35), transparent 55%),
    linear-gradient(135deg, var(--rose-soft) 0%, var(--peach) 50%, var(--gold-soft) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--rose-deep);
  padding: 24px;
}

/* repeating ornamental pattern */
.love-card__pattern {
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(circle at 25% 25%, rgba(255, 250, 240, 0.4) 1.2px, transparent 1.5px),
    radial-gradient(circle at 75% 75%, rgba(184, 127, 127, 0.25) 1px, transparent 1.3px);
  background-size: 24px 24px, 24px 24px;
  background-position: 0 0, 12px 12px;
  opacity: 0.7;
  pointer-events: none;
}

.love-card__face--back::before {
  content: '';
  position: absolute;
  inset: 12px;
  border: 1px solid rgba(255, 250, 240, 0.55);
  border-radius: 8px;
  pointer-events: none;
}
.love-card__face--back::after {
  content: '';
  position: absolute;
  inset: 16px;
  border: 1px solid rgba(184, 127, 127, 0.22);
  border-radius: 6px;
  pointer-events: none;
}

.love-card__corner {
  position: absolute;
  font-size: 0.9rem;
  color: var(--gold-deep);
  opacity: 0.8;
  z-index: 2;
}
.love-card__corner--tl { top: 8px;    left: 8px; }
.love-card__corner--tr { top: 8px;    right: 8px; }
.love-card__corner--bl { bottom: 8px; left: 8px; }
.love-card__corner--br { bottom: 8px; right: 8px; }

.love-card__back-inner {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-align: center;
}

.love-card__heart {
  width: clamp(54px, 8vw, 72px);
  height: clamp(54px, 8vw, 72px);
  color: var(--rose-deep);
  filter: drop-shadow(0 6px 12px rgba(184, 127, 127, 0.45));
  animation: heart-beat 2.4s ease-in-out infinite;
}
.love-card__heart svg { width: 100%; height: 100%; fill: currentColor; }

.love-card__hint {
  font-size: clamp(1.15rem, 1.7vw, 1.4rem);
  color: var(--rose-deep);
  opacity: 0.9;
  letter-spacing: 0.02em;
}

/* FRONT FACE — the full comic, never cropped */
.love-card__face--front {
  transform: rotateY(180deg);
  background: #fff;
}
.love-card__face--front img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  background: #fff;
}

/* Subtle shimmer on the back when card is in idle state */
.love-card:not(.is-flipped) .love-card__face--back::after {
  animation: shimmer-frame 4s ease-in-out infinite;
}
@keyframes shimmer-frame {
  0%, 100% { box-shadow: inset 0 0 0 0 rgba(255, 250, 240, 0); }
  50%      { box-shadow: inset 0 0 12px 1px rgba(255, 250, 240, 0.18); }
}

.love-is__note {
  margin-top: clamp(40px, 6vh, 64px);
  font-size: clamp(1.15rem, 1.7vw, 1.5rem);
  color: var(--rose-deep);
}

/* ============================================
   Timeline (enriched)
   ============================================ */
.timeline-track {
  position: relative;
  max-width: 900px;
  margin: 0 auto;
  padding: 30px 0 50px;
}

.timeline-line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 4px;
  transform: translateX(-50%);
  background:
    repeating-linear-gradient(180deg,
      rgba(201, 169, 110, 0.30) 0,
      rgba(201, 169, 110, 0.30) 6px,
      rgba(201, 169, 110, 0.10) 6px,
      rgba(201, 169, 110, 0.10) 12px);
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 4%, #000 96%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 4%, #000 96%, transparent 100%);
  border-radius: 4px;
  z-index: 0;
}

.timeline-line-fill {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 0%;
  background: linear-gradient(180deg,
    rgba(212, 165, 165, 0.95) 0%,
    rgba(232, 168, 120, 0.98) 30%,
    rgba(201, 169, 110, 0.98) 60%,
    rgba(212, 165, 165, 0.95) 100%);
  background-size: 100% 280%;
  border-radius: 4px;
  box-shadow:
    0 0 10px rgba(232, 168, 120, 0.55),
    0 0 22px rgba(212, 165, 165, 0.45);
  transition: height 0.1s linear;
  will-change: height;
  animation: timeline-flow 3.5s linear infinite;
}
@keyframes timeline-flow {
  0%   { background-position: 50% 0%; }
  100% { background-position: 50% 280%; }
}

/* Glowing comet head riding the leading edge of the fill */
.timeline-line-head {
  position: absolute;
  left: 50%;
  bottom: -6px;
  width: 16px;
  height: 16px;
  transform: translateX(-50%) scale(0);
  border-radius: 50%;
  background: radial-gradient(circle at 42% 36%, #fff8ee 0%, var(--peach-deep) 45%, var(--rose-deep) 70%, transparent 78%);
  box-shadow:
    0 0 10px 2px rgba(243, 201, 161, 0.9),
    0 0 22px 6px rgba(212, 165, 165, 0.55);
  opacity: 0;
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.timeline-track.is-tracing .timeline-line-head {
  opacity: 1;
  transform: translateX(-50%) scale(1);
  animation: timeline-head-pulse 1.6s ease-in-out infinite;
}
@keyframes timeline-head-pulse {
  0%, 100% { box-shadow: 0 0 10px 2px rgba(243, 201, 161, 0.9), 0 0 22px 6px rgba(212, 165, 165, 0.55); }
  50%      { box-shadow: 0 0 14px 4px rgba(243, 201, 161, 1),   0 0 34px 10px rgba(212, 165, 165, 0.7); }
}

.timeline-line-cap {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  color: var(--gold);
  font-size: 1.2rem;
  background: var(--cream);
  padding: 4px 6px;
  z-index: 3;
}
.timeline-line-cap--top    { top: -14px; }
.timeline-line-cap--bottom { bottom: -14px; }

.timeline-item {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 64px 1fr;
  align-items: center;
  margin: 44px 0;
  min-height: 110px;
}

.timeline-item--left  .timeline-card { grid-column: 1; text-align: right; margin-right: 26px; margin-left: auto; }
.timeline-item--left  .timeline-dot  { grid-column: 2; justify-self: center; }
.timeline-item--right .timeline-card { grid-column: 3; text-align: left;  margin-left: 26px; margin-right: auto; }
.timeline-item--right .timeline-dot  { grid-column: 2; justify-self: center; }

.timeline-item--center {
  grid-template-columns: 1fr;
  justify-items: center;
  margin-top: 64px;
}
.timeline-item--center .timeline-card {
  text-align: center;
  margin: 0;
}

.timeline-dot {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--gold-light), var(--gold-deep) 70%);
  box-shadow:
    0 0 0 5px var(--cream),
    0 0 0 6px rgba(201, 169, 110, 0.45),
    0 6px 14px -3px rgba(120, 80, 50, 0.4);
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: dot-pulse 3s ease-in-out infinite;
}
@keyframes dot-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.08); }
}

.timeline-dot span {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 600;
  color: rgba(255, 250, 240, 0.98);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}

.timeline-dot--accent {
  background: radial-gradient(circle at 35% 35%, #f4c8c0, var(--rose-deep) 70%);
  box-shadow:
    0 0 0 5px var(--cream),
    0 0 0 6px rgba(184, 127, 127, 0.55),
    0 6px 14px -3px rgba(140, 70, 70, 0.4),
    0 0 16px 2px rgba(212, 165, 165, 0.5);
}

/* Dot lights up once the scrolling line reaches it */
.timeline-dot {
  transition: box-shadow 0.55s ease, background 0.55s ease;
}
.timeline-item.is-reached .timeline-dot {
  background: radial-gradient(circle at 35% 35%, #fff1cf, var(--gold-deep) 70%);
  box-shadow:
    0 0 0 5px var(--cream),
    0 0 0 6px rgba(201, 169, 110, 0.7),
    0 6px 14px -3px rgba(120, 80, 50, 0.4),
    0 0 22px 5px rgba(243, 201, 161, 0.7);
}
.timeline-item.is-reached .timeline-dot--accent {
  background: radial-gradient(circle at 35% 35%, #ffd9d1, var(--rose-deep) 70%);
  box-shadow:
    0 0 0 5px var(--cream),
    0 0 0 6px rgba(184, 127, 127, 0.7),
    0 6px 14px -3px rgba(140, 70, 70, 0.45),
    0 0 26px 6px rgba(212, 165, 165, 0.8);
}

/* ── Chapter card frame — drawn beautifully as the line drives up ── */
.timeline-card::after {
  content: '';
  position: absolute;
  inset: -7px;
  border-radius: 16px;
  border: 1px solid rgba(201, 169, 110, 0);
  opacity: 0;
  transform: scale(0.94);
  transition:
    opacity 0.6s ease,
    transform 0.7s cubic-bezier(.2,.7,.2,1),
    border-color 0.6s ease;
  pointer-events: none;
  will-change: opacity, transform;
}

.timeline-item.is-reached .timeline-card {
  transform: translateY(-4px);
  border-color: rgba(201, 169, 110, 0.55);
}
.timeline-item.is-reached .timeline-card::after {
  opacity: 1;
  transform: scale(1);
  border-color: rgba(201, 169, 110, 0.6);
  box-shadow:
    0 0 0 3px rgba(255, 250, 240, 0.5),
    0 0 18px 2px rgba(243, 201, 161, 0.4),
    inset 0 0 0 1px rgba(255, 250, 240, 0.4);
  animation: card-frame-glow 2.8s ease-in-out infinite 0.5s;
}
@keyframes card-frame-glow {
  0%, 100% {
    box-shadow:
      0 0 0 3px rgba(255, 250, 240, 0.45),
      0 0 16px 2px rgba(243, 201, 161, 0.35),
      inset 0 0 0 1px rgba(255, 250, 240, 0.35);
  }
  50% {
    box-shadow:
      0 0 0 3px rgba(255, 250, 240, 0.6),
      0 0 28px 6px rgba(243, 201, 161, 0.55),
      inset 0 0 0 1px rgba(255, 250, 240, 0.5);
  }
}

/* Accent & final chapters glow rose instead of gold */
.timeline-item.is-reached .timeline-card--accent,
.timeline-item.is-reached .timeline-card--final {
  border-color: rgba(184, 127, 127, 0.5);
}
.timeline-item.is-reached .timeline-card--accent::after,
.timeline-item.is-reached .timeline-card--final::after {
  border-color: rgba(184, 127, 127, 0.55);
}

.timeline-card {
  position: relative;
  background: linear-gradient(180deg, #fffaf0 0%, var(--paper) 100%);
  padding: 24px 28px 26px;
  border-radius: 10px;
  box-shadow: var(--shadow-soft);
  border: 1px solid rgba(201, 169, 110, 0.20);
  transition:
    transform 0.5s cubic-bezier(.2,.7,.2,1),
    box-shadow 0.5s ease;
  max-width: 380px;
}
.timeline-card:hover {
  transform: translateY(-5px);
  box-shadow:
    0 26px 44px -16px rgba(120, 80, 50, 0.35),
    0 6px 12px -4px rgba(120, 80, 50, 0.16);
}

.timeline-card::before {
  content: '';
  position: absolute;
  top: 50%;
  width: 26px;
  height: 1px;
  transform: translateY(-50%);
}
.timeline-item--left  .timeline-card::before { right: -26px; background: linear-gradient(to right, rgba(201, 169, 110, 0.55), transparent); }
.timeline-item--right .timeline-card::before { left: -26px;  background: linear-gradient(to left,  rgba(201, 169, 110, 0.55), transparent); }
.timeline-item--center .timeline-card::before { display: none; }

.timeline-card__flourish {
  display: block;
  width: 60px;
  height: 14px;
  color: var(--gold);
  opacity: 0.55;
  margin-bottom: 8px;
}
.timeline-item--left .timeline-card__flourish { margin-left: auto; }
.timeline-item--right .timeline-card__flourish { margin-right: auto; }
.timeline-item--center .timeline-card__flourish { margin: 0 auto 10px; }
.timeline-card__flourish--big { width: 80px; height: 16px; }

.timeline-chapter {
  display: block;
  font-size: clamp(1.05rem, 1.5vw, 1.25rem);
  color: var(--gold-deep);
  margin-bottom: 6px;
  letter-spacing: 0.02em;
}

.timeline-heading {
  font-family: var(--serif);
  font-weight: 600;
  font-style: italic;
  font-size: clamp(1.3rem, 2vw, 1.7rem);
  color: var(--ink);
  margin-bottom: 8px;
  line-height: 1.2;
}

.timeline-text {
  font-family: var(--serif);
  font-size: clamp(1rem, 1.4vw, 1.1rem);
  color: var(--ink-soft);
  line-height: 1.55;
}

.timeline-card--accent {
  background: linear-gradient(180deg, #fff6e9 0%, #fbeacc 100%);
  border-color: rgba(201, 169, 110, 0.4);
  box-shadow:
    0 18px 34px -14px rgba(180, 130, 80, 0.35),
    inset 0 0 0 1px rgba(255, 255, 255, 0.55);
}

.timeline-card--final {
  background: linear-gradient(180deg, #fff 0%, #fff6e9 100%);
  padding: 32px 38px 34px;
  border: 1px solid rgba(184, 127, 127, 0.25);
  box-shadow:
    0 26px 52px -18px rgba(184, 127, 127, 0.35),
    inset 0 0 0 1px rgba(255, 255, 255, 0.6);
}
.timeline-card--final .timeline-heading {
  color: var(--rose-deep);
  font-size: clamp(1.5rem, 2.4vw, 2rem);
}
.timeline-flourish {
  display: block;
  margin-top: 14px;
  font-size: 1.4rem;
  color: var(--gold);
  opacity: 0.7;
}

/* Timeline reveal animations (override default) */
.timeline-item--left[data-reveal]   { transform: translate(-32px, 12px); }
.timeline-item--right[data-reveal]  { transform: translate(32px, 12px); }
.timeline-item--center[data-reveal] { transform: translateY(24px); }
.timeline-item[data-reveal].is-visible { transform: translate(0, 0); }

/* Timeline mobile */
@media (max-width: 720px) {
  .timeline-line { left: 24px; }
  .timeline-line-cap { left: 24px; }

  /* Drop the 3-column desktop grid entirely. On phones every chapter is a plain
     block whose card spans the full width, and the numbered dot is ABSOLUTELY
     pinned to the rail beside its own card. Because the dot lives inside its
     item, it can never drift away from its block — no grid alignment, no
     left/right asymmetry, no dependence on card height. */
  .timeline-item,
  .timeline-item--left,
  .timeline-item--right {
    display: block;
    position: relative;
    grid-template-columns: none;
    align-items: initial;
    padding-left: 54px;          /* room for the rail + dot */
    min-height: 0;
    margin: 24px 0;
  }

  .timeline-item--left  .timeline-card,
  .timeline-item--right .timeline-card {
    grid-column: auto;
    text-align: left;
    margin: 0;
    max-width: none;
  }
  .timeline-item--left  .timeline-card__flourish,
  .timeline-item--right .timeline-card__flourish { margin-left: 0; margin-right: 0; }

  /* Dot centred on the rail (rail at 24px, dot is 34px → left edge at 7px),
     pinned near the top of its card. No transform is used for placement, so the
     idle scale-pulse animation keeps it centred. */
  .timeline-item--left  .timeline-dot,
  .timeline-item--right .timeline-dot {
    position: absolute;
    left: 7px;
    top: 28px;
    grid-column: auto;
    justify-self: auto;
    margin: 0;
  }

  /* Little connector from the card to the dot's centre (top 28 + 17px radius) */
  .timeline-item--left  .timeline-card::before,
  .timeline-item--right .timeline-card::before {
    left: -18px; right: auto;
    top: 45px;
    width: 18px;
    background: linear-gradient(to left, transparent, rgba(201, 169, 110, 0.55));
  }

  .timeline-item--center {
    padding-left: 0;
    text-align: center;
  }
  .timeline-item--center .timeline-card { margin: 0 auto; }

  /* Fade straight up on phones — no sideways slide that could desync the rail. */
  .timeline-item--left[data-reveal],
  .timeline-item--right[data-reveal] { transform: translateY(18px); }
}

/* ============================================
   Confessions — sticky notes
   ============================================ */
.notes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: clamp(36px, 5vw, 56px);
  max-width: 1000px;
  margin: 0 auto;
  padding: 28px 8px 20px;
}

.note {
  position: relative;
  padding: clamp(32px, 4.5vw, 44px) clamp(24px, 3.5vw, 36px) clamp(28px, 4vw, 38px);
  border-radius: 4px;
  min-height: 190px;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: rotate(var(--tilt, 0deg));
  transition:
    transform 0.55s cubic-bezier(.2,.7,.2,1),
    box-shadow 0.55s ease;
  box-shadow:
    0 14px 26px -10px rgba(180, 130, 110, 0.4),
    0 4px 8px -2px rgba(180, 130, 110, 0.18),
    inset 0 0 0 1px rgba(255, 255, 255, 0.3);
}

.note::before {
  /* paper noise */
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/><feColorMatrix values='0 0 0 0 0.55  0 0 0 0 0.42  0 0 0 0 0.28  0 0 0 0.08 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  opacity: 0.5;
  mix-blend-mode: multiply;
  border-radius: inherit;
  pointer-events: none;
}

.note__tape {
  position: absolute;
  top: -10px;
  left: 50%;
  transform: translateX(-50%) rotate(-3deg);
  width: 64px;
  height: 18px;
  background:
    linear-gradient(180deg, rgba(255, 250, 240, 0.85) 0%, rgba(255, 250, 240, 0.55) 100%);
  box-shadow:
    0 2px 4px rgba(80, 50, 30, 0.18),
    inset 0 0 0 1px rgba(255, 255, 255, 0.4);
  z-index: 2;
}
.note__tape::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    repeating-linear-gradient(90deg,
      rgba(255, 255, 255, 0.2) 0,
      rgba(255, 255, 255, 0.2) 1px,
      transparent 1px,
      transparent 3px);
  opacity: 0.5;
}

.note__text {
  position: relative;
  z-index: 1;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.1rem, 1.7vw, 1.4rem);
  line-height: 1.55;
  color: var(--ink);
  text-align: center;
  letter-spacing: 0.005em;
}
.note__text em {
  font-family: var(--hand);
  font-weight: 600;
  font-style: normal;
  font-size: 1.2em;
  color: var(--rose-deep);
}

.note:hover {
  transform: rotate(0) translateY(-8px) scale(1.03);
  box-shadow:
    0 30px 50px -16px rgba(180, 130, 110, 0.5),
    0 8px 16px -4px rgba(180, 130, 110, 0.28),
    inset 0 0 0 1px rgba(255, 255, 255, 0.4);
  z-index: 3;
}

/* Color variants */
.note--rose {
  background:
    radial-gradient(circle at 75% 12%, rgba(255, 255, 255, 0.4), transparent 50%),
    linear-gradient(180deg, var(--rose-soft) 0%, #f4d4ce 100%);
}
.note--peach {
  background:
    radial-gradient(circle at 75% 12%, rgba(255, 255, 255, 0.4), transparent 50%),
    linear-gradient(180deg, #fadcb8 0%, #f3c9a1 100%);
}
.note--cream {
  background:
    radial-gradient(circle at 75% 12%, rgba(255, 255, 255, 0.5), transparent 50%),
    linear-gradient(180deg, var(--cream) 0%, var(--cream-deep) 100%);
}
.note--gold {
  background:
    radial-gradient(circle at 75% 12%, rgba(255, 255, 255, 0.4), transparent 50%),
    linear-gradient(180deg, #f3e1b2 0%, var(--gold-soft) 100%);
}

/* ============================================
   Book / Letter
   ============================================ */
.letter {
  padding-bottom: clamp(80px, 12vh, 140px);
  overflow: visible;
}

.letter__hint {
  display: inline-block;
  padding: 6px 14px;
  border: 1px solid rgba(201, 169, 110, 0.4);
  border-radius: 30px;
  background: rgba(255, 250, 240, 0.6);
  font-family: var(--hand);
  font-size: clamp(0.95rem, 1.3vw, 1.1rem);
  color: var(--gold-deep);
}

/* The 3D stage — slightly larger now so text is readable */
.book-stage {
  --book-w: clamp(320px, calc(100vw - 24px), 900px);
  --book-h: calc(var(--book-w) * 0.7);
  --page-w: calc(var(--book-w) / 2);

  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: clamp(20px, 4vh, 40px) auto 0;
  padding: 30px 0 60px;
  perspective: 2600px;
  perspective-origin: 50% 30%;
}

.desk-surface {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 130%;
  max-width: min(1200px, 100%);
  height: 300px;
  transform: translate(-50%, -8%) rotateX(74deg);
  transform-style: preserve-3d;
  background:
    radial-gradient(ellipse at 50% 50%, rgba(120, 80, 50, 0.18), transparent 70%);
  opacity: 0;
  transition: opacity 1.2s ease;
  pointer-events: none;
  z-index: 0;
}
.book-stage .desk-surface { opacity: 0.4; }
.book-stage.is-active .desk-surface { opacity: 0.28; }

.book-shadow {
  position: absolute;
  top: calc(50% + var(--book-h) * 0.45);
  left: 50%;
  width: calc(var(--book-w) * 0.9);
  height: 44px;
  /* Match the book's translateX(-25%) so the shadow lines up with the cover when closed */
  transform: translate(-50%, -50%) translateX(calc(var(--book-w) * -0.25));
  background: radial-gradient(ellipse at center, rgba(80, 50, 30, 0.55), transparent 65%);
  filter: blur(14px);
  opacity: 0.7;
  transition: all 1.6s cubic-bezier(.2,.7,.2,1);
  pointer-events: none;
  z-index: 0;
}
.book-stage.is-active .book-shadow {
  opacity: 0.28;
  width: calc(var(--book-w) * 0.6);
  filter: blur(22px);
  top: calc(50% + var(--book-h) * 0.55);
  /* still cover-centered */
  transform: translate(-50%, -50%) translateX(calc(var(--book-w) * -0.25));
}
.book-stage.is-opened .book-shadow {
  /* book is centered now */
  transform: translate(-50%, -50%);
  width: calc(var(--book-w) * 0.8);
}

/* The book itself — centered on the desk via translateX(-25%) trick.
   Initial closed: shifted left so only the right-half (the cover) is centered.
   Opened: translateX(0) for symmetric spread. */
.book-3d {
  position: relative;
  width: var(--book-w);
  height: var(--book-h);
  transform-style: preserve-3d;
  /* Initial: lying tilted on the desk, shifted left to visually center the cover */
  transform:
    translateX(-25%)
    translateY(40px)
    translateZ(-160px)
    rotateX(62deg)
    scale(0.88);
  transition: transform 1.6s cubic-bezier(.2,.7,.2,1);
  z-index: 1;
}

.book-stage.is-active .book-3d {
  /* Upright, still cover-centered */
  transform:
    translateX(-25%)
    translateY(0)
    translateZ(0)
    rotateX(0deg)
    scale(1);
}

.book-stage.is-opened .book-3d {
  /* Opened: shifted back so the full spread is centered */
  transform:
    translateX(0)
    translateY(0)
    translateZ(0)
    rotateX(0deg)
    scale(1);
}

/* Subtle idle float once fully opened */
.book-stage.is-active.is-idle .book-3d {
  animation: book-float 6s ease-in-out infinite;
}
@keyframes book-float {
  0%, 100% { transform: translateX(0) translateY(0) rotateX(0); }
  50%      { transform: translateX(0) translateY(-6px) rotateX(-1deg); }
}

/* Back cover — hidden when closed, fades in as the book opens */
.back-cover {
  position: absolute;
  top: -10px;
  left: -14px;
  right: -14px;
  bottom: -12px;
  background:
    radial-gradient(ellipse at 50% 100%, rgba(0, 0, 0, 0.25), transparent 55%),
    linear-gradient(135deg, var(--burgundy) 0%, var(--rose-dark) 50%, var(--burgundy-deep) 100%);
  border-radius: 4px;
  box-shadow:
    inset 0 0 0 1px rgba(255, 220, 180, 0.12),
    inset 8px 0 14px -6px rgba(0, 0, 0, 0.4),
    inset -8px 0 14px -6px rgba(0, 0, 0, 0.4),
    0 30px 60px -20px rgba(60, 30, 30, 0.55);
  z-index: 0;
  transform: translateZ(-3px);
  opacity: 0;
  transition: opacity 1.0s ease 0.15s;
}
.book-stage.is-opened .back-cover { opacity: 1; }

/* Leaves */
.leaf {
  position: absolute;
  top: 0;
  left: 50%;
  width: var(--page-w);
  height: 100%;
  transform-origin: left center;
  transform-style: preserve-3d;
  transition: transform 1.4s cubic-bezier(0.45, 0.05, 0.15, 1);
  will-change: transform;
}

/* iOS Safari sorts coplanar preserve-3d siblings by their real Z position and
   ignores z-index — so every right-hand page painted on top of the others.
   Give each leaf a distinct Z depth so opaque front pages occlude the ones
   beneath, on every browser. (Values are tiny — visually imperceptible.) */
.leaf[data-leaf="0"] { z-index: 40; transform: translateZ(3px); }
.leaf[data-leaf="1"] { z-index: 39; transform: translateZ(2px); }
.leaf[data-leaf="2"] { z-index: 38; transform: translateZ(1px); }
.leaf[data-leaf="3"] { z-index: 37; transform: translateZ(0px); }

.leaf[data-leaf="0"].is-flipped { z-index: 20; transform: rotateY(-180deg) translateZ(3px); }
.leaf[data-leaf="1"].is-flipped { z-index: 21; transform: rotateY(-180deg) translateZ(2px); }
.leaf[data-leaf="2"].is-flipped { z-index: 22; transform: rotateY(-180deg) translateZ(1px); }
.leaf[data-leaf="3"].is-flipped { z-index: 23; transform: rotateY(-180deg) translateZ(0px); }

.leaf.is-flipping { z-index: 50 !important; }

/* Leaf faces */
.leaf-face {
  position: absolute;
  inset: 0;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  border-radius: 2px 6px 6px 2px;
  overflow: hidden;
  /* Hard-swap face visibility around the mid-point of the 1.4s flip so a
     page can never show through to the opposite side. The noise overlay
     (mix-blend-mode) and the animated seal create compositing layers that
     otherwise ignore backface-visibility. */
  transition: opacity 0.18s linear 0.62s;
}

/* Keep only the face turned toward the reader opaque */
.leaf.is-flipped .leaf-face--front { opacity: 0; }
.leaf:not(.is-flipped) .leaf-face--back { opacity: 0; }

/* Leaves outside the current spread are fully hidden (JS-driven). `visibility`
   is respected by iOS Safari where 3D occlusion is not, so no page can bleed
   through the one on top. */
.leaf.is-buried { visibility: hidden; }

.leaf-face--back {
  transform: rotateY(180deg);
  border-radius: 6px 2px 2px 6px;
}

/* Spine-side shadow */
.leaf-face::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  width: 24px;
  pointer-events: none;
  opacity: 0.55;
}
.leaf-face--front::after {
  left: 0;
  background: linear-gradient(to right, rgba(40, 20, 10, 0.18), transparent);
}
.leaf-face--back::after {
  right: 0;
  background: linear-gradient(to left, rgba(40, 20, 10, 0.18), transparent);
}

/* Top edge gilt */
.leaf-face::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 3px;
  background: linear-gradient(90deg,
    rgba(201, 169, 110, 0) 0%,
    rgba(232, 207, 145, 0.6) 20%,
    rgba(232, 207, 145, 0.7) 80%,
    rgba(201, 169, 110, 0) 100%);
  pointer-events: none;
  z-index: 5;
}

/* ────── COVER FACE ────── */
.cover-face {
  background:
    radial-gradient(circle at 30% 20%, rgba(255, 210, 160, 0.12), transparent 60%),
    linear-gradient(135deg, var(--burgundy) 0%, var(--rose-dark) 55%, var(--burgundy-deep) 100%);
  color: rgba(232, 207, 145, 0.95);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6%;
}
.cover-face::before { background: none; }

.cover-frame {
  position: absolute;
  inset: 14px;
  border: 1px solid rgba(232, 207, 145, 0.45);
  border-radius: 3px;
  pointer-events: none;
}
.cover-frame::before,
.cover-frame::after {
  content: '';
  position: absolute;
  inset: 6px;
  border: 1px solid rgba(232, 207, 145, 0.25);
  border-radius: 2px;
}

.cover-inner {
  position: relative;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(10px, 1.6vw, 18px);
  z-index: 2;
}

.cover-eyebrow {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(0.9rem, calc(var(--book-w) * 0.013), 1.15rem);
  letter-spacing: 0.18em;
  text-transform: lowercase;
  opacity: 0.7;
}

.cover-flourish {
  font-size: clamp(1.1rem, calc(var(--book-w) * 0.018), 1.5rem);
  opacity: 0.8;
}

.cover-title {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(2.6rem, calc(var(--book-w) * 0.07), 4.4rem);
  letter-spacing: 0.06em;
  background: linear-gradient(135deg, #f5d8a0 0%, #e8c98a 45%, #c9a96e 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
  line-height: 1;
  padding: 4px 0;
}

.cover-rule {
  width: clamp(70px, calc(var(--book-w) * 0.12), 120px);
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(232, 207, 145, 0.6), transparent);
}

.cover-sub {
  font-size: clamp(1.2rem, calc(var(--book-w) * 0.024), 1.7rem);
  opacity: 0.85;
  letter-spacing: 0.04em;
}

.cover-date {
  font-family: var(--serif);
  font-size: clamp(0.85rem, calc(var(--book-w) * 0.013), 1.05rem);
  letter-spacing: 0.3em;
  opacity: 0.6;
  margin-top: 4px;
}

.cover-hint {
  position: absolute;
  bottom: 18px;
  left: 0; right: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  font-size: 0.8rem;
  opacity: 0;
  color: rgba(232, 207, 145, 0.85);
  transition: opacity 0.6s ease 0.4s;
}
.book-stage.is-active .cover-hint { opacity: 0.75; }
.book-stage.is-opened .cover-hint { opacity: 0; transition-delay: 0s; }
.cover-hint .hand { font-size: 1rem; }

/* ────── PAGE FACE ────── */
.page-face {
  background:
    linear-gradient(180deg, #fffaf0 0%, var(--paper) 50%, var(--paper-deep) 100%);
  color: var(--ink);
  padding:
    clamp(18px, calc(var(--book-w) * 0.045), 44px)
    clamp(22px, calc(var(--book-w) * 0.055), 52px);
  display: flex;
  flex-direction: column;
}

.page-face > .page-content { flex: 1; position: relative; }

.page-face .page-content::before {
  content: '';
  position: absolute;
  inset: -10px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2'/><feColorMatrix values='0 0 0 0 0.55  0 0 0 0 0.42  0 0 0 0 0.28  0 0 0 0.1 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  pointer-events: none;
  opacity: 0.45;
  mix-blend-mode: multiply;
  border-radius: inherit;
  z-index: 0;
}

.page-content { position: relative; z-index: 1; }

.page-content--centered {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 20px;
}
.page-content--final {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.page-deco {
  font-size: clamp(0.85rem, calc(var(--book-w) * 0.013), 1rem);
  color: var(--gold);
  letter-spacing: 0.4em;
  opacity: 0.7;
}

.page-quote {
  font-size: clamp(1.25rem, calc(var(--book-w) * 0.038), 1.95rem);
  line-height: 1.5;
  color: var(--rose-deep);
}
.page-quote em {
  font-style: normal;
  color: var(--rose-dark);
  font-weight: 600;
}

.page-tip {
  margin-top: 8px;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(0.85rem, calc(var(--book-w) * 0.013), 1rem);
  color: var(--ink-faint);
  letter-spacing: 0.04em;
}

.page-greeting {
  font-family: var(--hand);
  font-size: clamp(1.8rem, calc(var(--book-w) * 0.05), 2.8rem);
  color: var(--rose-deep);
  margin-bottom: clamp(14px, 2vw, 22px);
}

.page-heading {
  font-size: clamp(1.5rem, calc(var(--book-w) * 0.042), 2.4rem);
  color: var(--rose-deep);
  margin-bottom: clamp(14px, 2vw, 22px);
  text-align: center;
}

.page-para {
  font-family: var(--serif);
  font-size: clamp(1rem, calc(var(--book-w) * 0.023), 1.3rem);
  line-height: 1.65;
  margin-bottom: clamp(12px, 1.6vw, 18px);
  text-indent: 1.4em;
  color: var(--ink);
}
.page-para em {
  font-family: var(--hand);
  font-weight: 600;
  font-style: normal;
  color: var(--rose-deep);
  font-size: 1.18em;
}
.page-para--centered {
  text-align: center;
  text-indent: 0;
  font-style: italic;
  color: var(--rose-deep);
  font-size: clamp(1.15rem, calc(var(--book-w) * 0.03), 1.55rem);
  margin: 10px 0;
}
.page-para--em {
  font-size: clamp(1.7rem, calc(var(--book-w) * 0.05), 2.6rem);
  color: var(--rose-dark);
  font-weight: 500;
  margin-bottom: clamp(24px, 4vw, 36px);
}

.page-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: clamp(8px, 1.4vw, 14px);
  max-width: 92%;
  margin: 0 auto;
}
.page-list li {
  font-family: var(--serif);
  font-size: clamp(1rem, calc(var(--book-w) * 0.023), 1.3rem);
  line-height: 1.5;
  color: var(--ink);
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.page-list-marker {
  color: var(--rose-deep);
  font-size: 0.9em;
  padding-top: 4px;
  flex-shrink: 0;
}
.page-list--wishes .page-list-marker { color: var(--gold-deep); }

.page-sign {
  margin-top: clamp(20px, 3vw, 36px);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  color: var(--rose-deep);
  padding-right: 8%;
}
.page-sign .hand { font-size: clamp(1.15rem, calc(var(--book-w) * 0.022), 1.5rem); }
.page-sign .hand--big {
  font-size: clamp(1.9rem, calc(var(--book-w) * 0.05), 2.8rem);
  font-weight: 600;
  line-height: 1;
}

.page-number {
  display: block;
  text-align: center;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(0.75rem, calc(var(--book-w) * 0.013), 0.95rem);
  color: var(--ink-faint);
  letter-spacing: 0.2em;
  padding-top: 6px;
  position: relative;
  z-index: 1;
}

.seal {
  position: absolute;
  bottom: 8%;
  left: 10%;
  width: clamp(46px, calc(var(--book-w) * 0.065), 70px);
  height: clamp(46px, calc(var(--book-w) * 0.065), 70px);
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #d65b5b, var(--rose-deep) 60%, #5a2828);
  color: rgba(255, 240, 230, 0.95);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(1.3rem, calc(var(--book-w) * 0.024), 1.8rem);
  box-shadow:
    0 6px 14px -4px rgba(120, 50, 50, 0.6),
    inset 2px 4px 8px rgba(255, 255, 255, 0.15),
    inset -2px -4px 8px rgba(0, 0, 0, 0.25);
  transform: rotate(-10deg);
  animation: seal-pulse 3s ease-in-out infinite;
  z-index: 2;
}
@keyframes seal-pulse {
  0%, 100% { transform: rotate(-10deg) scale(1); }
  50%      { transform: rotate(-10deg) scale(1.06); }
}

/* Book controls */
.book-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  margin-top: clamp(36px, 5vw, 56px);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.6s ease 0.4s, transform 0.6s ease 0.4s;
}
.book-stage.is-opened .book-controls {
  opacity: 1;
  transform: translateY(0);
}

.book-btn {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: 1px solid rgba(201, 169, 110, 0.5);
  background: linear-gradient(180deg, #fffaf0, var(--paper));
  color: var(--rose-deep);
  font-family: var(--serif);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: var(--shadow-soft);
}
.book-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  background: linear-gradient(180deg, #fff, #fff6e0);
  box-shadow:
    0 14px 28px -10px rgba(120, 80, 50, 0.35),
    0 4px 8px -2px rgba(120, 80, 50, 0.15);
}
.book-btn:disabled { opacity: 0.35; cursor: not-allowed; }

.book-progress {
  font-family: var(--hand);
  font-size: 1.15rem;
  color: var(--gold-deep);
  min-width: 110px;
  text-align: center;
  letter-spacing: 0.02em;
}

/* Sparkles */
.sparkles {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 60;
}
.sparkle {
  position: absolute;
  top: 0; left: 0;
  font-size: 14px;
  opacity: 0;
  animation: sparkle-burst 1.6s ease-out forwards;
  will-change: transform, opacity;
}
@keyframes sparkle-burst {
  0%   { opacity: 0; transform: translate(0, 0) scale(0.4); }
  20%  { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--sx, 0), var(--sy, 0)) scale(1.2); }
}

/* Book mobile adjustments */
@media (max-width: 720px) {
  .letter { padding-left: 8px; padding-right: 8px; }
  .book-btn { width: 42px; height: 42px; font-size: 1.3rem; }
  .book-progress { font-size: 1rem; min-width: 90px; }
}

@media (max-width: 480px) {
  .page-para { text-indent: 0.7em; line-height: 1.5; }
  .page-list { max-width: 96%; }
}

/* ============================================
   July — birth symbols
   ============================================ */
.july-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: clamp(20px, 3vw, 36px);
  max-width: 1000px;
  margin: 0 auto;
}

.july-card {
  position: relative;
  padding: clamp(28px, 3.5vw, 42px) clamp(20px, 2.5vw, 30px);
  border-radius: 14px;
  background: linear-gradient(180deg, #fffaf0 0%, var(--paper) 100%);
  border: 1px solid rgba(201, 169, 110, 0.22);
  box-shadow: var(--shadow-soft);
  text-align: center;
  transition:
    transform 0.5s cubic-bezier(.2,.7,.2,1),
    box-shadow 0.5s ease;
}
.july-card:hover {
  transform: translateY(-6px);
  box-shadow: var(--shadow-card);
}

.july-icon {
  width: clamp(56px, 7vw, 72px);
  height: clamp(56px, 7vw, 72px);
  margin: 0 auto clamp(12px, 1.6vw, 16px);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  color: var(--gold-deep);
  background: radial-gradient(circle at 35% 30%, #fff7e6, #f1e1bf);
  box-shadow:
    inset 0 0 0 1px rgba(201, 169, 110, 0.4),
    0 6px 14px -6px rgba(120, 80, 50, 0.3);
  animation: july-bob 5s ease-in-out infinite;
}
.july-icon svg { width: 56%; height: 56%; display: block; }
@keyframes july-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-5px); }
}
.july-card:nth-child(2) .july-icon { animation-delay: 0.6s; }
.july-card:nth-child(3) .july-icon { animation-delay: 1.2s; }
.july-card:nth-child(4) .july-icon { animation-delay: 1.8s; }

.july-card--ruby .july-icon {
  color: var(--rose-deep);
  background: radial-gradient(circle at 35% 30%, #ffe9e4, #f3d2cc);
}
.july-card--moon .july-icon {
  color: var(--gold-deep);
  background: radial-gradient(circle at 35% 30%, #fff3d6, #ecdcb4);
}

.july-kicker {
  display: block;
  font-size: clamp(1rem, 1.5vw, 1.2rem);
  color: var(--gold-deep);
  margin-bottom: 2px;
  letter-spacing: 0.02em;
}

.july-name {
  font-family: var(--serif);
  font-weight: 600;
  font-style: italic;
  font-size: clamp(1.4rem, 2.2vw, 1.95rem);
  color: var(--ink);
  margin-bottom: 8px;
  line-height: 1.15;
}

.july-text {
  font-family: var(--serif);
  font-size: clamp(0.98rem, 1.4vw, 1.12rem);
  color: var(--ink-soft);
  line-height: 1.55;
}

/* ============================================
   Gift — surprise reveal
   ============================================ */
.gift-stage {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(18px, 3vh, 30px);
  max-width: 720px;
  margin: 0 auto;
}

.gift-box {
  position: relative;
  width: clamp(150px, 32vw, 196px);
  height: clamp(150px, 32vw, 196px);
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  transition: transform 0.5s cubic-bezier(.2,.7,.2,1);
}
.gift-box:hover { transform: translateY(-6px) rotate(-1deg); }
.gift-box:focus-visible {
  outline: 2px solid var(--gold-deep);
  outline-offset: 8px;
  border-radius: 10px;
}
.gift-box.is-open { cursor: default; }

/* soft glow behind the box, blooms on open */
.gift-glow {
  position: absolute;
  left: 50%; top: 55%;
  width: 120%; height: 120%;
  transform: translate(-50%, -50%) scale(0.4);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(243, 201, 161, 0.6), transparent 65%);
  opacity: 0;
  transition: opacity 0.8s ease, transform 0.8s ease;
  pointer-events: none;
  z-index: 0;
}
.gift-box.is-open .gift-glow { opacity: 1; transform: translate(-50%, -50%) scale(1); }

/* body */
.gift-body {
  position: absolute;
  left: 9%;
  bottom: 0;
  width: 82%;
  height: 62%;
  border-radius: 7px;
  background: linear-gradient(180deg, #fbeacc 0%, var(--paper-deep) 100%);
  box-shadow:
    var(--shadow-card),
    inset 0 0 0 1px rgba(255, 255, 255, 0.45);
  z-index: 1;
}
.gift-ribbon {
  position: absolute;
  left: 50%; top: 0; bottom: 0;
  width: 18%;
  transform: translateX(-50%);
  background: linear-gradient(180deg, var(--rose-deep), var(--gold-deep));
  opacity: 0.9;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
}

/* lid (holds the bow) — lifts away on open */
.gift-lid {
  position: absolute;
  left: 2%;
  top: 22%;
  width: 96%;
  height: 22%;
  border-radius: 7px;
  background: linear-gradient(180deg, #fff3da 0%, #f0d9af 100%);
  box-shadow:
    var(--shadow-soft),
    inset 0 0 0 1px rgba(255, 255, 255, 0.55);
  transform-origin: 50% 100%;
  transition: transform 0.75s cubic-bezier(.34,.6,.3,1.2), opacity 0.75s ease;
  z-index: 3;
}
.gift-lid-ribbon {
  position: absolute;
  left: 50%; top: 0; bottom: 0;
  width: 18%;
  transform: translateX(-50%);
  background: linear-gradient(180deg, var(--rose-deep), var(--gold-deep));
  opacity: 0.9;
}
.gift-box.is-open .gift-lid {
  transform: translateY(-150%) rotate(-16deg);
  opacity: 0.9;
}

.gift-bow {
  position: absolute;
  left: 50%; top: -52%;
  width: 72%;
  height: auto;
  transform: translateX(-50%);
  color: var(--rose-deep);
  filter: drop-shadow(0 4px 6px rgba(140, 70, 70, 0.3));
}
.gift-bow path { fill: currentColor; }
.gift-bow .gift-knot { fill: var(--rose-dark); }

.gift-hint {
  font-size: clamp(1.05rem, 1.6vw, 1.35rem);
  color: var(--gold-deep);
  letter-spacing: 0.02em;
  transition: opacity 0.4s ease;
  animation: gift-hint-bob 2.2s ease-in-out infinite;
}
.gift-stage.is-open .gift-hint { opacity: 0; animation: none; }
@keyframes gift-hint-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(4px); }
}

/* burst layer */
.gift-burst {
  position: absolute;
  left: 50%;
  top: clamp(75px, 16vw, 98px);
  width: 0; height: 0;
  z-index: 6;
  pointer-events: none;
}
.gift-burst .spark {
  position: absolute;
  top: 0; left: 0;
  opacity: 0;
  will-change: transform, opacity;
  animation: gift-spark 1.5s ease-out forwards;
}
@keyframes gift-spark {
  0%   { opacity: 0; transform: translate(0, 0) scale(0.3); }
  18%  { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--bx, 0), var(--by, 0)) scale(1.1) rotate(var(--br, 0deg)); }
}

/* revealed content */
.gift-reveal {
  width: 100%;
  max-width: 620px;
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.8s ease, transform 0.8s cubic-bezier(.2,.7,.2,1);
}
.gift-reveal.is-shown { opacity: 1; transform: translateY(0); }

.gift-message {
  font-family: var(--serif);
  font-size: clamp(1.2rem, 2.1vw, 1.6rem);
  line-height: 1.5;
  color: var(--ink);
  margin-bottom: clamp(18px, 3vh, 28px);
}
.gift-message .hand {
  display: inline-block;
  margin-top: 8px;
  font-size: 1.3em;
  color: var(--rose-deep);
}

.gift-coupons-title {
  font-size: clamp(1.05rem, 1.5vw, 1.25rem);
  color: var(--gold-deep);
  margin-bottom: 16px;
}
.gift-coupons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(10px, 1.6vw, 16px);
}
.coupon {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: 30px;
  border: 1px dashed rgba(184, 127, 127, 0.5);
  background: rgba(255, 250, 240, 0.7);
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(0.95rem, 1.4vw, 1.12rem);
  color: var(--ink);
  box-shadow: var(--shadow-soft);
  transition: transform 0.4s cubic-bezier(.2,.7,.2,1), box-shadow 0.4s ease;
}
.coupon:hover {
  transform: translateY(-3px) rotate(-1deg);
  box-shadow: var(--shadow-card);
}
.coupon__star { color: var(--gold-deep); }

/* ============================================
   Footer
   ============================================ */
.footer {
  position: relative;
  z-index: 5;
  text-align: center;
  padding: clamp(48px, 8vh, 96px) 24px clamp(48px, 8vh, 96px);
  color: var(--ink-soft);
}
.footer__ornament {
  font-size: 0.9rem;
  color: var(--gold);
  letter-spacing: 0.4em;
  margin-bottom: 18px;
  opacity: 0.7;
}
.footer__line .hand {
  font-size: clamp(1.2rem, 2vw, 1.6rem);
  color: var(--rose-deep);
}
.footer__date {
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(1.4rem, 2.4vw, 2rem);
  letter-spacing: 0.2em;
  color: var(--ink);
  margin: 8px 0 4px;
}
.footer__name {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1rem, 1.6vw, 1.2rem);
  color: var(--ink-faint);
  letter-spacing: 0.05em;
}

/* ============================================
   Phones — touch & small-screen polish
   ============================================ */

/* On touch screens :hover fires on tap and then "sticks" — the card stays
   lifted/rotated until you tap elsewhere. Neutralise the transform-based
   hover states so tapping never leaves an element stuck. */
@media (hover: none) {
  .love-card:hover {
    transform: none;
    filter: drop-shadow(0 14px 22px rgba(120, 80, 50, 0.2));
  }
  .july-card:hover,
  .coupon:hover,
  .gift-box:hover {
    transform: none;
  }
  .note:hover {
    transform: rotate(var(--tilt, 0deg));
    z-index: 1;
  }
}

/* Give the book spread a taller page ratio on narrow screens so the longer
   pages (wish lists, paragraphs) have room to breathe, and shrink the copy so
   nothing gets clipped at the bottom of a page. */
@media (max-width: 600px) {
  .book-stage { --book-h: calc(var(--book-w) * 0.98); }

  .page-face {
    padding:
      clamp(14px, calc(var(--book-w) * 0.04), 30px)
      clamp(16px, calc(var(--book-w) * 0.05), 34px);
  }
  .page-greeting { font-size: clamp(1.4rem, calc(var(--book-w) * 0.058), 2rem); margin-bottom: 8px; }
  .page-heading  { font-size: clamp(1.2rem, calc(var(--book-w) * 0.05), 1.7rem); margin-bottom: 10px; }
  .page-para {
    font-size: clamp(0.78rem, calc(var(--book-w) * 0.036), 1.1rem);
    line-height: 1.4;
    margin-bottom: 7px;
    text-indent: 1em;
  }
  .page-list { gap: 5px; max-width: 100%; }
  .page-list li {
    font-size: clamp(0.78rem, calc(var(--book-w) * 0.035), 1.1rem);
    line-height: 1.32;
  }
  .page-quote { font-size: clamp(1rem, calc(var(--book-w) * 0.05), 1.6rem); line-height: 1.4; }
  .page-para--centered { font-size: clamp(0.95rem, calc(var(--book-w) * 0.042), 1.3rem); }
  .page-para--em { font-size: clamp(1.3rem, calc(var(--book-w) * 0.07), 2rem); margin-bottom: 16px; }
}

/* Trim the generous vertical rhythm a touch on small phones. */
@media (max-width: 480px) {
  section {
    padding-top: clamp(56px, 9vh, 100px);
    padding-bottom: clamp(56px, 9vh, 100px);
  }
  .section__subtitle { margin-bottom: 40px; }
  .notes { gap: clamp(28px, 7vw, 40px); }
}

/* ============================================
   Reduced motion
   ============================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .petals { display: none; }
  .book-3d {
    transform: translateX(0) !important;
  }
}
