/* ═══ liquid-text.css — OWNER: B2 (v3 liquid-glass pass).
   Liquid distortion on REAL HTML headings via SVG feTurbulence + feDisplacementMap
   (filter def: #wa-liquid, B2:LIQUID slot). DESIGN_LAW #10, #12, #15.

   Gate chain (ALL required before any filter paints):
     html.wa-anim       — global animation gate (inline head bootstrap)
     html.wa-liquid-ok  — set by js/liquid-text.js AFTER capability checks
                          (never set under prefers-reduced-motion, on WebKit/Safari,
                          or when SVG filters are unsupported)
     .wa-liquid-morph / .wa-liquid-idle — per-heading class WINDOW toggled by JS

   Perf note (DESIGN_LAW #15): at rest a .wa-liquid heading carries NO filter at
   all — not even url(#wa-liquid) at scale 0 — so idle paint cost is truly nil
   and filter invalidations during a morph touch only the heading(s) inside the
   class window, never all twelve consumers. Text is pixel-crisp at rest. ═══ */

/* Rest state: plain text. Selectable, indexable, screen-reader identical. */
.wa-liquid{filter:none;}

/* Entry morph window (≤600ms, once per heading) — JS drives #wa-liquid scale 8→0 */
html.wa-anim.wa-liquid-ok .wa-liquid.wa-liquid-morph{
  filter:url(#wa-liquid);
  will-change:filter;            /* ONLY inside the morph window — class removed at rest */
}

/* Hero-h1-only gentle idle ripple (scale 0–2, ≥8s period, hero on-screen only) */
html.wa-anim.wa-liquid-ok .wa-liquid.wa-liquid-idle{
  filter:url(#wa-liquid);
}

/* Belt-and-suspenders: even if a stale wa-liquid-ok class survives a
   reduced-motion toggle, no filter ever paints under reduced motion. */
@media (prefers-reduced-motion: reduce){
  .wa-liquid,
  .wa-liquid.wa-liquid-morph,
  .wa-liquid.wa-liquid-idle{filter:none!important;will-change:auto!important;}
}
