/* ============================================================
   HAPPY BIRTHDAY — a cinematic birthday film in four acts
   Vanilla + GSAP. One page, one continuous piece:
     1. a beating heart you open with a bow & arrow
     2. it falls, and bursts into a flood of rose wine
     3. a kinetic wish hinges up out of that colour
     4. a gold light blooms, and a tree grows into a heart of blossoms
   One grain + vignette lens sits over all of it.
   ============================================================ */

:root{
  /* --- cream / off-white (Act 1 + the tree's dawn) --- */
  --paper-0:  #fffaf4;
  --paper-1:  #f7ece0;
  --paper-2:  #eddac6;

  /* --- wine-red flood (Acts 2–3) --- */
  --rose-deep: #63102c;
  --rose:      #93203f;
  --rose-lift: #b23a5c;
  --wine:      #2c0714;

  /* --- accents / ink --- */
  --gold-1:    #f0c274;
  --gold-2:    #d79a3f;
  --ink:       #5c1a2c;   /* wine ink              */
  --ink-soft:  #8a5566;   /* muted eyebrow / sub   */
  --cream:     #fffaf4;

  --ease-out:  cubic-bezier(.2,.7,.2,1);
}

*{ box-sizing:border-box; margin:0; padding:0; }
html, body{ height:100%; }

body{
  background:#12060c;                 /* seam colour under everything */
  overflow:hidden;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  cursor:auto;
}

/* Cross-device tap hardening */
button{
  -webkit-tap-highlight-color:transparent;
  -webkit-touch-callout:none;
  -webkit-user-select:none;
  user-select:none;
}

.scene{ position:fixed; inset:0; overflow:hidden; }
.page{ overscroll-behavior:contain; }

.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;
}

/* ============================================================
   THE TREE CANVAS (Act 4) — z0, transparent until it plays
   ============================================================ */
.tree{
  position:absolute; inset:0;
  width:100%; height:100%;
  display:block;
  z-index:1;
}

/* ============================================================
   ACT 1 — THE INVITATION
   ============================================================ */
.hero{
  position:absolute; inset:0;
  z-index:3;
  overflow:hidden;
}

/* the warm field the heart sits on */
.hero__bg{
  position:absolute; inset:0;
  background:
    radial-gradient(120% 88% at 50% 24%, #fff8f1 0%, var(--paper-0) 38%, var(--paper-1) 74%, var(--paper-2) 100%);
}
.hero__bg::after{
  content:""; position:absolute; left:50%; top:44%;
  width:min(78vw,720px); aspect-ratio:1; transform:translate(-50%,-50%);
  background:radial-gradient(circle, rgba(240,194,116,.45), rgba(147,32,63,.14) 46%, transparent 70%);
  filter:blur(6px);
}

/* drifting light motes */
.hero__motes{ position:absolute; inset:0; pointer-events:none; }
.mote{
  position:absolute; border-radius:50%;
  background:radial-gradient(circle, rgba(255,236,214,.9), rgba(255,206,180,.15) 55%, transparent 72%);
  will-change:transform, opacity;
}

.hero__eyebrow{
  position:absolute; top:13%; left:0; right:0;
  text-align:center;
  font-family:"Cormorant Garamond", Georgia, serif;
  font-style:italic; font-weight:600;
  font-size:clamp(15px, 3.6vw, 26px);
  letter-spacing:.06em;
  color:var(--ink);
  text-shadow:0 1px 10px rgba(255,248,241,.9);
  opacity:0;
}

/* ---- the target heart (GSAP animates .target on hit -> fall -> burst) ---- */
.targetWrap{
  position:absolute; top:33%; left:0; right:0;
  display:flex; justify-content:center;
  transform:translateY(-50%);
  pointer-events:none;
}
.target{
  position:relative;
  width:clamp(120px, 27vw, 208px);
  aspect-ratio:100/92;
  will-change:transform;
  transform-origin:50% 60%;
}
.target__heart{ position:absolute; inset:0; display:block; }

/* radial bloom behind the heart — swells on beat */
.heart__glow{
  position:absolute; left:50%; top:52%;
  width:230%; aspect-ratio:1; transform:translate(-50%,-50%) scale(1);
  border-radius:50%;
  background:radial-gradient(circle, rgba(147,32,63,.5), rgba(122,16,56,.18) 42%, transparent 68%);
  filter:blur(4px);
  pointer-events:none;
  will-change:transform, opacity;
}
.heart__svg{
  width:100%; height:100%; display:block;
  transform-origin:50% 60%;
  filter:
    drop-shadow(0 10px 22px rgba(168,15,64,.34))
    drop-shadow(0 3px 6px rgba(120,10,48,.30));
  will-change:transform;
}

/* ---- the bow + arrow rig ---- */
.archery{
  position:absolute; top:0; left:0;
  width:clamp(100px, 18vw, 168px);
  cursor:grab;
  -webkit-tap-highlight-color:transparent;
  touch-action:none;
  will-change:transform;
}
.archery:active{ cursor:grabbing; }
.archery:focus-visible{ outline:none; }
.archery:focus-visible .bow{ filter:drop-shadow(0 0 0 3px rgba(255,255,255,.85)) drop-shadow(0 10px 18px rgba(120,50,20,.4)); }
.bow{
  display:block; width:100%; height:auto;
  filter:drop-shadow(0 12px 18px rgba(90,40,15,.3));
  overflow:visible;
}

/* the aim line points straight at the heart */
.aim{
  position:absolute; left:50%; bottom:32%;
  width:2px; height:190%; margin-left:-1px;
  transform-origin:bottom center;
  background:linear-gradient(0deg, rgba(240,194,116,.6) 0%, rgba(147,32,63,.22) 52%, transparent 78%);
  opacity:0; pointer-events:none;
}

/* the arrow overlaps the bow at the nock and flies to the heart */
.arrow{
  position:absolute; left:0; right:0; margin-inline:auto;
  bottom:36%;
  width:17.5%; height:auto;
  overflow:visible;
  will-change:transform;
  filter:drop-shadow(0 5px 7px rgba(90,40,15,.36));
}
.arrow__wings{ transform-box:fill-box; transform-origin:50% 90%; }
.arrow__wings .wingL,
.arrow__wings .wingR{ transform-box:fill-box; }
.wingL{ transform-origin:88% 60%; animation:flapL 2.6s ease-in-out infinite; }
.wingR{ transform-origin:12% 60%; animation:flapR 2.6s ease-in-out infinite; }
@keyframes flapL{ 0%,100%{ transform:rotate(0deg); } 50%{ transform:rotate(-11deg); } }
@keyframes flapR{ 0%,100%{ transform:rotate(0deg); } 50%{ transform:rotate(11deg); } }

/* ---- the draw / release hint ---- */
.hero__hint{
  position:absolute; bottom:8.5%; left:0; right:0;
  text-align:center;
  font-family:"Cormorant Garamond", Georgia, serif;
  font-weight:600; font-style:italic;
  font-size:clamp(13px, 3.1vw, 19px);
  letter-spacing:.16em; text-transform:uppercase;
  color:var(--ink-soft);
  opacity:0;
}

@media (max-height:500px) and (orientation:landscape){
  .hero__eyebrow{ top:4%; font-size:clamp(13px, 2.6vw, 20px); }
  .targetWrap{ top:50%; }
  .target{ width:clamp(96px, 16vw, 150px); }
  .archery{ width:clamp(80px, 13vw, 130px); }
  .hero__hint{ bottom:4%; }
}

/* ============================================================
   ACT 2 — THE FLOOD (the burst circle)
   ============================================================ */
.flood{
  position:absolute; left:50%; top:50%;
  width:140px; height:140px; margin:-70px 0 0 -70px;
  border-radius:50%;
  background:radial-gradient(circle at 40% 34%, var(--rose-lift), var(--rose) 46%, var(--rose-deep) 100%);
  z-index:5;
  opacity:0; transform:scale(.001);
  will-change:transform, opacity;
  pointer-events:none;
}

/* ============================================================
   ACT 3 — THE WISH FIELD (rose world + kinetic type)
   ============================================================ */
.field{
  position:absolute; inset:0;
  z-index:4;
  opacity:0;
  pointer-events:none;
  overflow:hidden;
  background:
    radial-gradient(120% 100% at 50% 8%, #a8284a 0%, var(--rose) 42%, var(--rose-deep) 78%, var(--wine) 100%);
  color:#fff;
}
.blob{
  position:absolute; border-radius:50%;
  filter:blur(46px); opacity:0;
  mix-blend-mode:screen;
  will-change:transform, opacity;
}
.blob--1{ width:58vmax; height:58vmax; left:-18vmax; top:-16vmax;
  background:radial-gradient(circle, rgba(178,58,92,.85), transparent 62%); }
.blob--2{ width:46vmax; height:46vmax; right:-14vmax; top:22vmax;
  background:radial-gradient(circle, rgba(147,32,63,.7), transparent 64%); }
.blob--3{ width:52vmax; height:52vmax; left:24vmax; bottom:-22vmax;
  background:radial-gradient(circle, rgba(99,16,44,.75), transparent 66%); }

/* faint grid */
.fgrid{
  position:absolute; inset:-6%;
  background-image:
    linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
  background-size:clamp(38px,7vw,74px) clamp(38px,7vw,74px);
  will-change:transform;
}
.fvignette{
  position:absolute; inset:0;
  background:radial-gradient(128% 96% at 50% 44%, transparent 50%, rgba(70,6,28,.5) 100%);
}

/* the camera — slow continuous push */
.camera{
  position:absolute; inset:0;
  display:flex; flex-direction:column; justify-content:center; align-items:center;
  gap:clamp(4px,1.2vh,12px);
  padding:0 6vw; text-align:center;
  will-change:transform;
}
.kEyebrow{
  font-family:"Cormorant Garamond", Georgia, serif;
  font-style:italic; font-weight:500;
  font-size:clamp(15px, 3.6vw, 27px);
  letter-spacing:.08em;
  color:#f6dfc2;
  opacity:0; transform:translateY(10px);
  margin-bottom:clamp(2px,1vh,10px);
}

.headline{ font-family:"Fraunces", Georgia, serif; line-height:.92; }
.hl__line{ display:block; }
.mask{
  display:inline-block; overflow:hidden;
  padding:.14em .06em;
  margin:-.14em -.06em;
}
.hl__word{
  display:inline-block;
  font-weight:900;
  font-size:clamp(52px, 15vw, 168px);
  letter-spacing:-.02em;
  color:#fff6f1;
  text-shadow:0 6px 34px rgba(60,4,24,.34), 0 2px 3px rgba(90,8,36,.42);
}
.hl__word--long{ font-size:clamp(42px, 12vw, 138px); letter-spacing:-.01em; }
.hl__ch{ display:inline-block; will-change:transform; }

/* gold hand-drawn underline under Birthday */
.uline{
  width:clamp(150px, 40vw, 380px); height:auto;
  margin-top:clamp(4px,1.4vh,14px);
  color:var(--gold-1);
  filter:drop-shadow(0 2px 8px rgba(255,180,90,.5));
}
.kSub{
  margin-top:clamp(12px,2.4vh,26px);
  font-family:"Cormorant Garamond", Georgia, serif;
  font-weight:500; font-style:italic;
  font-size:clamp(14px, 3.4vw, 24px);
  letter-spacing:.05em;
  color:#f6e2d8;
  opacity:0; transform:translateY(10px);
}

/* cinema bars */
.bar{
  position:absolute; left:0; right:0; height:16vh;
  background:#12040b; z-index:3; will-change:transform; pointer-events:none;
}
.bar--top{ top:0; }
.bar--bot{ bottom:0; }

/* ============================================================
   THE HANDOFF BLOOM (rose wish -> dawn of the tree)
   ============================================================ */
.bloom{
  position:absolute; left:50%; top:50%;
  width:60px; height:60px; margin:-30px 0 0 -30px;
  border-radius:50%;
  background:radial-gradient(circle, #fff 0%, #fff2d6 30%, rgba(255,214,150,.85) 55%, rgba(255,190,150,0) 74%);
  z-index:8; opacity:0; transform:scale(.001);
  will-change:transform, opacity; pointer-events:none;
}

/* ============================================================
   ACT 4 — THE HAND-LETTERED WISH (over the tree)
   ============================================================ */
.wish{
  position:absolute;
  left:5.5%; bottom:10%;
  max-width:48%;
  z-index:6;
  pointer-events:none;
  color:var(--ink);
  visibility:hidden;
}
.wish.is-in{ visibility:visible; }
.wish::before{
  content:""; position:absolute; inset:-18% -24% -24% -16%;
  background:radial-gradient(84% 98% at 34% 52%, rgba(255,250,243,.94), rgba(255,250,243,.6) 48%, rgba(255,250,243,0) 80%);
  z-index:-1; opacity:0; transition:opacity 1s ease;
}
.wish.is-in::before{ opacity:1; }
.wish__eyebrow{
  font-family:"Cormorant Garamond", Georgia, serif;
  font-style:italic; font-weight:600;
  font-size:clamp(13px, 3.2vw, 24px);
  letter-spacing:.05em; color:#7a2c40;
  text-shadow:0 1px 2px #fff8f1, 0 0 8px rgba(255,248,241,.95);
}
.wish__heroWrap{ position:relative; display:inline-block; }
.wish__heroWrap::before{
  content:""; position:absolute; left:-12%; right:-12%; top:-26%; bottom:-22%;
  background:radial-gradient(60% 70% at 46% 52%, rgba(255,214,168,.5), rgba(255,150,150,.2) 52%, transparent 74%);
  filter:blur(14px); z-index:-1; opacity:0; pointer-events:none;
}
.wish__heroWrap::after{
  content:"\2726";
  position:absolute; right:-1%; top:-14%;
  font-size:clamp(15px, 3.6vw, 32px);
  color:#ffe1a0; text-shadow:0 0 12px rgba(255,205,120,.95);
  opacity:0; pointer-events:none;
}
.wish__hero{
  font-family:"Great Vibes", cursive; font-weight:400;
  font-size:clamp(40px, 9.6vw, 86px);
  line-height:.98; margin:-.02em 0 .06em;
  background:linear-gradient(180deg, #b23a5c 0%, #93203f 50%, #63102c 100%);
  -webkit-background-clip:text; background-clip:text; color:transparent;
  filter:
    drop-shadow(0 1px 1px rgba(255,252,248,.98))
    drop-shadow(0 2px 6px rgba(130,18,55,.45));
  clip-path:inset(0 100% -28% -10%);
  transform-origin:8% 60%;
}
.wish__rule{
  display:block; width:clamp(46px, 13vw, 110px); height:2px;
  margin:.12em 0 .48em;
  background:linear-gradient(90deg, var(--gold-2), rgba(232,162,61,0));
  box-shadow:0 0 8px rgba(255,247,240,.9);
  transform-origin:left center;
}
.wish__sub{
  font-family:"Cormorant Garamond", Georgia, serif;
  font-weight:600; font-size:clamp(12px, 2.9vw, 20px);
  letter-spacing:.03em; color:var(--ink);
  text-shadow:0 1px 2px #fff8f1, 0 0 8px rgba(255,248,241,.98);
}
.wish__eyebrow, .wish__rule, .wish__sub{
  opacity:0; transform:translateY(12px); filter:blur(5px);
  transition:opacity .8s ease, transform .9s var(--ease-out), filter .8s ease;
}
.wish__rule{ transform:translateY(12px) scaleX(.3); }
.wish.is-in .wish__eyebrow,
.wish.is-in .wish__sub{ opacity:1; transform:translateY(0); filter:blur(0); }
.wish.is-in .wish__rule{ opacity:1; transform:translateY(0) scaleX(1); }
.wish.is-in .wish__rule{ transition-delay:1.35s; }
.wish.is-in .wish__sub{  transition-delay:1.55s; }
.wish.is-in .wish__hero{
  animation:write 1.2s cubic-bezier(.62,.04,.24,1) .35s forwards,
            wishBreath 4s ease-in-out 1.9s infinite;
}
@keyframes wishBreath{ 0%,100%{ transform:scale(1); } 50%{ transform:scale(1.02); } }
.wish.is-in .wish__heroWrap::before{ animation:hlin .8s ease .3s forwards, hlpulse 3.4s ease-in-out 1.7s infinite; }
.wish.is-in .wish__heroWrap::after{ animation:twk 2.6s ease-in-out 1.6s infinite; }
@keyframes write{ from{ clip-path:inset(0 100% -28% -10%); } to{ clip-path:inset(0 -10% -28% -10%); } }
@keyframes hlin{ from{ opacity:0; transform:scale(.86); } to{ opacity:.92; transform:scale(1); } }
@keyframes hlpulse{ 0%,100%{ opacity:.72; } 50%{ opacity:1; } }
@keyframes twk{ 0%,100%{ opacity:0; transform:scale(.5) rotate(-12deg); } 45%{ opacity:1; transform:scale(1.05) rotate(16deg); } }

/* ============================================================
   REPLAY / CONTINUE
   ============================================================ */
.replay{
  position:absolute; right:clamp(16px,4vw,32px); bottom:clamp(16px,4vh,32px); z-index:7;
  display:inline-flex; flex-direction:row-reverse; align-items:center; gap:8px;
  padding:12px 22px; border-radius:999px;
  font:600 13px/1 "Cormorant Garamond", Georgia, serif; letter-spacing:.16em; text-transform:uppercase;
  color:#fff6f1; background:linear-gradient(135deg, #7a1638, #4c0c22);
  border:1px solid rgba(255,223,180,.35);
  box-shadow:0 10px 26px -10px rgba(60,4,20,.55);
  cursor:pointer; opacity:0; transform:translateY(8px);
  transition:opacity .5s ease, transform .5s var(--ease-out), box-shadow .3s ease;
}
.replay.is-shown{ opacity:1; transform:translateY(0); }
.replay:hover{ box-shadow:0 12px 30px -8px rgba(60,4,20,.7); transform:translateY(-2px); }
.replay:active{ transform:translateY(0) scale(.98); }
.replay svg{ opacity:.9; }

/* ============================================================
   THE LENS — grain + vignette over every act
   ============================================================ */
.grade{ position:absolute; inset:0; z-index:9; pointer-events:none; }
.grade__vignette{
  position:absolute; inset:0;
  background:radial-gradient(125% 95% at 50% 42%, transparent 54%, rgba(60,18,30,.14) 84%, rgba(40,12,22,.3) 100%);
  mix-blend-mode:multiply;
}
.grade__grain{
  position:absolute; inset:0;
  background:url('./textures/grain.png') repeat;
  background-size:300px; opacity:.05; mix-blend-mode:overlay;
}

@media (prefers-reduced-motion: reduce){
  /* intentionally kept animated as this is an interactive surprise film */
}
