/* 082 — Dot Ripple Grid
   Grille de points rendue en canvas (un seul draw call par frame — voir
   README pour le choix canvas vs DOM). Une puce draggable (drag pointer,
   pas HTML5 drag) déclenche une onde au drop ; anim.js pilote tout. */

.dot-ripple {
  position: relative;
  width: min(320px, 100%);
  height: 230px;
  overflow: hidden;
  border-radius: 16px;
  background: var(--ml-surface, #151a24);
  border: 1px solid rgba(124, 140, 255, 0.14);
  touch-action: none;
}

.dot-ripple__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.dot-ripple__hint {
  position: absolute;
  top: 10px;
  left: 0;
  right: 0;
  margin: 0;
  text-align: center;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--ml-muted, #8b91a3);
  pointer-events: none;
}

/* Puce draggable — le JS pilote son transform (spring), ne pas y mettre
   de transition: transform. */
.dot-ripple__chip {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  padding: 7px 14px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  border-radius: 999px;
  color: var(--ml-bg, #0d1017);
  background: var(--dot-ripple-chip, var(--ml-accent-2, #2dd4bf));
  border: 0;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
  box-shadow: 0 4px 16px rgba(45, 212, 191, 0.3);
  will-change: transform;
}

.dot-ripple__chip:active {
  cursor: grabbing;
}

.dot-ripple--dragging .dot-ripple__chip {
  box-shadow: 0 10px 26px rgba(45, 212, 191, 0.4);
}

@media (prefers-reduced-motion: reduce) {
  /* Grille statique (anim.js ne lance ni bombement ni ondes) ; la puce
     reste posée. */
  .dot-ripple__chip {
    cursor: default;
  }
}
