/*!
 * KNO Animation v4.2.0 — https://kraineuolek.com/
 * Copyright 2023-2026 Oleksandr Khrashchevskyi
 * Licensed — https://kraineuolek.com/
 *
 * v4 architecture: every animation is expressed as a set of CSS custom
 * properties (translate / rotate / scale / skew / blur / clip). A single
 * composed `transform` chain consumes them, so animations never overwrite
 * each other and can be freely combined.
 */

/* Registering the channels makes them interpolable. That is what lets the
   browser drive --kno-p off a scroll timeline (section 17) and lets keyframe
   effects animate a single channel without taking over the whole transform. */
@property --kno-p   { syntax: '<number>'; inherits: false; initial-value: 0 }
@property --kno-x   { syntax: '<length-percentage>'; inherits: false; initial-value: 0px }
@property --kno-y   { syntax: '<length-percentage>'; inherits: false; initial-value: 0px }
@property --kno-z   { syntax: '<length>'; inherits: false; initial-value: 0px }
@property --kno-rx  { syntax: '<angle>'; inherits: false; initial-value: 0deg }
@property --kno-ry  { syntax: '<angle>'; inherits: false; initial-value: 0deg }
@property --kno-rz  { syntax: '<angle>'; inherits: false; initial-value: 0deg }
@property --kno-skx { syntax: '<angle>'; inherits: false; initial-value: 0deg }
@property --kno-sky { syntax: '<angle>'; inherits: false; initial-value: 0deg }
@property --kno-sx  { syntax: '<number>'; inherits: false; initial-value: 1 }
@property --kno-sy  { syntax: '<number>'; inherits: false; initial-value: 1 }
@property --kno-op  { syntax: '<number>'; inherits: false; initial-value: 1 }
@property --kno-blur{ syntax: '<length>'; inherits: false; initial-value: 0px }

/* ==========================================================================
   1. TOKENS
   ========================================================================== */
:root {
  /* geometry */
  --kno-distance: 60px;
  --kno-distance-sm: 24px;
  --kno-distance-lg: 120px;
  --kno-scale-in: 0.6;
  --kno-scale-out: 1.4;
  --kno-blur-amount: 12px;
  --kno-skew-amount: 16deg;
  --kno-rotate-amount: 360deg;
  --kno-stretch-amount: 1.4;
  --kno-perspective: 1200px;

  /* timing */
  --kno-duration-default: 700ms;
  --kno-delay-default: 0ms;
  --kno-easing-default: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ==========================================================================
   2. BASE — the composed transform
   ========================================================================== */
[kno-position],
[kno],
[kno-tilt],
[kno-magnetic] {
  /* per-element channels (identity values) */
  --kno-x: 0px;
  --kno-y: 0px;
  --kno-z: 0px;
  --kno-rx: 0deg;
  --kno-ry: 0deg;
  --kno-rz: 0deg;
  --kno-skx: 0deg;
  --kno-sky: 0deg;
  --kno-sx: 1;
  --kno-sy: 1;
  --kno-op: 1;
  --kno-origin: center center;

  /* resolved timing (JS writes these; CSS can override) */
  --kno-duration: var(--kno-duration-default);
  --kno-delay: var(--kno-delay-default);
  --kno-easing: var(--kno-easing-default);

  opacity: var(--kno-op);
  transform-origin: var(--kno-origin);
  transform:
    perspective(var(--kno-perspective))
    translate3d(var(--kno-x), var(--kno-y), var(--kno-z))
    rotateX(var(--kno-rx))
    rotateY(var(--kno-ry))
    rotateZ(var(--kno-rz))
    skew(var(--kno-skx), var(--kno-sky))
    scale3d(var(--kno-sx), var(--kno-sy), 1);

  transition-property: transform, opacity;
  transition-duration: var(--kno-duration);
  transition-delay: var(--kno-delay);
  transition-timing-function: var(--kno-easing);
  backface-visibility: hidden;
}

/* `will-change` is applied by JS only while an element is near/at the
   viewport — a permanent will-change on hundreds of nodes costs memory. */
.kno-active {
  will-change: transform, opacity;
}

/* Momentary, applied only while a programmatic replay snaps an element back
   to its start pose. Without it the reset would itself be animated — and it
   would honour transition-delay, so an element with a delay never actually
   returns before the replay starts. */
.kno-snap,
.kno-snap * {
  transition: none !important;
  animation: none !important;
}

/* Resting (in-view) state: every channel returns to identity.
   Because it targets the same specificity level but comes later, and JS adds
   the class, this always wins over the per-animation start states below. */
[kno-position].kno-in,
[kno].kno-in {
  --kno-x: 0px;
  --kno-y: 0px;
  --kno-z: 0px;
  --kno-rx: 0deg;
  --kno-ry: 0deg;
  --kno-rz: 0deg;
  --kno-skx: 0deg;
  --kno-sky: 0deg;
  --kno-sx: 1;
  --kno-sy: 1;
  --kno-op: 1;
  --kno-blur: 0px;
  --kno-clip: inset(0 0 0 0);
}

/* v3 compatibility: `.kno-animation` was the old resting-state class. */
[kno-position].kno-animation {
  --kno-x: 0px;
  --kno-y: 0px;
  --kno-z: 0px;
  --kno-rx: 0deg;
  --kno-ry: 0deg;
  --kno-rz: 0deg;
  --kno-skx: 0deg;
  --kno-sky: 0deg;
  --kno-sx: 1;
  --kno-sy: 1;
  --kno-op: 1;
  --kno-blur: 0px;
  --kno-clip: inset(0 0 0 0);
}

/* ==========================================================================
   3. DISTANCE SCALE  (kno-distance="sm|md|lg" or any CSS length)
   ========================================================================== */
[kno-distance="sm"] { --kno-distance: var(--kno-distance-sm); }
[kno-distance="lg"] { --kno-distance: var(--kno-distance-lg); }
[kno-distance="xl"] { --kno-distance: 200px; }

/* ==========================================================================
   4. FADE
   ========================================================================== */
[kno-position~="fade"]            { --kno-op: 0; }
[kno-position~="fade-up"]         { --kno-op: 0; --kno-y: var(--kno-distance); }
[kno-position~="fade-down"]       { --kno-op: 0; --kno-y: calc(-1 * var(--kno-distance)); }
[kno-position~="fade-left"]       { --kno-op: 0; --kno-x: var(--kno-distance); }
[kno-position~="fade-right"]      { --kno-op: 0; --kno-x: calc(-1 * var(--kno-distance)); }

/* diagonals — both v3 and v4 naming supported */
[kno-position~="fade-up-left"],
[kno-position~="fade-left-up"]    { --kno-op: 0; --kno-x: var(--kno-distance); --kno-y: var(--kno-distance); }
[kno-position~="fade-down-left"],
[kno-position~="fade-left-down"]  { --kno-op: 0; --kno-x: var(--kno-distance); --kno-y: calc(-1 * var(--kno-distance)); }
[kno-position~="fade-up-right"],
[kno-position~="fade-right-up"]   { --kno-op: 0; --kno-x: calc(-1 * var(--kno-distance)); --kno-y: var(--kno-distance); }
[kno-position~="fade-down-right"],
[kno-position~="fade-right-down"] { --kno-op: 0; --kno-x: calc(-1 * var(--kno-distance)); --kno-y: calc(-1 * var(--kno-distance)); }

/* ==========================================================================
   5. ZOOM
   ========================================================================== */
[kno-position*="zoom"]           { --kno-op: 0; }
[kno-position~="zoom-in"]         { --kno-sx: var(--kno-scale-in);  --kno-sy: var(--kno-scale-in); }
[kno-position~="zoom-out"]        { --kno-sx: var(--kno-scale-out); --kno-sy: var(--kno-scale-out); }
[kno-position~="zoom-in-up"]      { --kno-sx: var(--kno-scale-in);  --kno-sy: var(--kno-scale-in);  --kno-y: var(--kno-distance); }
[kno-position~="zoom-in-down"]    { --kno-sx: var(--kno-scale-in);  --kno-sy: var(--kno-scale-in);  --kno-y: calc(-1 * var(--kno-distance)); }
[kno-position~="zoom-in-left"]    { --kno-sx: var(--kno-scale-in);  --kno-sy: var(--kno-scale-in);  --kno-x: var(--kno-distance); }
[kno-position~="zoom-in-right"]   { --kno-sx: var(--kno-scale-in);  --kno-sy: var(--kno-scale-in);  --kno-x: calc(-1 * var(--kno-distance)); }
[kno-position~="zoom-out-up"]     { --kno-sx: var(--kno-scale-out); --kno-sy: var(--kno-scale-out); --kno-y: var(--kno-distance); }
[kno-position~="zoom-out-down"]   { --kno-sx: var(--kno-scale-out); --kno-sy: var(--kno-scale-out); --kno-y: calc(-1 * var(--kno-distance)); }
[kno-position~="zoom-out-left"]   { --kno-sx: var(--kno-scale-out); --kno-sy: var(--kno-scale-out); --kno-x: var(--kno-distance); }
[kno-position~="zoom-out-right"]  { --kno-sx: var(--kno-scale-out); --kno-sy: var(--kno-scale-out); --kno-x: calc(-1 * var(--kno-distance)); }

/* ==========================================================================
   6. SLIDE — movement only, element stays fully opaque
   ========================================================================== */
[kno-position~="slide-up"]        { --kno-y: 100%; }
[kno-position~="slide-down"]      { --kno-y: -100%; }
[kno-position~="slide-left"]      { --kno-x: 100%; }
[kno-position~="slide-right"]     { --kno-x: -100%; }

/* ==========================================================================
   7. FLIP (3D)
   ========================================================================== */
[kno-position*="flip"]           { --kno-op: 0; }
[kno-position~="flip-left"]       { --kno-ry: -90deg; }
[kno-position~="flip-right"]      { --kno-ry: 90deg; }
[kno-position~="flip-up"]         { --kno-rx: -90deg; }
[kno-position~="flip-down"]       { --kno-rx: 90deg; }
[kno-position~="flip-diagonal"]   { --kno-rx: 60deg; --kno-ry: 60deg; }

/* ==========================================================================
   8. SPIN / ROTATE
   ========================================================================== */
[kno-position*="spin"]           { --kno-op: 0; }
[kno-position~="spin-right"]      { --kno-rz: var(--kno-rotate-amount); }
[kno-position~="spin-left"]       { --kno-rz: calc(-1 * var(--kno-rotate-amount)); }
[kno-position~="spin-up"]         { --kno-rx: -180deg; }
[kno-position~="spin-down"]       { --kno-rx: 180deg; }
[kno-position~="spin-diagonal"]   { --kno-rz: 720deg; --kno-sx: 0.5; --kno-sy: 0.5; }
[kno-position~="spin-zoom"]       { --kno-rz: 180deg; --kno-sx: 0.2; --kno-sy: 0.2; }

[kno-position~="rotate-left"]     { --kno-op: 0; --kno-rz: -45deg; }
[kno-position~="rotate-right"]    { --kno-op: 0; --kno-rz: 45deg; }

/* ==========================================================================
   9. SKEW
   ========================================================================== */
[kno-position*="skew"]           { --kno-op: 0; }
[kno-position~="skew-left"]       { --kno-skx: calc(-1 * var(--kno-skew-amount)); }
[kno-position~="skew-right"]      { --kno-skx: var(--kno-skew-amount); }
[kno-position~="skew-up"]         { --kno-sky: calc(-1 * var(--kno-skew-amount)); }
[kno-position~="skew-down"]       { --kno-sky: var(--kno-skew-amount); }
[kno-position~="skew-diagonal"]   { --kno-skx: var(--kno-skew-amount); --kno-sky: var(--kno-skew-amount); }

/* ==========================================================================
   10. STRETCH / SHRINK
   ========================================================================== */
[kno-position*="stretch"],
[kno-position*="shrink"]         { --kno-op: 0; }
[kno-position~="stretch-x"]       { --kno-sx: var(--kno-stretch-amount); }
[kno-position~="stretch-y"]       { --kno-sy: var(--kno-stretch-amount); }
[kno-position~="shrink-x"]        { --kno-sx: 0.4; }
[kno-position~="shrink-y"]        { --kno-sy: 0.4; }

/* ==========================================================================
   11. ROLL / HINGE / SWING
   ========================================================================== */
[kno-position*="roll"],
[kno-position*="hinge"],
[kno-position*="swing"]          { --kno-op: 0; }
[kno-position~="roll-in-left"]    { --kno-x: -100%; --kno-rz: -120deg; }
[kno-position~="roll-in-right"]   { --kno-x: 100%;  --kno-rz: 120deg; }
[kno-position~="roll-out-left"]   { --kno-x: -100%; --kno-rz: 120deg; }
[kno-position~="roll-out-right"]  { --kno-x: 100%;  --kno-rz: -120deg; }

[kno-position~="hinge-top"]       { --kno-origin: top left;     --kno-rz: -90deg; }
[kno-position~="hinge-bottom"]    { --kno-origin: bottom right; --kno-rz: 90deg; }
[kno-position~="hinge-left"]      { --kno-origin: top left;     --kno-ry: -90deg; }
[kno-position~="hinge-right"]     { --kno-origin: top right;    --kno-ry: 90deg; }

[kno-position~="swing-top"]       { --kno-origin: top center;    --kno-rz: 25deg; --kno-y: calc(-1 * var(--kno-distance)); }
[kno-position~="swing-bottom"]    { --kno-origin: bottom center; --kno-rz: -25deg; --kno-y: var(--kno-distance); }

/* ==========================================================================
   12. BLUR — filter channel (scoped so no other element pays the cost)
   ========================================================================== */
[kno-position*="blur"] {
  --kno-blur: var(--kno-blur-amount);
  --kno-op: 0;
  filter: blur(var(--kno-blur));
  transition-property: transform, opacity, filter, clip-path;
}
[kno-position~="blur-up"]         { --kno-y: var(--kno-distance); }
[kno-position~="blur-down"]       { --kno-y: calc(-1 * var(--kno-distance)); }
[kno-position~="blur-left"]       { --kno-x: var(--kno-distance); }
[kno-position~="blur-right"]      { --kno-x: calc(-1 * var(--kno-distance)); }
[kno-position~="blur-zoom"]       { --kno-sx: 1.15; --kno-sy: 1.15; }

/* ==========================================================================
   13. REVEAL / CURTAIN — clip-path channel
   ========================================================================== */
[kno-position*="reveal"],
[kno-position*="curtain"],
[kno-position*="wipe"] {
  clip-path: var(--kno-clip);
  transition-property: transform, opacity, filter, clip-path;
}
[kno-position~="reveal-up"]       { --kno-clip: inset(100% 0 0 0); }
[kno-position~="reveal-down"]     { --kno-clip: inset(0 0 100% 0); }
[kno-position~="reveal-left"]     { --kno-clip: inset(0 0 0 100%); }
[kno-position~="reveal-right"]    { --kno-clip: inset(0 100% 0 0); }
[kno-position~="reveal-center-x"] { --kno-clip: inset(0 50% 0 50%); }
[kno-position~="reveal-center-y"] { --kno-clip: inset(50% 0 50% 0); }
[kno-position~="curtain"]         { --kno-clip: inset(0 0 100% 0); --kno-y: 30px; }
[kno-position~="wipe-circle"]     { --kno-clip: circle(0% at 50% 50%); }
[kno-position~="wipe-circle"].kno-in,
[kno-position~="wipe-circle"].kno-animation { --kno-clip: circle(75% at 50% 50%); }

/* combined reveal + slide (very common in editorial layouts) */
[kno-position~="reveal-slide-up"] { --kno-clip: inset(100% 0 0 0); --kno-y: 40px; }

/* ==========================================================================
   14. DROP / POP / RISE
   ========================================================================== */
[kno-position~="drop"]            { --kno-op: 0; --kno-y: calc(-2 * var(--kno-distance)); --kno-sy: 1.2; }
[kno-position~="rise"]            { --kno-op: 0; --kno-y: calc(2 * var(--kno-distance)); --kno-sy: 1.2; }
[kno-position~="pop"]             { --kno-op: 0; --kno-sx: 0.3; --kno-sy: 0.3; }
[kno-position~="pop-up"]          { --kno-op: 0; --kno-sx: 0.3; --kno-sy: 0.3; --kno-y: var(--kno-distance); }

/* ==========================================================================
   14b. 3D DOOR / FOLD / TILT — channel-based, so they still combine
   ========================================================================== */
[kno-position*="door"],
[kno-position*="fold"],
[kno-position*="unfold"],
[kno-position*="tilt"]           { --kno-op: 0; }

[kno-position~="door-left"]      { --kno-origin: left center;   --kno-ry: 90deg; }
[kno-position~="door-right"]     { --kno-origin: right center;  --kno-ry: -90deg; }
[kno-position~="fold-up"]        { --kno-origin: bottom center; --kno-rx: -85deg; }
[kno-position~="fold-down"]      { --kno-origin: top center;    --kno-rx: 85deg; }
[kno-position~="unfold-x"]       { --kno-sx: 0; }
[kno-position~="unfold-y"]       { --kno-sy: 0; }
[kno-position~="tilt-left"]      { --kno-ry: -40deg; --kno-x: var(--kno-distance); }
[kno-position~="tilt-right"]     { --kno-ry: 40deg;  --kno-x: calc(-1 * var(--kno-distance)); }
[kno-position~="tilt-up"]        { --kno-rx: 40deg;  --kno-y: var(--kno-distance); }
[kno-position~="tilt-down"]      { --kno-rx: -40deg; --kno-y: calc(-1 * var(--kno-distance)); }

/* ==========================================================================
   14c. SOFT MASK REVEALS
   A gradient mask three times the size of the element slides across it, so the
   edge feathers instead of cutting — the difference between a wipe and a
   dissolve.
   ========================================================================== */
[kno-position*="mask-"] {
  --kno-mask-img: linear-gradient(to top, #000 0%, #000 33%, transparent 66%);
  --kno-mask-size: 100% 300%;
  --kno-mask-pos: 0% 0%;
  -webkit-mask-image: var(--kno-mask-img);
          mask-image: var(--kno-mask-img);
  -webkit-mask-size: var(--kno-mask-size);
          mask-size: var(--kno-mask-size);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: var(--kno-mask-pos);
          mask-position: var(--kno-mask-pos);
  transition-property: transform, opacity,
                       -webkit-mask-position, mask-position,
                       -webkit-mask-size, mask-size;
}
[kno-position~="mask-up"]        { --kno-mask-img: linear-gradient(to top, #000 0%, #000 33%, transparent 66%);   --kno-mask-pos: 0% 0%; }
[kno-position~="mask-down"]      { --kno-mask-img: linear-gradient(to bottom, #000 0%, #000 33%, transparent 66%);--kno-mask-pos: 0% 100%; }
[kno-position~="mask-left"]      { --kno-mask-img: linear-gradient(to left, #000 0%, #000 33%, transparent 66%);  --kno-mask-size: 300% 100%; --kno-mask-pos: 0% 0%; }
[kno-position~="mask-right"]     { --kno-mask-img: linear-gradient(to right, #000 0%, #000 33%, transparent 66%); --kno-mask-size: 300% 100%; --kno-mask-pos: 100% 0%; }
[kno-position~="mask-up"].kno-in,   [kno-position~="mask-up"].kno-animation   { --kno-mask-pos: 0% 100%; }
[kno-position~="mask-down"].kno-in, [kno-position~="mask-down"].kno-animation { --kno-mask-pos: 0% 0%; }
[kno-position~="mask-left"].kno-in, [kno-position~="mask-left"].kno-animation { --kno-mask-pos: 100% 0%; }
[kno-position~="mask-right"].kno-in,[kno-position~="mask-right"].kno-animation{ --kno-mask-pos: 0% 0%; }

[kno-position~="mask-circle"] {
  --kno-mask-img: radial-gradient(circle at center, #000 45%, transparent 72%);
  --kno-mask-size: 0% 0%;
  --kno-mask-pos: center;
}
[kno-position~="mask-circle"].kno-in,
[kno-position~="mask-circle"].kno-animation { --kno-mask-size: 280% 280%; }

/* ==========================================================================
   14d. KEYFRAME EFFECTS
   Multi-step entrances a transition cannot express. They animate the discrete
   `translate` / `rotate` / `scale` properties rather than `transform`, so the
   composed transform chain above stays intact underneath.
   ========================================================================== */
:is(
  [kno-position~="bounce-in"],   [kno-position~="bounce-in-up"],
  [kno-position~="bounce-in-down"], [kno-position~="bounce-in-left"],
  [kno-position~="bounce-in-right"], [kno-position~="rubber-band"],
  [kno-position~="jello"],       [kno-position~="jack-in-box"],
  [kno-position~="light-speed-left"], [kno-position~="light-speed-right"],
  [kno-position~="flip-in-x"],   [kno-position~="flip-in-y"],
  [kno-position~="swing-in"],    [kno-position~="wobble-in"],
  [kno-position~="glitch-in"],   [kno-position~="track-in"],
  [kno-position~="track-out"],   [kno-position~="focus-in"],
  [kno-position~="vibrate-in"],  [kno-position~="expand-in"]
) { --kno-op: 0; }

:is(
  [kno-position~="bounce-in"],   [kno-position~="bounce-in-up"],
  [kno-position~="bounce-in-down"], [kno-position~="bounce-in-left"],
  [kno-position~="bounce-in-right"], [kno-position~="rubber-band"],
  [kno-position~="jello"],       [kno-position~="jack-in-box"],
  [kno-position~="light-speed-left"], [kno-position~="light-speed-right"],
  [kno-position~="flip-in-x"],   [kno-position~="flip-in-y"],
  [kno-position~="swing-in"],    [kno-position~="wobble-in"],
  [kno-position~="glitch-in"],   [kno-position~="track-in"],
  [kno-position~="track-out"],   [kno-position~="focus-in"],
  [kno-position~="vibrate-in"],  [kno-position~="expand-in"]
):is(.kno-in, .kno-animation) {
  animation-duration: var(--kno-duration);
  animation-delay: var(--kno-delay);
  animation-timing-function: var(--kno-easing);
  animation-fill-mode: both;
}

[kno-position~="bounce-in"]:is(.kno-in,.kno-animation)        { animation-name: kno-fx-bounce-in; }
[kno-position~="bounce-in-up"]:is(.kno-in,.kno-animation)     { animation-name: kno-fx-bounce-up; }
[kno-position~="bounce-in-down"]:is(.kno-in,.kno-animation)   { animation-name: kno-fx-bounce-down; }
[kno-position~="bounce-in-left"]:is(.kno-in,.kno-animation)   { animation-name: kno-fx-bounce-left; }
[kno-position~="bounce-in-right"]:is(.kno-in,.kno-animation)  { animation-name: kno-fx-bounce-right; }
[kno-position~="rubber-band"]:is(.kno-in,.kno-animation)      { animation-name: kno-fx-rubber; }
[kno-position~="jello"]:is(.kno-in,.kno-animation)            { animation-name: kno-fx-jello; }
[kno-position~="jack-in-box"]:is(.kno-in,.kno-animation)      { animation-name: kno-fx-jack; --kno-origin: center bottom; }
[kno-position~="light-speed-left"]:is(.kno-in,.kno-animation) { animation-name: kno-fx-light-left; }
[kno-position~="light-speed-right"]:is(.kno-in,.kno-animation){ animation-name: kno-fx-light-right; }
[kno-position~="flip-in-x"]:is(.kno-in,.kno-animation)        { animation-name: kno-fx-flip-x; }
[kno-position~="flip-in-y"]:is(.kno-in,.kno-animation)        { animation-name: kno-fx-flip-y; }
[kno-position~="swing-in"]:is(.kno-in,.kno-animation)         { animation-name: kno-fx-swing-in; --kno-origin: top center; }
[kno-position~="wobble-in"]:is(.kno-in,.kno-animation)        { animation-name: kno-fx-wobble-in; }
[kno-position~="glitch-in"]:is(.kno-in,.kno-animation)        { animation-name: kno-fx-glitch; }
[kno-position~="track-in"]:is(.kno-in,.kno-animation)         { animation-name: kno-fx-track-in; }
[kno-position~="track-out"]:is(.kno-in,.kno-animation)        { animation-name: kno-fx-track-out; }
[kno-position~="focus-in"]:is(.kno-in,.kno-animation)         { animation-name: kno-fx-focus-in; }
[kno-position~="vibrate-in"]:is(.kno-in,.kno-animation)       { animation-name: kno-fx-vibrate; }
[kno-position~="expand-in"]:is(.kno-in,.kno-animation)        { animation-name: kno-fx-expand; }

@keyframes kno-fx-bounce-in {
  0%   { opacity: 0; scale: .3 }
  25%  { opacity: 1; scale: 1.13 }
  45%  { scale: .89 }
  65%  { scale: 1.05 }
  82%  { scale: .97 }
  100% { opacity: 1; scale: 1 }
}
@keyframes kno-fx-bounce-up {
  0%   { opacity: 0; translate: 0 var(--kno-distance) }
  55%  { opacity: 1; translate: 0 -16px }
  73%  { translate: 0 9px }
  88%  { translate: 0 -4px }
  100% { opacity: 1; translate: 0 0 }
}
@keyframes kno-fx-bounce-down {
  0%   { opacity: 0; translate: 0 calc(-1 * var(--kno-distance)) }
  55%  { opacity: 1; translate: 0 16px }
  73%  { translate: 0 -9px }
  88%  { translate: 0 4px }
  100% { opacity: 1; translate: 0 0 }
}
@keyframes kno-fx-bounce-left {
  0%   { opacity: 0; translate: var(--kno-distance) 0 }
  55%  { opacity: 1; translate: -16px 0 }
  73%  { translate: 9px 0 }
  88%  { translate: -4px 0 }
  100% { opacity: 1; translate: 0 0 }
}
@keyframes kno-fx-bounce-right {
  0%   { opacity: 0; translate: calc(-1 * var(--kno-distance)) 0 }
  55%  { opacity: 1; translate: 16px 0 }
  73%  { translate: -9px 0 }
  88%  { translate: 4px 0 }
  100% { opacity: 1; translate: 0 0 }
}
@keyframes kno-fx-rubber {
  0%   { opacity: 0; scale: 1 1 }
  30%  { opacity: 1; scale: 1.25 .75 }
  40%  { scale: .75 1.25 }
  50%  { scale: 1.15 .85 }
  65%  { scale: .95 1.05 }
  75%  { scale: 1.05 .95 }
  100% { opacity: 1; scale: 1 1 }
}
@keyframes kno-fx-jello {
  0%   { opacity: 0; --kno-skx: 0deg }
  22%  { opacity: 1; --kno-skx: -12.5deg }
  33%  { --kno-skx: 6.25deg }
  44%  { --kno-skx: -3.1deg }
  55%  { --kno-skx: 1.5deg }
  66%  { --kno-skx: -.8deg }
  100% { opacity: 1; --kno-skx: 0deg }
}
@keyframes kno-fx-jack {
  0%   { opacity: 0; rotate: 30deg; scale: .1 }
  50%  { rotate: -10deg }
  70%  { rotate: 3deg }
  100% { opacity: 1; rotate: 0deg; scale: 1 }
}
@keyframes kno-fx-light-left {
  0%   { opacity: 0; translate: 100% 0; --kno-skx: -30deg }
  60%  { opacity: 1; translate: -20px 0; --kno-skx: 20deg }
  80%  { --kno-skx: -5deg }
  100% { opacity: 1; translate: 0 0; --kno-skx: 0deg }
}
@keyframes kno-fx-light-right {
  0%   { opacity: 0; translate: -100% 0; --kno-skx: 30deg }
  60%  { opacity: 1; translate: 20px 0; --kno-skx: -20deg }
  80%  { --kno-skx: 5deg }
  100% { opacity: 1; translate: 0 0; --kno-skx: 0deg }
}
@keyframes kno-fx-flip-x {
  0%   { opacity: 0; --kno-rx: 90deg }
  40%  { --kno-rx: -20deg }
  60%  { opacity: 1; --kno-rx: 10deg }
  80%  { --kno-rx: -5deg }
  100% { opacity: 1; --kno-rx: 0deg }
}
@keyframes kno-fx-flip-y {
  0%   { opacity: 0; --kno-ry: 90deg }
  40%  { --kno-ry: -20deg }
  60%  { opacity: 1; --kno-ry: 10deg }
  80%  { --kno-ry: -5deg }
  100% { opacity: 1; --kno-ry: 0deg }
}
@keyframes kno-fx-swing-in {
  0%   { opacity: 0; rotate: -70deg }
  40%  { opacity: 1; rotate: 22deg }
  60%  { rotate: -12deg }
  80%  { rotate: 5deg }
  100% { opacity: 1; rotate: 0deg }
}
@keyframes kno-fx-wobble-in {
  0%   { opacity: 0; translate: -60% 0; rotate: -6deg }
  30%  { opacity: 1; translate: 12% 0; rotate: 4deg }
  50%  { translate: -8% 0; rotate: -3deg }
  70%  { translate: 4% 0; rotate: 2deg }
  100% { opacity: 1; translate: 0 0; rotate: 0deg }
}
@keyframes kno-fx-glitch {
  0%   { opacity: 0; translate: 0 0; filter: none }
  10%  { opacity: 1; translate: -8px 0; filter: hue-rotate(90deg) }
  20%  { translate: 7px 0; filter: none }
  30%  { translate: -5px 2px; filter: hue-rotate(-90deg) }
  40%  { translate: 4px -2px; filter: none }
  55%  { translate: -2px 0 }
  70%  { translate: 2px 0; filter: contrast(1.6) }
  100% { opacity: 1; translate: 0 0; filter: none }
}
@keyframes kno-fx-track-in {
  0%   { opacity: 0; letter-spacing: .6em }
  40%  { opacity: .7 }
  100% { opacity: 1; letter-spacing: normal }
}
@keyframes kno-fx-track-out {
  0%   { opacity: 0; letter-spacing: -.14em }
  100% { opacity: 1; letter-spacing: normal }
}
@keyframes kno-fx-focus-in {
  0%   { opacity: 0; filter: blur(14px); letter-spacing: .3em }
  100% { opacity: 1; filter: blur(0); letter-spacing: normal }
}
@keyframes kno-fx-vibrate {
  0%   { opacity: 0; translate: 0 0 }
  10%  { opacity: 1; translate: -3px 3px }
  20%  { translate: 3px -3px }
  30%  { translate: -3px -3px }
  40%  { translate: 3px 3px }
  50%  { translate: -2px 2px }
  60%  { translate: 2px -2px }
  75%  { translate: -1px 1px }
  100% { opacity: 1; translate: 0 0 }
}
@keyframes kno-fx-expand {
  0%   { opacity: 0; scale: .2 1; --kno-blur: 8px }
  45%  { opacity: 1; scale: 1.04 1; --kno-blur: 0px }
  100% { opacity: 1; scale: 1 1 }
}

/* ==========================================================================
   15. TEXT SPLIT — applied to generated .kno-char / .kno-word / .kno-line
   ========================================================================== */
.kno-split .kno-word,
.kno-split .kno-char,
.kno-split .kno-line-inner {
  display: inline-block;
  white-space: pre-wrap;
}
.kno-split .kno-word .kno-char { white-space: pre; }
.kno-split .kno-line {
  display: block;
  overflow: hidden;
}

/* ==========================================================================
   16. LOOPING KEYFRAME ANIMATIONS  (kno-loop="...")
   Start only once the element is in view.
   ========================================================================== */
[kno-loop] {
  --kno-loop-duration: 2s;
  --kno-loop-delay: 0s;
  --kno-loop-count: infinite;
}
[kno-loop].kno-in,
[kno-loop].kno-animation {
  animation-duration: var(--kno-loop-duration);
  animation-delay: var(--kno-loop-delay);
  animation-iteration-count: var(--kno-loop-count);
  animation-timing-function: ease-in-out;
  animation-fill-mode: both;
}
[kno-loop="pulse"].kno-in,     [kno-loop="pulse"].kno-animation     { animation-name: kno-pulse; }
[kno-loop="float"].kno-in,     [kno-loop="float"].kno-animation     { animation-name: kno-float; }
[kno-loop="shake"].kno-in,     [kno-loop="shake"].kno-animation     { animation-name: kno-shake; }
[kno-loop="bounce"].kno-in,    [kno-loop="bounce"].kno-animation    { animation-name: kno-bounce; }
[kno-loop="wobble"].kno-in,    [kno-loop="wobble"].kno-animation    { animation-name: kno-wobble; }
[kno-loop="heartbeat"].kno-in, [kno-loop="heartbeat"].kno-animation { animation-name: kno-heartbeat; }
[kno-loop="spin"].kno-in,      [kno-loop="spin"].kno-animation      { animation-name: kno-spin; animation-timing-function: linear; }
[kno-loop="flicker"].kno-in,   [kno-loop="flicker"].kno-animation   { animation-name: kno-flicker; }
[kno-loop="glow"].kno-in,      [kno-loop="glow"].kno-animation      { animation-name: kno-glow; }
[kno-loop="tada"].kno-in,      [kno-loop="tada"].kno-animation      { animation-name: kno-tada; }
[kno-loop="breathe"].kno-in,   [kno-loop="breathe"].kno-animation   { animation-name: kno-breathe; }
[kno-loop="swing"].kno-in,     [kno-loop="swing"].kno-animation     { animation-name: kno-swing-loop; --kno-origin: top center; }
[kno-loop="jitter"].kno-in,    [kno-loop="jitter"].kno-animation    { animation-name: kno-jitter; animation-timing-function: steps(2, end); }
[kno-loop="orbit"].kno-in,     [kno-loop="orbit"].kno-animation     { animation-name: kno-orbit; animation-timing-function: linear; }
[kno-loop="rotate-y"].kno-in,  [kno-loop="rotate-y"].kno-animation  { animation-name: kno-rotate-y; animation-timing-function: linear; }
[kno-loop="blink"].kno-in,     [kno-loop="blink"].kno-animation     { animation-name: kno-blink-loop; animation-timing-function: steps(1, end); }

/* `shine` needs a highlight layer of its own */
[kno-loop="shine"] { position: relative; overflow: hidden; isolation: isolate; }
[kno-loop="shine"]::after {
  content: '';
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.42) 50%, transparent 62%);
  translate: -110% 0;
}
[kno-loop="shine"]:is(.kno-in, .kno-animation)::after {
  animation: kno-shine var(--kno-loop-duration) linear var(--kno-loop-delay) var(--kno-loop-count);
}

@keyframes kno-pulse     { 0%,100% { scale: 1 } 50% { scale: 1.06 } }
@keyframes kno-float     { 0%,100% { translate: 0 0 } 50% { translate: 0 -12px } }
@keyframes kno-shake     { 0%,100% { translate: 0 0 } 20% { translate: -8px 0 } 40% { translate: 8px 0 } 60% { translate: -5px 0 } 80% { translate: 5px 0 } }
@keyframes kno-bounce    { 0%,20%,53%,100% { translate: 0 0 } 40%,43% { translate: 0 -22px } 70% { translate: 0 -11px } 90% { translate: 0 -4px } }
@keyframes kno-wobble    { 0%,100% { rotate: 0deg } 15% { rotate: -6deg } 30% { rotate: 5deg } 45% { rotate: -4deg } 60% { rotate: 3deg } 75% { rotate: -2deg } }
@keyframes kno-heartbeat { 0%,28%,70%,100% { scale: 1 } 14%,42% { scale: 1.12 } }
@keyframes kno-spin      { to { rotate: 360deg } }
@keyframes kno-flicker   { 0%,100% { opacity: 1 } 45% { opacity: 1 } 50% { opacity: .35 } 55% { opacity: 1 } 70% { opacity: .6 } 75% { opacity: 1 } }
@keyframes kno-glow      { 0%,100% { filter: drop-shadow(0 0 0 currentColor) } 50% { filter: drop-shadow(0 0 12px currentColor) } }
@keyframes kno-tada      { 0%,100% { scale: 1; rotate: 0deg } 10%,20% { scale: .92; rotate: -3deg } 30%,50%,70%,90% { scale: 1.1; rotate: 3deg } 40%,60%,80% { scale: 1.1; rotate: -3deg } }
@keyframes kno-breathe   { 0%,100% { scale: 1; opacity: .82 } 50% { scale: 1.04; opacity: 1 } }
@keyframes kno-swing-loop{ 0%,100% { rotate: 0deg } 25% { rotate: 9deg } 75% { rotate: -9deg } }
@keyframes kno-jitter    { 0%,100% { translate: 0 0 } 25% { translate: 1.5px -1px } 50% { translate: -1.5px 1px } 75% { translate: 1px 1.5px } }
@keyframes kno-orbit     { from { --kno-rz: 0deg } to { --kno-rz: 360deg } }
@keyframes kno-rotate-y  { from { --kno-ry: 0deg } to { --kno-ry: 360deg } }
@keyframes kno-blink-loop{ 0%,49% { opacity: 1 } 50%,100% { opacity: .25 } }
@keyframes kno-shine     { to { translate: 210% 0 } }

/* ==========================================================================
   15b. TYPEWRITER
   ========================================================================== */
.kno-caret {
  display: inline-block;
  width: .07em;
  height: 1em;
  background: currentColor;
  vertical-align: -.14em;
  margin-left: .06em;
  animation: kno-caret-blink 1s steps(1) infinite;
}
@keyframes kno-caret-blink { 0%, 50% { opacity: 1 } 50.01%, 100% { opacity: 0 } }

/* ==========================================================================
   16b. COUNTERS
   Fixed-width digits, otherwise the element resizes on every frame and drags
   the surrounding layout around with it.
   ========================================================================== */
[kno-count] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ==========================================================================
   17. SCROLL-LINKED PROGRESS  (kno-progress) & PARALLAX (kno-parallax)
   --kno-p runs 0 → 1 as the element travels through the viewport.
   Where the browser supports scroll-driven animations it drives --kno-p off
   the compositor; otherwise the JS rAF loop writes the same variable. Both
   paths feed identical CSS, so behaviour does not fork.
   ========================================================================== */
[kno-progress],
[kno-parallax],
[kno-scrub] { --kno-p: 0; }

/* A scrubbed animation is positioned by the scroll bar, not played over time —
   a transition would only add lag between the finger and the pixels. */
[kno-scrub] {
  transition: none !important;
}

[kno-progress="fade"]    { opacity: var(--kno-p); }
[kno-progress="scale"]   { scale: calc(0.8 + 0.2 * var(--kno-p)); }
[kno-progress="rotate"]  { rotate: calc(var(--kno-p) * 360deg); }
[kno-progress="bar"]     { transform-origin: left center; scale: var(--kno-p) 1; }

/* Doubled attribute raises specificity above `.kno-in`, so parallax survives
   on an element that also carries a kno-position. */
[kno-parallax][kno-parallax] {
  --kno-y: calc((var(--kno-p) - 0.5) * var(--kno-speed, 0) * 200px);
}

@keyframes kno-drive-p { from { --kno-p: 0 } to { --kno-p: 1 } }

/* `view()` resolves against the nearest scroll container, and `overflow:hidden`
   counts as one — inside a clipping wrapper the element never moves, so its
   progress would freeze. JS marks those elements `kno-native="off"` and drives
   them from the rAF loop instead, keeping both paths identical. */
@supports (animation-timeline: view()) {
  [kno-progress]:not([kno-native="off"]),
  [kno-parallax]:not([kno-native="off"]),
  [kno-scrub]:not([kno-native="off"]) {
    animation: kno-drive-p linear both;
    animation-timeline: view();
    animation-range: entry 0% exit 100%;
  }
}

/* ==========================================================================
   17b. PINNED SECTIONS  (kno-pin inside kno-pin-track)
   The track supplies the scroll distance; the pinned child sticks while
   --kno-p advances across it.
   ========================================================================== */
[kno-pin-track] { position: relative; }
[kno-pin] {
  position: sticky;
  top: var(--kno-pin-top, 0px);
  --kno-p: 0;
}

/* ==========================================================================
   17c. SVG PATH DRAWING  (kno-draw)
   JS measures the geometry into --kno-len; the stroke then unrolls.
   ========================================================================== */
[kno-draw] {
  --kno-duration: var(--kno-duration-default);
  --kno-delay: var(--kno-delay-default);
  --kno-easing: var(--kno-easing-default);
  --kno-len: 1000;
  stroke-dasharray: var(--kno-len);
  stroke-dashoffset: var(--kno-len);
  transition: stroke-dashoffset var(--kno-duration) var(--kno-easing) var(--kno-delay);
}
[kno-draw="reverse"] { stroke-dashoffset: calc(-1 * var(--kno-len)); }
[kno-draw].kno-in,
[kno-draw].kno-animation { stroke-dashoffset: 0; }

/* ==========================================================================
   17d. PRESETS  (kno-preset on any container — inherited by the subtree)
   A whole page or section can share one rhythm without repeating attributes.
   ========================================================================== */
[kno-preset="calm"] {
  --kno-duration-default: 1100ms;
  --kno-easing-default: cubic-bezier(0.16, 1, 0.3, 1);
  --kno-distance: 80px;
}
[kno-preset="editorial"] {
  --kno-duration-default: 900ms;
  --kno-easing-default: cubic-bezier(0.22, 1, 0.36, 1);
  --kno-distance: 40px;
}
[kno-preset="snappy"] {
  --kno-duration-default: 420ms;
  --kno-easing-default: cubic-bezier(0.33, 1, 0.68, 1);
  --kno-distance: 28px;
}
[kno-preset="playful"] {
  --kno-duration-default: 800ms;
  --kno-easing-default: cubic-bezier(0.34, 1.56, 0.64, 1);
  --kno-distance: 70px;
}
[kno-preset="dramatic"] {
  --kno-duration-default: 1400ms;
  --kno-easing-default: cubic-bezier(0.87, 0, 0.13, 1);
  --kno-distance: 140px;
}

/* ==========================================================================
   17e. INTERACTION TRIGGERS  (kno-hover / kno-click / kno-focus)
   ========================================================================== */
[kno-click] { cursor: pointer; }
[kno-focus] { outline-offset: 3px; }

/* ==========================================================================
   17e2. POINTER EFFECTS  (kno-tilt / kno-magnetic)
   Both write into the same channels as every scroll animation, so an element
   can be tilted and animated in at once without either one fighting the other.
   ========================================================================== */
[kno-tilt] {
  transform-style: preserve-3d;
  cursor: pointer;
}
[kno-tilt] > * { transform: translateZ(var(--kno-tilt-lift, 0px)); }
[kno-magnetic] { cursor: pointer; }

/* Glare layer, opt in with kno-tilt-glare */
[kno-tilt-glare] { position: relative; overflow: hidden; }
[kno-tilt-glare]::after {
  content: '';
  position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background: radial-gradient(circle at var(--kno-glare-x, 50%) var(--kno-glare-y, 50%),
              rgba(255,255,255,.28), transparent 55%);
  opacity: var(--kno-glare, 0);
  transition: opacity .3s ease;
}

/* ==========================================================================
   17f. DEV OVERLAY  (kno-debug on <html>)
   ========================================================================== */
.kno-dbg-line {
  position: fixed; left: 0; right: 0; z-index: 2147483646; pointer-events: none;
  border-top: 1px dashed #00d3a7;
}
.kno-dbg-line::after {
  content: attr(data-label);
  position: absolute; left: 8px; top: 3px;
  font: 600 10px/1.4 ui-monospace, monospace; color: #00d3a7;
  background: rgba(0, 0, 0, .6); padding: 1px 6px; border-radius: 4px;
}
.kno-dbg-badge {
  position: fixed; right: 10px; bottom: 10px; z-index: 2147483647; pointer-events: none;
  font: 600 11px/1.5 ui-monospace, monospace; color: #fff; background: rgba(20, 20, 31, .92);
  border: 1px solid #7c5cff; border-radius: 8px; padding: 7px 11px; white-space: pre;
}
[data-kno-state] { outline: 1px solid rgba(255, 107, 157, .55); }
[data-kno-state="in"] { outline-color: rgba(0, 211, 167, .65); }
[data-kno-state="pending"] { outline-color: rgba(255, 200, 0, .65); }

/* ==========================================================================
   18. EASING PRESETS
   ========================================================================== */
[kno-easing="linear"]          { --kno-easing: linear; }
[kno-easing="ease"]            { --kno-easing: ease; }
[kno-easing="ease-in"]         { --kno-easing: ease-in; }
[kno-easing="ease-out"]        { --kno-easing: ease-out; }
[kno-easing="ease-in-out"]     { --kno-easing: ease-in-out; }

[kno-easing="sine-in"]         { --kno-easing: cubic-bezier(0.12, 0, 0.39, 0); }
[kno-easing="sine-out"]        { --kno-easing: cubic-bezier(0.61, 1, 0.88, 1); }
[kno-easing="sine-in-out"]     { --kno-easing: cubic-bezier(0.37, 0, 0.63, 1); }
[kno-easing="quad-out"]        { --kno-easing: cubic-bezier(0.5, 1, 0.89, 1); }
[kno-easing="cubic-out"]       { --kno-easing: cubic-bezier(0.33, 1, 0.68, 1); }
[kno-easing="quart-out"]       { --kno-easing: cubic-bezier(0.25, 1, 0.5, 1); }
[kno-easing="quint-out"]       { --kno-easing: cubic-bezier(0.22, 1, 0.36, 1); }
[kno-easing="expo-out"]        { --kno-easing: cubic-bezier(0.16, 1, 0.3, 1); }
[kno-easing="circ-out"]        { --kno-easing: cubic-bezier(0, 0.55, 0.45, 1); }
[kno-easing="expo-in-out"]     { --kno-easing: cubic-bezier(0.87, 0, 0.13, 1); }
[kno-easing="quart-in-out"]    { --kno-easing: cubic-bezier(0.76, 0, 0.24, 1); }

[kno-easing="back-in"]         { --kno-easing: cubic-bezier(0.36, 0, 0.66, -0.56); }
[kno-easing="back-out"]        { --kno-easing: cubic-bezier(0.34, 1.56, 0.64, 1); }
[kno-easing="back-in-out"]     { --kno-easing: cubic-bezier(0.68, -0.6, 0.32, 1.6); }

[kno-easing="bounce"]          { --kno-easing: cubic-bezier(0.34, 1.56, 0.64, 1); }
[kno-easing="bounce-soft"]     { --kno-easing: cubic-bezier(0.22, 1.2, 0.36, 1); }
[kno-easing="bounce-hard"]     { --kno-easing: cubic-bezier(0.18, 1.9, 0.5, 1); }
[kno-easing="elastic"]         { --kno-easing: cubic-bezier(0.16, 1.6, 0.3, 1); }
[kno-easing="elastic-soft"]    { --kno-easing: cubic-bezier(0.2, 1.3, 0.35, 1); }
[kno-easing="elastic-hard"]    { --kno-easing: cubic-bezier(0.1, 2.2, 0.35, 1); }
[kno-easing="overshoot"]       { --kno-easing: cubic-bezier(0.25, 1.7, 0.45, 1); }
[kno-easing="anticipate"]      { --kno-easing: cubic-bezier(0.7, -0.4, 0.4, 1.4); }

[kno-easing="snap"]            { --kno-easing: cubic-bezier(0, 1, 0, 1); }
[kno-easing="glide"]           { --kno-easing: cubic-bezier(0.4, 0, 0.2, 1); }
[kno-easing="swift"]           { --kno-easing: cubic-bezier(0.55, 0, 0.1, 1); }
[kno-easing="jelly"]           { --kno-easing: cubic-bezier(0.55, 0, 0.15, 1); }
[kno-easing="pop"]             { --kno-easing: cubic-bezier(0.34, 1.56, 0.64, 1); }
[kno-easing="swing"]           { --kno-easing: cubic-bezier(0.25, 0.25, 0.75, 0.75); }

[kno-easing="step-start"]      { --kno-easing: step-start; }
[kno-easing="step-end"]        { --kno-easing: step-end; }
[kno-easing="steps-3"]         { --kno-easing: steps(3, end); }
[kno-easing="steps-5"]         { --kno-easing: steps(5, end); }
[kno-easing="steps-7"]         { --kno-easing: steps(7, end); }

/* ==========================================================================
   18b. SCROLL DIRECTION
   KNO writes data-kno-dir="down|up" on <html>, so author CSS can react too.
   ========================================================================== */
[data-kno-dir="up"] [kno-direction="down"]:not(.kno-in),
[data-kno-dir="down"] [kno-direction="up"]:not(.kno-in) {
  /* held at the start pose until the reader scrolls the other way */
}

/* ==========================================================================
   19. UTILITY
   ========================================================================== */
[kno-disabled],
[kno-disabled] * {
  --kno-op: 1 !important;
  transform: none !important;
  filter: none !important;
  clip-path: none !important;
  transition: none !important;
  animation: none !important;
}

/* Swiper / carousel safety: slides clip their own overflow so a translating
   child never widens the track. */
.swiper-slide > [kno-position] { max-width: 100%; }

/* ==========================================================================
   20. ACCESSIBILITY — respect reduced motion at the CSS layer too,
   so content is readable even if JS never runs.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  [kno-draw] { stroke-dashoffset: 0 !important; transition: none !important; }
  [kno-position*="mask-"] { -webkit-mask-image: none !important; mask-image: none !important; }
  [kno-loop="shine"]::after, .kno-caret { animation: none !important; opacity: 0 }
  [kno-tilt], [kno-magnetic] { transform: none !important; }
  [kno-parallax] { --kno-y: 0px !important; }

  [kno-position],
  [kno],
  [kno-loop],
  [kno-progress],
  [kno-parallax],
  [kno-scrub] {
    --kno-x: 0px !important;
    --kno-y: 0px !important;
    --kno-z: 0px !important;
    --kno-rx: 0deg !important;
    --kno-ry: 0deg !important;
    --kno-rz: 0deg !important;
    --kno-skx: 0deg !important;
    --kno-sky: 0deg !important;
    --kno-sx: 1 !important;
    --kno-sy: 1 !important;
    --kno-op: 1 !important;
    --kno-blur: 0px !important;
    --kno-clip: inset(0 0 0 0) !important;
    transition-duration: 1ms !important;
    animation: none !important;
  }
}

/* Motion-safe opt-in: elements marked kno-force keep animating even when the
   OS asks for reduced motion (use only for essential feedback). */
@media (prefers-reduced-motion: reduce) {
  [kno-force] { transition-duration: var(--kno-duration) !important; }
}
