/* ==========================================================================
   Typed keys — the STACK / METHOD / GROWTH rows on jobopportunities.php.

   Each row's small mono key types itself out a character at a time, with a
   caret travelling along it, and the row's body arrives behind it. Rows go
   in sequence rather than together, so it reads as a record being written
   rather than three things appearing.

   Progressive: typed.js adds .ty-on, and only then does anything hide. With
   JavaScript off the class never lands and the page renders complete.
   ========================================================================== */

.ty-on .step{
  opacity: 0;
  transform: translateY(8px);
}
.ty-on.is-in .step{
  opacity: 1;
  transform: none;
  /* --d is the row's own place in the sequence, stamped by typed.js. */
  transition: opacity .5s cubic-bezier(.2,.8,.25,1) var(--d),
              transform .5s cubic-bezier(.2,.8,.25,1) var(--d);
}

/* Every character is its own span, created up front. Nothing is appended
   mid-run and no width or clip moves, so the layout is never caught half
   built while a key is still typing. */
/* Same reasoning as .steps__term .wd in case.css: every .ch is
   inline-block and therefore its own break opportunity, so a word has to
   be held together explicitly or it can wrap mid-word. */
.ty-on .step__n .wd{ white-space: nowrap; }
.ty-on .step__n .ch{
  display: inline-block;
  white-space: pre;
  position: relative;
  opacity: 0;
}
.ty-on.is-in .step__n .ch{
  /* Keys appear, they do not fade in. A character easing up to full
     opacity reads as a dissolve; a key either has been struck or has not. */
  animation: ty-key 1ms linear forwards;
  animation-delay: calc(var(--d) + var(--i) * 45ms);
}
@keyframes ty-key{ to{ opacity: 1 } }

/* The caret. Each character carries its own, lit for exactly its own beat
   and then out, so the caret lands on real glyph positions whatever their
   widths. One shared caret would have to be moved by a fixed character
   advance, which only works in a monospace of known size. */
.ty-on .step__n .ch::after{
  content: "";
  position: absolute;
  right: -2px;
  top: .12em;
  bottom: .12em;
  width: 1.5px;
  background: var(--accent);
  opacity: 0;
}
.ty-on.is-in .step__n .ch::after{
  animation: ty-caret .09s steps(1) forwards;
  animation-delay: calc(var(--d) + var(--i) * 45ms);
}
@keyframes ty-caret{
  0%  { opacity: 1 }
  100%{ opacity: 0 }
}

/* Everything present, nothing moving. */
@media (prefers-reduced-motion: reduce){
  .ty-on .step{ opacity: 1; transform: none; transition: none }
  .ty-on .step__n .ch{ opacity: 1 }
  .ty-on.is-in .step__n .ch,
  .ty-on.is-in .step{ animation: none }
  .ty-on .step__n .ch::after{ display: none }
}
