@layer animations {
  :root {
    /* === IMAGE ANIMATION VARIABLES === */
    --img-overexposure-duration: 0.3s;
    --img-overexposure-timing: ease-out forwards;
    --img-contrastslam-duration: 0.1s;
    --img-contrastslam-timing: steps(3, end);
    --img-colorbleed-duration: 0.5s;
    --img-colorbleed-timing: steps(6, end) forwards;
    --img-filmburn-duration: 0.4s;
    --img-filmburn-timing: steps(4, end) forwards;
    --img-malfunction-duration: 0.6s;
    --img-malfunction-timing: steps(6, end) forwards;
    --img-tonerstarvation-duration: 0.5s;
    --img-tonerstarvation-timing: steps(5, end) forwards;
    --img-corruption-duration: 0.4s;
    --img-corruption-timing: steps(8, end) forwards;
    --img-starkflash-duration: 0.2s;
    --img-starkflash-timing: linear forwards;

    /* == Base filter values == */
    --base-grayscale: 100;
    --base-contrast: 150;
    --base-brightness: 120;

    /* === TEXT ANIMATION VARIABLES === */

    /* == Strike Variables == */
    --strike-color: var(--color-primary);
    --strike-duration: 0.3s;
    --strike-timing: cubic-bezier(0.4, 0, 0.2, 1);
    --strike-radius: 50% / 0.25em 0.5em 0.9em 0.7em;
    --strike-border-width: 0.25em;
    --strike-height: 0.1875em;

    /* == Marker Highlight Variables == */
    --marker-bg: var(--color-surface-inverse);
    --marker-fg: var(--color-text-inverse);
    --marker-duration: 0.4s;
    --marker-timing: cubic-bezier(0.68, -0.55, 0.265, 1.55);

    /* == Label Maker Variables == */
    --label-duration: 0.1s;
    --label-timing: cubic-bezier(0.68, -0.55, 0.265, 1.55);
    --label-bg: var(--color-surface-inverse);
    --label-fg: var(--color-text-inverse);
    --label-margin: -0.2em -0.4em;
    --label-padding: 0.2em 0.4em;
    --label-border-width: 0.125em;
    --label-weight: bold;
    --label-transform: uppercase;
    --label-spacing: 0.05em;
    --label-shadow-offset: 0.125em 0.125em;
    --label-shadow-color: alpharize(var(--label-bg), 0.3);

    /* == Rubber Stamp Variables == */
    --stamp-duration: 0.08s;
    --stamp-timing: steps(2, end);
    --stamp-bg: var(--color-surface-inverse);
    --stamp-fg: var(--color-text-inverse);
    --stamp-rotate: -2deg;
    --stamp-scale: 0.95;
    --stamp-translate: 1px;
    --stamp-margin: -0.2em -0.4em;
    --stamp-padding: 0.2em 0.4em;
    --stamp-border-width: 0.25em;
    --stamp-weight: 900;
    --stamp-transform: uppercase;
    --stamp-spacing: 0.2em;
    --stamp-shadow-offset: 0.125em 0.125em;
    --stamp-shadow-color: alpharize(var(--stamp-fg), 0.8);

    /* Press Stamp Variables */
    --press-duration: 0.06s;
    --press-timing: c linear;
    --press-bg: var(--color-surface-elevated-4);
    --press-fg: var(--color-text-inverse);
    --press-scale-y: 0.85;
    --press-scale-x: 1.05;
    --press-translate: 3px;
    --press-margin: -0.05em -0.15em;
    --press-padding: 0.05em 0.15em;
    --press-weight: 900;
    --press-spacing: 0.1em;
    --press-border-color: var(--color-surface-elevated-4);
    --press-shadow-1: var(--color-surface-inverse);
    --press-shadow-2: alpharize(var(--stamp-fg), 0.7);

    /* Typewriter Variables */
    --typewriter-color: var(--color-text-primary);
    --typewriter-duration: 0.6s;
    --typewriter-timing: steps(15, end);
    --typewriter-offset: -3px;
    --typewriter-height: 2px;
    --typewriter-dash-length: 0.4em;
    --typewriter-gap-length: 0.45em;

    /* Hard Invert Variables */
    --invert-duration: 0.8s;
    --invert-timing: steps(2, end);
    --invert-bg: var(--color-surface-inverse);
    --invert-fg: var(--color-text-inverse);
    --invert-scale: 1.02;
    --invert-weight: 900;
    --invert-spacing: 0.05em;

    /* Pointer Variables */
    --pointer-color: inherit;
    --pointer-transition: all 0.3s ease-out;
    --pointer-left-symbol: '[';
    --pointer-right-symbol: ']';
    --pointer-distance: 0.375em;

    /* Corner Box Variables */
    --corner-margin: -0.3em;
    --corner-padding: 0.3em;
    --corner-size: 0.5em;
    --corner-border: 2px solid var(--color-text-primary);
    --corner-transition: all 0.75s ease-out;
    --corner-font-weight: 600;

    /* Character Glitch Variables */
    --glitch-duration: 0.3s;
    --glitch-timing: steps(8, end);
    --glitch-text-shadow-1: 2px 0 var(--color-palette-heliotrope), -2px 0 var(--color-palette-electric-blue);
    --glitch-text-shadow-2: 1px 0 var(--color-palette-ruby), -1px 0 var(--color-palette-electric-green);
    --glitch-fg-step: var(--color-text-inverse);
    --glitch-bg-step: var(--color-surface-inverse);

    /* Pixel Shift Variables */
    --pixel-bg: var(--color-surface-inverse);
    --pixel-fg: var(--color-text-inverse);
    --pixel-duration: 0.5s;
    --pixel-timing: steps(2, start) forwards;
    --pixel-line-height: 0.5em;
    --pixel-text-shadow: 2px 0 var(--color-primary), -1px 0 var(--color-secondary);
    --pixel-line-color-step: var(--color-primary);
    --pixel-line-color-end: var(--color-text-inverse);

    /* Redacted Variables */
    --redacted-bg: var(--color-text-primary);
    --redacted-duration: 0.4s;
    --redacted-timing: steps(3, end);
    --redacted-shadow: 0 0 8px alpharize(var(--color-palette-woodsmoke), 0.5);

    /* X-Ray Variables */
    --xray-duration: 0.2s;
    --xray-timing: steps(3, end);
    --xray-bg: var(--color-palette-ice-blue);
    --xray-fg: var(--color-text-inverse);
    --xray-weight: 900;
    --xray-glow: var(--color-surface-inverse);
    --xray-invert: 1;
    --xray-contrast: 300%;
    --xray-brightness: 150%;
    --xray-saturate: 0;
    --xray-border: var(--color-surface-inverse);
    --xray-outer-glow: alpharize(var(--color-palette-ice-blue), 0.5);

    /* === KEYFRAME NAME VARIABLES === */
    --kf-overexposure: overexposure;
    --kf-color-bleed: color-bleed;
    --kf-film-burn: film-burn;
    --kf-malfunction: malfunction;
    --kf-toner-fade: toner-fade;
    --kf-digital-corrupt: digital-corrupt;
    --kf-stark-flash: stark-flash;
    --kf-bd-overexposure: bd-overexposure;
    --kf-bd-color-bleed: bd-color-bleed;
    --kf-bd-film-burn: bd-film-burn;
    --kf-bd-malfunction: bd-malfunction;
    --kf-bd-toner-fade: bd-toner-fade;
    --kf-bd-digital-corrupt: bd-digital-corrupt;
    --kf-bd-stark-flash: bd-stark-flash;
    --kf-strike-slam: strike-slam;
    --kf-text-glitch: text-glitch;
    --kf-char-scramble: char-scramble;
    --kf-glitch-line: glitch-line;
    --kf-text-entry-glitch: text-entry-glitch;
  }

  /* === IMAGE KEYFRAMES === */

  @keyframes overexposure {
    0% { filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness)); }
    50% { filter: grayscale(var(--base-grayscale)) contrast(100%) brightness(350%); }
    100% { filter: grayscale(var(--base-grayscale)) contrast(200%) brightness(180%); }
  }

  @keyframes color-bleed {
    0% { filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness)); }
    16% { filter: grayscale(0.7) contrast(200%) brightness(180%) saturate(300); }
    33% { filter: grayscale(0.4) contrast(300%) brightness(150%) saturate(500) hue-rotate(15deg); }
    50% { filter: grayscale(0.8) contrast(250%) brightness(200%) saturate(400) hue-rotate(-10deg); }
    66% { filter: grayscale(0.3) contrast(400%) brightness(160%) saturate(600) hue-rotate(25deg); }
    83% { filter: grayscale(0.6) contrast(300%) brightness(180%) saturate(300) hue-rotate(-5deg); }
    100% { filter: grayscale(0.5) contrast(250%) brightness(170%) saturate(400); }
  }

  @keyframes film-burn {
    0% { filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness)); }
    25% { filter: invert(1) contrast(200%) brightness(150%); }
    50% { filter: grayscale(var(--base-grayscale)) contrast(300%) brightness(80%); }
    75% { filter: grayscale(var(--base-grayscale)) contrast(100%) brightness(250%); }
    100% { filter: grayscale(var(--base-grayscale)) contrast(200%) brightness(160%); }
  }

  @keyframes malfunction {
    0% {
      transform: scaleX(1);
      filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness));
    }

    16% {
      transform: scaleX(0.95) translateX(2px);
      filter: grayscale(var(--base-grayscale)) contrast(200%) brightness(200%);
    }

    33% {
      transform: scaleX(1.05) translateX(-2px);
      filter: grayscale(var(--base-grayscale)) contrast(300%) brightness(80%);
    }

    50% {
      transform: scaleX(0.98) translateX(1px);
      filter: grayscale(var(--base-grayscale)) contrast(100%) brightness(250%);
    }

    66% {
      transform: scaleX(1.02) translateX(-1px);
      filter: grayscale(var(--base-grayscale)) contrast(250%) brightness(100%);
    }

    100% {
      transform: scaleX(1) translateX(0);
      filter: grayscale(var(--base-grayscale)) contrast(180%) brightness(140%);
    }
  }

  @keyframes toner-fade {
    0% { filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness)); }
    20% { filter: grayscale(var(--base-grayscale)) contrast(80%) brightness(180%); }
    40% { filter: grayscale(var(--base-grayscale)) contrast(50%) brightness(220%); }
    60% { filter: grayscale(var(--base-grayscale)) contrast(100%) brightness(160%); }
    80% { filter: grayscale(var(--base-grayscale)) contrast(120%) brightness(140%); }
    100% { filter: grayscale(var(--base-grayscale)) contrast(200%) brightness(130%); }
  }

  @keyframes digital-corrupt {
    0% { filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness)); }
    12.5% { filter: grayscale(var(--base-grayscale)) contrast(300%) brightness(50%) blur(1px); }
    25% { filter: grayscale(var(--base-grayscale)) contrast(80%) brightness(300%) saturate(2); }
    37.5% { filter: grayscale(var(--base-grayscale)) contrast(400%) brightness(80%) hue-rotate(180deg); }
    50% { filter: grayscale(var(--base-grayscale)) contrast(100%) brightness(400%) invert(0.3); }
    62.5% { filter: grayscale(var(--base-grayscale)) contrast(500%) brightness(60%); }
    75% { filter: grayscale(var(--base-grayscale)) contrast(200%) brightness(200%) blur(0.5px); }
    87.5% { filter: grayscale(var(--base-grayscale)) contrast(180%) brightness(150%); }
    100% { filter: grayscale(var(--base-grayscale)) contrast(200%) brightness(140%); }
  }

  @keyframes stark-flash {
    0% { filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness)); }
    30% { filter: grayscale(var(--base-grayscale)) contrast(800%) brightness(800%) invert(1); }
    70% { filter: grayscale(var(--base-grayscale)) contrast(600%) brightness(600%); }
    100% { filter: grayscale(var(--base-grayscale)) contrast(300%) brightness(180%); }
  }

  /* === TEXT KEYFRAMES === */

  @keyframes strike-slam {
    0% {
      left: 0;
      width: 0%;
    }

    100% {
      left: -0.125em;
      width: calc(100% + 0.25em);
    }
  }

  @keyframes text-glitch {
    0% {
      transform: translateX(0);
      color: var(--color-palette-light-silver);
    }

    50% {
      transform: translateX(-2px);
      color: var(--pixel-fg);
      text-shadow: var(--pixel-text-shadow);
    }

    100% {
      transform: translateX(0);
      color: var(--pixel-fg);
    }
  }

  @keyframes char-scramble {
    0% {
      transform: translateX(0);
      text-shadow: none;
      filter: none;
    }

    12.5% {
      font-family: monospace;
      text-shadow: var(--glitch-text-shadow-1);
    }

    25% {
      transform: translateX(2px);
      filter: contrast(200%) brightness(150%);
    }

    37.5% {
      transform: translateX(-1px) scaleY(1.1);
      letter-spacing: 0.2em;
    }

    50% {
      transform: translateX(1px) scaleX(0.9);
      color: var(--glitch-fg-step);
      background: var(--glitch-bg-step);
    }

    62.5% {
      transform: translateX(-2px);
      filter: invert(1) contrast(300%);
    }

    75% {
      transform: translateX(1px);
      text-shadow: var(--glitch-text-shadow-2);
    }

    87.5% {
      letter-spacing: 0.1em;
      filter: contrast(150%) brightness(120%);
    }

    100% {
      transform: translateX(0);
      color: var(--color-text-primary);
      text-shadow: none;
      filter: none;
    }
  }

  @keyframes glitch-line {
    0% {
      transform: translateX(0) scaleX(1);
      opacity: 0;
    }

    50% {
      transform: translateX(3px) scaleX(0.7);
      opacity: 1;
      background: var(--pixel-line-color-step);
    }

    100% {
      transform: translateX(0) scaleX(1);
      opacity: 1;
      background: var(--pixel-line-color-end);
    }
  }
}

@keyframes text-entry-glitch {
  0% {
    transform: translateX(-10px) scale(0.8);
    color: transparent;
    opacity: 0;
    filter: blur(2px);
  }

  25% {
    transform: translateX(3px) scale(1.05);

    color: var(--color-palette-light-silver);
    text-shadow: 2px 0 var(--color-primary), -1px 0 var(--color-secondary);

    opacity: 0.7;
    filter: blur(1px);
  }

  50% {
    transform: translateX(-2px) scale(0.95);

    color: var(--pixel-fg);
    text-shadow: var(--pixel-text-shadow);

    opacity: 0.9;
    filter: blur(0.5px);
  }

  75% {
    transform: translateX(1px) scale(1.02);

    color: var(--color-text-inverse);
    text-shadow: 1px 0 var(--color-primary);

    opacity: 1;
    filter: none;
  }

  100% {
    transform: translateX(0) scale(1);

    color: var(--pixel-line-color-end);
    text-shadow: none;

    opacity: 1;
    filter: none;
  }
}