/* STATE — the parts of the state recipe that inline styles cannot express.

   ELEVEN STATES, NO TWELFTH: default · hover · pressed · focus-visible ·
   selected · disabled · loading · empty · error · read-only · dragging.

   ONE HOVER RECIPE for every interactive surface, present or future:
   an INK OVERLAY at 4% hover / 8% pressed, cross-fading in 120ms and out
   80ms. On fills darker than the mid-ink it inverts to paper at 10% / 20%.

   NOTHING SCALES AND NOTHING MOVES ON STATE. No lift, no shrink, no nudge,
   no shadow change, no padding shift. A hover that moves an element makes
   the page feel unstable and breaks every drag, reorder and touch target
   underneath it. STRUCTURE CARRIES HIERARCHY; COLOR CARRIES STATE.

   An element that already carries a fill (a selected chip, an ink button)
   takes no wash on top of the fill's own inversion. An element already
   sitting on a wash steps one further.

   DISABLED is 40% opacity, or faint ink where the control has its own fill,
   and it never changes the layout's shape. */

.io-stateable{ position:relative; }
.io-stateable::after{
  content:"";
  position:absolute; inset:0;
  border-radius:inherit;
  background:var(--ink);
  opacity:0;
  pointer-events:none;
  transition:opacity var(--dur-out) var(--ease-linear);
}
.io-stateable:hover::after{ opacity:.04; transition-duration:var(--dur-fast); }
.io-stateable:active::after{ opacity:.08; transition-duration:var(--dur-fast); }
.io-stateable[disabled]::after,
.io-stateable[aria-disabled="true"]::after,
.io-stateable[data-selected="true"]::after{ opacity:0; }

/* on an ink or otherwise dark fill, the overlay inverts to paper */
.io-stateable-inverse::after{ background:var(--paper); }
.io-stateable-inverse:hover::after{ opacity:.10; }
.io-stateable-inverse:active::after{ opacity:.20; }

/* already on a wash — step one further so the change is still readable */
.io-stateable-on-wash:hover::after{ opacity:.08; }
.io-stateable-on-wash:active::after{ opacity:.12; }

.io-disabled,
[disabled].io-stateable,
[aria-disabled="true"].io-stateable{ opacity:.4; pointer-events:none; }
