/* ky-inkperf.css — the whole of the ink-suspend is this one rule.
   Pairs with ky/ky-inkperf.js, which only adds/removes html.ky-inkmove.
   See that file's header for the measurements that justify it. */

/* The ink treatments, by the selectors that actually declare them:
     index.html  html.honeykit:not(.nokitfx) .ky-heroname { filter: url(#goo-tight) url(#roughen) }
     plus the heading rules that carry url(#goo) / url(#roughen).
   `filter:none` is scoped to the moving state ONLY — at rest every one of
   these keeps the treatment exactly as authored. */
/* NARROWED 2026-08-13. The subject list used to be
       :is(.ky-heroname, .ky-ink, .ky-goo, h1, h2, h3, h4, [class*="heroname"])
   and the bare tag arms were doing active harm.

   1. THEY CAUGHT THINGS THAT HAVE NO url() FILTER. On singularity the only two
      elements in that whole set with a non-none filter were the two lensed
      display headings, whose filter is a pair of native CSS drop-shadows — not
      ink at all. This rule stripped them on every scroll burst, and because
      the Next export ships `.section-heading { transition-property: all;
      transition-duration: .5s }` the strip was not a swap but a HALF-SECOND
      CROSS-FADE, out and back, on a 1373x121px background-clip:text heading.
      That is the owner's "every time I scroll, even a little bit, it
      re-renders, and it looks very unprofessional." (Note that the comment
      below this rule asserts there is no transition on filter. That assertion
      was wrong — the export supplies one via `all`. Left in place with this
      correction attached rather than quietly rewritten.)

   2. THE REAL INK NO LONGER NEEDS THEM. ky/ky-ink.js strips the <animate>
      nodes out of #goo / #goo-tight / #roughen, so those filters are static
      and cacheable, and it marks the elements that carry ink with .ky-ink /
      .ky-ink-goo. Measured across nine scroll positions over the full
      document: the four inky h2s return exactly one distinct paint state each,
      i.e. they never invalidate, so gating them buys nothing and costs a
      visible flicker.

   3. WHAT DOES STILL INVALIDATE is the wordmark, and only the wordmark:
      ky-cursor.js splits .ky-heroname into ten .kycl spans and writes a
      transform on each from a spring sim, and ky-motion.js gusts that spring
      on SCROLL. A transform on a child of a filtered element cannot composite
      independently — it re-rasters the filtered subtree. That is the one case
      this module was built for, and it is the one case left in the list. */
html.ky-inkmove :is(
  .ky-heroname,
  [class*="heroname"]
){
  /* !important because the shipped declarations are themselves specific
     (html.honeykit:not(.nokitfx) .ky-heroname) and several are re-applied
     inline by the theme/flood modules. This is the one place the page is
     allowed to shout — it is a performance gate, not a style opinion, and it
     is live for at most ~140ms after the last scroll event. */
  filter:none !important;
}

/* No transition on the filter property. A filter transition would animate the
   goo weld pulling apart and snapping back on every scroll burst, which is
   both far more distracting than the swap and exactly the per-frame filter
   evaluation this file exists to avoid. The swap is instant and happens only
   while the type is in motion, where it is not resolvable. */

/* Belt and braces: if ky-inkperf.js never loads, nothing here applies and the
   page is byte-for-byte what it was. The class is the only trigger. */
