/* ============================================================================
   THE WORDMARK'S GLITCH LAYER
   ============================================================================

   Ported from `der-koloss-aaa` at the user's request — *"that needs to be
   animated just like the text is animated in the der-koloss-aaa directory on the
   menu screen... have some sick but subtle but still clear/visible text effect...
   i like the glitch we have there"*.

   THE BRIEF CHANGED, AND THIS FILE NOW CONTRADICTS ITS OWN PORT NOTE ABOVE.
   The original ask said *"sick but subtle"*, and the first version honoured that
   literally: about 200 ms of visible tearing per 8.9-second cycle. Watching it,
   the user's verdict was the opposite — *"isnt aniamted enough its too long
   between glitches and too subtle make it sicker jaw dropiping like wow s tier"*.
   So subtlety is no longer the goal and the numbers below are deliberately loud.
   The quoted line above is kept because it is the real history of this file, not
   because it is still the target.

   WHAT THE EFFECT IS NOW. Two chroma copies of each word, hard-cutting thin
   horizontal bands — but four times per cycle instead of twice, on periods a
   third as long, at roughly triple the displacement and double the opacity. Once
   per cycle each layer fires a BURST: five cuts inside ~200 ms, at different
   heights, alternating direction. The burst is the "wow" beat; the isolated
   tears between bursts are what stop it reading as a continuous strobe.

   Measured against the first version, per 10 s of wall clock: visible-tear time
   goes from ~0.22 s to ~1.4 s, tear events from 4 to 26, and peak displacement
   from 0.022em to 0.075em — about a third of a letter width.

   WHY IT IS STILL NOT A STROBE. Two things hold it back from noise. The bursts
   on the two layers can never coincide (see COPRIME PERIODS below), so there is
   always a lead layer and a trailing one. And every cut is still `steps(1)` —
   the eye gets discrete frames of a broken signal rather than motion, which is
   what separates "glitch" from "animation".

   WHY IT IS IN ITS OWN FILE. `style.css` is being rewritten by another session
   for the lobby, and a stylesheet two agents are appending to is how three
   sessions' findings once ended up filed under one commit about `git reset`. One
   line of `style.css` changes for this — the jitter, which has to join an
   existing `animation` list rather than duplicate it — and everything else is
   here. Consolidate into `style.css` once the lobby work lands.

   THREE THINGS THAT ARE DELIBERATE AND LOOK LIKE DETAILS:

   1. COPRIME PERIODS. 2.3 s and 3.1 s — both prime, so their least common
      multiple is 7.13 s and the two layers never land in the same relationship
      twice within it. The whole-wordmark slam runs at 6.1 s, prime again, so all
      three are mutually coprime and the full pattern is 43.5 s long. Equal or
      harmonic periods would produce a beat, and a beat is a pattern — the eye
      locks onto it and the effect stops being a glitch and starts being an
      animation. This matters *more* now, not less: at this density a detectable
      period would turn the wordmark into a metronome within seconds.

   2. `steps(1)`. Every band is a hard cut. Interpolating the opacity or the
      offset makes the slice *slide*, which reads as a wipe or a skeleton loader
      — the exact generated-looking move this project has been told to remove.

   3. OFFSETS IN `em`, NOT PIXELS. The title is `clamp(52px, 8.2vw, 120px)`, so a
      displacement fixed in pixels would be a violent tear at 52px and invisible
      at 120px. In `em` the tear is the same fraction of a letter at every size.

   WHY `mix-blend-mode: screen`. The copies ADD light to the letters instead of
   painting over them. Painted copies read as two words printed on top of each
   other; added light reads as one word misregistering. That difference is most
   of the effect.

   ACCESSIBILITY. The whole file sits inside `prefers-reduced-motion:
   no-preference`. Under `reduce` the layers are never drawn at all rather than
   frozen mid-tear — a tear held still is not a calmer version of this effect, it
   is a rendering fault. The wordmark is plain solid text in that case, which is
   what it already was.

   The layers are `aria-hidden` by construction: they are pseudo-elements whose
   content comes from `data-text`, so no assistive technology ever sees the word
   three times. That is also why the markup carries `data-text` rather than the
   CSS carrying the string — one place spells "MODERN", and it is the same place
   a reader sees it.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {

  /* The words are the positioning context for their own copies. `.brand h1 em`
     already carries a `-webkit-background-clip: text` specular sweep, so its
     pseudo-elements inherit a locked text fill and a clipped background — both
     are undone below, or the copies would render as invisible transparent text. */
  .brand h1 span,
  .brand h1 em { position: relative; }

  .brand h1 span::before, .brand h1 span::after,
  .brand h1 em::before,   .brand h1 em::after {
    content: attr(data-text);
    position: absolute;
    inset: 0;
    display: block;
    pointer-events: none;
    /* Undo the gold word's fill lock and its clipped gradient. Without these the
       copy inherits `-webkit-text-fill-color: var(--gold)` and a background
       clipped to text, and draws nothing at all. */
    -webkit-text-fill-color: currentColor;
    background: none;
    mix-blend-mode: screen;
    opacity: 0;
    /* The copies never participate in layout or hit-testing, and promoting them
       keeps the hard cuts off the main thread's paint path. */
    will-change: opacity, transform, clip-path;
  }

  /* Cyan leads, amber trails — the two ends of the page's own palette rather
     than the stock red/cyan of every CRT-glitch demo, which is the tell that
     would make this read as a template. Both are low-alpha: at full strength a
     chroma copy stops being a misregistration and becomes a second word. */
  .brand h1 span::before,
  .brand h1 em::before {
    color: rgba(150, 226, 255, 0.95);
    animation: mcTearA 2.3s steps(1) 0.6s infinite;
  }
  .brand h1 span::after,
  .brand h1 em::after {
    color: rgba(255, 176, 84, 0.9);
    animation: mcTearB 3.1s steps(1) 1.1s infinite;
  }

  /* The gold word runs off-phase from the white one on both layers, so the two
     lines tear separately. Simultaneous tears read as the whole panel flickering,
     which is a different and much cheaper-looking effect — and at this density it
     would be the difference between a glitching wordmark and a failing monitor.
     The offsets are deliberately NOT half a period: that would put the two lines
     in strict alternation, which is itself a rhythm. */
  .brand h1 em::before { animation-delay: 1.42s; }
  .brand h1 em::after  { animation-delay: 2.37s; }
}

/* Each band is clipped to a different horizontal slice and displaced a different
   way, so no two tears in the cycle look alike. `clip-path: inset(0 0 100% 0)`
   is the resting state — a zero-height window — which means the copy is not
   merely transparent between flashes but has no area at all.

   THE BURST is the block from ~59% to ~66% of each cycle: five cuts in a row at
   different heights with alternating displacement, no gap between them. That
   contiguity is the point — isolated tears read as interference, but five
   back-to-back cuts read as the signal collapsing, which is the beat the eye
   actually registers as spectacular. Everything outside the burst is spaced out
   so the burst has something to be louder than. */
@keyframes mcTearA {
  0%, 8%    { opacity: 0;    transform: none;                       clip-path: inset(0 0 100% 0); }
  8.4%      { opacity: 0.88; transform: translate3d(-0.060em, 0, 0); clip-path: inset(22% 0 66% 0); }
  10%       { opacity: 0;    transform: none;                       clip-path: inset(0 0 100% 0); }
  30%       { opacity: 0; }
  30.5%     { opacity: 0.70; transform: translate3d(0.045em, 0, 0);  clip-path: inset(52% 0 36% 0); }
  32%       { opacity: 0;    transform: none;                       clip-path: inset(0 0 100% 0); }
  /* ---- the burst: five hard cuts, ~200 ms, no gaps ---- */
  59%       { opacity: 0; }
  59.4%     { opacity: 0.95; transform: translate3d(-0.075em, 0, 0); clip-path: inset(8% 0 80% 0); }
  60.8%     { opacity: 0.55; transform: translate3d(0.050em, 0, 0);  clip-path: inset(40% 0 48% 0); }
  62.2%     { opacity: 0.92; transform: translate3d(-0.030em, 0, 0); clip-path: inset(66% 0 22% 0); }
  63.6%     { opacity: 0.62; transform: translate3d(0.070em, 0, 0);  clip-path: inset(18% 0 70% 0); }
  65%       { opacity: 0.85; transform: translate3d(-0.055em, 0, 0); clip-path: inset(78% 0 10% 0); }
  66.2%     { opacity: 0;    transform: none;                       clip-path: inset(0 0 100% 0); }
  /* ---- one trailing tear, so the cycle does not end on the burst ---- */
  88%       { opacity: 0; }
  88.4%     { opacity: 0.66; transform: translate3d(0.028em, 0, 0);  clip-path: inset(34% 0 58% 0); }
  89.7%     { opacity: 0;    transform: none;                       clip-path: inset(0 0 100% 0); }
  100%      { opacity: 0; }
}
@keyframes mcTearB {
  0%, 14%   { opacity: 0;    transform: none;                       clip-path: inset(0 0 100% 0); }
  14.4%     { opacity: 0.72; transform: translate3d(0.052em, 0, 0);  clip-path: inset(12% 0 74% 0); }
  15.9%     { opacity: 0;    transform: none;                       clip-path: inset(0 0 100% 0); }
  /* B's burst sits at a different phase from A's, so the two never coincide even
     at the one moment in 7.13 s when the periods come closest to aligning. */
  36%       { opacity: 0; }
  36.4%     { opacity: 0.90; transform: translate3d(-0.068em, 0, 0); clip-path: inset(70% 0 18% 0); }
  37.8%     { opacity: 0.50; transform: translate3d(0.038em, 0, 0);  clip-path: inset(30% 0 60% 0); }
  39.2%     { opacity: 0.86; transform: translate3d(-0.058em, 0, 0); clip-path: inset(46% 0 42% 0); }
  40.6%     { opacity: 0.58; transform: translate3d(0.064em, 0, 0);  clip-path: inset(4% 0 86% 0); }
  42%       { opacity: 0.80; transform: translate3d(-0.042em, 0, 0); clip-path: inset(84% 0 6% 0); }
  43.3%     { opacity: 0;    transform: none;                       clip-path: inset(0 0 100% 0); }
  70%       { opacity: 0; }
  70.4%     { opacity: 0.68; transform: translate3d(-0.036em, 0, 0); clip-path: inset(58% 0 30% 0); }
  71.8%     { opacity: 0;    transform: none;                       clip-path: inset(0 0 100% 0); }
  93%       { opacity: 0; }
  93.4%     { opacity: 0.74; transform: translate3d(0.048em, 0, 0);  clip-path: inset(26% 0 64% 0); }
  94.8%     { opacity: 0;    transform: none;                       clip-path: inset(0 0 100% 0); }
  100%      { opacity: 0; }
}

/* THE SLAM — the whole wordmark, not a copy of it. Three frames every 6.1 s: the
   line kicks sideways and squashes vertically, then over-corrects, then settles.
   This is the only part of the effect that moves the REAL text rather than a
   chroma ghost, which is exactly why it is rare: the tears are a signal problem,
   the slam is the picture itself losing lock, and doing that often would read as
   the page being broken rather than the wordmark being cool.

   `scaleY` and not `scale`: a uniform scale is a pulse, which is the breath's
   job. Squashing one axis is a vertical-hold failure. Attached in `style.css`
   alongside `mcBreath` and `mcTitleJitter` — see the note there for why every
   `.brand h1` animation name has to live in one shorthand. */
@keyframes mcTitleSlam {
  0%, 52%  { transform: none; }
  52.4%    { transform: translate3d(0.038em, 0, 0) scaleY(1.07); }
  53%      { transform: translate3d(-0.030em, 0, 0) scaleY(0.94); }
  53.6%    { transform: translate3d(0.013em, 0, 0) scaleY(1.02); }
  54.2%    { transform: none; }
  100%     { transform: none; }
}

/* THE JITTER — the whole wordmark, two frames, roughly a pixel at full size.
   Declared here but ATTACHED in `style.css`, where it joins `mcBreath` in the
   existing `animation` list on `.brand h1`. It cannot be attached from this file:
   `animation` is a shorthand, so re-declaring it here to add one name would drop
   the breath, and duplicating the breath's timings into a second file is exactly
   the drift this project has paid for repeatedly.

   4.3 s against the breath's 9 s, the slam's 6.1 s and the two tear periods is
   the last member of the coprime set, so nothing in the wordmark ever repeats in
   step with anything else. `steps(1)` again — this is a signal dropping frames,
   not a wobble.

   Raised from 7.3 s / one 3-frame event / 0.006em to 4.3 s / two events / 0.014em
   under the same "not animated enough, too subtle" note that drove the tears. It
   stays the QUIETEST of the four layers on purpose: the jitter is the floor the
   others stand on, and if it competes with the burst there is no floor.

   `translate:` and not `transform: translate3d()` — see the note on `mcBreath` in
   `style.css`. Three animations on one element all writing `transform` do not
   compose; the last in the list wins outright, which had silently killed the
   breath. The individual `translate` / `scale` properties do compose. */
@keyframes mcTitleJitter {
  0%, 26%  { translate: none; }
  26.4%    { translate: 0.014em 0; }
  26.9%    { translate: -0.009em 0; }
  27.4%    { translate: 0.004em 0; }
  27.9%    { translate: none; }
  73%      { translate: none; }
  73.4%    { translate: -0.011em 0; }
  74%      { translate: 0.007em 0; }
  74.5%    { translate: none; }
  100%     { translate: none; }
}
