/* styles-fx.css — Phase C/D. */

/* ======================================================================
   C4-C6 effects layer (ui/fx.js, ui/feedback.js).
   Every rule here decorates a real event — a gate landing, a column
   firing, one measurement — and every one is switched off under reduced
   motion (bottom of this block), where the end state shows at once.
   ====================================================================== */

/* The scroller is the containing block for everything parked in it
   (refusal marker, wire-pulse canvas, snap ring), so overlays scroll with
   the grid instead of staying pinned to the panel. */
.canvas-scroll { position: relative; }

/* ---- C5: the light travelling a wire as its gate fires ---------------- */
.fx-wires {
  position: absolute;
  z-index: 4;
  pointer-events: none;
}
.fx-wires[hidden] { display: none; }

/* ---- C6: a gate landing — squash, glow ring in its own colour, snap ---- */
.gbox.gate-settle,
.xor.gate-settle,
.dot.gate-settle,
.swapx.gate-settle {
  animation:
    fx-squash 320ms ease-out both,
    fx-glow 560ms ease-out backwards;
}
@keyframes fx-squash {
  0%   { transform: translateY(-7px) scale(.86, 1.14); opacity: .35; }  /* falling, stretched */
  30%  { transform: translateY(0) scale(1.14, .8); opacity: 1; }         /* impact: squash */
  55%  { transform: scale(.95, 1.07); }                                   /* rebound: stretch */
  78%  { transform: scale(1.02, .985); }                                  /* overshoot */
  100% { transform: none; opacity: 1; }
}
@keyframes fx-glow {
  0% {
    box-shadow:
      0 0 0 0 color-mix(in srgb, var(--fx-col, var(--accent)) 85%, transparent),
      0 0 0 0 color-mix(in srgb, var(--fx-col, var(--accent)) 0%, transparent);
  }
  30% {
    box-shadow:
      0 0 0 3px color-mix(in srgb, var(--fx-col, var(--accent)) 60%, transparent),
      0 0 18px 4px color-mix(in srgb, var(--fx-col, var(--accent)) 55%, transparent);
  }
  100% {
    box-shadow:
      0 0 0 11px color-mix(in srgb, var(--fx-col, var(--accent)) 0%, transparent),
      0 0 22px 0 color-mix(in srgb, var(--fx-col, var(--accent)) 0%, transparent);
  }
}
.fx-snap {
  position: absolute;
  z-index: 5;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 2px solid var(--fx-col, var(--accent));
  box-shadow: 0 0 10px color-mix(in srgb, var(--fx-col, var(--accent)) 60%, transparent);
  pointer-events: none;
  transform: translate(-50%, -50%) scale(.35);
  opacity: 0;
}

/* ---- C4: Measure once -------------------------------------------------- */
.runbar .fx-measure {
  margin-left: auto;
  /* Wide enough for both labels, so toggling never reflows the run bar. */
  min-width: 10.5em;
}
.fx-measure.on {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-soft);
}
/* The burst canvas is parked on #hist itself (which clears it on its next
   render), so #hist is its containing block. Absolute children of a grid
   are out of flow — the rows do not move. */
.hist { position: relative; }
.fx-burst {
  position: absolute;
  z-index: 3;
  pointer-events: none;
}
.hrow.fx-faded { opacity: .38; }
.hrow.fx-measured .lbl { color: var(--accent); }
.hrow.fx-measured .val { color: var(--ink); }
.fx-badge {
  position: absolute;
  right: 3px;
  top: 50%;
  transform: translateY(-50%);
  padding: 2px 6px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--on-accent) 40%, transparent);
  font: 600 10px/1 "IBM Plex Mono", ui-monospace, monospace;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  animation: fx-badge-in .28s ease-out .8s forwards;
}
@keyframes fx-badge-in {
  from { opacity: 0; transform: translateY(-50%) scale(.85); }
  to   { opacity: 1; transform: translateY(-50%) scale(1); }
}

/* ---- reduced motion: the end state, at once, with nothing moving ------- */
@media (prefers-reduced-motion: reduce) {
  .gbox.gate-settle, .xor.gate-settle, .dot.gate-settle, .swapx.gate-settle { animation: none; }
  .fx-snap, .fx-wires, .fx-burst { display: none; }
  .fx-badge { animation: none; opacity: 1; }
}
:root[data-reduced-motion="true"] .gbox.gate-settle,
:root[data-reduced-motion="true"] .xor.gate-settle,
:root[data-reduced-motion="true"] .dot.gate-settle,
:root[data-reduced-motion="true"] .swapx.gate-settle { animation: none; }
:root[data-reduced-motion="true"] .fx-snap,
:root[data-reduced-motion="true"] .fx-wires,
:root[data-reduced-motion="true"] .fx-burst { display: none; }
:root[data-reduced-motion="true"] .fx-badge { animation: none; opacity: 1; }
