/* the homepage's moving parts. only the homepage loads this. */

@property --tint {
  syntax: "<number>";
  inherits: false;
  initial-value: 0;
}

html.js,
html.js body {
  overscroll-behavior: none;
}

/* once the script runs, the dot and the i-dot are played by actors laid over
   the wordmark. the shapes in the svg stay as the fallback. */
.js .wordmark .dot,
.js .wordmark .idot {
  visibility: hidden;
}

.js .mark {
  position: relative;
  z-index: 1;
}

body {
  transition: transform var(--slow) ease-in-out;
}

html.flipped body {
  transform: rotate(180deg);
}

.dragging,
.dragging * {
  cursor: grabbing !important;
  user-select: none;
  -webkit-user-select: none;
}

/* ---------- the hidden grid, ripples, shadows and threads ---------- */

.fx {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}

/* ---------- the cast ---------- */

.actor {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 2;
  border-radius: 50%;
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  will-change: transform;
}

/* a bigger target than the dot itself, so it's easy to grab with a thumb */
.actor::before {
  content: "";
  position: absolute;
  inset: -14px;
  border-radius: 50%;
}

.actor:focus {
  outline: none;
}

.actor:focus-visible {
  outline: 2px solid var(--dot);
  outline-offset: 4px;
}

.dot-actor {
  background: var(--dot);
}

.idot-actor {
  background: color-mix(in srgb, var(--dot) calc(var(--tint) * 100%), var(--ink));
  transition: --tint var(--normal) ease-out;
}

/* almost. it never gets all the way. */
.idot-actor.tinting {
  --tint: 0.8;
  transition-duration: 40s;
  transition-timing-function: linear;
}

.hidden-actor {
  visibility: hidden;
}

/* eyes, once someone types `eyes` */
.pupil {
  display: none;
  position: absolute;
  top: 30%;
  width: 24%;
  height: 24%;
  border-radius: 50%;
  background: var(--bg);
  transform: translate(var(--ex, 0px), var(--ey, 0px)) scale(var(--wide, 1));
  transition: transform 90ms ease-out, height 90ms ease-out, top 90ms ease-out;
}

.pupil.left {
  left: 20%;
}

.pupil.right {
  right: 20%;
}

.has-eyes .pupil {
  display: block;
}

.blinking .pupil,
.asleep .pupil {
  top: 44%;
  height: 6%;
  border-radius: 2px;
}

/* the little z over a sleeping dot */
.zzz {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 2;
  color: var(--muted);
  font-size: 0.75rem;
  line-height: 1;
  pointer-events: none;
  opacity: 0;
}

.zzz.on {
  animation: zzz 2.6s ease-out infinite;
}

@keyframes zzz {
  0% {
    opacity: 0;
    translate: 0 0;
  }
  25% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    translate: 10px -28px;
  }
}

/* the comma, as an actor, for its homepage appearances */
.comma-actor {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 2;
  pointer-events: none;
  will-change: transform;
}

/* corner hits, counted in dots */
.tally {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 1;
  color: var(--muted);
  font-size: 0.75rem;
  letter-spacing: 0.35em;
  pointer-events: none;
}

/* ---------- the grey line ---------- */

.js .line {
  position: relative;
  min-height: 1.5em;
  transition: opacity var(--quick) ease-out;
  user-select: text;
}

.js .line.out {
  opacity: 0;
  transition: opacity var(--normal) ease-in;
}

/* ---------- typing ---------- */

.typed {
  position: absolute;
  left: 0;
  top: 0;
  margin: 0;
  color: var(--ink);
  font-weight: 600;
  line-height: 1;
  white-space: pre;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--normal) ease-out;
}

.typing .typed {
  opacity: 1;
  transition-duration: 0s;
}

.typing .wordmark .letters {
  visibility: hidden;
}

/* ---------- the letters ---------- */

.letter {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  cursor: pointer;
}

.letter.wobble {
  animation: wobble 520ms ease-out;
}

@keyframes wobble {
  20% {
    transform: rotate(-7deg);
  }
  45% {
    transform: rotate(5deg);
  }
  70% {
    transform: rotate(-2deg);
  }
  100% {
    transform: none;
  }
}

.letter.flinch {
  animation: flinch 360ms ease-out;
}

@keyframes flinch {
  35% {
    transform: translate(var(--away, 3px), 0) rotate(calc(var(--away, 3px) * 0.8deg / 1px));
  }
  100% {
    transform: none;
  }
}

.letters.kern .letter {
  animation: kern 1300ms ease-in-out;
}

@keyframes kern {
  30% {
    transform: translateX(calc(var(--k) * 26px));
  }
  50% {
    transform: translateX(calc(var(--k) * -7px));
  }
  80% {
    transform: translateX(calc(var(--k) * -7px));
  }
  100% {
    transform: none;
  }
}

.letters.italic .letter {
  animation: italic 900ms ease-in-out;
}

@keyframes italic {
  35% {
    transform: skewX(-9deg);
  }
  45% {
    transform: skewX(-9deg);
  }
  100% {
    transform: none;
  }
}

.letters.shudder .letter {
  animation: shudder 600ms linear;
}

@keyframes shudder {
  0%,
  100% {
    transform: none;
  }
  10%,
  30%,
  50%,
  70%,
  90% {
    transform: translateX(-1.5px);
  }
  20%,
  40%,
  60%,
  80% {
    transform: translateX(1.5px);
  }
}

.letters.panic .letter {
  animation: panic 900ms ease-in-out;
  animation-delay: calc(var(--k) * 40ms);
}

@keyframes panic {
  0%,
  100% {
    transform: none;
  }
  15% {
    transform: translate(-3px, -4px) rotate(-6deg);
  }
  30% {
    transform: translate(3px, 1px) rotate(5deg);
  }
  45% {
    transform: translate(-2px, -3px) rotate(-4deg);
  }
  60% {
    transform: translate(2px, 0) rotate(3deg);
  }
  80% {
    transform: translate(-1px, -1px) rotate(-1deg);
  }
}

/* after bowling: back on their feet, with a little shake */
.letter.dust {
  animation: dust 420ms ease-out;
}

@keyframes dust {
  30% {
    transform: rotate(3deg);
  }
  60% {
    transform: rotate(-2deg);
  }
  100% {
    transform: none;
  }
}

/* ---------- print ---------- */

/* paper gets the wordmark's own shapes, not the moving actors */
@media print {
  .js .wordmark .dot,
  .js .wordmark .idot {
    visibility: visible;
  }

  .actor,
  .fx,
  .zzz,
  .tally,
  .comma-actor,
  .typed {
    display: none !important;
  }

  .typing .wordmark .letters {
    visibility: visible;
  }
}

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  body,
  .js .line,
  .js .line.out,
  .typed,
  .pupil {
    transition: none;
  }

  .idot-actor.tinting {
    transition-duration: 1ms;
  }

  .zzz.on {
    animation: none;
    opacity: 1;
  }

  .letter.wobble,
  .letter.flinch,
  .letter.dust,
  .letters.kern .letter,
  .letters.italic .letter,
  .letters.shudder .letter,
  .letters.panic .letter {
    animation: none;
  }
}
