/* ============================================================================
 * animations.css — Every @keyframes used on the site, in one place.
 *
 * These used to live in <style> blocks nested inside React components, which
 * meant React re-inserted the same stylesheet into the DOM on each render.
 * Declaring them once here means the browser parses them once, ever.
 *
 * Naming convention:
 *   *In      — one-shot entrance, runs once with `both` fill
 *   float*   — infinite idle drift, decorative only
 *   draw*    — SVG stroke-dashoffset reveals
 * ==========================================================================*/

/* ─── Entrances (one-shot) ───────────────────────────────────────────────── */

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes badgeIn {
  from { opacity: 0; transform: translateY(-12px) scale(0.95); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes graphicIn {
  from { opacity: 0; transform: scale(0.92); }
  to   { opacity: 1; transform: scale(1); }
}

/* Hero graphic cards slide in from their respective edges. */
@keyframes cardSlideR {
  from { opacity: 0; transform: translateX(40px) rotate(2deg); }
  to   { opacity: 1; transform: translateX(0) rotate(0); }
}

@keyframes cardSlideL {
  from { opacity: 0; transform: translateX(-40px) rotate(-2deg); }
  to   { opacity: 1; transform: translateX(0) rotate(0); }
}

/* Specialty pills on the About cards. */
@keyframes tagIn {
  from { opacity: 0; transform: translateY(8px) scale(0.92); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Contact form success state. */
@keyframes sentIn {
  from { opacity: 0; transform: scale(0.95); }
  to   { opacity: 1; transform: scale(1); }
}

@keyframes checkPop {
  from { transform: scale(0) rotate(-45deg); }
  to   { transform: scale(1) rotate(0); }
}

/* ─── Idle loops (decorative) ────────────────────────────────────────────── */

@keyframes pulse {
  0%, 100% { transform: scale(1);   opacity: 1; }
  50%      { transform: scale(1.4); opacity: 0.7; }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

@keyframes spinSlow {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

@keyframes blink {
  0%, 50%   { opacity: 1; }
  51%, 100% { opacity: 0; }
}

@keyframes scrollLine {
  0%, 100% { transform: scaleY(1);   opacity: 0.4; }
  50%      { transform: scaleY(0.3); opacity: 0.1; }
}

/* Four float variants so neighbouring elements drift out of sync. */
@keyframes floatA {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}

@keyframes floatB {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(8px); }
}

@keyframes floatC {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}

@keyframes floatD {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(10px); }
}

@keyframes glyphFloat {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(8px, -14px); }
}

/* Background colour orbs behind the About and Contact sections. */
@keyframes orbA {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(60px, 40px) scale(1.15); }
}

@keyframes orbB {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(-50px, -40px) scale(1.1); }
}

/* ─── SVG stroke reveals ─────────────────────────────────────────────────── */

@keyframes drawLine {
  from { stroke-dashoffset: 400; }
  to   { stroke-dashoffset: 0; }
}

@keyframes dashFlow {
  from { stroke-dashoffset: 100; }
  to   { stroke-dashoffset: 0; }
}
