/* ==========================================================================
   Radha Krishna wedding theme — Opening section
   --------------------------------------------------------------------------
   1. Fonts
   2. Reset
   3. Tokens          <- timings + easings live here, edit these only
   4. Composition     <- static layout (the reference screenshot)
   5. Responsive      <- per-breakpoint composition values
   6. Animation       <- the intro sequence, layered on top of 4
   7. Reduced motion
   ========================================================================== */


/* 1. Fonts ================================================================ */

/* Ananda is the theme's display face: every name, title and heading is set
   in it. IT HAS NO NUMERALS — a digit set in Ananda comes out as a missing
   glyph — so anything with a number in it (the date, the time, the
   address, the day badge) stays in Poppins. That is not a preference, it
   is the reason those rules are written the way they are.

   Norican stays behind it as the fallback: it was the theme's face before
   and it is still in the project, so a failed download is a change of
   voice rather than a change of layout.                                  */
@font-face {
  font-family: "Ananda";
  src: url("../fonts/Ananda%20Personal%20Use.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Ananda";
  src: url("../fonts/Ananda%20Black%20Personal%20Use.ttf") format("truetype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Norican";
  src: url("../fonts/norican.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Poppins";
  src: url("../fonts/poppins-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}


/* 2. Reset ================================================================ */

*,
*::before,
*::after { box-sizing: border-box; }

html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  min-width: 100%;
}

/* Only the root gets this. Setting overflow-x on <body> as well is what
   produces two scrollbars: once the root is no longer `visible`, the body's
   overflow stops propagating to the viewport and the body becomes a second,
   independent scroll container of its own. One declaration here, on the
   element the viewport actually takes its overflow from, is enough — the
   sections clip their own bleeding decoration internally. */
html { overflow-x: hidden; }

/* The sky belongs to the opening section, not to the page — otherwise it
   shows through anywhere the opening is not, which put a blue band above
   the invitation. The page itself is the invitation's paper.             */
body { background: #f4f2e4; }

.rk-opening { background: #d8f0fb; }

img {
  display: block;
  max-width: none;
  -webkit-user-drag: none;
  user-select: none;
}


/* 3. Tokens =============================================================== */

.rk-opening {
  /* --- sequence timing (single source of truth) --- */
  --t-feather-start: 0.35s;
  --t-feather-dur:   4s;      /* four sweeps need a little more room         */
  --t-feather-end:   4.35s;   /* = start + dur, when the idle float begins   */

  --t-hand-left:     4.45s;
  --t-hand-right:    4.65s;   /* small offset so the pair feels organic      */
  --t-hand-dur:      2.4s;

  --t-name-1:        7.15s;   /* Riya  */
  --t-name-2:        7.55s;   /* Weds  */
  --t-name-3:        7.85s;   /* Kunal */
  --t-name-dur:      1.5s;

  --t-scene-dur:     1.6s;    /* sky + clouds + birds settle in              */

  /* --- easings --- */
  --ease-fall:   cubic-bezier(0.33, 0.15, 0.18, 1);   /* long, soft landing  */
  --ease-drift:  cubic-bezier(0.37, 0.00, 0.63, 1);   /* sine in-out         */
  --ease-glide:  cubic-bezier(0.32, 0.02, 0.18, 1);   /* no overshoot        */
  --ease-reveal: cubic-bezier(0.22, 0.61, 0.36, 1);

  /* --- flight path (scaled per breakpoint) ---
     --f-sweep is how far LEFT of its resting place the feather swings at the
     far end of each sweep. The path never crosses to the right of where it
     lands, so it drifts in rather than hunting for the spot.               */
  --f-sweep: 30vw;
  --f-rise: 90vh;             /* how far above its resting place it starts   */

  /* --- cloud drift amplitudes: big enough to read as movement --- */
  --amp-l: clamp(30px, 4.2vw,  92px);   /* large / far   */
  --amp-m: clamp(40px, 5.6vw, 118px);   /* medium        */
  --amp-s: clamp(48px, 6.8vw, 140px);   /* small / near  */

  /* --- palette (sampled from the reference artwork) --- */
  --ink-name: #3a4a20;
  --ink-weds: #26333c;
  --weds-blob: #a9d6ec;

  /* gold picked to sit with the bangles in the hand artwork */
  --cta-ivory: #fdf8ec;
  --cta-ivory-lit: #fffdf6;
  --cta-gold: #c8a03c;
  --cta-gold-lit: #b8892a;
  --cta-gold-soft: rgba(200, 160, 60, 0.42);
  --cta-ink: rgba(58, 74, 32, 0.85);
  --cta-ink-soft: rgba(58, 74, 32, 0.62);

  /* --- CTA timing: starts only once the last name has finished --- */
  --t-cta-1: 9.9s;            /* blessing line  */
  --t-cta-2: 10.25s;          /* invitation line */
  --t-cta-3: 10.65s;          /* button          */
  --t-cta-dur: 1s;
  --t-cta-idle: 11.75s;       /* = t-cta-3 + dur, when breathing starts */
}


/* 4. Composition ========================================================== */

.rk-opening {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  isolation: isolate;
}

/* --- sky ---------------------------------------------------------------
   The asset is a pure vertical gradient with no shapes in it, so filling
   the box keeps the designed top-to-bottom sky at every aspect ratio.
   Every other layer is aspect-locked.                                     */
.rk-sky {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: fill;
  z-index: 0;
}

/* --- clouds ------------------------------------------------------------
   Each cloud is a sprite window onto overlay-clouds.png showing exactly one
   whole cloud. background-size / background-position are percentages, so a
   cloud keeps its shape and its crop at any size — nothing to recalculate.
   Only clouds with no cut edge in the source sheet are used.              */
.rk-clouds {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}

.rk-cloud {
  position: absolute;
  display: block;
  aspect-ratio: var(--ar);
  background-image: url("../../images/overlay-clouds.png");
  background-repeat: no-repeat;
  filter: blur(var(--haze, 0px));
}

/* Atmospheric perspective: the far clouds sit slightly out of focus, the
   near ones stay crisp. Static blur, so it rasterises once and the drift
   is still a pure transform.                                             */
.rk-cloud--a,
.rk-cloud--b,
.rk-cloud--c { --haze: 2.6px; }

.rk-cloud--d,
.rk-cloud--f,
.rk-cloud--g { --haze: 1.3px; }

.rk-cloud--e,
.rk-cloud--h,
.rk-cloud--i { --haze: 0.4px; }

/* --- mist ---------------------------------------------------------------
   Same artwork, blown up and blurred past recognition into pure haze.     */
.rk-mist {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}

.rk-mist__wisp {
  position: absolute;
  left: 0;
  display: block;
  width: var(--w);
  aspect-ratio: var(--ar);
  top: var(--y);
  background-image: url("../../images/overlay-clouds.png");
  background-repeat: no-repeat;
  filter: blur(var(--blur));
  opacity: 0;
}

.rk-mist__wisp--1 {
  --ar: 1559 / 432; background-size: 236.95% 1115.74%; background-position: 36.96% 9.25%;
  --w: 62vw; --y: 10%; --blur: 22px; --peak: 0.30;
}

.rk-mist__wisp--2 {
  --ar: 1122 / 311; background-size: 329.23% 1549.84%; background-position: 42.11% 75.96%;
  --w: 48vw; --y: 44%; --blur: 18px; --peak: 0.24;
}

.rk-mist__wisp--3 {
  --ar: 1237 / 320; background-size: 298.63% 1506.25%; background-position: 86.69% 22.22%;
  --w: 70vw; --y: 68%; --blur: 26px; --peak: 0.22;
}

/* sprite windows — fixed properties of the artwork, never change */
.rk-cloud--a { --ar: 1559 / 432; background-size: 236.95% 1115.74%; background-position: 36.96%  9.25%; }
.rk-cloud--b { --ar: 1237 / 320; background-size: 298.63% 1506.25%; background-position: 86.69% 22.22%; }
.rk-cloud--c { --ar: 1122 / 311; background-size: 329.23% 1549.84%; background-position: 42.11% 75.96%; }
.rk-cloud--d { --ar:  890 / 231; background-size: 415.06% 2086.58%; background-position: 73.04% 83.94%; }
.rk-cloud--e { --ar:  721 / 129; background-size: 512.34% 3736.43%; background-position:  9.55%  4.99%; }
.rk-cloud--f { --ar:  582 / 161; background-size: 634.71% 2993.79%; background-position: 90.52% 54.60%; }
.rk-cloud--g { --ar:  515 / 143; background-size: 717.28% 3370.63%; background-position: 12.77% 46.93%; }
.rk-cloud--h { --ar:  450 / 122; background-size: 820.89% 3950.82%; background-position:  1.05%  0.66%; }
.rk-cloud--i { --ar:  518 /  93; background-size: 713.13% 5182.80%; background-position: 22.67% 69.83%; }

/* --- birds ------------------------------------------------------------- */
.rk-birds {
  position: absolute;
  z-index: 2;
  pointer-events: none;
}

.rk-birds--upper {
  width: var(--b1-w);
  left: var(--b1-x);
  top: var(--b1-y);
}

.rk-birds--lower {
  width: var(--b2-w);
  left: var(--b2-x);
  top: var(--b2-y);
}

/* --- morpankh ---------------------------------------------------------- */
.rk-feather {
  position: absolute;
  z-index: 3;
  width: var(--f-w);
  left: var(--f-x);
  top: var(--f-y);
  pointer-events: none;
}

.rk-feather__fall,
.rk-feather__drift,
.rk-feather__tilt,
.rk-feather__idle { width: 100%; }

.rk-feather img { width: 100%; height: auto; }

/* --- names ------------------------------------------------------------- */
.rk-names {
  position: absolute;
  z-index: 4;
  left: var(--n-x);
  top: var(--n-y);
  transform: translateX(-50%);
  pointer-events: none;
}

.rk-names__pair {
  position: relative;
  margin: 0;
  font-family: "Ananda", "Norican", "Segoe Script", cursive;
  font-weight: 400;
  font-size: var(--n-size);
  line-height: 1.2;
  color: var(--ink-name);
  text-align: center;
  white-space: nowrap;
}

.rk-name { display: block; }

.rk-name--groom { margin-left: var(--n-groom-shift); }

/* "Weds" — small label sitting between the two names */
.rk-weds {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(calc(-50% + var(--weds-dx)), calc(-50% + var(--weds-dy)));
  display: grid;
  place-items: center;
}

/* the soft blue blob behind it — grid items stack in their own order, so
   both need an explicit z-index or the blob paints over the word */
.rk-weds::before {
  content: "";
  grid-area: 1 / 1;
  z-index: 0;
  width: 0.62em;
  height: 0.33em;
  border-radius: 50%;
  background: var(--weds-blob);
  transform: rotate(-5deg);
}

.rk-weds__text {
  grid-area: 1 / 1;
  z-index: 1;
  font-family: "Poppins", system-ui, sans-serif;
  font-weight: 600;
  font-size: 0.145em;
  line-height: 1;
  letter-spacing: 0.005em;
  color: var(--ink-weds);
}

/* --- hands -------------------------------------------------------------
   <picture> is the positioned box; the image inside simply fills its width
   and takes its own height, so whichever cut loads keeps its aspect ratio
   and can never be stretched.                                             */
.rk-hand {
  position: absolute;
  z-index: 5;
  display: block;
  pointer-events: none;
}

.rk-hand img {
  display: block;
  width: 100%;
  height: auto;
}

.rk-hand--krishna {
  width: var(--k-w);
  left: var(--k-x);
  top: var(--k-y);
}

.rk-hand--radha {
  width: var(--r-w);
  right: var(--r-x);
  top: var(--r-y);
}

/* --- invitation CTA -----------------------------------------------------
   Deliberately quiet: the names stay the loudest thing on the screen.     */
.rk-cta {
  position: absolute;
  z-index: 6;
  left: var(--cta-x);
  bottom: var(--cta-bottom);
  transform: translateX(-50%);
  width: max-content;
  max-width: var(--cta-maxw);
  text-align: center;
}

.rk-cta__blessing,
.rk-cta__invite {
  margin: 0;
  font-family: "Poppins", system-ui, sans-serif;
  font-weight: 600;
  line-height: 1.45;
}

/* muted with colour, not opacity — opacity belongs to the reveal */
.rk-cta__blessing {
  font-size: var(--cta-blessing-size);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cta-ink-soft);
}

.rk-cta__invite {
  margin-top: 0.5em;
  font-size: var(--cta-invite-size);
  letter-spacing: 0.015em;
  color: var(--cta-ink);
}

/* the button reads as an invitation seal: ivory card, double gold rule */
.rk-cta__button {
  margin-top: var(--cta-gap);
  padding: var(--cta-pad-y) var(--cta-pad-x);
  min-height: var(--cta-tap);
  font-family: "Poppins", system-ui, sans-serif;
  font-weight: 600;
  font-size: var(--cta-button-size);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-name);
  background: var(--cta-ivory);
  border: 1px solid var(--cta-gold);
  border-radius: 5px;
  box-shadow:
    inset 0 0 0 3px var(--cta-ivory),
    inset 0 0 0 4px var(--cta-gold-soft);
  cursor: pointer;
  transition:
    background-color 300ms ease,
    border-color 300ms ease,
    transform 300ms ease;
}

.rk-cta__button:hover {
  background: var(--cta-ivory-lit);
  border-color: var(--cta-gold-lit);
  transform: translateY(-2px);
}

.rk-cta__button:focus-visible {
  outline: 2px solid var(--cta-gold-lit);
  outline-offset: 3px;
}


/* 5. Responsive =========================================================== */

/* --- default: portrait, reference proportions (tablet / large phone) ---- */
.rk-opening {
  --k-w: 39.7vw;  --k-x: -1.3vw;  --k-y: 4.4%;
  --r-w: 42.4vw;  --r-x: -0.5vw;  --r-y: 8.2%;
  --f-w: 42.3vw;  --f-x: 52.3vw;  --f-y: 42.1%;
  --b1-w: 18.8vw; --b1-x: 39.7vw; --b1-y: 4.6%;
  --b2-w: 23vw;   --b2-x: 57.9vw; --b2-y: 66.8%;

  --n-size: 15.2vw;
  --n-x: 47.3vw;
  --n-y: 46%;
  --n-groom-shift: -0.06em;
  --weds-dx: 0.2em;
  --weds-dy: 0.23em;

  --cta-x: 47.3vw;
  --cta-bottom: 5%;
  --cta-maxw: 78vw;
  --cta-blessing-size: clamp(9px, 1.55vmin, 13px);
  --cta-invite-size:   clamp(11px, 1.95vmin, 16px);
  --cta-button-size:   clamp(11px, 1.8vmin, 14px);
  --cta-gap:    clamp(10px, 1.8vmin, 18px);
  --cta-pad-y:  clamp(9px, 1.5vmin, 14px);
  --cta-pad-x:  clamp(18px, 3.4vmin, 32px);
  --cta-tap:    44px;
}

/* cloud placement — portrait / tablet */
.rk-cloud--h { width: 26vw; left: 1vw;   top: 3%; }
.rk-cloud--a { width: 38vw; left: 34vw;  top: 7%; }
.rk-cloud--b { width: 32vw; right: -4vw; top: 17%; }
.rk-cloud--e { width: 21vw; left: 4vw;   top: 24%; }
.rk-cloud--g { width: 25vw; left: -5vw;  top: 35%; }
.rk-cloud--f { width: 23vw; right: -3vw; top: 46%; }
.rk-cloud--c { width: 42vw; left: -6vw;  top: 76%; }
.rk-cloud--d { width: 34vw; right: -5vw; top: 85%; }
.rk-cloud--i { width: 20vw; left: 38vw;  top: 92%; }

/* --- tall / narrow portrait (phones) ----------------------------------
     The reference frame is far wider than a phone, so the artwork is
     enlarged and the vertical rhythm opened up instead of shrinking the
     whole composition down.                                              */
@media (max-aspect-ratio: 62 / 100) {
  .rk-opening {
    --k-w: 52vw;    --k-x: -3vw;    --k-y: 9%;
    --r-w: 55vw;    --r-x: -2vw;    --r-y: 15.5%;
    --f-w: 55vw;    --f-x: 46vw;    --f-y: 47%;
    --b1-w: 24vw;   --b1-x: 36vw;   --b1-y: 8%;
    --b2-w: 30vw;   --b2-x: 52vw;   --b2-y: 72%;

    --n-size: 20vw;
    --n-x: 47vw;
    --n-y: 50%;

    --f-sweep: 34vw;

    --cta-x: 47vw;
    --cta-bottom: 3%;
    --cta-maxw: 86vw;
  }

  /* fewer, larger clouds so a narrow screen does not turn into confetti */
  .rk-cloud--h { width: 34vw; left: -2vw;  top: 4%; }
  .rk-cloud--a { width: 46vw; left: 40vw;  top: 9%; }
  .rk-cloud--b { width: 42vw; right: -8vw; top: 20%; }
  .rk-cloud--e { display: none; }
  .rk-cloud--g { width: 32vw; left: -8vw;  top: 40%; }
  .rk-cloud--f { width: 30vw; right: -6vw; top: 52%; }
  .rk-cloud--c { width: 54vw; left: -10vw; top: 76%; }
  .rk-cloud--d { width: 44vw; right: -8vw; top: 86%; }
  .rk-cloud--i { display: none; }
}

/* --- landscape (laptop / desktop) -------------------------------------
     Sized from the viewport height so the artwork keeps the reference's
     visual weight, and anchored to the true screen edges so the hands
     still enter from off-screen left / right.                            */
@media (min-aspect-ratio: 1 / 1) {
  /* clouds pull back to the edges so the middle stays open for the names */
  .rk-cloud--h { width: 15vw;   left: 1vw;   top: 5%; }
  .rk-cloud--a { width: 27vw;   left: 20vw;  top: 9%; }
  .rk-cloud--b { width: 23vw;   right: 6vw;  top: 5%;  left: auto; }
  .rk-cloud--e { width: 14vw;   left: 12vw;  top: 27%; }
  .rk-cloud--g { width: 13vw;   left: -2vw;  top: 52%; }
  .rk-cloud--f { width: 14vw;   right: -2vw; top: 44%; left: auto; }
  .rk-cloud--c { width: 25vw;   left: 3vw;   top: 74%; }
  .rk-cloud--d { width: 21vw;   right: 5vw;  top: 80%; left: auto; }
  .rk-cloud--i { width: 12vw;   right: 24vw; top: 92%; left: auto; }

  .rk-opening {
    /* the long-armed PC cuts are 16:9, so they are sized from the width and
       reach in from each edge rather than sitting in a top corner */
    --k-w: 49vw;    --k-x: -6vw;    --k-y: 0%;
    --r-w: 51vw;    --r-x: -6vw;    --r-y: 5%;
    --f-w: 46vh;    --f-x: 54%;     --f-y: 40%;
    --b1-w: 20vh;   --b1-x: 32%;    --b1-y: 5%;
    --b2-w: 24vh;   --b2-x: 62%;    --b2-y: 74%;   /* clear of the feather */

    --n-size: 16.8vh;
    --n-x: 48%;
    --n-y: 43%;

    --f-sweep: min(28vw, 57vh);
    --f-rise: 92vh;   /* the feather is taller here, so it must start higher */

    --cta-x: 48%;
    --cta-bottom: 3%;
    --cta-maxw: 46vw;
    --cta-blessing-size: clamp(9px, 1.35vh, 13px);
    --cta-invite-size:   clamp(11px, 1.75vh, 16px);
    --cta-button-size:   clamp(11px, 1.6vh, 14px);
    --cta-gap:   clamp(7px, 1.3vh, 15px);
    --cta-pad-y: clamp(8px, 1.3vh, 13px);
  }
}


/* 6. Animation ============================================================
   Every rule below only moves an element away from the resting position
   defined in section 4 and brings it back, so switching the animations off
   leaves the finished composition intact.                                  */

/* --- scene: sky, clouds, birds ----------------------------------------- */
@keyframes rk-scene-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.rk-sky,
.rk-clouds,
.rk-birds {
  animation: rk-scene-in var(--t-scene-dur) var(--ease-reveal) both;
}

.rk-birds { animation-delay: 0.5s; }

/* --- ambient: the sky keeps breathing ----------------------------------
   One shared pair of keyframes, but every cloud supplies its own distance,
   direction, drift height, duration and (negative) delay, so no two are
   ever in step and nothing moves as a block. Each cycle returns to its own
   start, so the loop is seamless — there is no reset jump.
   Speed rises from the big far clouds to the small near ones, which is
   what gives the sky its sense of depth.                                  */
@keyframes rk-cloud-drift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  25%  { transform: translate3d(calc(var(--dx) * 0.42), var(--dy1), 0) scale(1.012); }
  50%  { transform: translate3d(var(--dx), 0, 0) scale(1.026); }
  75%  { transform: translate3d(calc(var(--dx) * 0.55), var(--dy2), 0) scale(1.013); }
  100% { transform: translate3d(0, 0, 0) scale(1); }
}

/* small clouds only — a gentle density change as they billow, never a fade */
@keyframes rk-cloud-drift-soft {
  0%   { transform: translate3d(0, 0, 0) scale(1); opacity: 1; }
  25%  { transform: translate3d(calc(var(--dx) * 0.42), var(--dy1), 0) scale(1.015); opacity: 0.93; }
  50%  { transform: translate3d(var(--dx), 0, 0) scale(1.03); opacity: 1; }
  75%  { transform: translate3d(calc(var(--dx) * 0.55), var(--dy2), 0) scale(1.015); opacity: 0.92; }
  100% { transform: translate3d(0, 0, 0) scale(1); opacity: 1; }
}

.rk-cloud {
  --dy1: 0px;
  --dy2: 0px;
  animation: rk-cloud-drift var(--dur) ease-in-out var(--wait) infinite;
}

/* layer 1 — large, far, slowest */
.rk-cloud--a { --dx: var(--amp-l);              --dur: 44s; --wait:  -7s; }
.rk-cloud--b { --dx: calc(-1 * var(--amp-l));   --dur: 52s; --wait: -22s; }
.rk-cloud--c { --dx: var(--amp-l);              --dur: 48s; --wait: -38s; }

/* layer 2 — medium: quicker, with a soft rise and fall */
.rk-cloud--d { --dx: calc(-1 * var(--amp-m));   --dur: 32s; --wait: -13s; --dy1: -9px;  --dy2: 7px; }
.rk-cloud--f { --dx: var(--amp-m);              --dur: 28s; --wait: -26s; --dy1: -7px;  --dy2: 9px; }
.rk-cloud--g { --dx: calc(-1 * var(--amp-m));   --dur: 35s; --wait:  -5s; --dy1: -9px;  --dy2: 6px; }

/* layer 3 — small, nearest: the most movement, counter to their neighbours */
.rk-cloud--e { --dx: var(--amp-s);              --dur: 24s; --wait: -16s; --dy1: -13px; --dy2: 8px;
               animation-name: rk-cloud-drift-soft; }
.rk-cloud--h { --dx: calc(-1 * var(--amp-s));   --dur: 20s; --wait:  -9s; --dy1: -9px;  --dy2: 12px;
               animation-name: rk-cloud-drift-soft; }
.rk-cloud--i { --dx: var(--amp-s);              --dur: 26s; --wait: -19s; --dy1: -11px; --dy2: 7px;
               animation-name: rk-cloud-drift-soft; }

/* --- mist: slow, one-way crossings that fade in and out at the edges ---- */
@keyframes rk-mist-right {
  0%   { transform: translate3d(-70vw, 0, 0) scale(1);    opacity: 0; }
  20%  { opacity: var(--peak); }
  80%  { opacity: var(--peak); }
  100% { transform: translate3d(105vw, 0, 0) scale(1.14); opacity: 0; }
}

@keyframes rk-mist-left {
  0%   { transform: translate3d(105vw, 0, 0) scale(1.14); opacity: 0; }
  20%  { opacity: var(--peak); }
  80%  { opacity: var(--peak); }
  100% { transform: translate3d(-70vw, 0, 0) scale(1);    opacity: 0; }
}

.rk-mist__wisp {
  animation: rk-mist-right var(--dur) linear var(--wait) infinite;
}

.rk-mist__wisp--1 { --dur: 96s;  --wait: -18s; }
.rk-mist__wisp--2 { --dur: 74s;  --wait: -50s; animation-name: rk-mist-left; }
.rk-mist__wisp--3 { --dur: 120s; --wait: -88s; }

/* --- phase 1: the morpankh flies in from the top ------------------------
   The path is composed from three independent, differently-eased tracks:
   a long vertical fall, a lateral breeze (right, then left, then centre)
   and a slow tilt. Combined, they trace a smooth curve, and every value is
   viewport-relative so the path scales with the screen.                   */

/* Descent. Slow while it is still high, a little quicker through the middle,
   then easing off into the landing — the vertical half of the drawn path. */
@keyframes rk-feather-fall {
  0%   { transform: translate3d(0, calc(var(--f-rise) * -1.00), 0);
         animation-timing-function: cubic-bezier(0.35, 0, 0.5, 1); }
  28%  { transform: translate3d(0, calc(var(--f-rise) * -0.55), 0);
         animation-timing-function: linear; }
  52%  { transform: translate3d(0, calc(var(--f-rise) * -0.40), 0);
         animation-timing-function: linear; }
  76%  { transform: translate3d(0, calc(var(--f-rise) * -0.20), 0);
         animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
  100% { transform: translate3d(0, 0, 0); }
}

/* Four lateral sweeps: out to the left, back, out again, then in to rest.
   Sine easing on every segment, so each turn rolls over instead of kinking. */
@keyframes rk-feather-drift {
  0%   { transform: translate3d(0, 0, 0); }
  28%  { transform: translate3d(calc(var(--f-sweep) * -1.00), 0, 0); }
  52%  { transform: translate3d(calc(var(--f-sweep) * -0.06), 0, 0); }
  76%  { transform: translate3d(calc(var(--f-sweep) * -0.92), 0, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

/* The tilt leans into whichever way it is travelling, settling as it lands. */
@keyframes rk-feather-tilt {
  0%   { transform: rotate(11deg)  scale(0.85); opacity: 0; }
  8%   { opacity: 1; }
  28%  { transform: rotate(-13deg) scale(0.89); }
  52%  { transform: rotate(10deg)  scale(0.93); }
  76%  { transform: rotate(-8deg)  scale(0.97); }
  100% { transform: rotate(0deg)   scale(1);    opacity: 1; }
}

.rk-feather__fall {
  animation: rk-feather-fall var(--t-feather-dur) linear
             var(--t-feather-start) both;
  will-change: transform;
}

.rk-feather__drift {
  animation: rk-feather-drift var(--t-feather-dur) var(--ease-drift)
             var(--t-feather-start) both;
  will-change: transform;
}

.rk-feather__tilt {
  animation: rk-feather-tilt var(--t-feather-dur) var(--ease-drift)
             var(--t-feather-start) both;
  will-change: transform, opacity;
}

/* --- settled: an almost imperceptible float ---------------------------- */
@keyframes rk-feather-idle {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg); }
  50%  { transform: translate3d(0.25%, -1.1%, 0) rotate(0.9deg); }
  100% { transform: translate3d(0, 0, 0) rotate(0deg); }
}

.rk-feather__idle {
  animation: rk-feather-idle 8s ease-in-out var(--t-feather-end) infinite;
}

/* --- phase 2: the hands enter ------------------------------------------ */
@keyframes rk-hand-left-in {
  from { transform: translate3d(-118%, 5%, 0) rotate(-2.5deg); }
  to   { transform: translate3d(0, 0, 0) rotate(0deg); }
}

@keyframes rk-hand-right-in {
  from { transform: translate3d(118%, 4%, 0) rotate(2.5deg); }
  to   { transform: translate3d(0, 0, 0) rotate(0deg); }
}

.rk-hand--krishna {
  animation: rk-hand-left-in var(--t-hand-dur) var(--ease-glide)
             var(--t-hand-left) both;
  will-change: transform;
}

.rk-hand--radha {
  animation: rk-hand-right-in var(--t-hand-dur) var(--ease-glide)
             var(--t-hand-right) both;
  will-change: transform;
}

/* --- phase 3: the names reveal ----------------------------------------- */
@keyframes rk-name-in {
  from { opacity: 0; transform: translate3d(0, 0.18em, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

.rk-name--bride,
.rk-weds,
.rk-name--groom {
  animation: rk-name-in var(--t-name-dur) var(--ease-reveal) both;
}

.rk-name--bride { animation-delay: var(--t-name-1); }
.rk-name--groom { animation-delay: var(--t-name-3); }

/* "Weds" is centred with a transform, so it needs its own keyframes to
   avoid fighting the positioning transform. */
@keyframes rk-weds-in {
  from {
    opacity: 0;
    transform: translate(calc(-50% + var(--weds-dx)),
                         calc(-50% + var(--weds-dy) + 0.16em));
  }
  to {
    opacity: 1;
    transform: translate(calc(-50% + var(--weds-dx)),
                         calc(-50% + var(--weds-dy)));
  }
}

.rk-weds {
  animation-name: rk-weds-in;
  animation-delay: var(--t-name-2);
}

/* --- phase 4: the invitation ------------------------------------------- */
@keyframes rk-cta-in {
  from { opacity: 0; transform: translate3d(0, 10px, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

/* a slow, shallow breath — never a blink */
@keyframes rk-cta-breathe {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.94; }
}

.rk-cta__blessing,
.rk-cta__invite,
.rk-cta__button {
  animation: rk-cta-in var(--t-cta-dur) var(--ease-glide) both;
}

.rk-cta__blessing { animation-delay: var(--t-cta-1); }
.rk-cta__invite   { animation-delay: var(--t-cta-2); }

.rk-cta__button {
  animation:
    rk-cta-in var(--t-cta-dur) var(--ease-glide) var(--t-cta-3) both,
    rk-cta-breathe 4s ease-in-out var(--t-cta-idle) infinite;
}

/* the whole scene steps aside when the invitation is opened */
.rk-opening {
  transition: opacity 700ms ease, transform 700ms ease;
}

.rk-opening.is-opening {
  opacity: 0;
  transform: scale(1.03);
}


/* 7. Reduced motion =======================================================
   Nothing moves; the composition is simply present, already finished.     */

@media (prefers-reduced-motion: reduce) {
  .rk-sky,
  .rk-clouds,
  .rk-birds,
  .rk-feather__fall,
  .rk-feather__drift,
  .rk-feather__tilt,
  .rk-feather__idle,
  .rk-hand--krishna,
  .rk-hand--radha,
  .rk-name--bride,
  .rk-name--groom,
  .rk-weds,
  .rk-cloud,
  .rk-mist__wisp,
  .rk-cta__blessing,
  .rk-cta__invite,
  .rk-cta__button {
    animation: none !important;
  }

  .rk-opening,
  .rk-cta__button { transition: none; }

  .rk-feather__fall,
  .rk-feather__drift,
  .rk-feather__tilt,
  .rk-feather__idle,
  .rk-hand--krishna,
  .rk-hand--radha { will-change: auto; }
}
