/* motion: everything moves in discrete steps, nothing eases, only the caret loops */

@keyframes tw-blink {
  50% { opacity: 0; }
}

@keyframes tw-strike {
  from { translate: 0 -4px; opacity: 0.4; }
}

@keyframes tw-rule {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0); }
}

@keyframes tw-feed {
  from { opacity: 0; translate: 0 1.6em; }
  to { opacity: 1; translate: 0 0; }
}

/* typed text: hidden until the script has split it into characters */
@media screen {
  .tw-pending [data-tw="strike"],
  .tw-pending [data-tw="type"] {
    visibility: hidden;
  }
}

/* the per-character copy is for the eye only; copy-paste gets the sr-only text */
[data-tw] > [aria-hidden] {
  -webkit-user-select: none;
  user-select: none;
}

.tw-char {
  position: relative;
  visibility: hidden;
}

.tw-char.is-on {
  visibility: visible;
}

/* caret */
.tw-char.is-caret::after {
  content: "";
  position: absolute;
  left: 100%;
  bottom: 0.1em;
  width: 0.55em;
  height: 1em;
  background: var(--ribbon);
}

.is-idle .tw-char.is-caret::after {
  animation: tw-blink 1s steps(1) 5;
}

/* key strike */
[data-tw="strike"] .tw-char {
  display: inline-block;
  rotate: var(--tw-r, 0deg);
  translate: 0 var(--tw-y, 0px);
  opacity: var(--tw-o, 1);
}

[data-tw="strike"] .tw-char.is-on {
  animation: tw-strike 90ms steps(2);
}

/* section reveal: the visible state is the resting state, so the page stays
   readable without script, without animation, and in print */
@media screen {
  .tw [data-reveal]:not(.is-inview)::before {
    clip-path: inset(0 100% 0 0);
  }

  .tw [data-reveal]:not(.is-inview) > * {
    opacity: 0;
    translate: 0 1.6em;
  }
}

.tw [data-reveal].is-inview::before {
  animation: tw-rule 600ms steps(24) backwards;
}

.tw [data-reveal].is-inview > * {
  animation: tw-feed 240ms steps(3) 200ms backwards;
}

@media print {
  .tw-char {
    visibility: visible;
  }

  .tw-char.is-caret::after {
    content: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
}
