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

:root {
  --bg-centre: #fff6f9;
  --bg-edge: #ffd9e6;
  --heart-dark: #c9184a;
}

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

html,
body {
  height: 100%;
}

body {
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: manipulation;
  background: radial-gradient(circle at 50% 45%, var(--bg-centre) 0%, var(--bg-edge) 100%);
  font-family: "Fredoka", ui-rounded, "Arial Rounded MT Bold", system-ui, sans-serif;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* ---------- main scene ---------- */

.stage {
  position: fixed;
  inset: 0;
  margin: auto;
  width: min(94vw, 94vh);
  height: min(94vw, 94vh);
  width: min(94vw, 94dvh);
  height: min(94vw, 94dvh);
  container-type: inline-size;
}

.stage svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.heart-pop,
.heart-beat,
.bloom,
.sway {
  transform-box: fill-box;
  transform-origin: 50% 50%;
}

.leaf {
  transform-box: fill-box;
  transform-origin: 50% 100%;
}

.sway {
  animation: sway 3s ease-in-out infinite alternate;
}

.message {
  position: absolute;
  left: 0;
  right: 0;
  top: 47%;
  transform: translateY(-50%);
  text-align: center;
  font-size: 12.5cqi;
  font-weight: 600;
  line-height: 1;
  color: #fff;
  text-shadow:
    0 0.05em 0 var(--heart-dark),
    0 0.12em 0.3em rgba(201, 24, 74, 0.35);
  pointer-events: none;
}

.word,
.ch {
  display: inline-block;
}

.alive .heart-beat,
.alive .word {
  animation: beat 1.6s ease-in-out infinite;
}

/* ---------- background ---------- */

.sky,
.bursts {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.sky {
  animation: fade-in 1.5s ease-out both;
}

.floaty {
  position: absolute;
  bottom: -40px;
  left: var(--x);
  width: var(--s);
  height: var(--s);
  opacity: 0;
  animation: rise var(--dur) ease-in-out var(--delay) infinite;
}

.sparkle {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: var(--s);
  height: var(--s);
  animation: twinkle var(--dur) ease-in-out var(--delay) infinite;
}

.pop {
  position: absolute;
}

.fallback {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 18vmin;
  font-weight: 600;
  color: #ff4d6d;
}

/* ---------- keyframes ---------- */

@keyframes beat {
  0%, 45%, 100% { transform: scale(1); }
  12% { transform: scale(1.06); }
  22% { transform: scale(0.99); }
  32% { transform: scale(1.04); }
}

@keyframes sway {
  from { transform: rotate(-10deg); }
  to { transform: rotate(10deg); }
}

@keyframes rise {
  0% { transform: translate(0, 0) rotate(var(--r)); opacity: 0; }
  10% { opacity: var(--o); }
  50% { transform: translate(var(--drift), -55vh) rotate(calc(var(--r) * -1)); }
  85% { opacity: var(--o); }
  100% { transform: translate(0, -115vh) rotate(var(--r)); opacity: 0; }
}

@keyframes twinkle {
  0%, 100% { transform: scale(0.3) rotate(0deg); opacity: 0.2; }
  50% { transform: scale(1) rotate(45deg); opacity: 1; }
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
  }

  .floaty {
    display: none;
  }
}
