/* ── Reset ───────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; overscroll-behavior: none; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background-color 0.6s ease, color 0.4s ease;
}
img { max-width: 100%; display: block; }
button { cursor: pointer; border: none; background: none; font-family: inherit; }
::selection { background: var(--rose-light); color: var(--text); }

/* ── Custom properties (Royal Floral Gala default) ───────────────── */
:root {
  --bg:          #FFF0F3;
  --bg-warm:     #FDF5F0;
  --cream:       #FDF3E3;
  --rose:        #C0185F;
  --rose-light:  #F4A0B0;
  --rose-mid:    #E8789A;
  --rose-dark:   #8B1A4A;
  --gold:        #D4A017;
  --gold-light:  #F0D080;
  --brown:       #3D2B1F;
  --sage:        #6B8F5E;
  --text:        #3D2B1F;
  --text-soft:   #6B5040;

  /* Crescendo gradient stops */
  --crescendo-dark: #1C000D;
  --crescendo-mid:  #6B0A35;

  /* Theme selector background */
  --selector-bg-a:  var(--bg);
  --ts-start-bg:    rgba(255,255,255,0.65);

  /* Placeholder image background */
  --ph-bg-start: #FBE8F0;
  --ph-bg-end:   #EFC0D5;

  /* Orb glow */
  --orb-shadow: rgba(192,24,95,0.35);

  /* Petal colors (overridden per theme) */
  --petal-1: #F4A0B0;
  --petal-2: #E8789A;
  --petal-3: #FBBEC9;
  --petal-4: #D4A0B8;
  --petal-5: #F9C4D4;
  --petal-6: #EFAABF;

  --font-display: 'Playfair Display', Georgia, serif;
  --font-body:    'Lato', system-ui, -apple-system, sans-serif;

  --dur-fast:      200ms;
  --dur-base:      400ms;
  --dur-slow:      800ms;
  --dur-cinematic: 2000ms;
  --ease-out:      cubic-bezier(0.0, 0.0, 0.2, 1);
  --ease-spring:   cubic-bezier(0.34, 1.56, 0.64, 1);

  --max-w:         900px;
  --pad-x:         clamp(1.75rem, 5vw, 3rem);
  --pad-section:   clamp(4rem, 10vw, 7rem);
}

/* ── Falling petals ──────────────────────────────────────────────── */
#petals-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 5;
  overflow: hidden;
}
.petal {
  position: absolute;
  border-radius: 50% 0 50% 0;
  opacity: 0;
  pointer-events: none;
  animation: driftDown linear infinite;
}
.petal-color-1 { background: var(--petal-1); }
.petal-color-2 { background: var(--petal-2); }
.petal-color-3 { background: var(--petal-3); }
.petal-color-4 { background: var(--petal-4); }
.petal-color-5 { background: var(--petal-5); }
.petal-color-6 { background: var(--petal-6); }
@keyframes driftDown {
  0%   { transform: translateX(0) translateY(-40px) rotate(0deg); opacity: 0; }
  6%   { opacity: 0.75; }
  92%  { opacity: 0.55; }
  100% { transform: translateX(var(--drift, 40px)) translateY(110vh) rotate(var(--end-rotate, 540deg)); opacity: 0; }
}

/* ── Screen-reader utility ───────────────────────────────────────── */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip: rect(0,0,0,0);
  white-space: nowrap; border: 0;
}

/* ═══════════════════════════════════════════════════════════════════
   THEME SELECTOR
   ═══════════════════════════════════════════════════════════════════ */
#theme-selector {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow: hidden;
}
#theme-selector.dismissed {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.7s ease, visibility 0.7s ease;
}

/* Background — background-color is animatable */
.ts-bg {
  position: absolute;
  inset: 0;
  background-color: var(--selector-bg-a, var(--bg));
  transition: background-color 0.55s ease;
  z-index: 0;
}
.ts-bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 80% 55% at 50% 90%, rgba(0,0,0,0.06) 0%, transparent 70%);
}

.ts-inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 460px;
  padding: clamp(1.5rem, 6dvh, 4rem) var(--pad-x);
  display: flex;
  flex-direction: column;
  align-items: center;
}

.ts-label {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 1.75rem;
  transition: color 0.55s ease;
}

/* Orb area: flanked by minimal nav chevrons */
.ts-orb-area {
  display: flex;
  align-items: center;
  gap: 1.75rem;
  margin-bottom: 2rem;
}
.ts-nav-btn {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(255,255,255,0.35);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(255,255,255,0.6);
  color: var(--rose);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.2s ease, transform 0.15s ease, color 0.55s ease;
}
.ts-nav-btn:hover  { background: rgba(255,255,255,0.65); }
.ts-nav-btn:active { transform: scale(0.88); }
.ts-nav-btn:focus-visible { outline: 2px solid var(--rose); outline-offset: 3px; }

/* Animated orb */
.ts-orb-wrap {
  position: relative;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.ts-orb-wrap:focus-visible { outline: 2px solid var(--rose); outline-offset: 8px; border-radius: 50%; }
.ts-orb {
  width: min(170px, 44vw);
  height: min(170px, 44vw);
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, var(--gold-light) 0%, var(--rose) 55%, var(--rose-dark) 100%);
  box-shadow: 0 0 70px 18px var(--orb-shadow);
  animation: orbFloat 4s ease-in-out infinite;
  transition: background 0.55s ease, box-shadow 0.55s ease;
}
@keyframes orbFloat {
  0%, 100% { transform: translateY(0) translateX(0) scale(1); }
  50%       { transform: translateY(-14px) translateX(5px) scale(1.04); }
}

/* Theme name / tagline — ts-name has a fixed height so the whole block is CLS-free */
.ts-content {
  margin-bottom: 1.75rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.ts-content--exit {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.18s ease, transform 0.18s ease;
}
@keyframes tsContentIn {
  from { opacity: 0; transform: translateY(-12px); }
  to   { opacity: 1; transform: none; }
}
.ts-content--enter { animation: tsContentIn 0.35s ease both; }

.ts-icon {
  font-size: 2.25rem;
  line-height: 1;
  margin-bottom: 0.5rem;
  color: var(--rose);
  transition: color 0.55s ease;
  display: block;
  animation: iconSpin 0.4s ease;
}
@keyframes iconSpin {
  from { transform: rotate(-15deg) scale(0.85); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
.ts-name {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.625rem, 5vw, 2.5rem);
  color: var(--rose);
  line-height: 1.2;
  margin-bottom: 0.4rem;
  /* Fixed height = 2 lines at max font (2.5rem × 1.2 LH × 2) + buffer.
     Prevents CLS when names wrap differently across themes. */
  height: 6.5rem;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  text-wrap: balance;
  overflow: hidden;
  transition: color 0.55s ease;
}
.ts-tagline {
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 300;
  letter-spacing: 0.09em;
  color: var(--text-soft);
  transition: color 0.55s ease;
}

/* Dot indicators */
.ts-dots {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 2rem;
  align-items: center;
  /* Fixed width prevents flex parent from shifting on active-dot expansion (CLS fix) */
  width: clamp(180px, 55vw, 220px);
  justify-content: center;
}
.ts-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--rose-light);
  border: none;
  cursor: pointer;
  padding: 0;
  min-width: 8px;
  transition: width 0.3s var(--ease-spring), border-radius 0.3s ease, background 0.3s ease, transform 0.2s ease;
}
.ts-dot--active {
  background: var(--rose);
  width: 22px;
  border-radius: 4px;
}
.ts-dot:not(.ts-dot--active):hover { transform: scale(1.4); background: var(--rose-mid); }
.ts-dot:focus-visible { outline: 2px solid var(--rose); outline-offset: 3px; }

/* Surprise Me — small ✦ icon overlaid on orb */
.ts-surprise-btn {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(255,255,255,0.55);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,0.8);
  color: var(--gold);
  font-size: 0.65rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.2s ease, background 0.2s ease;
  z-index: 2;
}
.ts-surprise-btn:hover  { background: rgba(255,255,255,0.8); }
.ts-surprise-btn:active { transform: scale(0.85) rotate(90deg); }
.ts-surprise-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* Begin: minimal downward arrow, no text, bounces to invite interaction */
.ts-start-btn {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: none;
  color: var(--rose);
  opacity: 0.6;
  cursor: pointer;
  margin-top: 1rem;
  padding: 0;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  animation: arrowBounce 2.2s ease infinite;
  transition: opacity 0.3s ease, color 0.55s ease;
}
.ts-start-btn:hover, .ts-start-btn:focus-visible { opacity: 1; outline: none; animation: none; }
.ts-start-btn:active { transform: scale(0.88); animation: none; }
@keyframes arrowBounce {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(6px); }
}

/* ═══════════════════════════════════════════════════════════════════
   OPENING CEREMONY
   ═══════════════════════════════════════════════════════════════════ */
#ceremony {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: linear-gradient(160deg, var(--bg) 0%, var(--cream) 60%, var(--bg-warm) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  transition: opacity var(--dur-slow) ease, visibility var(--dur-slow) ease;
}
#ceremony.dismissed { opacity: 0; visibility: hidden; pointer-events: none; }

.ceremony-inner {
  padding: clamp(2rem, 8dvh, 5rem) var(--pad-x);
  max-width: 520px;
  width: 100%;
}

/* Bloom */
.ceremony-bloom {
  position: relative;
  width: 110px;
  height: 110px;
  margin: 0 auto 2.25rem;
}
.bloom-center {
  position: absolute;
  width: 22px; height: 22px;
  background: radial-gradient(circle, var(--gold-light), var(--gold));
  border-radius: 50%;
  top: 50%; left: 50%;
  z-index: 2;
  transform: translate(-50%, -50%) scale(0);
  animation: bloomCenter 0.5s var(--ease-spring) 1.6s both;
}
.bloom-petal {
  position: absolute;
  width: 15px; height: 32px;
  background: linear-gradient(to bottom, var(--rose-light), var(--rose));
  border-radius: 50% 50% 50% 50% / 40% 40% 60% 60%;
  top: 50%; left: 50%;
  margin-left: -7.5px;
  margin-top: -32px;
  transform-origin: 50% 100%;
  animation: bloomPetal 0.65s var(--ease-spring) var(--delay, 0.5s) both;
}
@keyframes bloomPetal {
  from { transform: rotate(var(--rot, 0deg)) scaleY(0); opacity: 0; }
  to   { transform: rotate(var(--rot, 0deg)) scaleY(1); opacity: 1; }
}
@keyframes bloomCenter {
  from { transform: translate(-50%, -50%) scale(0); }
  to   { transform: translate(-50%, -50%) scale(1); }
}

.ceremony-title {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(2.5rem, 9vw, 5rem);
  color: var(--rose);
  line-height: 1.15;
  text-wrap: balance;
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 1s ease, transform 1s ease, color 0.55s ease;
}
.ceremony-title.visible { opacity: 1; transform: none; }

.ceremony-date {
  font-family: var(--font-body);
  font-size: 0.8125rem;
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
  margin-top: 0.6rem;
  opacity: 0;
  transition: opacity 0.9s ease 0.3s, color 0.55s ease;
}
.ceremony-date.visible { opacity: 1; }

/* ── Begin button — circular bloom ──────────────────────────────── */
.begin-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 80px;
  margin-top: 2.5rem;
  border: 1.5px solid var(--rose);
  color: var(--rose);
  border-radius: 50%;
  background: none;
  opacity: 0;
  transition: opacity 0.6s ease, background var(--dur-base) ease, color var(--dur-base) ease,
              border-color 0.55s ease, transform 0.3s var(--ease-spring);
}
.begin-btn.visible {
  opacity: 1;
  animation: pulseBorder 2.4s ease 0.6s infinite;
}
.begin-btn:hover,
.begin-btn:focus-visible {
  background: var(--rose);
  color: white;
  outline: none;
  transform: scale(1.07);
}
.begin-btn:active { transform: scale(0.94); }
.begin-icon {
  width: 44px;
  height: 44px;
  transition: transform 0.4s var(--ease-spring);
}
.begin-btn:hover .begin-icon,
.begin-btn:focus-visible .begin-icon {
  transform: rotate(45deg) scale(1.1);
}
@keyframes pulseBorder {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--rose) 35%, transparent); }
  50%       { box-shadow: 0 0 0 12px color-mix(in srgb, var(--rose) 0%, transparent); }
}

/* ═══════════════════════════════════════════════════════════════════
   JOURNEY
   ═══════════════════════════════════════════════════════════════════ */
#opening  { padding-top: var(--pad-section); padding-bottom: var(--pad-section); }

.opening-poem {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: clamp(3rem, 8vw, 5rem) var(--pad-x) clamp(2rem, 5vw, 3rem);
  text-align: center;
}
.opening-poem p {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.5rem, 4.5vw, 2.5rem);
  color: var(--rose);
  line-height: 1.6;
  white-space: pre-line;
  transition: color 0.55s ease;
}

#opening-panels {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 var(--pad-x);
}
.opening-panel {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
  padding: clamp(2.5rem, 6vw, 4rem) 0;
  border-top: 1px solid var(--rose-light);
}
.panel-text {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.125rem, 3vw, 1.5rem);
  color: var(--text-soft);
  line-height: 1.75;
  display: flex;
  align-items: center;
  transition: color 0.55s ease;
}

/* Floral divider */
.floral-divider { max-width: var(--max-w); margin: 0 auto; padding: 0.5rem var(--pad-x); }
.floral-divider svg { width: 100%; height: auto; display: block; }

/* Chapters */
#chapters { padding-bottom: var(--pad-section); }
#chapters-container { max-width: var(--max-w); margin: 0 auto; padding: 0 var(--pad-x); }

.chapter {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
  padding: clamp(3.5rem, 8vw, 5rem) 0;
  border-bottom: 1px dashed rgba(192,24,95,0.2);
  align-items: center;
  position: relative;
}
.chapter-number {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 1.25rem;
  transition: color 0.55s ease;
}
.chapter-title {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 5vw, 2.875rem);
  color: var(--rose);
  line-height: 1.2;
  margin-bottom: 1.1rem;
  text-wrap: balance;
  transition: color 0.55s ease;
}
.chapter-body {
  font-family: var(--font-body);
  font-size: clamp(0.9375rem, 2vw, 1.0625rem);
  line-height: 1.9;
  color: var(--text);
  font-weight: 300;
  transition: color 0.55s ease;
}
.chapter-ornament {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1.5rem;
}
.chapter-ornament::before { content: ''; display: block; height: 1px; flex: 1; background: linear-gradient(to right, transparent, var(--rose-light)); }
.chapter-ornament::after  { content: ''; display: block; height: 1px; flex: 1; background: linear-gradient(to left, transparent, var(--rose-light)); }
.chapter-ornament-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--gold); flex-shrink: 0; transition: background 0.55s ease; }

.chapter-flourish { text-align: center; padding: 1.5rem 0 0; opacity: 0.5; }
.chapter-flourish svg { margin: 0 auto; }

/* Image placeholder */
.image-placeholder {
  width: 100%;
  aspect-ratio: var(--aspect, 4/3);
  background: linear-gradient(145deg, var(--ph-bg-start) 0%, var(--ph-bg-end) 100%);
  border: 1.5px dashed var(--rose-mid);
  border-radius: 5px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.875rem;
  overflow: hidden;
  position: relative;
  transition: background 0.55s ease, border-color 0.55s ease;
}
.image-placeholder::before {
  content: '';
  position: absolute;
  inset: 10px;
  border: 1px dashed var(--rose-mid);
  border-radius: 3px;
  opacity: 0.28;
}
.ph-icon { width: 30px; height: 30px; color: var(--rose-mid); opacity: 0.5; flex-shrink: 0; }
.ph-text {
  font-family: var(--font-body);
  font-size: 0.75rem;
  color: var(--rose);
  text-align: center;
  padding: 0 1.5rem;
  opacity: 0.65;
  line-height: 1.5;
  transition: color 0.55s ease;
}
.image-placeholder img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 4px;
  z-index: 3;
  filter: blur(18px);
  transform: scale(1.04);
  opacity: 0;
  transition: filter 0.7s ease, transform 0.7s ease, opacity 0.7s ease;
}
.image-placeholder img.ph-loaded {
  filter: none;
  transform: scale(1);
  opacity: 1;
}
.image-placeholder:has(img.ph-photo)::after {
  display: none !important;
}
.image-placeholder--loaded {
  border-style: solid;
  border-color: transparent;
  box-shadow: 0 6px 28px rgba(0,0,0,0.13), 0 2px 8px rgba(0,0,0,0.07);
}
.image-placeholder--loaded::before { display: none; }
/* Kill shimmer on loaded photos — ::after is the shimmer layer */
.image-placeholder--loaded::after  { display: none; }

/* Reveal animations */
.reveal { opacity: 0; transform: translateY(30px); transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out); }
.reveal.visible { opacity: 1; transform: none; }
.reveal-left  { transform: translateX(-30px); }
.reveal-right { transform: translateX(30px);  }
.reveal-left.visible, .reveal-right.visible { transform: none; }

/* Crescendo */
#crescendo {
  min-height: 75vh;
  background: linear-gradient(155deg,
    var(--crescendo-dark) 0%,
    var(--crescendo-mid)  35%,
    var(--rose)           70%,
    var(--gold)           120%
  );
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--pad-section) var(--pad-x);
  position: relative;
  overflow: hidden;
  transition: background 0.55s ease;
}
#crescendo::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 60% 50% at 50% 50%, rgba(255,255,255,0.07) 0%, transparent 70%);
  pointer-events: none;
}
.crescendo-inner { position: relative; z-index: 1; max-width: 720px; }
.crescendo-line {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(2.25rem, 7vw, 4.25rem);
  color: rgba(255,255,255,0.92);
  line-height: 1.25;
  margin-bottom: 0.25rem;
  text-wrap: balance;
}
.crescendo-highlight {
  display: block;
  font-family: var(--font-display);
  font-style: normal;
  font-weight: 700;
  font-size: clamp(1.4rem, 4vw, 2.5rem);
  color: var(--gold-light);
  letter-spacing: 0.04em;
  margin-top: 1.25rem;
  transition: color 0.55s ease;
}

/* Closing */
#closing {
  padding: var(--pad-section) var(--pad-x);
  background: linear-gradient(180deg, var(--cream) 0%, var(--bg) 100%);
  transition: background 0.55s ease;
}
.closing-inner { max-width: 560px; margin: 0 auto; text-align: center; }
.closing-image-wrap { margin-bottom: 3rem; }
.closing-message {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.0625rem, 2.8vw, 1.4375rem);
  color: var(--text);
  line-height: 2.1;
  margin-bottom: 1.5rem;
  transition: color 0.55s ease;
}
.closing-signoff {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.375rem, 3.5vw, 1.75rem);
  color: var(--rose);
  position: relative;
  padding-top: 3rem;
  transition: color 0.55s ease;
}
.closing-signoff::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 60px;
  height: 1px;
  background: linear-gradient(to right, transparent, var(--rose-light), transparent);
}

/* SVG heart */
.heart-wrap { width: clamp(70px, 18vw, 110px); margin: 5rem auto 2rem; }
.heart-svg { width: 100%; height: auto; display: block; }
#heart-path { transition: stroke-dashoffset 1.6s cubic-bezier(0.4,0,0.2,1), stroke 0.55s ease; stroke: var(--rose); }

/* ── Responsive — tablet up ──────────────────────────────────────── */
@media (min-width: 768px) {
  .opening-panel {
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: clamp(2rem, 5vw, 4rem);
  }
  .opening-panel.opening-panel--right .panel-image { order: 2; }
  .opening-panel.opening-panel--right .panel-text  { order: 1; }

  /* Image gets 45fr, text gets 55fr — applied per layout direction */
  .chapter {
    position: relative;
    grid-template-columns: 55fr 45fr; /* --right: text(order:1) → 55fr, image(order:2) → 45fr */
    gap: clamp(2rem, 5vw, 4.5rem);
  }
  .chapter--left {
    grid-template-columns: 45fr 55fr; /* image → 45fr, text → 55fr */
  }
  .chapter.chapter--right .chapter-image-wrap { order: 2; }
  .chapter.chapter--right .chapter-text-wrap  { order: 1; }

  .chapter--left  .chapter-text-wrap.reveal  { transition-delay: 120ms; }
  .chapter--right .chapter-image-wrap.reveal { transition-delay: 120ms; }

  /* Ghost chapter number */
  .chapter::before {
    content: attr(data-num);
    position: absolute;
    font-family: var(--font-display);
    font-size: clamp(6rem, 12vw, 12rem);
    color: var(--rose);
    opacity: 0.04;
    right: -0.5rem;
    top: 50%;
    transform: translateY(-50%);
    pointer-events: none;
    line-height: 1;
    z-index: 0;
    transition: color 0.55s ease;
  }

  /* Image hover lift */
  .chapter--left  .chapter-image-wrap:hover .image-placeholder {
    transform: rotate(0.8deg) scale(1.018);
    transition: transform 0.5s var(--ease-spring);
  }
  .chapter--right .chapter-image-wrap:hover .image-placeholder {
    transform: rotate(-0.8deg) scale(1.018);
    transition: transform 0.5s var(--ease-spring);
  }
}

/* ── Reduced motion ──────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .petal { display: none !important; }
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .reveal-child { opacity: 1 !important; transform: none !important; transition: none !important; }
  .title-word { opacity: 1 !important; transform: none !important; }
  .typewriter-cursor { display: none !important; }
}

/* ── Motion custom properties (defaults, overridden per theme) ───── */
:root {
  --motion-duration:      0.8s;
  --motion-ease:          cubic-bezier(0.0, 0.0, 0.2, 1);
  --motion-stagger:       80ms;
  --motion-reveal-offset: 30px;
}

/* ── Reveal — use theme motion properties ────────────────────────── */
.reveal {
  opacity: 0;
  transform: translateY(var(--motion-reveal-offset));
  transition:
    opacity   var(--motion-duration) var(--motion-ease),
    transform var(--motion-duration) var(--motion-ease);
}
.reveal.visible { opacity: 1; transform: none; }
.reveal-left  { transform: translateX(calc(-1 * var(--motion-reveal-offset))); }
.reveal-right { transform: translateX(var(--motion-reveal-offset)); }
.reveal-left.visible, .reveal-right.visible { transform: none; }

/* ── Staggered child reveals ─────────────────────────────────────── */
.reveal-child {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity   var(--motion-duration) var(--motion-ease),
    transform var(--motion-duration) var(--motion-ease);
}
.chapter-text-wrap.visible .reveal-child:nth-child(1) { opacity: 1; transform: none; transition-delay: 0ms; }
.chapter-text-wrap.visible .reveal-child:nth-child(2) { opacity: 1; transform: none; transition-delay: var(--motion-stagger); }
.chapter-text-wrap.visible .reveal-child:nth-child(3) { opacity: 1; transform: none; transition-delay: calc(var(--motion-stagger) * 2); }
.chapter-text-wrap.visible .reveal-child:nth-child(4) { opacity: 1; transform: none; transition-delay: calc(var(--motion-stagger) * 3); }

/* ── Word-level title animation ──────────────────────────────────── */
.title-word {
  display: inline-block;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.4s var(--motion-ease), transform 0.4s var(--motion-ease);
}
.chapter-text-wrap.visible .title-word { opacity: 1; transform: none; }

/* ── Odometer chapter number flip ────────────────────────────────── */
.chapter-number {
  display: inline-block;
  transform-origin: 50% 100%;
}
.chapter-number.odometer-flip { animation: odometerFlip var(--motion-duration) var(--motion-ease) both; }
@keyframes odometerFlip {
  from { transform: rotateX(-80deg) translateY(-6px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

/* ── Typewriter cursor ───────────────────────────────────────────── */
.typewriter-cursor {
  display: inline-block;
  width: 2px;
  height: 1.1em;
  background: var(--rose);
  vertical-align: text-bottom;
  margin-left: 2px;
  animation: cursorBlink 0.75s step-end infinite;
  border-radius: 1px;
}
@keyframes cursorBlink {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0; }
}

/* ── Grain texture overlay ───────────────────────────────────────── */
#grain-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 6;
  opacity: 0.022;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 300px 300px;
}

/* ── Scroll progress bar ─────────────────────────────────────────── */
#scroll-progress {
  position: fixed;
  top: 0;
  right: 0;
  width: 3px;
  height: 0%;
  background: linear-gradient(to bottom, var(--rose-light), var(--rose), var(--gold));
  z-index: 100;
  pointer-events: none;
  will-change: height;
  border-radius: 0 0 2px 2px;
  transition: background 0.55s ease;
}

/* ── Image frame ornament ────────────────────────────────────────── */
.image-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 2;
  overflow: visible;
}
.image-frame path { transition: stroke 0.55s ease; }

/* ── Chapter image depth + rotation (desktop only) ───────────────── */
@media (min-width: 481px) {
  .chapter--left  .chapter-image-wrap .image-placeholder {
    transform: rotate(0.8deg);
    box-shadow: 0 8px 40px rgba(0,0,0,0.10), 0 2px 8px rgba(0,0,0,0.06);
    transition: transform 0.6s var(--motion-ease), box-shadow 0.55s ease;
  }
  .chapter--right .chapter-image-wrap .image-placeholder {
    transform: rotate(-0.8deg);
    box-shadow: 0 8px 40px rgba(0,0,0,0.10), 0 2px 8px rgba(0,0,0,0.06);
    transition: transform 0.6s var(--motion-ease), box-shadow 0.55s ease;
  }
}

/* ── Floating section decorations ────────────────────────────────── */
.section-float {
  position: absolute;
  pointer-events: none;
  will-change: transform;
  z-index: 0;
}
@keyframes floatDrift {
  0%   { transform: translateY(0) rotate(0deg); }
  33%  { transform: translateY(-12px) rotate(6deg); }
  66%  { transform: translateY(6px) rotate(-4deg); }
  100% { transform: translateY(0) rotate(0deg); }
}

/* ── Burst particles (ceremony + crescendo) ──────────────────────── */
@keyframes burstOut {
  from { transform: translate(0,0) scale(1); opacity: 1; }
  to   { transform: translate(var(--tx), var(--ty)) scale(0); opacity: 0; }
}
@keyframes confettiFall {
  0%   { transform: translate(0,0) rotate(0deg); opacity: 1; }
  100% { transform: translate(var(--tx), calc(var(--ty) + 80px)) rotate(var(--rot)); opacity: 0; }
}

/* ── Heart fill on draw complete ─────────────────────────────────── */
#heart-path.filled {
  fill: var(--rose);
  fill-opacity: 0;
  animation: heartFill 0.5s var(--ease-spring) 0.2s both;
}
@keyframes heartFill {
  from { fill-opacity: 0; transform: scale(0.95); }
  to   { fill-opacity: 0.85; transform: scale(1); }
}
.heart-wrap {
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.heart-wrap:active .heart-svg { transform: scale(0.9); }
.heart-svg { transition: transform 0.15s var(--ease-spring); }

/* ── Sound toggle button ─────────────────────────────────────────── */
#sound-toggle {
  position: fixed;
  bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
  right: 1.25rem;
  /* Ensure it's always above any overlay elements that might cover it */
  z-index: 55 !important;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(255,255,255,0.9);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1.5px solid var(--rose-light);
  color: var(--rose);
  font-size: 1.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
  box-shadow: 0 4px 20px rgba(0,0,0,0.10);
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  opacity: 0;
  transform: scale(0.8) translateY(8px);
  transition: opacity 0.4s ease, transform 0.4s var(--ease-spring), background 0.3s ease, color 0.3s ease, border-color 0.55s ease;
}
#sound-toggle.visible {
  opacity: 1;
  transform: scale(1) translateY(0);
}
#sound-toggle:active { transform: scale(0.88); }
#sound-toggle.playing {
  background: var(--rose);
  color: white;
  border-color: var(--rose);
}
/* SVG icon states: muted shows X lines, playing shows wave arcs */
#sound-toggle .sound-wave { opacity: 0; transition: opacity 0.3s ease; }
#sound-toggle .sound-muted { opacity: 1; transition: opacity 0.3s ease; }
#sound-toggle.playing .sound-wave { opacity: 1; }
#sound-toggle.playing .sound-wave-2 {
  animation: soundWavePulse 1.4s ease-in-out infinite 0.15s;
}
#sound-toggle.playing .sound-muted { opacity: 0; }
.sound-icon { pointer-events: none; }
@keyframes soundWavePulse {
  0%, 100% { opacity: 0.55; }
  50%       { opacity: 1; }
}

/* ── Share button ────────────────────────────────────────────────── */
#share-btn {
  position: fixed;
  bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
  left: 1.25rem;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(255,255,255,0.9);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1.5px solid var(--rose-light);
  color: var(--rose);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
  box-shadow: 0 4px 20px rgba(0,0,0,0.10);
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  opacity: 0;
  transform: scale(0.8) translateY(8px);
  transition: opacity 0.4s ease 0.1s, transform 0.4s var(--ease-spring) 0.1s, border-color 0.55s ease;
}
#share-btn.visible {
  opacity: 1;
  transform: scale(1) translateY(0);
}
#share-btn:active { transform: scale(0.88); }
#share-btn svg { pointer-events: none; }

/* ── Image mode toggle button ────────────────────────────────────── */
.image-mode-btn {
  position: fixed;
  /* Sit cleanly above the sound button (48px height + 0.75rem gap) */
  bottom: calc(1.5rem + 48px + 0.75rem + env(safe-area-inset-bottom, 0px));
  right: 1.25rem;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(255,255,255,0.88);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1.5px solid var(--rose-light);
  color: var(--rose);
  font-size: 1.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 55;
  box-shadow: 0 4px 16px rgba(0,0,0,0.10);
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  opacity: 0;
  transform: scale(0.8) translateY(8px);
  transition: opacity 0.4s ease 0.2s, transform 0.4s var(--ease-spring) 0.2s, border-color 0.55s ease;
}
.image-mode-btn.visible {
  opacity: 1;
  transform: scale(1) translateY(0);
}
.image-mode-btn:active { transform: scale(0.88); }

/* ── Chapter navigation dots ─────────────────────────────────────── */
#chapter-nav {
  position: fixed;
  bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  display: flex;
  gap: 5px;
  align-items: center;
  background: rgba(255,255,255,0.88);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--rose-light);
  border-radius: 100px;
  padding: 8px 14px;
  z-index: 50;
  box-shadow: 0 4px 20px rgba(0,0,0,0.09);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease, transform 0.4s var(--ease-spring), border-color 0.55s ease;
  /* Prevent nav from growing wide enough to overlap the sound/share buttons */
  max-width: calc(100vw - 160px);
  overflow-x: auto;
  overflow-y: visible;
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* IE */
  scroll-behavior: smooth;
}
#chapter-nav::-webkit-scrollbar { display: none; }
#chapter-nav.visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}
.chapter-nav-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--rose-light);
  border: none;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  padding: 0;
  min-width: 7px;
  transition: background 0.3s ease, width 0.3s var(--ease-spring), border-radius 0.3s ease;
}
.chapter-nav-dot.active {
  background: var(--rose);
  width: 18px;
  border-radius: 4px;
}
.chapter-nav-dot:focus-visible { outline: 2px solid var(--rose); outline-offset: 2px; }

/* ── Orientation lock overlay ────────────────────────────────────── */
#orientation-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.88);
  z-index: 600;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  text-align: center;
  padding: 2rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}
#orientation-overlay.visible {
  opacity: 1;
  pointer-events: auto;
}
.orient-icon {
  font-size: 3rem;
  animation: rotatePh 1.8s ease-in-out infinite alternate;
}
@keyframes rotatePh {
  from { transform: rotate(0deg); }
  to   { transform: rotate(90deg); }
}
#orientation-overlay p {
  font-family: var(--font-body);
  font-size: 1rem;
  color: rgba(255,255,255,0.88);
  max-width: 260px;
  line-height: 1.6;
}

/* ── Safe area overrides for bottom-padding ──────────────────────── */
#closing {
  padding-bottom: calc(var(--pad-section) + env(safe-area-inset-bottom, 0px));
}
#ceremony .ceremony-inner {
  padding-top: calc(2rem + env(safe-area-inset-top, 0px));
}

/* ── Global touch target + tap delay removal ─────────────────────── */
button, a, [role="button"] {
  touch-action: manipulation;

}

/* ════════════════════════════════════════════════════════════════════
   PHASE 4-13 ADDITIONS
   ════════════════════════════════════════════════════════════════════ */

/* ── Skip link ───────────────────────────────────────────────────── */
.skip-link {
  position: fixed;
  top: -100%;
  left: 1rem;
  z-index: 700;
  background: var(--rose);
  color: white;
  padding: 0.75rem 1.25rem;
  border-radius: 4px;
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 700;
  text-decoration: none;
  transition: top 0.2s ease;
}
.skip-link:focus { top: 1rem; }

/* ── Portal transition overlay ───────────────────────────────────── */
#portal-overlay {
  position: fixed;
  inset: 0;
  background: radial-gradient(circle at var(--pcx, 50%) var(--pcy, 50%), var(--gold-light) 0%, var(--rose) 40%, var(--rose-dark) 100%);
  z-index: 350;
  pointer-events: none;
  clip-path: circle(0px at 50% 40%);
  transition: background 0.55s ease;
}
#portal-overlay.expanding {
  animation: portalExpand 0.28s cubic-bezier(0.4,0,1,1) both;
}
#portal-overlay.collapsing {
  animation: portalCollapse 0.34s cubic-bezier(0,0,0.2,1) both;
}
@keyframes portalExpand {
  from { clip-path: circle(0px at var(--pcx, 50%) var(--pcy, 40%)); }
  to   { clip-path: circle(200vmax at var(--pcx, 50%) var(--pcy, 40%)); }
}
@keyframes portalCollapse {
  from { clip-path: circle(200vmax at var(--pcx, 50%) var(--pcy, 40%)); }
  to   { clip-path: circle(0px at var(--pcx, 50%) var(--pcy, 40%)); }
}

/* ── Ambient background breathing ───────────────────────────────── */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  background: radial-gradient(ellipse 60% 50% at 50% 30%, var(--bg-warm) 0%, transparent 70%);
  pointer-events: none;
  z-index: 0;
  animation: bgBreathe 12s ease-in-out infinite;
  transition: background 0.55s ease;
}
@keyframes bgBreathe {
  0%, 100% { opacity: 0.25; }
  50%       { opacity: 0.6; }
}

/* ── Ceremony: recipient + days counter ──────────────────────────── */
.ceremony-recipient {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1rem, 3vw, 1.375rem);
  color: var(--gold);
  margin-top: 0.4rem;
  opacity: 0;
  transition: opacity 0.8s ease, color 0.55s ease;
}
.ceremony-recipient.visible { opacity: 1; }

.ceremony-days {
  font-family: var(--font-body);
  font-size: 0.8125rem;
  font-weight: 300;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-soft);
  margin-top: 0.3rem;
  opacity: 0;
  min-height: 1.4em;
  transition: opacity 0.8s ease, color 0.55s ease;
}
.ceremony-days.visible { opacity: 1; }

/* ── Begin button + countdown ring ──────────────────────────────── */
.begin-btn-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 2.75rem;
}
.begin-btn {
  margin-top: 0;
  position: relative;
  z-index: 1;
}
.begin-countdown-ring {
  position: absolute;
  inset: -10px;
  width: calc(100% + 20px);
  height: calc(100% + 20px);
  pointer-events: none;
  transform: rotate(-90deg);
  opacity: 0;
  transition: opacity 0.4s ease;
}
.begin-countdown-ring.active { opacity: 1; }
.countdown-circle {
  fill: none;
  stroke: var(--rose-light);
  stroke-width: 2;
  stroke-dasharray: 188;
  stroke-dashoffset: 188;
  stroke-linecap: round;
  transition: stroke 0.55s ease;
}
.countdown-circle.running {
  animation: countdownFill 10s linear forwards;
}
@keyframes countdownFill {
  from { stroke-dashoffset: 188; }
  to   { stroke-dashoffset: 0; }
}


/* ── Theme preview bubble ────────────────────────────────────────── */
#ts-preview-bubble {
  position: fixed;
  background: var(--cream);
  border: 1px solid var(--rose-light);
  border-radius: 8px;
  padding: 0.4rem 0.8rem;
  font-family: var(--font-body);
  font-size: 0.75rem;
  color: var(--text);
  white-space: nowrap;
  z-index: 400;
  box-shadow: 0 4px 16px rgba(0,0,0,0.1);
  pointer-events: none;
  transform: translateY(-4px);
  transition: background 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}
#ts-preview-bubble::after {
  content: '';
  position: absolute;
  bottom: -6px;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--rose-light);
  border-bottom: none;
}

/* ── Pull-to-restart indicator ───────────────────────────────────── */
#pull-restart-indicator {
  position: fixed;
  top: 0;
  left: 50%;
  transform: translateX(-50%) translateY(-60px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  z-index: 400;
  pointer-events: none;
  opacity: 0;
  padding-top: calc(0.75rem + env(safe-area-inset-top, 0px));
}
.pull-icon {
  font-size: 1.5rem;
  color: var(--rose);
  line-height: 1;
}
.pull-label {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-soft);
}

/* ── Scroll-direction chapter header ─────────────────────────────── */
#chapter-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 60;
  height: 50px;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0 var(--pad-x);
  padding-top: env(safe-area-inset-top, 0px);
  background: rgba(255,255,255,0.88);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--rose-light);
  transform: translateY(-100%);
  transition: transform 0.3s var(--ease-spring), border-color 0.55s ease, background 0.55s ease;
  pointer-events: none;
}
#chapter-header.visible {
  transform: translateY(0);
  pointer-events: auto;
}
#chapter-header-num {
  font-family: var(--font-body);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--gold);
  flex-shrink: 0;
  transition: color 0.55s ease;
}
#chapter-header-title {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 0.9375rem;
  color: var(--rose);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 0.55s ease;
}

/* ── TOC bottom sheet ────────────────────────────────────────────── */
#toc-sheet {
  position: fixed;
  inset: 0;
  z-index: 400;
}
#toc-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,0.45);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
#toc-content {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  max-height: 80vh;
  background: var(--bg);
  border-radius: 20px 20px 0 0;
  padding: 0 var(--pad-x) calc(2rem + env(safe-area-inset-bottom, 0px));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  transform: translateY(100%);
  transition: transform 0.4s var(--ease-spring), background 0.55s ease;
}
#toc-sheet.open #toc-content { transform: translateY(0); }
#toc-handle {
  width: 40px;
  height: 4px;
  background: var(--rose-light);
  border-radius: 2px;
  margin: 1rem auto 0;
  transition: background 0.55s ease;
}
#toc-heading {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.375rem;
  color: var(--rose);
  margin: 1.25rem 0 1rem;
  transition: color 0.55s ease;
}
#toc-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}
.toc-item {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.875rem 0;
  border-bottom: 1px solid rgba(192,24,95,0.08);
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: opacity 0.2s ease;
}
.toc-item:active { opacity: 0.6; }
.toc-item-num {
  font-family: var(--font-body);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.28em;
  color: var(--gold);
  flex-shrink: 0;
  width: 2rem;
  transition: color 0.55s ease;
}
.toc-item-title {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.0625rem;
  color: var(--text);
  transition: color 0.55s ease;
}
.toc-item-mood {
  margin-left: auto;
  font-size: 1rem;
  flex-shrink: 0;
}
.toc-item.active .toc-item-title { color: var(--rose); }
.toc-item.active .toc-item-num { color: var(--rose); }

/* ── Replay button ───────────────────────────────────────────────── */
#replay-wrap {
  margin-top: 3.5rem;
  text-align: center;
}
#replay-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-soft);
  padding: 0.6rem;
  touch-action: manipulation;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  opacity: 0.5;
  transition: opacity 0.3s ease, color 0.3s ease, transform 0.5s var(--ease-spring);
}
#replay-btn:hover, #replay-btn:focus-visible {
  opacity: 1;
  color: var(--rose);
  transform: rotate(-180deg);
  outline: none;
}
#replay-btn:active { transform: rotate(-180deg) scale(0.9); }
.replay-icon {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
}
.replay-label {
  font-family: var(--font-body);
  font-size: 0.52rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.75;
  /* Counter-rotate label so it reads correctly during the spin */
  transition: transform 0.5s var(--ease-spring);
}
#replay-btn:hover .replay-label,
#replay-btn:focus-visible .replay-label {
  transform: rotate(180deg);
}

/* ── Crescendo pulse rings ───────────────────────────────────────── */
.crescendo-inner::before, .crescendo-inner::after {
  content: '';
  position: absolute;
  width: min(400px, 90vw);
  height: min(400px, 90vw);
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.12);
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.2);
  opacity: 0;
  pointer-events: none;
}
.crescendo-inner.rings-active::before {
  animation: ringPulse 3s ease-out 0.2s infinite;
}
.crescendo-inner.rings-active::after {
  animation: ringPulse 3s ease-out 1.1s infinite;
}
@keyframes ringPulse {
  0%   { transform: translate(-50%, -50%) scale(0.2); opacity: 0.7; }
  100% { transform: translate(-50%, -50%) scale(1.4); opacity: 0; }
}

/* ── Crescendo line stagger ──────────────────────────────────────── */
.crescendo-text.visible .reveal-child:nth-child(1) {
  opacity: 1; transform: none; transition-delay: 0ms;
}
.crescendo-text.visible .reveal-child:nth-child(2) {
  opacity: 1; transform: none; transition-delay: 420ms;
}
.crescendo-text.visible .reveal-child:nth-child(3) {
  opacity: 1; transform: none; transition-delay: 860ms;
}
.crescendo-highlight.visible,
.crescendo-text.visible .crescendo-highlight {
  animation: highlightScale 0.6s var(--ease-spring) 1.1s both;
}
@keyframes highlightScale {
  from { transform: scale(0.92); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

/* ── Image curtain reveal ────────────────────────────────────────── */
.image-curtain {
  position: absolute;
  inset: 0;
  background: var(--rose);
  transform-origin: right center;
  transform: scaleX(1);
  z-index: 4;
  border-radius: 4px;
  transition: transform 0.85s cubic-bezier(0.4,0,0.8,0), background 0.55s ease;
  pointer-events: none;
}
.chapter-image-wrap.visible .image-curtain,
.panel-image.visible .image-curtain,
.closing-image-wrap.visible .image-curtain {
  transform: scaleX(0);
}
.image-curtain.curtain-done {
  visibility: hidden;
}

/* ── Heart pulse after fill ──────────────────────────────────────── */
.heart-wrap.heart-done {
  animation: heartPulse 1.2s ease-in-out 0.6s 5;
}
@keyframes heartPulse {
  0%, 100% { transform: scale(1); }
  50%       { transform: scale(1.07); }
}

/* ── Love heart double-tap popup ─────────────────────────────────── */
.love-heart-popup {
  position: fixed;
  pointer-events: none;
  z-index: 300;
  font-size: 2.5rem;
  line-height: 1;
  color: var(--rose);
  transform: translate(-50%, -50%) scale(0);
  animation: loveHeartPop 0.85s ease-out both;
}
@keyframes loveHeartPop {
  0%   { transform: translate(-50%, -50%) scale(0); opacity: 1; }
  45%  { transform: translate(-50%, -80%) scale(1.3); opacity: 1; }
  100% { transform: translate(-50%, -130%) scale(0.8); opacity: 0; }
}

/* ── Poem underline SVG ──────────────────────────────────────────── */
.poem-underline {
  display: block;
  width: min(320px, 80%);
  height: 20px;
  margin: 0.75rem auto 0;
}
#poem-underline-path {
  stroke: var(--rose);
  stroke-dasharray: 340;
  stroke-dashoffset: 340;
  transition: stroke-dashoffset 1.6s ease 0.3s, stroke 0.55s ease;
}
#poem-underline-path.drawn { stroke-dashoffset: 0; }

/* ── Chapter mood tag ────────────────────────────────────────────── */
.chapter-mood {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-top: 1rem;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.1em;
  color: var(--gold);
  opacity: 0.8;
  transition: color 0.55s ease;
}

/* ── Chapter breadcrumb ──────────────────────────────────────────── */

/* ── Hidden easter egg chapter ───────────────────────────────────── */
#chapter-hidden {
  border-top: 1px dashed rgba(192,24,95,0.2);
  padding-top: clamp(2.5rem, 6vw, 4.5rem);
  margin-top: 2rem;
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.9s ease, transform 0.9s ease;
  pointer-events: none;
}
#chapter-hidden.revealed {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
#chapter-hidden .chapter-number {
  color: var(--rose);
  font-size: 1.5rem;
  letter-spacing: 0;
}


/* ── Closing signoff typewriter ──────────────────────────────────── */
.closing-signoff {
  position: relative;
  display: inline-block;
}
.signoff-underline {
  position: absolute;
  bottom: -4px;
  left: 0;
  width: 100%;
  height: 14px;
  pointer-events: none;
}
.signoff-underline path {
  stroke: var(--rose);
  fill: none;
  stroke-dasharray: 80;
  stroke-dashoffset: 80;
  stroke-linecap: round;
  stroke-width: 1.5;
  transition: stroke-dashoffset 1s ease 0.5s, stroke 0.55s ease;
}
.signoff-underline path.drawn { stroke-dashoffset: 0; }

/* ── Theme flash overlay ─────────────────────────────────────────── */
.theme-flash {
  position: fixed;
  inset: 0;
  z-index: 350;
  pointer-events: none;
  background: var(--rose);
  opacity: 0;
  transition: opacity 0.15s ease;
}

/* ── Floral divider — CSS var overrides (SVG presentation attrs have lower specificity) */
.fd-line        { stroke: var(--gold); }
.fd-petal       { fill: var(--rose-light); }
.fd-center      { fill: var(--rose); }
.fd-center-dot  { fill: var(--gold); }
.fd-accent      { fill: var(--gold); }

/* ── Orb pulse: handled via inline boxShadow in JS (avoids animation conflict) */

/* ── Image placeholder shimmer ───────────────────────────────────── */
@keyframes shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}
.image-placeholder::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255,255,255,0.18) 50%,
    transparent 100%
  );
  background-size: 200% 100%;
  animation: shimmer 2.8s ease-in-out infinite;
  z-index: 1;
  border-radius: 4px;
  pointer-events: none;
}
.ph-icon { z-index: 2; }
.ph-text  { z-index: 2; }

/* ── TOC active item accent ──────────────────────────────────────── */
.toc-item.active {
  background: rgba(192,24,95,0.05);
  border-radius: 4px;
  margin: 0 -0.5rem;
  padding: 0.875rem 0.5rem;
}

/* ── Chapter nav — desktop vertical side rail ────────────────────── */
@media (min-width: 1024px) {
  #chapter-nav {
    left: 1.5rem;
    bottom: 50%;
    transform: translateY(50%) translateX(-12px);
    flex-direction: column;
    padding: 14px 8px;
    gap: 5px;
  }
  #chapter-nav.visible {
    transform: translateY(50%) translateX(0);
  }
  .chapter-nav-dot.active {
    width: 7px;
    height: 18px;
    border-radius: 4px;
  }
}

/* ── Desktop — wider max-width ───────────────────────────────────── */
@media (min-width: 1280px) {
  :root {
    --max-w:       1100px;
    --pad-section: 8rem;
  }
}

/* ── TOC discovery hint ──────────────────────────────────────────── */
.chapter-nav-hint {
  position: fixed;
  bottom: calc(3.5rem + env(safe-area-inset-bottom, 0px) + 40px);
  left: 50%;
  transform: translateX(-50%);
  background: rgba(30,15,20,0.78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: rgba(255,255,255,0.9);
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: 0.14em;
  padding: 0.45rem 0.9rem;
  border-radius: 8px;
  white-space: nowrap;
  pointer-events: none;
  z-index: 60;
  opacity: 0;
  transition: opacity 0.4s ease;
}
.chapter-nav-hint.visible { opacity: 1; }
.chapter-nav-hint::after {
  content: '';
  position: absolute;
  bottom: -5px;
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: rgba(30,15,20,0.78);
  border-bottom: none;
}

/* ── Theme selector dedication line ──────────────────────────────── */
.ts-dedication {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 0.875rem;
  color: var(--rose-mid);
  letter-spacing: 0.06em;
  margin-bottom: 0.75rem;
  opacity: 0.7;
  transition: color 0.55s ease;
}

/* ── Closing author name ──────────────────────────────────────────── */
.closing-author {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.125rem, 3vw, 1.375rem);
  color: var(--rose);
  margin-top: 0.35rem;
  transition: color 0.55s ease;
}

/* ── Begin hint text in ceremony ─────────────────────────────────── */
.begin-hint {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 300;
  letter-spacing: 0.16em;
  color: var(--text-soft);
  opacity: 0;
  margin-top: 0.875rem;
  transition: opacity 0.8s ease 0.4s, color 0.55s ease;
}
.begin-hint.visible { opacity: 0.5; }

/* ── Anniversary dedication reveal below heart ───────────────────── */
.anniversary-dedication {
  font-family: var(--font-display);
  font-style: normal;
  font-size: clamp(1.625rem, 4.5vw, 2.25rem);
  color: var(--rose);
  text-align: center;
  margin-top: 3rem;
  letter-spacing: 0.02em;
  opacity: 0;
  transition: opacity 0.9s ease, color 0.55s ease;
}
.anniversary-dedication.visible { opacity: 1; }

/* ── Hidden chapter revealed: warm dark background ───────────────── */
#chapter-hidden.revealed {
  background: rgba(61,43,31,0.04);
  border-radius: 12px;
  padding-left:  var(--pad-x);
  padding-right: var(--pad-x);
  margin-left:   calc(-1 * var(--pad-x));
  margin-right:  calc(-1 * var(--pad-x));
}

/* ── Sound hint toast ────────────────────────────────────────────── */
.sound-hint-toast {
  position: fixed;
  bottom: calc(5.5rem + env(safe-area-inset-bottom, 0px));
  right: 1.25rem;
  background: rgba(30,15,20,0.78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: rgba(255,255,255,0.92);
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: 0.12em;
  padding: 0.45rem 0.9rem;
  border-radius: 8px;
  white-space: nowrap;
  pointer-events: none;
  z-index: 60;
  opacity: 0;
  transition: opacity 0.4s ease;
}
.sound-hint-toast.visible { opacity: 1; }
.sound-hint-toast::after {
  content: '';
  position: absolute;
  bottom: -5px;
  right: 14px;
  border: 5px solid transparent;
  border-top-color: rgba(30,15,20,0.78);
  border-bottom: none;
}

/* ── Touch action on overlay sections ────────────────────────────── */
#theme-selector, #ceremony {
  touch-action: manipulation;
}

/* ═══════════════════════════════════════════════════════════════════
   AMBIENT THEME EFFECTS
   ═══════════════════════════════════════════════════════════════════ */

/* Layer container */
#theme-effects-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 4;
  overflow: hidden;
}

/* ── Keyframes ───────────────────────────────────────────────────── */
@keyframes fireflyGlow {
  0%, 100% { opacity: 0.15; transform: scale(0.7); }
  50%       { opacity: 1;    transform: scale(1.4); }
}
@keyframes fireflyDrift {
  0%   { transform: translate(0,   0);   }
  25%  { transform: translate(28px, -18px); }
  50%  { transform: translate(-8px, -38px); }
  75%  { transform: translate(36px, -20px); }
  100% { transform: translate(0,   0);   }
}
@keyframes shootingStar {
  0%   { opacity: 0; transform: translate(0, 0)            rotate(-40deg) scaleX(0.01); }
  8%   { opacity: 1; transform: translate(-25px, 25px)     rotate(-40deg) scaleX(1);    }
  100% { opacity: 0; transform: translate(-380px, 380px)   rotate(-40deg) scaleX(1);    }
}
@keyframes moonFloat {
  0%, 100% { transform: translateY(0)    scale(1);    opacity: 0.85; }
  50%       { transform: translateY(-16px) scale(1.04); opacity: 1;    }
}
@keyframes petalGust {
  0%   { opacity: 0.9; transform: translate(0, 0) rotate(0deg); }
  100% { opacity: 0;   transform: translate(var(--gx, 130px), var(--gy, 55px)) rotate(var(--gr, 360deg)); }
}
@keyframes wingFlapLeft {
  0%, 100% { transform: rotateY(0deg)  scaleX(1);   }
  50%       { transform: rotateY(55deg) scaleX(0.38); }
}
@keyframes wingFlapRight {
  0%, 100% { transform: rotateY(0deg)   scaleX(1);   }
  50%       { transform: rotateY(-55deg) scaleX(0.38); }
}
@keyframes divaFlicker {
  0%, 100% { opacity: 0.9;  transform: scaleY(1)    skewX(0deg);  }
  20%       { opacity: 1;    transform: scaleY(1.14) skewX(-4deg); }
  50%       { opacity: 0.82; transform: scaleY(0.9)  skewX(3deg);  }
  75%       { opacity: 0.95; transform: scaleY(1.08) skewX(-1deg); }
}
@keyframes candleFlicker {
  0%, 100% { opacity: 0.85; transform: scaleY(1)    translateX(0);   filter: blur(0px);   }
  25%       { opacity: 1;    transform: scaleY(1.1)  translateX(-2px); filter: blur(0.5px); }
  75%       { opacity: 0.9;  transform: scaleY(0.94) translateX(1px);  filter: blur(0px);   }
}
@keyframes leafTumble {
  0%   { opacity: 0.85; transform: translate(0, 0) rotate(0deg); }
  100% { opacity: 0;    transform: translate(var(--lx, 65px), var(--ly, 90px)) rotate(var(--lr, 540deg)); }
}
@keyframes fireworkSpark {
  0%   { opacity: 1; transform: translate(0, 0) scale(1);    }
  100% { opacity: 0; transform: translate(var(--fx, 0px), var(--fy, 0px)) scale(0); }
}
@keyframes walkBob {
  0%, 100% { transform: translateY(0);    }
  50%       { transform: translateY(-6px); }
}
@keyframes peacockWalk {
  0%   { transform: translateX(0); }
  100% { transform: translateX(calc(100vw + 140px)); }
}
@keyframes cloudDrift {
  0%   { transform: translateX(0);    opacity: 0; }
  8%   {                              opacity: 0.65; }
  92%  {                              opacity: 0.65; }
  100% { transform: translateX(115vw); opacity: 0; }
}
@keyframes sprinkleFall {
  0%   { transform: translateY(0)     rotate(0deg); opacity: 0; }
  8%   {                                            opacity: 0.85; }
  100% { transform: translateY(110vh) rotate(var(--sr, 360deg)); opacity: 0; }
}
@keyframes starTwinkle {
  0%, 100% { opacity: 0.25; transform: scale(0.75); }
  50%       { opacity: 1;   transform: scale(1.25); }
}
@keyframes ladybirdHop {
  0%, 100% { transform: translateY(0)    rotate(var(--lb-rot, 0deg)); }
  50%       { transform: translateY(-8px) rotate(var(--lb-rot, 0deg)); }
}

/* ── Fireflies ───────────────────────────────────────────────────── */
.firefly {
  position: absolute;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  pointer-events: none;
  background: #F0E060;
  box-shadow: 0 0 6px 2px rgba(240,224,96,0.7);
  animation:
    fireflyDrift var(--ffd, 8s) ease-in-out infinite,
    fireflyGlow  var(--ffg, 2.2s) ease-in-out infinite;
  animation-delay: var(--ffl, 0s);
}
[data-theme="starry-snuggle"] .firefly {
  background: #B4A8F8;
  box-shadow: 0 0 8px 3px rgba(139,125,212,0.6);
}

/* ── Shooting stars ──────────────────────────────────────────────── */
.shooting-star {
  position: absolute;
  height: 1.5px;
  border-radius: 100px;
  background: linear-gradient(90deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,0.9) 55%,
    rgba(255,255,255,0.3) 100%);
  pointer-events: none;
  transform-origin: right center;
  animation: shootingStar var(--ssd, 1.1s) ease-in both;
  animation-delay: var(--ssl, 0s);
}

/* ── Moon glow ───────────────────────────────────────────────────── */
.moon-glow {
  position: fixed;
  top: 36px;
  right: 52px;
  width: 110px;
  height: 110px;
  border-radius: 50%;
  background: radial-gradient(circle at 38% 35%, #FFF8DC 0%, #E8D8FF 45%, transparent 70%);
  box-shadow: 0 0 50px 16px rgba(200,178,255,0.38);
  pointer-events: none;
  animation: moonFloat 6.5s ease-in-out infinite;
  opacity: 0;
  transition: opacity 2s ease;
  will-change: opacity, transform;
}
.moon-glow.visible { opacity: 1; }

/* ── Butterfly ───────────────────────────────────────────────────── */
.butterfly-el {
  position: absolute;
  width: 30px;
  height: 20px;
  pointer-events: none;
  will-change: transform;
}
.butterfly-el .wing-l,
.butterfly-el .wing-r {
  position: absolute;
  top: 0;
  width: 14px;
  height: 18px;
  border-radius: 50% 50% 45% 0 / 60% 60% 40% 30%;
  opacity: 0.82;
}
.butterfly-el .wing-l {
  left: 0;
  background: var(--rose-light);
  transform-origin: right center;
  animation: wingFlapLeft var(--wfd, 0.48s) ease-in-out infinite;
}
.butterfly-el .wing-r {
  right: 0;
  background: var(--rose-mid);
  transform-origin: left center;
  animation: wingFlapRight var(--wfd, 0.48s) ease-in-out infinite;
}

/* ── Drifting clouds ─────────────────────────────────────────────── */
.cloud-drift {
  position: absolute;
  pointer-events: none;
  opacity: 0;
  border-radius: 60px;
  background: rgba(255,255,255,0.78);
  box-shadow:
    0 0 0 10px rgba(255,255,255,0.45),
    0 0 0 20px rgba(255,255,255,0.20);
  animation: cloudDrift var(--cdd, 32s) linear var(--cdl, 0s) both;
}

/* ── Diya (oil lamp) ─────────────────────────────────────────────── */
.diya-wrap {
  position: absolute;
  width: 28px;
  height: 30px;
  pointer-events: none;
}
.diya-base {
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 22px;
  height: 10px;
  background: radial-gradient(ellipse, #C8860A 0%, #8B5A0A 100%);
  border-radius: 50% 50% 0 0 / 60% 60% 0 0;
}
.diya-flame {
  position: absolute;
  left: 50%;
  bottom: 9px;
  transform: translateX(-50%);
  width: 8px;
  height: 14px;
  background: radial-gradient(ellipse at 50% 88%, #FFD700 0%, #FF6B35 55%, transparent 100%);
  border-radius: 50% 50% 50% 50% / 38% 38% 62% 62%;
  animation: divaFlicker var(--dfl, 1.05s) ease-in-out infinite;
  filter: blur(0.4px);
}
.diya-glow {
  position: absolute;
  left: 50%;
  bottom: 8px;
  transform: translateX(-50%);
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,190,50,0.55) 0%, transparent 70%);
  animation: divaFlicker var(--dfl, 1.05s) ease-in-out infinite;
}

/* ── Candle ──────────────────────────────────────────────────────── */
.candle-wrap {
  position: absolute;
  width: 18px;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.candle-flame {
  width: 9px;
  height: 13px;
  background: radial-gradient(ellipse at 50% 88%, #FFD700 0%, #FF8C00 60%, transparent 100%);
  border-radius: 50% 50% 55% 55% / 38% 38% 62% 62%;
  animation: candleFlicker var(--cfl, 1.3s) ease-in-out infinite;
  filter: blur(0.35px);
}
.candle-body {
  width: 10px;
  height: 34px;
  background: linear-gradient(180deg, #FFF8E1 0%, #FFE082 100%);
  border-radius: 3px 3px 1px 1px;
}

/* ── Gold leaf particles ─────────────────────────────────────────── */
.gold-leaf {
  position: absolute;
  pointer-events: none;
  width: 10px;
  height: 13px;
  background: linear-gradient(135deg, #D4A017 0%, #F0C040 50%, #B8860B 100%);
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  opacity: 0.75;
  animation: leafTumble var(--gld, 3.2s) ease-in var(--gll, 0s) forwards;
}

/* ── Cherry blossom gust particles ──────────────────────────────── */
.cherry-petal {
  position: absolute;
  pointer-events: none;
  border-radius: 55% 45% 55% 45% / 45% 55% 45% 55%;
  opacity: 0.85;
  animation: petalGust var(--cpd, 1.8s) ease-in var(--cpl, 0s) forwards;
}

/* ── Sprinkle (candy cloud) ──────────────────────────────────────── */
.sprinkle {
  position: absolute;
  pointer-events: none;
  width: 5px;
  height: 10px;
  border-radius: 3px;
  animation: sprinkleFall var(--spd, 4s) linear var(--spl, 0s) forwards;
}

/* ── Peacock walk ────────────────────────────────────────────────── */
.peacock-wrap {
  position: fixed;
  bottom: 0;
  left: -140px;
  pointer-events: none;
  z-index: 6;
  will-change: transform;
  animation: peacockWalk var(--pwd, 24s) linear var(--pwl, 1s) both;
}
.peacock-body {
  font-size: 3.2rem;
  display: block;
  line-height: 1;
  animation: walkBob 0.58s ease-in-out infinite;
}

/* ── Ladybird (PetalPop) ─────────────────────────────────────────── */
.ladybird {
  position: absolute;
  font-size: 1.2rem;
  pointer-events: none;
  animation: ladybirdHop var(--lbd, 2.4s) ease-in-out infinite;
}

/* ── Constellation dots (Starry) ─────────────────────────────────── */
.constellation-dot {
  position: absolute;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: #fff;
  pointer-events: none;
  animation: starTwinkle var(--ctd, 2s) ease-in-out infinite;
  animation-delay: var(--ctl, 0s);
}

/* ── Per-theme CSS overrides ─────────────────────────────────────── */

/* SangeetSpark: scroll progress bar in gold/orange */
[data-theme="sangeetspark"] #scroll-progress {
  background: linear-gradient(to bottom, #FFB800, #FF6B35);
}

/* Moonlight: chapter body text italic */
[data-theme="moonlight-mithai"] .chapter-body {
  font-style: italic;
}

/* VelvetVows: slightly wider letter-spacing on titles */
[data-theme="velvet-vows"] .chapter-title {
  letter-spacing: 0.04em;
}

/* ── Purrfect Pair cat-theme keyframes ───────────────────────────── */
@keyframes pawAppear {
  0%   { opacity: 0;    transform: scale(0.6)  rotate(-8deg); }
  20%  { opacity: 0.55; transform: scale(1.0)  rotate(0deg);  }
  75%  { opacity: 0.42; }
  100% { opacity: 0;    transform: scale(0.85); }
}
@keyframes whiskerFloat {
  0%   { transform: translateY(0)    rotate(var(--whr,  5deg)); opacity: 0;    }
  15%  { opacity: 0.28; }
  85%  { opacity: 0.18; }
  100% { transform: translateY(-90px) rotate(var(--whr, 5deg)); opacity: 0; }
}
@keyframes yarnRoll {
  0%   { transform: translateX(-50px) translateY(0)     rotate(0deg); }
  14%  { transform: translateX(14vw)  translateY(-26px) rotate(100deg); }
  28%  { transform: translateX(28vw)  translateY(0)     rotate(200deg); }
  42%  { transform: translateX(42vw)  translateY(-20px) rotate(302deg); }
  57%  { transform: translateX(57vw)  translateY(0)     rotate(405deg); }
  71%  { transform: translateX(71vw)  translateY(-16px) rotate(508deg); }
  85%  { transform: translateX(85vw)  translateY(0)     rotate(610deg); }
  100% { transform: translateX(115vw) translateY(0)     rotate(720deg); }
}
@keyframes catEnter {
  from { transform: translateX(-50%) translateY(110px); opacity: 0; }
  to   { transform: translateX(-50%) translateY(0);     opacity: 1; }
}
@keyframes catExit {
  from { transform: translateX(0);    opacity: 1; }
  to   { transform: translateX(130px); opacity: 0; }
}
@keyframes catBlink {
  0%, 92%, 100% { transform: scaleY(1);    }
  96%            { transform: scaleY(0.06); }
}
@keyframes heartPop {
  0%   { transform: translateX(-50%) scale(0.4); opacity: 0;   }
  30%  { transform: translateX(-50%) scale(1.1); opacity: 1;   }
  70%  { transform: translateX(-50%) scale(1.0); opacity: 0.9; }
  100% { transform: translateX(-50%) scale(0.8); opacity: 0;   }
}

/* ── Paw print element ───────────────────────────────────────────── */
.kitty-paw {
  position: fixed;
  pointer-events: none;
  width: 22px;
  height: 22px;
  z-index: 4;
  animation: pawAppear var(--pawd, 4s) ease both;
  animation-delay: var(--pawl, 0s);
}

/* ── Floating whisker element ────────────────────────────────────── */
.cat-whisker {
  position: fixed;
  pointer-events: none;
  z-index: 4;
  animation: whiskerFloat var(--wfd, 6s) ease var(--wfl, 0s) both;
}

/* ── Yarn ball ───────────────────────────────────────────────────── */
.yarn-ball {
  position: fixed;
  pointer-events: none;
  z-index: 4;
  border-radius: 50%;
  animation: yarnRoll var(--yrd, 8s) ease-in var(--yrl, 0s) both;
}

/* ── Cat cameo wrapper ───────────────────────────────────────────── */
.cat-cameo-wrap {
  position: fixed;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 6;
  display: flex;
  gap: 8px;
  align-items: flex-end;
  animation: catEnter 0.8s cubic-bezier(0.34,1.56,0.64,1) both;
}
.cat-cameo-wrap.exiting {
  animation: none;
}
.cat-cameo-wrap .cat-svg {
  flex-shrink: 0;
}
.cat-cameo-wrap .cat-blink .cat-pupil {
  animation: catBlink 4s ease-in-out infinite;
  transform-origin: center;
}
.cat-heart-bubble {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  font-size: 1.2rem;
  pointer-events: none;
  animation: heartPop 2.5s ease both;
}

/* ── Per-theme overrides: Purrfect Pair ─────────────────────────── */
[data-theme="purrfect-pair"] .chapter-body {
  line-height: 1.88;
}
[data-theme="purrfect-pair"] .chapter-title {
  font-style: italic;
  letter-spacing: 0.015em;
}
[data-theme="purrfect-pair"] #scroll-progress {
  background: linear-gradient(to bottom, var(--rose-light), var(--rose));
}
[data-theme="purrfect-pair"] .chapter-ornament-dot {
  background: var(--gold);
  box-shadow: 0 0 8px 2px var(--gold-light);
}

/* Reduce motion: kill ALL effect animations */
@media (prefers-reduced-motion: reduce) {
  .firefly, .shooting-star, .moon-glow,
  .butterfly-el .wing-l, .butterfly-el .wing-r,
  .cloud-drift, .diya-flame, .diya-glow, .candle-flame,
  .gold-leaf, .cherry-petal, .sprinkle,
  .peacock-wrap, .peacock-body,
  .ladybird, .constellation-dot {
    animation: none !important;
    opacity: 0 !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   PHASE 15 — Mobile Premium Polish
   ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 768px) {
  .image-placeholder img {
    filter: none;
    transform: none;
    opacity: 0;
  }
  .image-placeholder img.ph-loaded {
    opacity: 1;
  }
  .image-placeholder--loaded:has(img.ph-loaded) {
    box-shadow: 0 0 60px color-mix(in srgb, var(--rose) 35%, transparent);
  }
  #chapter-nav {
    display: none !important;
  }
}

@keyframes kenBurns {
  0%   { transform: scale(1) translate(0, 0); }
  100% { transform: scale(1.06) translate(-1%, -1%); }
}
.chapter-image-wrap.ken-burns-active .image-placeholder img.ph-loaded {
  animation: kenBurns 14s ease-in-out infinite alternate;
  will-change: transform;
}

.chapter-image-wrap--polaroid .image-placeholder {
  border: 8px solid #fff;
  box-shadow: 0 8px 32px rgba(0,0,0,0.12);
}
.chapter-image-wrap--polaroid::after {
  content: attr(data-image-id);
  position: absolute;
  bottom: 12px;
  right: 14px;
  font-family: var(--font-body);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  color: var(--gold);
  z-index: 5;
  pointer-events: none;
  opacity: 0.7;
}

@keyframes imageBurst {
  to { transform: translate(var(--ibx), var(--iby)); opacity: 0; }
}

.chapter-mood.mood-bounce {
  animation: moodBounce 0.55s var(--ease-spring) both;
}
@keyframes moodBounce {
  from { opacity: 0; transform: translateY(8px) scale(0.85); }
  to   { opacity: 1; transform: none; }
}

/* Micro toast */
.micro-toast {
  position: fixed;
  bottom: calc(5.5rem + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translateX(-50%);
  background: rgba(30,15,20,0.82);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: rgba(255,255,255,0.92);
  font-family: var(--font-body);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  padding: 0.5rem 1rem;
  border-radius: 100px;
  z-index: 80;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s ease;
  max-width: calc(100vw - 2rem);
  text-align: center;
}
.micro-toast.visible { opacity: 1; }

/* Mobile action dock */
.mobile-dock {
  position: fixed;
  bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translateX(-50%) translateY(12px);
  z-index: 70;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.4rem 0.5rem;
  background: rgba(255,255,255,0.92);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--rose-light);
  border-radius: 100px;
  box-shadow: 0 6px 28px rgba(0,0,0,0.12);
  opacity: 0;
  transition: opacity 0.4s ease, transform 0.4s var(--ease-spring);
}
.mobile-dock.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.mobile-dock #share-btn,
.mobile-dock #sound-toggle,
.mobile-dock .image-mode-btn,
.mobile-dock .dock-chapters-btn {
  position: static;
  width: 48px;
  height: 48px;
  min-width: 48px;
  border-radius: 50%;
  background: transparent;
  border: none;
  box-shadow: none;
  opacity: 1;
  transform: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--rose);
  touch-action: manipulation;
}
.mobile-dock #sound-toggle.playing {
  background: var(--rose);
  color: white;
}
.mobile-dock .dock-chapters-btn {
  width: auto;
  min-width: 48px;
  max-width: 140px;
  padding: 0 0.75rem;
  gap: 0.35rem;
  border-radius: 100px;
  font-family: var(--font-body);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--rose-dark);
}
.mobile-dock #dock-chapters-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 96px;
}

@media (max-width: 768px) {
  #share-btn:not(.mobile-dock *),
  #sound-toggle:not(.mobile-dock *) { display: none; }
}

@media (min-width: 769px) {
  .mobile-dock {
    display: contents;
  }
  .mobile-dock .dock-chapters-btn {
    display: none;
  }
  .mobile-dock #share-btn,
  .mobile-dock #sound-toggle,
  .mobile-dock .image-mode-btn {
    position: fixed;
  }
  .mobile-dock #share-btn {
    bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
    left: 1.25rem;
  }
  .mobile-dock #sound-toggle {
    bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
    right: 1.25rem;
    z-index: 55;
  }
  .mobile-dock .image-mode-btn {
    bottom: calc(1.5rem + 48px + 0.75rem + env(safe-area-inset-bottom, 0px));
    right: 1.25rem;
    z-index: 55;
  }
}

/* Photo stage */
#photo-stage {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.32s ease;
}
#photo-stage:not([hidden]) { pointer-events: auto; }
#photo-stage.open { opacity: 1; }
.photo-stage-backdrop {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, var(--crescendo-dark) 0%, var(--rose-dark) 100%);
  opacity: 0.96;
}
.photo-stage-frame {
  position: relative;
  z-index: 2;
  max-width: min(92vw, 720px);
  padding: 1rem;
  text-align: center;
}
.photo-stage-frame::before {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 12px;
  background: conic-gradient(from 0deg, var(--rose), var(--gold), var(--petal-1), var(--petal-2), var(--rose));
  animation: stageBorderSpin 8s linear infinite;
  z-index: -1;
  opacity: 0.85;
}
@keyframes stageBorderSpin {
  to { transform: rotate(360deg); }
}
.photo-stage-img {
  max-height: 75dvh;
  max-width: 100%;
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 12px 48px rgba(0,0,0,0.35);
}
#photo-stage.open .photo-stage-img:not(.reduced-motion *) {
  animation: kenBurns 12s ease-in-out infinite alternate;
}
.photo-stage-caption {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(0.9375rem, 3vw, 1.125rem);
  color: rgba(255,255,255,0.88);
  margin-top: 1rem;
  line-height: 1.5;
}
body.photo-stage-open { overflow: hidden; }

/* Theme stage accents */
.photo-stage-accent {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}
.photo-stage-accent--purrfect-pair {
  box-shadow: inset 0 0 120px rgba(200,180,255,0.25);
}
.photo-stage-accent--petalpop {
  background: radial-gradient(circle at 50% 0%, rgba(255,160,192,0.2), transparent 50%);
}
.photo-stage-accent--moonlight-mithai {
  background: radial-gradient(circle at 85% 8%, rgba(255,248,220,0.35), transparent 25%);
}
.photo-stage-accent--sangeetspark {
  background: linear-gradient(to top, rgba(245,158,11,0.15), transparent 30%);
}

/* New ambient effect elements */
.marigold-dot {
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: radial-gradient(circle, #FDBA60 0%, #E8850A 100%);
  opacity: 0.75;
  animation: marigoldPulse 3s ease-in-out infinite;
}
.marigold-dot--drift {
  animation: marigoldDrift 4s ease-out forwards;
}
@keyframes marigoldPulse {
  0%, 100% { transform: scale(0.85); opacity: 0.6; }
  50%       { transform: scale(1.15); opacity: 0.95; }
}
@keyframes marigoldDrift {
  to { transform: translateY(40px); opacity: 0; }
}
.mint-leaf {
  position: absolute;
  width: 14px;
  height: 8px;
  border-radius: 50% 0 50% 0;
  background: rgba(104,211,145,0.65);
  animation: mintDrift var(--mld, 5s) ease-in-out forwards;
}
@keyframes mintDrift {
  to { transform: translate(var(--mlx, 30px), 110vh) rotate(180deg); opacity: 0; }
}
.elephant-silhouette {
  position: absolute;
  bottom: calc(12% + env(safe-area-inset-bottom, 0px));
  left: -60px;
  opacity: 0.7;
  animation: elephantWalk 12s linear forwards;
  filter: grayscale(0.2);
}
@keyframes elephantWalk {
  to { left: calc(100% + 60px); }
}

/* Closing lock-screen days */
#closing {
  position: relative;
  overflow: hidden;
}
.closing-days-lock {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-family: var(--font-display);
  font-size: clamp(5rem, 22vw, 9rem);
  font-weight: 700;
  color: var(--rose-light);
  opacity: 0.06;
  pointer-events: none;
  z-index: 0;
  line-height: 1;
}

/* Themed image frames */
.image-frame--sangeetspark path { stroke: var(--gold-light); stroke-width: 3; }
.image-frame--velvet-vows path { stroke: var(--rose); }
.image-frame--butterfly-blush path { stroke: var(--gold); stroke-width: 2; }

.cat-cameo-wrap--mobile {
  bottom: calc(5rem + env(safe-area-inset-bottom, 0px)) !important;
  transform: scale(0.85);
  transform-origin: bottom center;
}

@media (prefers-reduced-motion: reduce) {
  .chapter-image-wrap.ken-burns-active .image-placeholder img,
  #photo-stage.open .photo-stage-img,
  .photo-stage-frame::before {
    animation: none !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   PHASE 16 — Sounds everywhere + theme life from frame one
   ═══════════════════════════════════════════════════════════════════ */

/* ── Ceremony floating particles ─────────────────────────────────── */
.ceremony-particle {
  position: absolute;
  pointer-events: none;
  border-radius: 50% 45% 50% 45% / 45% 50% 45% 50%;
  animation: petalFall 10s ease-in var(--del, 0s) infinite;
  z-index: 1;
  opacity: 0.22;
}
/* #ceremony is already position:fixed inset:0, so absolute children are contained */

/* ── Orb micro-particles (orbit the orb in theme selector) ──────── */
.ts-orb-wrap { position: relative; }

.orb-particle {
  position: absolute;
  pointer-events: none;
  font-size: 0.75rem;
  line-height: 1;
  color: var(--rose);
  opacity: 0;
  animation: orbParticleOrbit 4s ease-in-out infinite;
  animation-delay: calc(var(--op-i, 0) * 1s);
  /* orbit placement: each particle starts at a different angle */
  top: 50%;
  left: 50%;
  transform-origin: 0 0;
}

@keyframes orbParticleOrbit {
  0%   { opacity: 0; transform: rotate(calc(var(--op-i, 0) * 90deg)) translateX(calc(min(105px, 28vw))) scale(0.8); }
  20%  { opacity: 0.65; }
  50%  { opacity: 0.45; transform: rotate(calc(var(--op-i, 0) * 90deg + 180deg)) translateX(calc(min(115px, 30vw))) scale(1.1); }
  80%  { opacity: 0.65; }
  100% { opacity: 0; transform: rotate(calc(var(--op-i, 0) * 90deg + 360deg)) translateX(calc(min(105px, 28vw))) scale(0.8); }
}

/* ── Orb breathing — per-theme animation override ───────────────── */
/* Default orbFloat is 4s ease-in-out (defined earlier) */
/* Purrfect Pair: slow cat-breathing, gentle sway */
.ts-orb.orb-breathe--purrfect-pair {
  animation: orbBreathePurrfect 3.8s cubic-bezier(0.45, 0.05, 0.55, 0.95) infinite;
}
@keyframes orbBreathePurrfect {
  0%, 100% { transform: translateY(0) translateX(0) scale(1); }
  35%       { transform: translateY(-10px) translateX(-4px) scale(1.025); }
  65%       { transform: translateY(-8px) translateX(5px) scale(1.03); }
}

/* Moonlight Mithai: long cinematic float */
.ts-orb.orb-breathe--moonlight-mithai {
  animation: orbBreatheMoon 6s cubic-bezier(0.0, 0.0, 0.2, 1) infinite;
}
@keyframes orbBreatheMoon {
  0%, 100% { transform: translateY(0) scale(1); }
  50%       { transform: translateY(-18px) translateX(3px) scale(1.045); }
}

/* SangeetSpark: bouncy spring */
.ts-orb.orb-breathe--sangeetspark {
  animation: orbBounceSangeet 1.6s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
}
@keyframes orbBounceSangeet {
  0%, 100% { transform: translateY(0) scale(1); }
  45%       { transform: translateY(-16px) scale(1.06); }
  65%       { transform: translateY(-14px) scale(0.97); }
}

/* CandyCloud: gentle bobbing */
.ts-orb.orb-breathe--candy-cloud {
  animation: orbBobCandy 3s ease-in-out infinite;
}
@keyframes orbBobCandy {
  0%, 100% { transform: translateY(0) scale(1); }
  50%       { transform: translateY(-12px) translateX(3px) scale(1.035); }
}

/* VelvetVows: slow stately rise */
.ts-orb.orb-breathe--velvet-vows {
  animation: orbRiseVelvet 5.5s cubic-bezier(0.0, 0.0, 0.1, 1) infinite;
}
@keyframes orbRiseVelvet {
  0%, 100% { transform: translateY(0) scale(1); }
  50%       { transform: translateY(-20px) scale(1.05); }
}

/* Starry Snuggle: twinkle pulse */
.ts-orb.orb-breathe--starry-snuggle {
  animation: orbTwinkleStarry 2.8s ease-in-out infinite;
}
@keyframes orbTwinkleStarry {
  0%, 100% { transform: scale(1) translateY(0); }
  30%       { transform: scale(1.05) translateY(-12px); }
  60%       { transform: scale(0.97) translateY(-10px); }
}

/* Gulabo Garden: festive spin-bob */
.ts-orb.orb-breathe--gulabo-garden {
  animation: orbFestiveGulabo 2.0s ease-in-out infinite;
}
@keyframes orbFestiveGulabo {
  0%, 100% { transform: translateY(0) rotate(0deg) scale(1); }
  50%       { transform: translateY(-14px) rotate(2deg) scale(1.04); }
}

/* ButterflyBlush: light airy lift */
.ts-orb.orb-breathe--butterfly-blush {
  animation: orbAiryButterfly 3.2s cubic-bezier(0.34, 1.4, 0.64, 1) infinite;
}
@keyframes orbAiryButterfly {
  0%, 100% { transform: translateY(0) scale(1); }
  50%       { transform: translateY(-16px) translateX(6px) scale(1.04); }
}

/* PetalPop: snappy spring */
.ts-orb.orb-breathe--petalpop {
  animation: orbSpringPetal 1.8s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
}
@keyframes orbSpringPetal {
  0%, 100% { transform: translateY(0) scale(1); }
  40%       { transform: translateY(-14px) scale(1.055); }
  70%       { transform: translateY(-12px) scale(0.98); }
}

/* ── Per-chapter reveal mark (theme stamp on chapter number) ─────── */
.ch-reveal-mark {
  display: inline-block;
  position: absolute;
  top: -0.2em;
  right: -1.2em;
  font-size: 0.85em;
  opacity: 0;
  transform: scale(0.4) translateY(8px);
  transition: opacity 0.25s ease, transform 0.3s cubic-bezier(0.34,1.56,0.64,1);
  pointer-events: none;
  color: var(--rose);
  line-height: 1;
}
/* Animate in after JS adds the element */
.chapter-number { position: relative; }
.ch-reveal-mark:not(.ch-reveal-mark--out) {
  opacity: 0.75;
  transform: scale(1) translateY(0);
}
.ch-reveal-mark--out {
  opacity: 0;
  transform: scale(1.4) translateY(-10px);
  transition: opacity 0.45s ease, transform 0.5s ease;
}

/* SangeetSpark: chapter number bounces on reveal */
.ts-orb.orb-breathe--sangeetspark ~ * .chapter-number,
html[data-theme="sangeetspark"] .chapter-number {
  /* spring-in override via odometer-flip — no separate class needed */
}

/* ── Ceremony particle + reduced-motion guards ───────────────────── */
@media (prefers-reduced-motion: reduce) {
  .orb-particle,
  .ceremony-particle,
  .ch-reveal-mark {
    display: none !important;
  }
  .ts-orb[class*="orb-breathe--"] {
    animation: orbFloat 4s ease-in-out infinite !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   PHASE 17 — Artistic Polish
   Editorial typography, drop caps, ceremony depth, cursor trail,
   and visual refinements that elevate the piece beyond greeting-card.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Editorial font variable ─────────────────────────────────────── */
:root {
  --font-editorial: 'Cormorant Garamond', 'Garamond', Georgia, serif;
}

/* ── Chapter body — Cormorant Garamond italic (literary) ─────────── */
.chapter-body {
  font-family: var(--font-editorial);
  font-size: clamp(1.0625rem, 2.25vw, 1.2rem);
  font-weight: 400;
  font-style: italic;
  line-height: 2.15;
  color: var(--text);
}

/* ── Opening poem — editorial serif, more commanding ─────────────── */
.opening-poem p {
  font-family: var(--font-editorial);
  font-size: clamp(2rem, 5.5vw, 2.75rem);
  line-height: 1.75;
  letter-spacing: -0.01em;
  text-align: center;
}

/* ── Opening panels — editorial prose ───────────────────────────── */
.panel-text {
  font-family: var(--font-editorial);
  font-size: clamp(1.125rem, 2.6vw, 1.55rem);
  font-style: italic;
  line-height: 2.05;
}

/* ── Closing message — editorial serif ──────────────────────────── */
.closing-message {
  font-family: var(--font-editorial);
  font-size: clamp(1.3125rem, 3.5vw, 1.65rem);
  font-style: italic;
  line-height: 2.15;
}

/* ── Drop cap — first letter of each chapter body ───────────────── */
.chapter-body::first-letter {
  font-family: var(--font-display);
  font-size: 4.6em;
  font-weight: 700;
  font-style: italic;
  float: left;
  line-height: 0.78;
  margin: 0.04em 0.13em 0 0;
  padding-top: 0.03em;
  color: var(--rose);
  transition: color 0.55s ease;
}

/* ── Chapter number — editorial micro-label above ───────────────── */
/* "Chapter" in spaced small caps above the number */
.chapter:not(#chapter-hidden) .chapter-number::before {
  content: 'Chapter';
  display: block;
  font-family: var(--font-body);
  font-size: 0.5rem;
  font-weight: 700;
  letter-spacing: 0.46em;
  text-transform: uppercase;
  color: var(--gold);
  opacity: 0.62;
  margin-bottom: 0.2em;
  transition: color 0.55s ease;
}

/* ── Chapter breadcrumb — "01 of 20" below the number ───────────── */
.chapter:not(#chapter-hidden) .chapter-number::after {
  content: attr(data-breadcrumb);
  display: block;
  font-family: var(--font-body);
  font-size: 0.46rem;
  font-weight: 400;
  letter-spacing: 0.22em;
  color: var(--gold);
  opacity: 0.38;
  margin-top: 0.45em;
  transition: color 0.55s ease;
}

/* ── Ghost chapter number — bigger and bolder on desktop ─────────── */
@media (min-width: 768px) {
  .chapter::before {
    font-size: clamp(8rem, 20vw, 17rem);
    opacity: 0.058;
    right: -2rem;
    top: 46%;
    letter-spacing: -0.04em;
  }
}

/* ── Chapter separator — elegant gold hairline (replace dashed) ──── */
.chapter {
  border-bottom-style: solid;
  border-bottom-color: rgba(212, 160, 23, 0.14);
}

/* ── Chapter title — more commanding scale ───────────────────────── */
.chapter-title {
  font-size: clamp(1.9rem, 5.5vw, 3.2rem);
  letter-spacing: -0.01em;
}

/* ── Chapter ornament dot — subtle glow ─────────────────────────── */
.chapter-ornament-dot {
  width: 6px;
  height: 6px;
  box-shadow: 0 0 10px 2px var(--orb-shadow);
}

/* ── Ceremony — atmospheric vignette + z-index context ──────────── */
#ceremony::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 72% 72% at 50% 50%,
    transparent 38%,
    rgba(0, 0, 0, 0.07) 100%);
  pointer-events: none;
  z-index: 0;
}
.ceremony-inner {
  position: relative;
  z-index: 1;
}

/* ── Ceremony bloom — two pulsing botanical rings ───────────────── */
.ceremony-bloom::before,
.ceremony-bloom::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  border: 1px solid var(--rose-light);
  transition: border-color 0.55s ease;
  opacity: 0;
}
.ceremony-bloom::before {
  width: 154px;
  height: 154px;
  animation: ceremonyRingBreath 5.5s ease-in-out 0.8s infinite;
}
.ceremony-bloom::after {
  width: 204px;
  height: 204px;
  animation: ceremonyRingBreath 5.5s ease-in-out 2.4s infinite;
}
@keyframes ceremonyRingBreath {
  0%, 100% { opacity: 0.12; transform: translate(-50%, -50%) scale(1); }
  50%       { opacity: 0.36; transform: translate(-50%, -50%) scale(1.055); }
}

/* ── Ceremony title — more monumental ───────────────────────────── */
.ceremony-title {
  font-size: clamp(2.8rem, 10.5vw, 5.75rem);
  letter-spacing: -0.018em;
  text-shadow: 0 4px 48px var(--orb-shadow);
}

/* ── Crescendo — typographic opening quote ──────────────────────── */
.crescendo-text {
  position: relative;
  z-index: 1;
}
.crescendo-text::before {
  content: '\201C';  /* left double quotation mark */
  position: absolute;
  top: -0.28em;
  left: -0.22em;
  font-family: var(--font-display);
  font-size: clamp(9rem, 22vw, 18rem);
  color: rgba(255, 255, 255, 0.045);
  font-style: italic;
  line-height: 1;
  pointer-events: none;
  z-index: 0;
  user-select: none;
  -webkit-user-select: none;
}
.crescendo-line,
.crescendo-highlight { position: relative; z-index: 1; }

/* ── Crescendo lines — bigger impact ────────────────────────────── */
.crescendo-line {
  font-size: clamp(2.3rem, 7.5vw, 5rem);
}
.crescendo-highlight {
  font-size: clamp(1.5rem, 4.5vw, 2.8rem);
}

/* ── Theme selector dedication — emotional entry point ───────────── */
/* Override existing .ts-dedication which is 0.875rem/opacity 0.7 */
.ts-dedication {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.35rem, 5.5vw, 2.1rem);
  color: var(--rose);
  opacity: 0.92;
  letter-spacing: 0.018em;
  margin-bottom: 2.5rem;
  line-height: 1.38;
  text-wrap: balance;
}
.ts-dedication::after {
  content: '';
  display: block;
  width: 42px;
  height: 1px;
  background: linear-gradient(to right, transparent, var(--gold), transparent);
  margin: 0.9rem auto 0;
  transition: background 0.55s ease;
}

/* ── Theme selector label — subtler, more poetic ─────────────────── */
.ts-label {
  font-size: 0.5rem;
  letter-spacing: 0.42em;
  opacity: 0.7;
  margin-bottom: 2.25rem;
}

/* ── Closing signoff — more ceremonial scale ─────────────────────── */
.closing-signoff {
  font-size: clamp(1.625rem, 4.5vw, 2.2rem);
}

/* ── Opening section — more generous breathing room ─────────────── */
.opening-poem {
  padding-top: clamp(4rem, 10vw, 7rem);
  padding-bottom: clamp(3rem, 7vw, 5rem);
}

/* ── Page-edge vignette — adds dimensional depth ─────────────────── */
#vignette-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 2;
  background: radial-gradient(
    ellipse 90% 90% at 50% 50%,
    transparent 52%,
    rgba(0, 0, 0, 0.052) 100%
  );
}

/* ── Grain — slightly more visible for depth ─────────────────────── */
#grain-layer { opacity: 0.03; }

/* ── Desktop cursor petal trail ──────────────────────────────────── */
#cursor-trail-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 4;
  overflow: hidden;
}
.cursor-petal {
  position: absolute;
  width: 7px;
  height: 11px;
  border-radius: 50% 0 50% 0;
  background: var(--rose-light);
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%);
  will-change: transform, opacity;
  transition: background 0.55s ease;
}
.cursor-petal--active {
  animation: cursorPetalDrift 0.78s ease-out forwards;
}
@keyframes cursorPetalDrift {
  0%   {
    opacity: 0.62;
    transform: translate(-50%, -50%) rotate(45deg) scale(1);
  }
  100% {
    opacity: 0;
    transform:
      translate(
        calc(-50% + var(--drift, 8px)),
        calc(-50% + 40px)
      )
      rotate(calc(45deg + var(--rot, 200deg)))
      scale(0.22);
  }
}

/* ── Ambient body gradient — richer breathe ─────────────────────── */
body::after {
  background: radial-gradient(
    ellipse 68% 58% at 50% 28%,
    var(--bg-warm) 0%,
    transparent 72%
  );
  animation: bgBreathe 15s ease-in-out infinite;
}

/* ── Reduced motion guards ───────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .ceremony-bloom::before,
  .ceremony-bloom::after { animation: none !important; opacity: 0.18; }
  .cursor-petal           { display: none !important; }
  #cursor-trail-layer     { display: none !important; }
  .chapter-body::first-letter { float: none; font-size: 1em; }
}

/* ═══════════════════════════════════════════════════════════════════
   PHASE 19 — 10 Hyper-Personal Signals
   ═══════════════════════════════════════════════════════════════════ */

/* ── 1. Next milestone countdown ────────────────────────────────── */
.next-milestone {
  font-family: var(--font-editorial);
  font-style: italic;
  font-size: clamp(0.6875rem, 1.6vw, 0.8125rem);
  color: var(--gold);
  text-align: center;
  margin-top: 0.6rem;
  letter-spacing: 0.02em;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 1.8s ease 0.5s, transform 1.8s ease 0.5s, color 0.55s ease;
}
.next-milestone.visible { opacity: 0.52; transform: translateY(0); }

/* ── 2. Opening datestamp ────────────────────────────────────────── */
.opening-datestamp {
  font-family: var(--font-editorial);
  font-style: italic;
  font-size: clamp(0.6875rem, 1.5vw, 0.8125rem);
  color: var(--text-soft);
  text-align: center;
  max-width: 420px;
  margin: 0 auto;
  padding: clamp(0.75rem, 2vw, 1.25rem) 1rem clamp(1.5rem, 4vw, 3rem);
  letter-spacing: 0.015em;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 2s ease, transform 2s ease, color 0.55s ease;
}
.opening-datestamp.visible { opacity: 0.4; transform: translateY(0); }

/* ── 3. Ch1 GPS coordinates ─────────────────────────────────────── */
.ch1-coordinates {
  font-family: 'Courier New', monospace;
  font-size: 0.625rem;
  color: var(--text-soft);
  letter-spacing: 0.14em;
  opacity: 0.32;
  margin-top: 0.6rem;
  transition: opacity 0.35s ease, color 0.55s ease;
  cursor: default;
}
.ch1-coordinates:hover { opacity: 0.65; }

/* ── 5. Candle flame cursor (desktop only) ──────────────────────── */
#candle-cursor-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 997;
}
.candle-flame {
  position: fixed;
  top: 0;
  left: 0;
  will-change: transform;
  pointer-events: none;
  transition: opacity 0.3s ease;
}
.candle-flame-inner {
  animation: flameFlicker 0.62s ease-in-out infinite alternate;
  transform-origin: 50% 100%;
}
@keyframes flameFlicker {
  from { transform: scaleX(1) scaleY(1) rotate(-0.6deg);   filter: brightness(1);    }
  to   { transform: scaleX(0.87) scaleY(1.1) rotate(1deg); filter: brightness(1.22); }
}
@media (max-width: 768px), (pointer: coarse) {
  #candle-cursor-layer { display: none; }
}

/* ── 6. Warm vignette on fast scroll ────────────────────────────── */
#scroll-vignette {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background: rgba(255, 145, 35, 0);
  transition: background 0.22s ease-out;
}
#scroll-vignette.active {
  background: rgba(255, 145, 35, 0.038);
  transition: background 0.04s ease-in;
}

/* ── 7. Ch20 — reverse reveal stagger ──────────────────────────── */
#chapter-20 .chapter-text-wrap.visible .reveal-child:nth-child(1) {
  transition-delay: calc(var(--motion-stagger) * 3);
}
#chapter-20 .chapter-text-wrap.visible .reveal-child:nth-child(2) {
  transition-delay: calc(var(--motion-stagger) * 2);
}
#chapter-20 .chapter-text-wrap.visible .reveal-child:nth-child(3) {
  transition-delay: var(--motion-stagger);
}
#chapter-20 .chapter-text-wrap.visible .reveal-child:nth-child(4) {
  transition-delay: 0ms;
}

/* ── 8. Morse code under Animesh ────────────────────────────────── */
.morse-line {
  font-family: 'Courier New', monospace;
  font-size: 0.48rem;
  color: var(--text-soft);
  opacity: 0.15;
  letter-spacing: 0.2em;
  text-align: center;
  margin-top: 0.3rem;
  user-select: none;
  cursor: default;
  transition: opacity 0.55s ease, color 0.55s ease;
}
.morse-line:hover { opacity: 0.5; }

/* ── 9. Return visit welcome message ────────────────────────────── */
.welcome-back-msg {
  font-family: var(--font-editorial);
  font-style: italic;
  font-size: clamp(0.875rem, 2.5vw, 1.125rem);
  color: var(--gold);
  text-align: center;
  margin: 0 0 0.5rem;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 1.2s ease, transform 1.2s ease, color 0.55s ease;
}
.welcome-back-msg.visible { opacity: 0.78; transform: translateY(0); }

/* ── 10. Final whisper below Begin Again ────────────────────────── */
.final-whisper {
  font-family: var(--font-editorial);
  font-style: italic;
  font-size: clamp(0.8125rem, 1.9vw, 0.9375rem);
  color: var(--text-soft);
  text-align: center;
  margin-top: 1.25rem;
  letter-spacing: 0.01em;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 2s ease, transform 2s ease, color 0.55s ease;
}
.final-whisper.visible { opacity: 0.48; transform: translateY(0); }

/* ── Phase 19 reduced-motion guards ─────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .candle-flame-inner { animation: none; }
  #scroll-vignette    { display: none; }
}

/* ── Mobile: drop cap too large — scale down ─────────────────────── */
@media (max-width: 480px) {
  .chapter-body::first-letter {
    font-size: 3.6em;
    margin: 0.04em 0.1em 0 0;
  }
  #cursor-trail-layer { display: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   PHASE 18 — Ultra Refinement
   ═══════════════════════════════════════════════════════════════════ */

/* ── Calligraphic script font ────────────────────────────────────── */
:root {
  --font-script: 'Alex Brush', 'Dancing Script', cursive;
}

/* ── Calligraphic closing signoff and author ─────────────────────── */
.closing-signoff {
  font-family: var(--font-script);
  font-style: normal;
  font-size: clamp(2.25rem, 5.5vw, 3rem);
  letter-spacing: 0.01em;
}
.closing-author {
  font-family: var(--font-script);
  font-style: normal;
  font-size: clamp(1.75rem, 4.5vw, 2.25rem);
  margin-top: 0.1rem;
}

/* ── Ink-bleed texture on Cormorant prose ───────────────────────── */
.chapter-body,
.panel-text,
.closing-message {
  text-shadow: 0.35px 0.4px 0 rgba(0, 0, 0, 0.06);
}

/* ── Live time-together counter in closing ───────────────────────── */
.live-counter {
  font-family: var(--font-editorial);
  font-style: italic;
  font-size: clamp(0.875rem, 2vw, 1rem);
  color: var(--text-soft);
  text-align: center;
  margin-top: 1.75rem;
  letter-spacing: 0.015em;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 1.8s ease, transform 1.8s ease, color 0.55s ease;
}
.live-counter.visible {
  opacity: 0.65;
  transform: translateY(0);
}

/* ── Hidden chapter second whisper ──────────────────────────────── */
.hidden-whisper {
  font-family: var(--font-editorial);
  font-style: italic;
  font-size: clamp(0.875rem, 2.5vw, 1rem);
  color: var(--gold);
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(212, 160, 23, 0.18);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 2.5s ease, transform 2.5s ease;
  text-align: center;
  letter-spacing: 0.015em;
  line-height: 1.9;
}
.hidden-whisper.visible {
  opacity: 0.68;
  transform: translateY(0);
}

/* ── Anniversary Day ceremony variant ───────────────────────────── */
.anniversary-day {
  color: var(--gold) !important;
  font-style: italic;
  letter-spacing: 0.08em;
  animation: anniversaryGlow 3s ease-in-out infinite;
}
@keyframes anniversaryGlow {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.6; }
}

/* ═══════════════════════════════════════════════════════════════════
   PHASE 20 — Artful Mobile Refinements
   ═══════════════════════════════════════════════════════════════════ */

/* ── B2. Chapter body — tighter leading on mobile ────────────────── */
@media (max-width: 768px) {
  .chapter-body    { line-height: 1.95; }
  .closing-message { max-width: 400px; margin-left: auto; margin-right: auto; }
}

/* ── B4. Widow control + hanging punctuation on all prose ────────── */
.chapter-body,
.panel-text,
.closing-message {
  text-wrap: pretty;
  hanging-punctuation: first last;
}

/* ── D3. Ch1 drop cap — rose-coloured opening letter ─────────────── */
#chapter-01 .chapter-body::first-letter {
  color: var(--rose);
  font-size: 5.2em;
  margin-right: 0.08em;
}
@media (max-width: 480px) {
  #chapter-01 .chapter-body::first-letter { font-size: 4.2em; }
}

/* ── D2. Ghost chapter number on mobile ──────────────────────────── */
@media (max-width: 767px) {
  .chapter:not(#chapter-hidden) {
    overflow: visible;
  }
  .chapter:not(#chapter-hidden)::before {
    content: attr(data-num);
    position: absolute;
    font-family: var(--font-display);
    font-size: clamp(5.5rem, 28vw, 9rem);
    color: var(--rose);
    opacity: 0.045;
    right: -0.25rem;
    top: 44%;
    transform: translateY(-50%);
    pointer-events: none;
    line-height: 1;
    z-index: 0;
    transition: color 0.55s ease;
    letter-spacing: -0.02em;
  }
}

/* ── E1. Warm paper glow in the reading zone ─────────────────────── */
#chapters {
  background-image: radial-gradient(
    ellipse 100% 30% at 50% 8%,
    var(--cream) 0%,
    transparent 60%
  );
}

/* ── E3. Framed image presence ───────────────────────────────────── */
.image-placeholder {
  box-shadow: 0 3px 16px rgba(0,0,0,0.06), 0 1px 4px rgba(0,0,0,0.04);
}
.image-placeholder--loaded {
  box-shadow: 0 4px 22px rgba(0,0,0,0.08), 0 1px 6px rgba(0,0,0,0.05);
}

/* ── Phase 20 reduced-motion guards ──────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  #chapter-01 .chapter-body::first-letter { font-size: 4.6em; }
  .chapter:not(#chapter-hidden)::before   { display: none; }
}
