/* ── Scroll reveal + shared keyframes ────────────────────────── */
.reveal { opacity: 0; transform: translateY(16px); transition: opacity .7s cubic-bezier(.22,1,.36,1), transform .7s cubic-bezier(.22,1,.36,1); }
.reveal.in { opacity: 1; transform: none; }

@keyframes spin { to { transform: rotate(360deg); } }
@keyframes breathe { 0%, 100% { transform: scale(1); opacity: .75; } 50% { transform: scale(1.06); opacity: 1; } }
@keyframes nodePulse { 0%, 100% { box-shadow: 0 6px 18px rgba(22,153,214,.12); } 50% { box-shadow: 0 8px 30px rgba(22,153,214,.34); } }
@keyframes nodePulseGreen { 0%, 100% { box-shadow: 0 6px 18px rgba(31,157,99,.12); } 50% { box-shadow: 0 8px 30px rgba(31,157,99,.32); } }
@keyframes coreGlow { 0%, 100% { box-shadow: 0 10px 30px rgba(12,18,28,.08); } 50% { box-shadow: 0 10px 30px rgba(12,18,28,.10), 0 0 30px rgba(22,153,214,.20); } }
@keyframes floaty { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-9px); } }
