/* Background effects */

.background-grid-layer {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.pixel-grid-line {
  position: absolute;
  display: block;
  box-sizing: border-box;
  pointer-events: none;
}

.pixel-grid-line--vertical {
  top: 0;
  bottom: 0;
  width: 0;
  border-left: 3px solid var(--grid-color);
}

.pixel-grid-line--horizontal {
  left: 0;
  right: 0;
  height: 0;
  border-top: 3px solid var(--grid-color);
}

/* Pointer-following black grid reveal. */
.grid-hover-layer {
  --hover-grid-x: 50vw;
  --hover-grid-y: 50vh;
  position: fixed;
  inset: 0;
  z-index: 0;
  contain: strict;
  isolation: isolate;
  pointer-events: none;
  opacity: 0;
  -webkit-mask-image: radial-gradient(
    circle 120px at var(--hover-grid-x) var(--hover-grid-y),
    #000 0 66%,
    rgba(0, 0, 0, 0.94) 76%,
    rgba(0, 0, 0, 0.58) 88%,
    transparent 100%
  );
  mask-image: radial-gradient(
    circle 120px at var(--hover-grid-x) var(--hover-grid-y),
    #000 0 66%,
    rgba(0, 0, 0, 0.94) 76%,
    rgba(0, 0, 0, 0.58) 88%,
    transparent 100%
  );
  transition: opacity 220ms ease;
  will-change: opacity, -webkit-mask-position, mask-position;
}

.grid-hover-layer.is-active {
  opacity: 1;
}

.grid-hover-layer .pixel-grid-line--vertical {
  border-left-color: #000;
}

.grid-hover-layer .pixel-grid-line--horizontal {
  border-top-color: #000;
}


.grid-hover-ripple {
  position: fixed;
  left: 0;
  top: 0;
  width: 8px;
  height: 8px;
  box-sizing: border-box;
  border: var(--ripple-width, 3px) solid rgba(126, 205, 255, var(--ripple-alpha, 0.92));
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0.08);
  opacity: 0;
  pointer-events: none;
  animation: grid-hover-droplet var(--ripple-duration, 1050ms) cubic-bezier(0.16, 0.68, 0.22, 1) forwards;
}

@keyframes grid-hover-droplet {
  0% { transform: translate(-50%, -50%) scale(0.08); opacity: 0; }
  4% { opacity: var(--ripple-alpha, 0.92); }
  65% { opacity: calc(var(--ripple-alpha, 0.92) * 0.48); }
  100% { transform: translate(-50%, -50%) scale(var(--ripple-scale, 14)); opacity: 0; }
}

/* Optional random filled cells. */
.grid-random-cells {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.grid-random-cell {
  position: absolute;
  width: 31px;
  height: 31px;
  background: #000;
  opacity: 0;
  transition-property: opacity;
  transition-timing-function: cubic-bezier(0.45, 0, 0.55, 1);
  will-change: opacity;
}

.grid-random-cell.is-visible {
  opacity: 0.8;
}

#page {
  position: relative;
  z-index: 1;
}

@media (prefers-reduced-motion: reduce) {
  .grid-random-cells {
    display: none;
  }

  .grid-hover-layer,
  .grid-hover-ripple {
    transition: none;
    animation: none;
  }
}

/* Achievement faces built from background-grid cells. */
.grid-face-layer {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.grid-face-cell {
  position: absolute;
  width: 31px;
  height: 31px;
  box-sizing: border-box;
  background: #000;
  opacity: 0;
  transform: scale(0.68);
  transform-origin: center;
  transition:
    opacity 750ms ease,
    transform 750ms cubic-bezier(0.2, 0.75, 0.25, 1);
  will-change: opacity, transform;
}

.grid-face-cell.is-visible {
  opacity: 0.8;
  transform: scale(1);
}

.grid-face-cell.is-leaving {
  opacity: 0;
  transform: scale(0.68);
}

/* Code-rendered heart frames switch instantly so their 200/600ms timing is exact. */
.grid-heart-layer {
  opacity: 1;
  transition: opacity 800ms ease;
}

.grid-heart-layer.is-leaving {
  opacity: 0;
}

.grid-heart-cell {
  opacity: 0.8;
  transform: none;
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  .grid-face-cell {
    transform: none;
    transition: opacity 150ms linear;
  }

  .grid-face-cell.is-visible {
    transform: none;
  }

  .grid-heart-cell {
    transition: none;
  }
}


/* Desktop background canvas*/

/* Decorative layers share the page's 1920px desktop coordinate space.*/
@media (hover: hover) and (pointer: fine) {
  /* Keep effect artwork in the same centred 1920px composition as the reference layout. */
  .grid-hover-layer,
  .grid-random-cells,
  .grid-face-layer {
    inset: 0 auto 0 var(--background-canvas-left, 0px);
  }

  /* 1920px contains 56 complete 34px cells plus a 16px remainder. */
  .grid-hover-layer {
    width: 1907px;
  }

  .grid-random-cells,
  .grid-face-layer {
    width: 1920px;
  }
}

/* Code-rendered 20/20 celebration pattern, timed to the achievement popup. */
.grid-completion-layer {
  opacity: 0;
  transition: opacity 800ms ease;
}

.grid-completion-layer.is-visible {
  opacity: 1;
}

.grid-completion-cell {
  transition: none;
}

@media (max-width: 700px) and (hover: none) and (pointer: coarse) {
  .grid-completion-layer {
    display: none;
  }
}

/* Keep the pointer-following grid visible against the dark theme. */
html[data-theme="dark"] .grid-hover-layer .pixel-grid-line--vertical {
  border-left-color: #fff;
}

html[data-theme="dark"] .grid-hover-layer .pixel-grid-line--horizontal {
  border-top-color: #fff;
}
