/* ============================================================
   LOVE LETTER — cute interactive pixel-art valentine card
   Vanilla CSS. Animate only transform / opacity.
   ============================================================ */

:root{
  --cream:      #f7efe3;   /* page background          */
  --coral:      #d97b73;   /* window frame / borders   */
  --coral-dk:   #b9554d;   /* darker frame line        */
  --pink:       #f0b6c6;   /* title bar                */
  --pink-lt:    #f7d8e0;   /* heart-row bar            */
  --gingham:    #f3c6d2;   /* content base             */
  --gingham-2:  rgba(206,118,142,.28);
  --maroon:     #7a2230;   /* dark pixel text          */
  --red:        #e23b4e;   /* hearts                   */
  --red-dk:     #b22a3b;
  --paper:      #fdf4ef;   /* buttons / envelope body  */
  --sel:        #2f54d6;   /* "selection" highlight    */

  --heart-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 21.6 4.1 13.7a5.1 5.1 0 0 1 7.2-7.2l.7.7.7-.7a5.1 5.1 0 1 1 7.2 7.2z'/%3E%3C/svg%3E");

  --font-pix:  "Press Start 2P", monospace;
  --font-body: "Pixelify Sans", "Press Start 2P", monospace;
  --ease:      cubic-bezier(.34,1.56,.64,1);   /* gentle overshoot */
}

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

html,body{ height:100%; }

body{
  min-height:100svh;
  display:grid;
  place-items:center;
  padding:24px;
  font-family:var(--font-body);
  color:var(--maroon);
  background:var(--cream);
  -webkit-font-smoothing:antialiased;
  overflow:hidden;
}

/* ---------- reusable heart primitive (masked SVG) ---------- */
.heart{
  display:inline-block;
  width:14px; height:14px;
  background:var(--red);
  -webkit-mask:var(--heart-mask) center/contain no-repeat;
          mask:var(--heart-mask) center/contain no-repeat;
}
.heart--inline{ width:.9em; height:.9em; vertical-align:-.05em; }

/* ============================================================
   ATMOSPHERE — animated background, vignette, film grain
   ============================================================ */
.fx{ position:fixed; inset:0; z-index:0; pointer-events:none; overflow:hidden; }

.fx__aurora{ position:absolute; inset:-10%; }
.fx__aurora::before,
.fx__aurora::after{
  content:""; position:absolute; border-radius:50%;
  will-change:transform;
}
.fx__aurora::before{          /* warm pink bloom */
  width:65vmax; height:65vmax; left:-12%; top:-18%;
  background:radial-gradient(circle at 50% 50%, rgba(255,193,212,.85), rgba(255,193,212,0) 62%);
  animation:auroraA 19s ease-in-out infinite alternate;
}
.fx__aurora::after{           /* peach bloom */
  width:70vmax; height:70vmax; right:-15%; bottom:-20%;
  background:radial-gradient(circle at 50% 50%, rgba(255,225,196,.8), rgba(255,225,196,0) 62%);
  animation:auroraB 24s ease-in-out infinite alternate;
}
@keyframes auroraA{
  0%  { transform:translate(0,0) scale(1); }
  100%{ transform:translate(8vw,6vh) scale(1.18); }
}
@keyframes auroraB{
  0%  { transform:translate(0,0) scale(1.1); }
  100%{ transform:translate(-7vw,-5vh) scale(.92); }
}

.fx__vignette{
  position:absolute; inset:0;
  background:radial-gradient(125% 110% at 50% 38%, transparent 52%, rgba(120,40,50,.12) 100%);
}
.fx__grain{
  position:absolute; inset:0;
  background:url("./textures/grain.png") repeat;
  background-size:180px 180px;
  opacity:.4;
  mix-blend-mode:multiply;
  animation:grainShift 5s steps(4) infinite;
}
@keyframes grainShift{
  0%{ transform:translate(0,0); }   25%{ transform:translate(-2%,1%); }
  50%{ transform:translate(1%,-2%); } 75%{ transform:translate(-1%,-1%); }
  100%{ transform:translate(0,0); }
}

/* ============================================================
   SCENE
   ============================================================ */
.scene{
  position:relative;
  width:100%;
  max-width:520px;
  display:grid;
  place-items:center;
  z-index:2;
}

/* ---------- heart confetti (parallax depth layers) ---------- */
.confetti{
  position:fixed; inset:0;
  pointer-events:none;
  z-index:1;
}
.confetti__layer{ position:absolute; inset:0; will-change:transform; }
.confetti .heart{
  position:absolute;
  opacity:.0;
  animation:drift linear infinite;
}
@keyframes drift{
  0%   { opacity:0; transform:translateY(10px) rotate(0deg) scale(.9); }
  10%  { opacity:.9; }
  90%  { opacity:.9; }
  100% { opacity:0; transform:translateY(-26px) rotate(12deg) scale(1.05); }
}

/* both stages occupy the same cell so they cross-fade in place */
.stage,
.window{ grid-area:1 / 1; position:relative; z-index:1; }

/* ============================================================
   STATE 1 — CUPID AIM GAME
   ============================================================ */
:root{
  --wood:    #b5793f;
  --wood-dk: #8a5a2b;
}

.stage--aim{
  position:relative;
  width:100%;
  height:min(80svh, 600px);
  touch-action:none;           /* drag-to-aim must not scroll the page */
  /* black crosshair (thin white halo keeps it visible over hearts) */
  cursor:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke-linecap='round'%3E%3Cg stroke='%23fff' stroke-width='4'%3E%3Cpath d='M12 2v6M12 16v6M2 12h6M16 12h6'/%3E%3C/g%3E%3Cg stroke='%23000' stroke-width='2'%3E%3Cpath d='M12 2v6M12 16v6M2 12h6M16 12h6'/%3E%3C/g%3E%3C/g%3E%3Ccircle cx='12' cy='12' r='2.4' fill='%23fff'/%3E%3Ccircle cx='12' cy='12' r='1.4' fill='%23000'/%3E%3C/svg%3E") 12 12, crosshair;
  transition:opacity .4s ease, transform .45s var(--ease);
}
.stage--aim:focus-visible{
  outline:3px dashed var(--coral-dk);
  outline-offset:6px;
  border-radius:16px;
}
.stage--aim.is-gone{
  opacity:0;
  transform:scale(.6) translateY(-14px);
  pointer-events:none;
}

/* ---- the floating target (envelope) ---- */
.target{
  position:absolute;
  left:50%; top:6%;
  transform:translateX(-50%);
  display:grid; justify-items:center; gap:18px;
  pointer-events:none;
  z-index:2;
}
.target__label{
  font-size:1.35rem;
  letter-spacing:.02em;
  color:var(--maroon);
  display:flex; align-items:center; gap:.4em;
}

.envelope{
  position:relative;
  width:200px; height:142px;
  border:5px solid var(--coral);
  border-radius:8px;
  background:var(--paper);
  animation:bob 3s ease-in-out infinite;
  box-shadow:0 18px 0 -8px rgba(185,85,77,.18);
}
.target.is-pulse .envelope{ outline:3px dashed var(--red); outline-offset:8px; }
.target.is-hit .envelope{ animation:hitwobble .45s ease; }

/* the closed flap = a triangle pointing down */
.envelope__flap{
  position:absolute; left:50%; top:0;
  transform:translateX(-50%);
  width:0; height:0;
  border-left:95px solid transparent;
  border-right:95px solid transparent;
  border-top:68px solid var(--pink);
}
/* the two lower body fold lines */
.envelope::after{
  content:"";
  position:absolute; inset:0;
  background:
    linear-gradient(to top right, transparent calc(50% - 2px), var(--coral) calc(50% - 2px) calc(50% + 2px), transparent calc(50% + 2px)) bottom left / 50% 60% no-repeat,
    linear-gradient(to top left,  transparent calc(50% - 2px), var(--coral) calc(50% - 2px) calc(50% + 2px), transparent calc(50% + 2px)) bottom right / 50% 60% no-repeat;
  opacity:.6;
}
.envelope__seal{
  position:absolute; left:50%; top:56px;
  transform:translateX(-50%);
  width:32px; height:32px;
  z-index:2;
  filter:drop-shadow(0 2px 0 var(--red-dk));
}

@keyframes bob{
  0%,100%{ transform:translateY(0)   rotate(-1deg); }
  50%    { transform:translateY(-9px) rotate(1deg); }
}
@keyframes hitwobble{
  0%,100%{ transform:translate(0,0) rotate(0); }
  25%    { transform:translate(4px,-3px) rotate(5deg); }
  55%    { transform:translate(-4px,2px) rotate(-4deg); }
  80%    { transform:translate(2px,-1px) rotate(2deg); }
}

/* ---- the bow (centred, shooting up at the letter) ---- */
.archer{
  position:absolute;
  left:50%; bottom:12%;
  width:180px; height:180px;
  transform:translateX(-50%);
  pointer-events:none;
  z-index:3;
}
.bow{
  position:absolute;
  left:56px; top:11px;
  width:34px; height:158px;           /* shallow depth + long limbs → a clean bow arc, not an oval */
  border:9px solid var(--wood);
  border-radius:90% / 50%;            /* round belly, limbs sweep gently to the tips */
  border-right-color:transparent;     /* open side = string + arrow, faces the target */
  transform-origin:100% 50%;          /* pivot on the string = the nock */
  transform:rotate(-90deg);           /* static fallback; JS aims + flexes it per frame */
  filter:drop-shadow(0 3px 0 rgba(122,74,34,.22));
}
.bow::before{                         /* grip / riser on the belly (centre of the bow) */
  content:"";
  position:absolute; left:-11px; top:50%;
  width:14px; height:44px;
  transform:translateY(-50%);
  background:var(--wood-dk);
  border-radius:6px;
}
.bow::after{                          /* taut bow string across the open side */
  content:"";
  position:absolute; right:-2px; top:-5px; bottom:-5px;
  width:3px; background:var(--wood-dk); border-radius:2px;
}
.nock{                               /* fixed launch point = bow string centre */
  position:absolute;
  left:90px; top:90px;
  width:1px; height:1px;
}

/* ---- the arrow ---- */
.arrow{
  position:absolute; left:0; top:0;
  width:58px; height:16px;
  transform-origin:0 50%;       /* rotate / fly from the tail */
  background:linear-gradient(var(--wood-dk), var(--wood-dk)) left 50% / 42px 4px no-repeat;
  z-index:6;
  pointer-events:none;
  opacity:0;
  will-change:transform;
}
.arrow.is-on{ opacity:1; }   /* draw + flight are rAF-driven; no CSS transition to smear them */
.arrow::after{                  /* arrowhead — points right at angle 0 */
  content:"";
  position:absolute; left:40px; top:50%;
  transform:translateY(-50%);
  width:0; height:0;
  border-left:16px solid var(--red);
  border-top:8px solid transparent;
  border-bottom:8px solid transparent;
}
.arrow::before{                 /* fletching */
  content:"";
  position:absolute; left:-1px; top:50%;
  transform:translateY(-50%);
  width:0; height:0;
  border-right:13px solid var(--pink);
  border-top:8px solid transparent;
  border-bottom:8px solid transparent;
}

/* soft heart trail left behind the flying arrow */
.trail{
  position:absolute;
  width:11px; height:11px;
  z-index:5;
  pointer-events:none;
  animation:trailFade .5s ease-out forwards;
}
@keyframes trailFade{
  0%   { opacity:.7; transform:scale(1); }
  100% { opacity:0;  transform:scale(.3); }
}

/* ---- hint ---- */
.hint{
  position:absolute; left:0; right:0; bottom:1%;
  text-align:center;
  font-size:1rem;
  color:var(--maroon);
  opacity:.78;
  pointer-events:none;
  display:flex; align-items:center; justify-content:center; gap:.4em;
  animation:hintpulse 2.4s ease-in-out infinite;
}
@keyframes hintpulse{ 0%,100%{ opacity:.55; } 50%{ opacity:.85; } }

/* ============================================================
   STATE 2 — "LOVE" WINDOW
   ============================================================ */
.window{
  width:min(86vw, 360px);
  border:5px solid var(--coral);
  border-radius:12px;
  background:var(--pink-lt);
  box-shadow:0 22px 44px -20px rgba(122,34,48,.5);
  overflow:hidden;
  opacity:0;
  transform:scale(.78);
  visibility:hidden;
  transition:opacity .4s ease, transform .5s var(--ease), visibility 0s linear .5s;
}
.window.is-open{
  opacity:1;
  transform:scale(1);
  visibility:visible;
  transition:opacity .4s ease, transform .55s var(--ease);
}

/* cinematic entrance — the sections cascade in */
.window .titlebar,
.window .heartrow,
.window .content{
  opacity:0; transform:translateY(12px);
  transition:opacity .45s ease, transform .55s var(--ease);
}
.window.is-open .titlebar{ opacity:1; transform:none; transition-delay:.16s; }
.window.is-open .heartrow{ opacity:1; transform:none; transition-delay:.26s; }
.window.is-open .content { opacity:1; transform:none; transition-delay:.36s; }

/* heart-row hearts pop in one by one */
.window .heartrow > *{ opacity:0; transform:scale(.3); transition:opacity .3s ease, transform .4s var(--ease); }
.window.is-open .heartrow > *{ opacity:1; transform:none; }
.window.is-open .heartrow > *:nth-child(1){ transition-delay:.42s; }
.window.is-open .heartrow > *:nth-child(2){ transition-delay:.48s; }
.window.is-open .heartrow > *:nth-child(3){ transition-delay:.54s; }
.window.is-open .heartrow > *:nth-child(4){ transition-delay:.60s; }
.window.is-open .heartrow > *:nth-child(5){ transition-delay:.66s; }

/* celebratory glow once you say yes */
.window.is-celebrate{ animation:winGlow 1.7s ease-in-out infinite; }
@keyframes winGlow{
  0%,100%{ box-shadow:0 22px 44px -20px rgba(122,34,48,.5), 0 0 0 0 rgba(226,59,78,0); }
  50%    { box-shadow:0 22px 52px -18px rgba(122,34,48,.55), 0 0 42px 6px rgba(226,59,78,.4); }
}

/* ---- title bar ---- */
.titlebar{
  display:flex; align-items:center; justify-content:space-between;
  padding:9px 10px;
  background:var(--pink);
  border-bottom:4px solid var(--coral);
}
.titlebar__name{
  font-family:var(--font-pix);
  font-size:.72rem;
  letter-spacing:.12em;
  color:var(--maroon);
}
.titlebar__btns{ display:flex; gap:5px; }
.winbtn{
  width:20px; height:20px;
  display:grid; place-items:center;
  font-family:var(--font-pix);
  font-size:.5rem; line-height:1;
  color:var(--maroon);
  background:var(--paper);
  border:2px solid var(--coral);
  border-radius:3px;
  cursor:pointer;
  transition:transform .12s ease, background .12s ease;
}
.winbtn:hover{ transform:translateY(-1px); }
.winbtn--x:hover{ background:var(--red); color:#fff; }
.winbtn:focus-visible{ outline:2px solid var(--coral-dk); outline-offset:2px; }

/* ---- heart row ---- */
.heartrow{
  display:flex; align-items:center; justify-content:center; gap:10px;
  padding:8px 0;
  background:var(--pink-lt);
  border-bottom:4px solid var(--coral);
}
.heartrow .heart{ width:18px; height:18px; }
.hdot{ width:5px; height:5px; background:var(--coral); border-radius:1px; }

/* ---- content (gingham) ---- */
.content{
  position:relative;
  padding:22px 18px 24px;
  min-height:300px;
  display:grid;
  justify-items:center;
  align-content:start;
  gap:18px;
  background-color:var(--gingham);
  background-image:
    repeating-linear-gradient(0deg,  transparent 0 9px, var(--gingham-2) 9px 18px),
    repeating-linear-gradient(90deg, transparent 0 9px, var(--gingham-2) 9px 18px);
}

.title{
  font-weight:600;
  font-size:1.5rem;
  line-height:1.15;
  text-align:center;
  color:var(--maroon);
  text-shadow:0 2px 0 rgba(255,255,255,.5);
}

.cat{
  width:150px; height:auto;
  image-rendering:pixelated;
  image-rendering:crisp-edges;
  animation:catbob 2.4s ease-in-out infinite;
  filter:drop-shadow(0 6px 0 rgba(178,42,59,.16));
}
@keyframes catbob{
  0%,100%{ transform:translateY(0)    scaleY(1); }
  50%    { transform:translateY(-5px) scaleY(1.02); }
}

/* the cat does a little happy dance once you say yes */
.content.is-won .cat{
  transform-origin:50% 88%;
  animation:catdance .8s ease-in-out infinite;
}
@keyframes catdance{
  0%   { transform:rotate(-9deg) translateY(0)     scaleY(1); }
  25%  { transform:rotate(-9deg) translateY(-11px) scaleY(1.04); }
  50%  { transform:rotate(9deg)  translateY(0)     scaleY(1); }
  75%  { transform:rotate(9deg)  translateY(-11px) scaleY(1.04); }
  100% { transform:rotate(-9deg) translateY(0)     scaleY(1); }
}

/* the floating heart that pops above the happy cat */
.cat-heart{
  position:absolute;
  width:26px; height:26px;
  z-index:3;
  opacity:0;
  pointer-events:none;
}
.content.is-won .cat-heart{
  opacity:1;
  animation:floatHeart 1.8s ease-in-out infinite;
}
@keyframes floatHeart{
  0%,100%{ transform:translateY(0)   scale(1); }
  50%    { transform:translateY(-10px) scale(1.12); }
}

/* ---- buttons ---- */
.buttons{
  display:flex; gap:16px;
  align-items:center; justify-content:center;
  min-height:46px;
}
/* a display value on .buttons would otherwise defeat the [hidden] attribute */
.buttons[hidden]{ display:none; }
.btn{
  font-family:var(--font-pix);
  font-size:.74rem;
  letter-spacing:.06em;
  padding:11px 16px;
  color:var(--red-dk);
  background:var(--paper);
  border:3px solid var(--coral);
  border-radius:6px;
  cursor:pointer;
  box-shadow:0 4px 0 0 var(--coral);
  transition:transform .14s var(--ease), background .14s ease, color .14s ease, box-shadow .14s ease;
}
.btn:active{ transform:translateY(2px); box-shadow:0 2px 0 0 var(--coral); }
.btn:focus-visible{ outline:3px dashed var(--coral-dk); outline-offset:3px; }
.btn--yes{ transform-origin:center; position:relative; }
.btn--yes::before{               /* pulsing glow halo */
  content:""; position:absolute; inset:0; border-radius:6px;
  opacity:0; z-index:-1; transition:opacity .3s ease;
}
.btn--yes:hover{ background:var(--red); color:#fff; box-shadow:0 4px 0 0 var(--red-dk); }
.btn--yes:hover::before,
.btn--yes.is-tempting::before{ opacity:1; animation:yesGlow 1.2s ease-in-out infinite; }
@keyframes yesGlow{
  0%,100%{ box-shadow:0 0 16px 2px rgba(226,59,78,.4); }
  50%    { box-shadow:0 0 28px 7px rgba(226,59,78,.6); }
}
.btn--no{ position:relative; transition:left .18s var(--ease), top .18s var(--ease), transform .14s var(--ease); }

/* hearts raining down on win */
.rain{ position:fixed; inset:0; pointer-events:none; z-index:6; }
.rainheart{
  position:absolute; top:-6%;
  pointer-events:none;
  animation:rainfall linear forwards;
}
@keyframes rainfall{
  0%  { opacity:0; transform:translateY(0) translateX(0) rotate(0); }
  12% { opacity:1; }
  100%{ opacity:0; transform:translateY(112vh) translateX(var(--rx)) rotate(var(--rr)); }
}

/* ---- final text ---- */
.final{
  font-size:1.05rem;
  line-height:1.4;
  text-align:center;
  color:var(--maroon);
  max-width:30ch;
  opacity:0;
  transform:translateY(8px);
  transition:opacity .5s ease .15s, transform .5s var(--ease) .15s;
}
.final.is-show{ opacity:1; transform:none; }
.final strong{ font-weight:700; }
.final mark{
  background:var(--sel);
  color:#fff;
  padding:0 .15em;
  border-radius:2px;
}

/* ---- heart burst (spawned on YES) ---- */
.burst{
  position:absolute;
  width:18px; height:18px;
  z-index:5;
  pointer-events:none;
  animation:burst .9s ease-out forwards;
}
@keyframes burst{
  0%   { opacity:1; transform:translate(0,0) scale(.4); }
  100% { opacity:0; transform:translate(var(--bx), var(--by)) scale(1.1); }
}

/* ---- celebration confetti hearts (position/rotation driven per-frame by JS) ---- */
.confetti-heart{
  position:absolute;
  top:0; left:0;
  pointer-events:none;
  opacity:0;
  will-change:transform, opacity;
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width:480px){
  body{ padding:14px; }
  .envelope{ width:164px; height:116px; }
  .envelope__flap{ border-left-width:77px; border-right-width:77px; border-top-width:56px; }
  .envelope__seal{ top:46px; }
  .target__label{ font-size:1.15rem; }
  .title{ font-size:1.3rem; }
  .cat{ width:128px; }
  .content{ padding:18px 14px 20px; min-height:260px; gap:14px; }
  .hint{ font-size:.92rem; }
}

/* ============================================================
   REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  .envelope,
  .cat,
  .hint,
  .fx__aurora::before,
  .fx__aurora::after,
  .fx__grain,
  .window.is-celebrate,
  .btn--yes::before,
  .content.is-won .cat,
  .content.is-won .cat-heart{ animation:none; }
  .confetti .heart{ animation:none; opacity:.55; }
  .window, .stage--aim, .final, .btn{ transition-duration:.001s; }
  .burst, .trail, .rainheart, .confetti-heart{ display:none; }
  .brand{ transition:none; }
  .brand:hover, .brand:focus-visible{ transform:none; }
}
