@keyframes shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-4px); } 75% { transform: translateX(4px); } }
@keyframes pulse { 0%,100% { box-shadow: inset 0 0 0 3px var(--yellow); } 50% { box-shadow: inset 0 0 0 3px transparent; } }
@keyframes pop { 0% { transform: scale(.3); opacity: 0; } 70% { transform: scale(1.25); } 100% { transform: scale(1); opacity: 1; } }
@keyframes glow { 0%,100% { filter: drop-shadow(0 0 2px var(--yellow)); } 50% { filter: drop-shadow(0 0 10px var(--yellow)); } }

.tile.hint { animation: pulse 1s infinite; }
.tile.err { animation: shake .4s; }
.type-source .node.src { animation: glow 2s infinite; }
.stars span { display: inline-block; }
.stars .on { animation: pop .45s both; }
.stars span:nth-child(2) { animation-delay: .15s; }
.stars span:nth-child(3) { animation-delay: .3s; }
.board.win { animation: pop .5s; }

html.reduce-motion *, html.reduce-motion *::before, html.reduce-motion *::after {
  animation-duration: .001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: .001ms !important;
  transition-delay: 0ms !important;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; transition-delay: 0ms !important; }
}

@keyframes warnflash { 0%, 100% { box-shadow: inset 0 0 0 3px var(--danger); background: #3b1620; } 50% { box-shadow: inset 0 0 0 3px transparent; } }
.tile.warn { animation: warnflash .35s infinite; }
