:root {
  --night: #000;
  --ink: #f4e9df;
  --ember: 232, 149, 90;
  --gold: 255, 211, 106;
  --sapphire: 40, 100, 245;
  --love: #ff5a72;
}

html, body {
  margin: 0;
  background: var(--night);
  color: var(--ink);
}

body {
  font-family: "Cormorant Garamond", Georgia, serif;
  -webkit-tap-highlight-color: transparent;
  overflow-x: hidden;
  /* a finger dragging across the page draws instead of scrolling; pinching still zooms */
  touch-action: pinch-zoom;
  /* a magic wand for a cursor, the point at its star; links keep their hand */
  cursor: url("wand.png") 7 7, auto;
  cursor: -webkit-image-set(url("wand.png") 1x, url("wand@2x.png") 2x) 7 7, auto;
  cursor: image-set(url("wand.png") 1x, url("wand@2x.png") 2x) 7 7, auto;
}

/* falling, twinkling dust, drawn by script.js */
.dust {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

main {
  position: relative;
  z-index: 1;
  min-height: 100vh;
  min-height: 100svh;
  box-sizing: border-box;
  padding: 32px 16px 40px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
}

/* the drawing's lines, straight on the night */
.fir {
  position: relative;
  margin: 0;
  width: min(80vw, 50svh, 420px);
  aspect-ratio: 1;
}

.fir img {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  -webkit-user-drag: none;
}

/* a glint over the star on top of the tree */
.star {
  position: absolute;
  left: 55.4%;
  top: 6.4%;
  width: 26%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  pointer-events: none;
  mix-blend-mode: screen;
  background:
    radial-gradient(circle, rgba(255, 250, 230, .9) 0 3%, rgba(var(--gold), .45) 9%, transparent 34%),
    linear-gradient(transparent 49.2%, rgba(255, 240, 200, .75) 50%, transparent 50.8%),
    linear-gradient(90deg, transparent 49.2%, rgba(255, 240, 200, .75) 50%, transparent 50.8%);
  -webkit-mask-image: radial-gradient(circle closest-side, #000 20%, transparent 100%);
  mask-image: radial-gradient(circle closest-side, #000 20%, transparent 100%);
  animation: twinkle 3.4s ease-in-out infinite;
}

/* stars in the drawing: the little fire's eyes and her earring, placed by script.js */
.sky {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.sky i {
  position: absolute;
  width: 2.6%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  mix-blend-mode: screen;
  background: radial-gradient(circle closest-side, #fffaf0 0 18%, rgba(255, 240, 215, .5) 32%, rgba(var(--gold), .14) 60%, transparent);
  animation: shine 4s ease-in-out infinite;
}

.sky .m2 { width: 3.6%; }

/* the little fire's eyes are little fires of their own, burning red:
   a red flame with a hot core, each flickering to its own beat */
.sky .flame {
  width: 2.5%;
  transform: translate(-50%, -62%);
  border-radius: 0;
  background: none;
  filter: drop-shadow(0 0 1.5px #ff3b1f) drop-shadow(0 0 5px rgba(255, 40, 20, .65));
  animation: none;
}

.sky .flame::before,
.sky .flame::after {
  content: "";
  position: absolute;
  border-radius: 50% 0 50% 50%;
  transform: rotate(-45deg);
  animation: burn .55s ease-in-out infinite;
}

.sky .flame::before {
  inset: 20%;
  background: radial-gradient(circle at 35% 65%, #ffb347 0 18%, #ff5a1f 45%, #d4142a 80%);
}

.sky .flame::after {
  inset: 42% 34% 18% 32%;
  background: radial-gradient(circle at 35% 65%, #fffbe0 0 25%, #ffd34a 70%, #ff9a2a);
  animation-duration: .38s;
}

.sky .flame + .flame::before { animation-duration: .47s; animation-delay: -.2s; }
.sky .flame + .flame::after { animation-duration: .33s; animation-delay: -.1s; }

/* the brightest, her earring, gets the tree star's cross of light, smaller */
.sky .m1 {
  width: 9%;
  border-radius: 0;
  background:
    radial-gradient(circle closest-side, #fff 0 9%, rgba(255, 240, 215, .55) 17%, rgba(var(--gold), .16) 34%, transparent 60%),
    linear-gradient(transparent 49%, rgba(255, 240, 200, .6) 50%, transparent 51%),
    linear-gradient(90deg, transparent 49%, rgba(255, 240, 200, .6) 50%, transparent 51%);
  -webkit-mask-image: radial-gradient(circle closest-side, #000 25%, transparent);
  mask-image: radial-gradient(circle closest-side, #000 25%, transparent);
}

/* while the drawing draws itself, script.js paints it on a canvas over the hidden picture;
   before it draws itself again, it fades away */
.fir.drawing img { opacity: 0; }

.fir { transition: opacity 1.2s ease; }
.fir.fading { opacity: 0; }

.fir canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* and each star pops on as the drawing reaches it, after going out at once */
.star,
.sky i {
  transition: scale .7s cubic-bezier(.2, 1.6, .4, 1);
}

.fir .unlit {
  scale: 0;
  transition: none;
}

/* her earring is a sapphire */
.sky .sapphire {
  background:
    radial-gradient(circle closest-side, #e6eeff 0 7%, rgba(var(--sapphire), .9) 14%, rgba(var(--sapphire), .3) 30%, transparent 60%),
    linear-gradient(transparent 49%, rgba(var(--sapphire), .75) 50%, transparent 51%),
    linear-gradient(90deg, transparent 49%, rgba(var(--sapphire), .75) 50%, transparent 51%);
}

.bio {
  margin: 18px 0 0;
  font-size: clamp(24px, 6vw, 32px);
  word-spacing: .35em;
}

.bio > * { display: inline-block; }

/* the pawn is a challenge on chess.com; a gold halo lifts its black off the night */
.pawn {
  text-decoration: none;
  filter: drop-shadow(0 0 3px rgba(var(--gold), .6)) drop-shadow(0 0 10px rgba(var(--ember), .4));
  transition: filter .3s;
}

.pawn:hover,
.pawn:focus-visible {
  filter: drop-shadow(0 0 5px rgba(var(--gold), .95)) drop-shadow(0 0 18px rgba(var(--ember), .6));
  outline: none;
}

.links {
  margin-top: 30px;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
}

.link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border: 1px solid rgba(var(--ember), .28);
  border-radius: 999px;
  color: rgba(244, 233, 223, .72);
  font-size: 20px;
  letter-spacing: .03em;
  text-decoration: none;
  transition: color .3s, border-color .3s, box-shadow .3s;
}

.link:hover,
.link:focus-visible {
  color: #ffe6c2;
  border-color: rgba(var(--gold), .6);
  box-shadow: 0 0 20px rgba(var(--ember), .3);
  outline: none;
}

/* while the drawing draws itself, the buttons below stay hidden; once it's
   done they come in after it one by one: the tree, the heart, the pawn, and
   last the Instagram button, drawn in from left to right.
   Before it draws itself again, they fade away with it */
.away .bio,
.away .links {
  opacity: 0;
  pointer-events: none;
}

.leaving .bio,
.leaving .links {
  transition: opacity 1.2s ease;
}

.back .bio > * { animation: pop .6s cubic-bezier(.2, 1.6, .4, 1) both; }
.back .bio > :nth-child(2) { animation-delay: .35s; }
.back .bio > :nth-child(3) { animation-delay: .7s; }

.back .link {
  -webkit-mask: linear-gradient(90deg, #000 40%, transparent 60%) 100% 0 / 250% 100% no-repeat;
  mask: linear-gradient(90deg, #000 40%, transparent 60%) 100% 0 / 250% 100% no-repeat;
  animation: unveil 1.2s ease-out 1.05s both;
}

/* full screen, in the top corner */
.full {
  position: fixed;
  top: 14px;
  right: 14px;
  z-index: 3;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(var(--ember), .28);
  border-radius: 50%;
  background: rgba(0, 0, 0, .4);
  color: rgba(244, 233, 223, .72);
  cursor: pointer;
  transition: color .3s, border-color .3s, box-shadow .3s;
}

.full[hidden] { display: none; }

.full:hover,
.full:focus-visible {
  color: #ffe6c2;
  border-color: rgba(var(--gold), .6);
  box-shadow: 0 0 20px rgba(var(--ember), .3);
  outline: none;
}

.full .leave,
.is-full .full .enter { display: none; }
.is-full .full .leave { display: block; }

/* starlight you draw by pressing and dragging, painted by script.js over everything */
.light {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  pointer-events: none;
}

/* a heart and a handful of sparkles wherever you tap */
.heart,
.spark {
  position: fixed;
  z-index: 2;
  pointer-events: none;
}

.heart {
  font-size: 30px;
  line-height: 1;
  color: var(--love);
  text-shadow: 0 0 10px rgba(255, 90, 114, .8), 0 0 28px rgba(255, 90, 114, .45);
  animation: rise 2.2s cubic-bezier(.2, .7, .3, 1) forwards;
}

.spark {
  width: 4px;
  height: 4px;
  margin: -2px 0 0 -2px;
  border-radius: 50%;
  background: rgb(var(--gold));
  box-shadow: 0 0 6px 1px rgba(var(--gold), .9);
  animation: burst 1.1s ease-out forwards;
}

@keyframes twinkle {
  0%, 100% { opacity: .55; transform: translate(-50%, -50%) scale(.8) rotate(0deg); }
  50% { opacity: 1; transform: translate(-50%, -50%) scale(1.1) rotate(8deg); }
}

@keyframes shine {
  0%, 100% { opacity: .45; transform: translate(-50%, -50%) scale(.8); }
  50% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

@keyframes burn {
  0%, 100% { transform: rotate(-45deg) scale(1); opacity: .95; }
  30% { transform: rotate(-40deg) scale(1.12); opacity: 1; }
  65% { transform: rotate(-49deg) scale(.9); opacity: .82; }
}

/* hidden, and so not clickable, until each one's turn comes */
@keyframes pop {
  from { transform: scale(0); visibility: hidden; }
  to { transform: scale(1); visibility: visible; }
}

@keyframes unveil {
  from { -webkit-mask-position: 100% 0; mask-position: 100% 0; visibility: hidden; }
  to { -webkit-mask-position: 0 0; mask-position: 0 0; visibility: visible; }
}

@keyframes rise {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.3); }
  15% { opacity: 1; transform: translate(-50%, -60%) scale(1.1); }
  100% { opacity: 0; transform: translate(calc(-50% + var(--drift)), calc(-50% - 160px)) scale(1.35); }
}

@keyframes burst {
  0% { opacity: 1; transform: translate(0, 0) scale(1); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.2); }
}

@media (prefers-reduced-motion: reduce) {
  .star, .sky i, .sky .flame::before, .sky .flame::after { animation: none; }
}
