/* Illustrated characters — cut-outs from design/heroes, animated slowly.
   Contract:
   <img class="char" data-anim="float|wave|walk-in|peek|bob" data-side="left|right"
        src="/characters/x.png" alt="" width=".." height="..">
   Parent section must be position: relative. Optional: class="char-keep" (stays on
   phones, smaller), data-size="s" (smaller) or "wide" (landscape figures like
   guide.png, speaker.png). Sized by HEIGHT so tall-slim and wide cut-outs read
   at the same scale; max-width keeps wide ones off the text column.
   data-flip (mirror horizontally), data-lift="40" (px above the section bottom). */

.char {
  position: absolute;
  bottom: 0;
  z-index: 1;
  height: clamp(150px, 18vw, 270px);
  width: auto;
  max-width: 38vw;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
  transform-origin: 50% 100%;
  filter: drop-shadow(0 6px 10px rgba(46, 24, 10, .16));
  animation-duration: 7s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}
.char[data-side="left"]  { left: clamp(4px, 2vw, 32px); }
.char[data-side="right"] { right: clamp(4px, 2vw, 32px); }
.char[data-size="s"]    { height: clamp(110px, 12vw, 180px); }
.char[data-size="wide"] { height: clamp(100px, 12vw, 170px); }
.char[data-flip] { scale: -1 1; }

/* the section clips sideways so walk-in never creates horizontal scroll;
   `clip` (not hidden) keeps the section from becoming a scroll container */
.has-char { overflow-x: clip; }
.has-char-peek { overflow-y: clip; }

/* idle loops — independent translate / rotate properties so they compose
   with walk-in and peek transitions */
@keyframes char-float { from { translate: 0 0; } to { translate: 0 -12px; } }
@keyframes char-bob   { from { rotate: -1.4deg; } to { rotate: 1.4deg; } }
@keyframes char-wave  { from { rotate: -3deg; } to { rotate: 2.5deg; } }

.char[data-anim="float"] { animation-name: char-float; animation-duration: 7s; }
.char[data-anim="bob"]   { animation-name: char-bob;   animation-duration: 5.5s; }
.char[data-anim="wave"]  { animation-name: char-wave;  animation-duration: 4.5s; }

/* entrances: only hidden once characters.js is running (html.char-js) */
.char-js .char[data-anim="walk-in"] {
  opacity: 0;
  transition: translate 2.4s cubic-bezier(.22, .8, .3, 1), opacity 1.6s ease;
}
.char-js .char[data-anim="walk-in"][data-side="left"]  { translate: -120% 0; }
.char-js .char[data-anim="walk-in"][data-side="right"] { translate: 120% 0; }
.char-js .char[data-anim="walk-in"].in {
  opacity: 1;
  translate: 0 0;
  animation-name: char-bob;
  animation-duration: 5.5s;
  animation-delay: 2.4s;
}

.char-js .char[data-anim="peek"] {
  translate: 0 100%;
  transition: translate 2.6s cubic-bezier(.22, .8, .3, 1);
}
.char-js .char[data-anim="peek"].in {
  translate: 0 0;
  animation-name: char-bob;
  animation-duration: 6.5s;
  animation-delay: 2.6s;
}

/* off-screen loops are paused by characters.js */
.char.char-paused { animation-play-state: paused; }

@media (max-width: 599px) {
  .char { display: none; }
  .char.char-keep { display: block; height: clamp(96px, 30vw, 150px); max-width: 46vw; }
  .char.char-keep[data-size="wide"] { height: clamp(64px, 19vw, 96px); }
}

@media (prefers-reduced-motion: reduce) {
  .char,
  .char-js .char[data-anim="walk-in"],
  .char-js .char[data-anim="peek"] {
    animation: none !important;
    transition: none !important;
    translate: none !important;
    rotate: none !important;
    opacity: 1 !important;
  }
}
