/*
 * The board is sized entirely from --rows / --cols, which JS sets from
 * config.json. Nothing here measures the viewport in JavaScript, which is what
 * used to leave the grid empty when layout had not settled at load time.
 */

.board {
  --rows: 5;
  --cols: 5;

  display: grid;
  grid-template-columns: repeat(var(--cols), 1fr);
  grid-template-rows: repeat(var(--rows), 1fr);
  gap: clamp(3px, 0.9vmin, 12px);

  /* Fits the shorter axis either way, so a 10x10 board stays on screen. */
  width: min(94vw, calc(58vh * var(--cols) / var(--rows)));
  max-width: 860px;
  aspect-ratio: var(--cols) / var(--rows);

  padding: clamp(8px, 1.8vmin, 20px);
  border-radius: 24px;
  background: radial-gradient(
      circle at 30% 20%,
      rgba(255, 255, 255, 0.18),
      transparent 55%
    ),
    linear-gradient(var(--grass), var(--grass-dark));
  box-shadow: var(--shadow), inset 0 -6px 0 rgba(0, 0, 0, 0.15);
  cursor: var(--mallet);
}

.hole {
  position: relative;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 50%;
  overflow: hidden;
  cursor: inherit;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

/* The pit the mole climbs out of. */
.hole-pit {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(
    ellipse at 50% 35%,
    var(--dirt-dark) 0%,
    var(--dirt) 70%,
    #7d5836 100%
  );
  box-shadow: inset 0 6px 10px rgba(0, 0, 0, 0.55);
}

/* A rim above the mole, so it reads as rising out of the hole. */
.hole-rim {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  pointer-events: none;
  box-shadow: inset 0 0 0 clamp(2px, 0.6vmin, 5px) rgba(47, 95, 44, 0.65),
    inset 0 4px 8px rgba(0, 0, 0, 0.35);
  transition: transform 0.08s ease;
}

.hole:active .hole-rim {
  transform: scale(0.95);
}

.mole {
  position: absolute;
  left: 4%;
  right: 4%;
  bottom: -4%;
  display: block;
  transform: translateY(104%);
  transform-origin: 50% 100%;
  transition: transform 0.16s cubic-bezier(0.34, 1.4, 0.64, 1);
  will-change: transform;
}

.hole.is-up .mole {
  transform: translateY(0);
}

.mole-art {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
}

.mole-art--dazed {
  display: none;
}

/* Whacked: swap to the dazed face and squash before dropping. */
.hole.is-hit .mole {
  transform: translateY(16%) scaleY(0.82) scaleX(1.08);
  transition-duration: 0.09s;
}

.hole.is-hit .mole-art--awake {
  display: none;
}

.hole.is-hit .mole-art--dazed {
  display: block;
}

/* Missed swing: a puff of dirt. */
.dirt {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
  background: radial-gradient(
    circle at 50% 60%,
    rgba(196, 150, 100, 0.95) 0%,
    rgba(150, 110, 70, 0.6) 45%,
    transparent 70%
  );
}

.hole.is-miss .dirt {
  animation: puff 0.4s ease-out;
}

.hole.is-miss .hole-pit {
  animation: shake 0.3s ease-out;
}

@keyframes puff {
  0% {
    opacity: 0;
    transform: scale(0.5);
  }
  30% {
    opacity: 1;
    transform: scale(1.05);
  }
  100% {
    opacity: 0;
    transform: scale(1.35);
  }
}

@keyframes shake {
  0%,
  100% {
    transform: translateX(0);
  }
  25% {
    transform: translateX(-6%);
  }
  75% {
    transform: translateX(6%);
  }
}
