/* =========================================================
   AMBIENT MOTION  (pairs with ambient.js)
   Slow, looping, never-abrupt movement. Everything here is
   decoration: pointer-events are off and reduced-motion turns
   it all off.
========================================================= */

/* ---------- water: the artwork's own pixels, gently rippling ---------- */
.fx-water {
  position: absolute;
  display: block;
  pointer-events: none;
  /* feather every edge so the moving patch melts into the still picture */
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%),
    linear-gradient(180deg, transparent 0, #000 14%, #000 86%, transparent 100%);
  mask-image:
    linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%),
    linear-gradient(180deg, transparent 0, #000 14%, #000 86%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
.fx-frame {
  position: relative;
  display: block;
  width: 100%;
  line-height: 0;
}

/* ---------- diya flames + sun: soft light that breathes ---------- */
.fx-glow {
  position: absolute;
  aspect-ratio: 1;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  mix-blend-mode: screen;
  will-change: opacity, transform;
}
.fx-flame {
  background: radial-gradient(
    circle,
    rgba(255, 214, 140, 0.95) 0,
    rgba(255, 160, 70, 0.5) 28%,
    rgba(255, 120, 40, 0) 68%
  );
  animation: fx-flame 3.6s ease-in-out infinite;
}
@keyframes fx-flame {
  0%,
  100% { opacity: 0.55; transform: translate(-50%, -50%) scale(0.85); }
  16%  { opacity: 1;    transform: translate(-50%, -54%) scale(1.12); }
  34%  { opacity: 0.65; transform: translate(-52%, -50%) scale(0.92); }
  52%  { opacity: 1;    transform: translate(-50%, -56%) scale(1.2); }
  73%  { opacity: 0.7;  transform: translate(-48%, -50%) scale(0.96); }
}
.fx-sun {
  background: radial-gradient(
    circle,
    rgba(255, 240, 200, 0.85) 0,
    rgba(255, 200, 120, 0.4) 30%,
    rgba(255, 160, 80, 0) 70%
  );
  animation: fx-sun 7s ease-in-out infinite;
}
/* slowly turning rays from the setting sun */
.fx-rays {
  position: absolute;
  aspect-ratio: 1;
  border-radius: 50%;
  pointer-events: none;
  mix-blend-mode: screen;
  background: repeating-conic-gradient(
    from 0deg,
    rgba(255, 226, 170, 0.2) 0deg 4deg,
    rgba(255, 226, 170, 0) 4deg 20deg
  );
  filter: blur(4px);
  -webkit-mask-image: radial-gradient(circle, #000 0, rgba(0, 0, 0, 0.35) 28%, transparent 60%);
  mask-image: radial-gradient(circle, #000 0, rgba(0, 0, 0, 0.35) 28%, transparent 60%);
  transform: translate(-50%, -50%);
  animation: fx-rays 70s linear infinite;
}
@keyframes fx-rays {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to   { transform: translate(-50%, -50%) rotate(360deg); }
}
@keyframes fx-sun {
  0%,
  100% { opacity: 0.45; transform: translate(-50%, -50%) scale(0.88); }
  50%  { opacity: 1;    transform: translate(-50%, -50%) scale(1.18); }
}

/* ---------- drifting golden motes over the opening picture ---------- */
.fx-motes {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.fx-motes i {
  box-shadow: 0 0 8px rgba(255, 220, 150, 0.8);
  position: absolute;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 232, 170, 0.95), rgba(255, 200, 110, 0) 70%);
  opacity: 0;
  animation: fx-mote 22s ease-in-out infinite;
}
@keyframes fx-mote {
  0%   { opacity: 0;    transform: translate(0, 0); }
  15%  { opacity: 0.8; }
  50%  { transform: translate(var(--sway), calc(var(--rise) * -0.5)); }
  85%  { opacity: 0.7; }
  100% { opacity: 0;    transform: translate(calc(var(--sway) * -0.4), calc(var(--rise) * -1)); }
}

/* ---------- section ornaments: a slow glint ---------- */
.sec-edge b,
.rule b,
.orn {
  animation: fx-orn 7s ease-in-out infinite;
}
@keyframes fx-orn {
  0%,
  100% { text-shadow: 0 0 0 rgba(255, 210, 130, 0); }
  50%  { text-shadow: 0 0 10px rgba(255, 210, 130, 0.75); }
}
.sec-edge i {
  animation: fx-line 9s ease-in-out infinite;
}
@keyframes fx-line {
  0%,
  100% { filter: brightness(0.85); }
  50%  { filter: brightness(1.5); }
}

/* ---------- the main call-to-action breathes, and its arrow nudges ---------- */
#home .c-btn {
  animation: fx-cta 4.8s ease-in-out infinite;
}
#home .c-btn span {
  display: inline-block;
  animation: fx-nudge 4.8s ease-in-out infinite;
}
@keyframes fx-cta {
  0%,
  100% { box-shadow: 0 0 0 0.25cqw rgba(110, 15, 34, 0.9), 0 1.2cqw 2.4cqw rgba(60, 5, 15, 0.35), 0 0 0 rgba(255, 200, 120, 0); }
  50%  { box-shadow: 0 0 0 0.25cqw rgba(110, 15, 34, 0.9), 0 1.2cqw 2.4cqw rgba(60, 5, 15, 0.35), 0 0 2.6cqw rgba(255, 200, 120, 0.55); }
}
@keyframes fx-nudge {
  0%,
  60%,
  100% { transform: translateX(0); }
  80%  { transform: translateX(0.35em); }
}

/* ---------- respect people who ask for less motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html:not(.fx-force) .fx-water,
  html:not(.fx-force) .fx-glow,
  html:not(.fx-force) .fx-motes,
  html:not(.fx-force) .fx-petals,
  html:not(.fx-force) .fx-blooms,
  html:not(.fx-force) .fx-rays {
    display: none;
  }
  html:not(.fx-force) .fx-ink,
  html:not(.fx-force) .inv-title.fx-title {
    animation: none;
    background: none;
    -webkit-text-fill-color: currentColor;
  }
  html:not(.fx-force) .fx-sway {
    display: none;
  }
  html:not(.fx-force) .sec-edge b,
  html:not(.fx-force) .rule b,
  html:not(.fx-force) .orn,
  html:not(.fx-force) .sec-edge i,
  html:not(.fx-force) #home .c-btn,
  html:not(.fx-force) #home .c-btn span {
    animation: none;
  }
}
.fx-off .fx-glow,
.fx-off .fx-motes,
.fx-off .fx-petals,
.fx-off .fx-blooms,
.fx-off .fx-rays,
.fx-off .fx-water,
.fx-off .fx-sway {
  display: none;
}
.fx-off .fx-ink,
.fx-off .inv-title.fx-title {
  animation: none;
  background: none;
  -webkit-text-fill-color: currentColor;
}

/* ---------- petals ---------- */
.fx-petals {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.fx-petal {
  position: absolute;
  top: -4%;
  opacity: 0;
  border-radius: 80% 0 80% 0;
  animation:
    fx-fall 22s linear infinite,
    fx-drift 8s ease-in-out infinite;
}
.fx-petal.jas {
  background: radial-gradient(ellipse at 30% 30%, #fffdf6, #f3e6c8 70%);
  box-shadow: 0 0 6px rgba(255, 244, 214, 0.6);
}
.fx-petal.rose {
  background: radial-gradient(ellipse at 30% 30%, #d8364c, #8a1226 75%);
  box-shadow: 0 0 5px rgba(160, 20, 40, 0.4);
}
@keyframes fx-fall {
  0%   { top: -4%;  opacity: 0; }
  8%   { opacity: 0.95; }
  88%  { opacity: 0.95; }
  100% { top: 102%; opacity: 0; }
}
@keyframes fx-drift {
  0%,
  100% { transform: translateX(calc(var(--sway) * -1)) rotate(0deg); }
  50%  { transform: translateX(var(--sway)) rotate(var(--spin)); }
}

/* ---------- headings: a slow gold shimmer ----------
   ambient.js adds .fx-title to every heading (so a visitor without JS, or
   with reduced motion, simply sees the plain heading).
   The shimmer paints the letters with background-clip:text, and that only
   paints inside the heading's own box. Script lettering has tall swashes
   (the A and P of "A Poetic Prelude") that stick out above the line, so the
   box is made taller with padding and the layout is given the same amount
   back with a negative margin: nothing moves, nothing is cut. */
.fx-ink,
.inv-title.fx-title {
  --fx-padt: 0.34em;
  --fx-padb: 0.26em;
  --fx-padx: 0.12em;
  background:
    linear-gradient(105deg, transparent 40%, var(--fx-sheen, #f0b94a) 50%, transparent 60%) 130% 0 / 260% 100% no-repeat,
    linear-gradient(currentColor, currentColor);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: fx-shine 7s ease-in-out infinite;
}
.fx-ink {
  padding: var(--fx-padt) var(--fx-padx) var(--fx-padb);
}
/* ambient.js wraps the heading's words in one .fx-ink box. It is inline-block
   with negative margins equal to its padding, so it takes up exactly the same
   room as the plain words did: layout, spacing and wrapping do not change. */
.fx-ink {
  display: inline-block;
  vertical-align: baseline;
  margin: calc(var(--fx-padt) * -1) calc(var(--fx-padx) * -1) calc(var(--fx-padb) * -1);
}
/* the Bengali card titles are swapped for English by script.js, so they get the
   padding directly (their own margin is 0) instead of a wrapper */
.inv .inv-title.fx-title {
  /* !important + vertical only: the English-mode card rules set their own
     padding with higher specificity, and padding and margin must always be
     changed together or the lines around the title shift */
  padding-top: var(--fx-padt) !important;
  padding-bottom: var(--fx-padb) !important;
  margin-top: calc(var(--fx-padt) * -1) !important;
  margin-bottom: calc(var(--fx-padb) * -1) !important;
}
/* English card titles ("The Wedding", "The Reception"): their line is only
   1.12x the letter size, so the tails of the g and p reach into the line
   underneath. A little room below the title (in em, so it scales with the
   card) keeps them apart. Not tied to JS or the shimmer: it applies always. */
html[data-lang="en"] .inv .inv-title {
  margin-bottom: 0.26em;
}
html[data-lang="en"] .inv .inv-title.fx-title {
  margin-bottom: calc(0.26em - var(--fx-padb)) !important;
}
/* little ornaments inside a heading keep their own colour */
.fx-ink > span { -webkit-text-fill-color: currentColor; }
.footer .fx-ink { --fx-sheen: #fff6dc; }
@keyframes fx-shine {
  0%,
  35%  { background-position: 130% 0; }
  75%,
  100% { background-position: -30% 0; }
}

/* ---------- leaves & flowers: a gentle breeze (ambient.js draws the patches) ---------- */
.fx-sway {
  /* the water mask already feathers the edges; sway patches reuse it */
  pointer-events: none;
}

/* ---------- falling flowers: a quiet, occasional shower ----------
   ambient.js adds a few flowers after the visitor scrolls / swipes; each
   falls once and fades away, so there is never constant motion.
   Three nested boxes keep the fall, the sway and the slow turn separate. */
.fx-blooms {
  position: fixed;
  inset: 0;
  z-index: 1800; /* over the pictures, under the menu (2000) and pop-ups */
  overflow: hidden;
  pointer-events: none;
}
.fx-bloom {
  position: absolute;
  top: 0;
  width: var(--s, 20px);
  height: var(--s, 20px);
  opacity: 0;
  will-change: transform, opacity;
  animation: fx-bloom-fall 13s linear 1 both;
}
.fx-bloom > i,
.fx-bloom > i > i {
  display: block;
  width: 100%;
  height: 100%;
}
.fx-bloom > i {
  animation: fx-bloom-sway 6s ease-in-out infinite;
}
.fx-bloom > i > i {
  background: center / contain no-repeat;
  filter: drop-shadow(0 1px 3px rgba(40, 8, 12, 0.4));
  animation: fx-bloom-turn 10s ease-in-out infinite;
}
@keyframes fx-bloom-fall {
  0%   { transform: translateY(-8vh); opacity: 0; }
  12%  { opacity: var(--o, 0.88); }
  75%  { opacity: var(--o, 0.88); }
  100% { transform: translateY(100vh); opacity: 0; }
}
@keyframes fx-bloom-sway {
  0%,
  100% { transform: translateX(calc(var(--sway) * -1)); }
  50%  { transform: translateX(var(--sway)); }
}
@keyframes fx-bloom-turn {
  0%,
  100% { transform: rotate(0deg) rotateX(0deg); }
  50%  { transform: rotate(var(--turn)) rotateX(45deg); }
}
.fx-blooms.fx-paused * { animation-play-state: paused !important; }
