/*
  Движения кота.

  Рисунки сцен лежат в index.html, здесь только то, как их части двигаются.
  Сцена оживает, когда scenes.js ставит ей класс is-playing; без скрипта играет первая.
  Длина сюжета сцены задана в --loop, проценты в ключевых кадрах считаются от неё.
  data-hold в разметке на 0,6 с короче --loop: повтор сюжета приходится на момент,
  когда сцена уже погасла. Сюжет первой сцены начинается и кончается одной позой,
  поэтому без скрипта она повторяется без рывка.

  При включённом в системе «уменьшении движения» ничего не двигается: остаётся рисунок.
*/

.scene {
  container-type: inline-size;
  -webkit-user-select: none;
  user-select: none;
}

.scene-art {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/*
  Реплики кота. Текст лежит в index.html, в абзацах .say внутри сцены.
  Облачко привязано к сцене процентами, а размер букв не опускается ниже 12,5 px,
  чтобы реплика читалась и на телефоне. Хвостик облачка: say--left или say--right.
*/
.say {
  position: absolute;
  z-index: 2;
  margin: 0;
  padding: .42em .78em .5em;
  border: 1.5px solid var(--ink);
  border-radius: 1.05em;
  background: var(--light);
  color: var(--ink);
  font: 600 12.5px/1.16 var(--display);
  font-size: clamp(12.5px, 3.6cqw, 17px);
  letter-spacing: -.01em;
  white-space: nowrap;
  opacity: 0;
}

.say::after {
  content: "";
  position: absolute;
  top: calc(100% - 1px);
  width: 1em;
  height: .875em;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 14'%3E%3Cpath d='M1.5 0 L4 12.5 L14.5 0' fill='%23FFF7EC' stroke='%23291F24' stroke-width='1.5' stroke-linejoin='round'/%3E%3C/svg%3E") 0 0 / 100% 100% no-repeat;
}

.say--left         { transform-origin: 1.3em 125%; }
.say--left::after  { left: .9em; }
.say--right        { transform-origin: calc(100% - 1.3em) 125%; }
.say--right::after { right: .9em; transform: scaleX(-1); }

.scene-repair .say  { right: 61.7%; bottom: 70%; }
.scene-code .say    { left: 60.6%; bottom: 71.8%; }
.scene-inspect .say { left: 64.4%; bottom: 71%; }
.scene-push .say    { right: 57.2%; bottom: 73.8%; }
.scene-nap .say     { left: 22.1%; bottom: 66.5%; }

.scene-repair  { --loop: 8s;   --tail: repair-tail;  --side: 1; }
.scene-code    { --loop: 8s;   --tail: code-tail;    --side: -1; }
.scene-inspect { --loop: 7.6s; --tail: inspect-tail; --side: -1; }
.scene-push    { --loop: 8.6s; --tail: push-tail;    --side: 1; }
.scene-nap     { --loop: 8s;   --tail: nap-tail;     --side: 1; }

/* Хвост из трёх звеньев: каждое следующее гнётся сильнее и чуть позже предыдущего. */
.tail     { --amp: calc(2deg * var(--side)); }
.tail-mid { --amp: calc(4deg * var(--side)); }
.tail-tip { --amp: calc(9deg * var(--side)); }

.scene-nap .tail     { --amp: 1.2deg; }
.scene-nap .tail-tip { --amp: 13deg; }

@media (prefers-reduced-motion: no-preference) {
  .is-playing .tail,
  .is-playing .tail-mid,
  .is-playing .tail-tip { animation: var(--tail) var(--loop) ease-in-out infinite both; }
  .is-playing .tail-mid { animation-delay: .1s; }
  .is-playing .tail-tip { animation-delay: .2s; }

  .is-playing .body { animation: breathe 3.6s ease-in-out infinite; }

  /* 1. Ремонт */
  .scene-repair.is-playing .torso    { animation: repair-lean var(--loop) ease-in-out infinite; }
  .scene-repair.is-playing .head     { animation: repair-head var(--loop) ease-in-out infinite; }
  .scene-repair.is-playing .ear-l    { animation: repair-ear-l var(--loop) ease-out infinite; }
  .scene-repair.is-playing .ear-r    { animation: repair-ear-r var(--loop) ease-out infinite; }
  .scene-repair.is-playing .brows    { animation: repair-brows var(--loop) ease-out infinite; }
  .scene-repair.is-playing .eye      { animation: repair-blink var(--loop) ease-in-out infinite; }
  .scene-repair.is-playing .pupil    { animation: repair-pupil var(--loop) ease-in-out infinite; }
  .scene-repair.is-playing .whiskers { animation: repair-whiskers var(--loop) ease-in-out infinite; }
  .scene-repair.is-playing .wrench   { animation: repair-wrench var(--loop) infinite; }
  .scene-repair.is-playing .arm      { animation: repair-arm var(--loop) infinite; }
  .scene-repair.is-playing .bolt     { animation: repair-bolt var(--loop) infinite; }
  .scene-repair.is-playing .tile     { animation: repair-tile var(--loop) infinite; }
  .scene-repair.is-playing .sparks   { animation: repair-sparks var(--loop) ease-out infinite; }
  .scene-repair.is-playing .nut      { animation: repair-nut var(--loop) infinite; }

  /* 2. Код */
  .scene-code.is-playing .head        { animation: code-head var(--loop) ease-in-out infinite; }
  .scene-code.is-playing .ear-l       { animation: code-ear-l var(--loop) ease-out infinite; }
  .scene-code.is-playing .ear-r       { animation: code-ear-r var(--loop) ease-out infinite; }
  .scene-code.is-playing .eye         { animation: code-blink var(--loop) ease-in-out infinite; }
  .scene-code.is-playing .pupil       { animation: code-pupil var(--loop) ease-in-out infinite; }
  .scene-code.is-playing .whiskers    { animation: code-whiskers var(--loop) ease-in-out infinite; }
  .scene-code.is-playing .arm         { animation: code-tap var(--loop) ease-out infinite; }
  .scene-code.is-playing .cover       { opacity: 1; }
  .scene-code.is-playing .cover-line  { animation: code-type var(--loop) step-end infinite; }
  .scene-code.is-playing .cover-brace { animation: code-brace var(--loop) step-end infinite; }
  .scene-code.is-playing .line-number { animation: code-line-number var(--loop) step-end infinite; }
  .scene-code.is-playing .caret       { animation: code-caret var(--loop) step-end infinite; }
  .scene-code.is-playing .caret-blink { animation: caret-blink 1.06s step-end infinite; }

  /* 3. Проверка */
  .scene-inspect.is-playing .pointer       { animation: inspect-pointer var(--loop) ease-in-out infinite; }
  .scene-inspect.is-playing .pointer-press { animation: inspect-press var(--loop) ease-out infinite; }
  .scene-inspect.is-playing .button        { animation: inspect-button var(--loop) ease-out infinite; }
  .scene-inspect.is-playing .sparkle       { animation: inspect-sparkle var(--loop) ease-out infinite; }
  .scene-inspect.is-playing .rump          { animation: inspect-wiggle var(--loop) ease-in-out infinite; }
  .scene-inspect.is-playing .swat          { animation: inspect-swat var(--loop) infinite; }
  .scene-inspect.is-playing .head          { animation: inspect-head var(--loop) ease-in-out infinite; }
  .scene-inspect.is-playing .ear-l         { animation: inspect-ear-l var(--loop) ease-out infinite; }
  .scene-inspect.is-playing .ear-r         { animation: inspect-ear-r var(--loop) ease-out infinite; }

  /* 4. Гравитация */
  .scene-push.is-playing .arm      { animation: push-arm var(--loop) infinite; }
  .scene-push.is-playing .tile     { animation: push-tile var(--loop) infinite; }
  .scene-push.is-playing .whoosh   { animation: push-whoosh var(--loop) ease-out infinite; }
  .scene-push.is-playing .head     { animation: push-head var(--loop) ease-in-out infinite; }
  .scene-push.is-playing .ear      { animation: push-ears var(--loop) ease-out infinite both; }
  .scene-push.is-playing .ear-r    { animation-delay: .07s; }
  .scene-push.is-playing .eye      { animation: push-blink var(--loop) ease-in-out infinite; }
  .scene-push.is-playing .whiskers { animation: push-whiskers var(--loop) ease-in-out infinite; }

  /* 5. Сон */
  .scene-nap.is-playing .body       { animation: nap-breathe 4s ease-in-out infinite; }
  .scene-nap.is-playing .head       { animation: nap-head 4s ease-in-out infinite; }
  .scene-nap.is-playing .ear-l      { animation: nap-ear-l var(--loop) ease-out infinite; }
  .scene-nap.is-playing .ear-r      { animation: nap-ear-r var(--loop) ease-out infinite; }
  .scene-nap.is-playing .whiskers   { animation: nap-whiskers var(--loop) ease-in-out infinite; }
  .scene-nap.is-playing .peek       { animation: nap-peek var(--loop) ease-in-out infinite; }
  .scene-nap.is-playing .peek-pupil { animation: nap-peek-pupil var(--loop) ease-in-out infinite; }
  .scene-nap.is-playing .zzz path   { animation: nap-zzz var(--loop) ease-out infinite backwards; }
  .scene-nap.is-playing .zzz path:nth-child(2) { animation-delay: .7s; }
  .scene-nap.is-playing .zzz path:nth-child(3) { animation-delay: 1.4s; }
  .scene-nap.is-playing .sparkle    { animation: nap-twinkle 4s ease-in-out infinite; }

  /* Реплики: появляются быстро, исчезают ещё быстрее */
  .is-playing .say { animation: var(--loop) cubic-bezier(.16, 1, .3, 1) infinite; }
  .scene-repair.is-playing .say-1  { animation-name: say-repair-1; }
  .scene-repair.is-playing .say-2  { animation-name: say-repair-2; }
  .scene-code.is-playing .say-1    { animation-name: say-code-1; }
  .scene-inspect.is-playing .say-1 { animation-name: say-inspect-1; }
  .scene-inspect.is-playing .say-2 { animation-name: say-inspect-2; }
  .scene-push.is-playing .say-1    { animation-name: say-push-1; }
  .scene-push.is-playing .say-2    { animation-name: say-push-2; }
  .scene-nap.is-playing .say-1     { animation-name: say-nap-1; }
}

/* ---------- Реплики: когда появляется и когда исчезает каждое облачко ---------- */

@keyframes say-repair-1 {
  0%, 41%     { opacity: 0; transform: scale(.85); }
  43.5%, 51%  { opacity: 1; transform: scale(1); animation-timing-function: ease-in; }
  52.5%, 100% { opacity: 0; transform: scale(.94); }
}

@keyframes say-repair-2 {
  0%, 67%     { opacity: 0; transform: scale(.85); }
  69.5%, 87%  { opacity: 1; transform: scale(1); animation-timing-function: ease-in; }
  88.5%, 100% { opacity: 0; transform: scale(.94); }
}

@keyframes say-code-1 {
  0%, 65.5%   { opacity: 0; transform: scale(.85); }
  68%, 89%    { opacity: 1; transform: scale(1); animation-timing-function: ease-in; }
  90.5%, 100% { opacity: 0; transform: scale(.94); }
}

@keyframes say-inspect-1 {
  0%, 31%     { opacity: 0; transform: scale(.85); }
  33.5%, 46%  { opacity: 1; transform: scale(1); animation-timing-function: ease-in; }
  47.5%, 100% { opacity: 0; transform: scale(.94); }
}

@keyframes say-inspect-2 {
  0%, 70%     { opacity: 0; transform: scale(.85); }
  72.5%, 91%  { opacity: 1; transform: scale(1); animation-timing-function: ease-in; }
  92.5%, 100% { opacity: 0; transform: scale(.94); }
}

@keyframes say-push-1 {
  0%, 21.5%   { opacity: 0; transform: scale(.85); }
  24%, 32%    { opacity: 1; transform: scale(1); animation-timing-function: ease-in; }
  33.5%, 100% { opacity: 0; transform: scale(.94); }
}

@keyframes say-push-2 {
  0%, 60%     { opacity: 0; transform: scale(.85); }
  62.5%, 75%  { opacity: 1; transform: scale(1); animation-timing-function: ease-in; }
  76.5%, 100% { opacity: 0; transform: scale(.94); }
}

@keyframes say-nap-1 {
  0%, 55%     { opacity: 0; transform: scale(.85); }
  57.5%, 68.5% { opacity: 1; transform: scale(1); animation-timing-function: ease-in; }
  70%, 100%   { opacity: 0; transform: scale(.94); }
}

@keyframes breathe {
  0%, 100% { transform: scale(1); }
  45% { transform: scale(1.005, 1.016); }
}

/* ---------- 1. Ремонт: три нажима, блок встал ровно, кот отпустил, блок сорвался ---------- */

@keyframes repair-wrench {
  0%, 9%    { transform: rotate(0deg); animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
  12%, 14%  { transform: rotate(-7deg); animation-timing-function: ease-in-out; }
  20%, 22%  { transform: rotate(0deg); animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
  25%, 27%  { transform: rotate(-7deg); animation-timing-function: ease-in-out; }
  33%, 35%  { transform: rotate(0deg); animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
  38%, 52%  { transform: rotate(-7.5deg); animation-timing-function: ease-in-out; }
  57%       { transform: rotate(0deg); animation-timing-function: ease-out; }
  59.5%     { transform: rotate(3deg); animation-timing-function: ease-in-out; }
  64%, 100% { transform: rotate(0deg); }
}

/* Лапа держит ключ: плечо на месте, лапа тянется за рукояткой. Кадры те же, что у ключа. */
@keyframes repair-arm {
  0%, 9%    { transform: rotate(0deg) scaleX(1); animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
  12%, 14%  { transform: rotate(8.4deg) scaleX(1.124); animation-timing-function: ease-in-out; }
  20%, 22%  { transform: rotate(0deg) scaleX(1); animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
  25%, 27%  { transform: rotate(8.4deg) scaleX(1.124); animation-timing-function: ease-in-out; }
  33%, 35%  { transform: rotate(0deg) scaleX(1); animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
  38%, 52%  { transform: rotate(8.9deg) scaleX(1.134); animation-timing-function: ease-in-out; }
  57%       { transform: rotate(0deg) scaleX(1); animation-timing-function: ease-out; }
  59.5%     { transform: rotate(-4.3deg) scaleX(.959); animation-timing-function: ease-in-out; }
  64%, 100% { transform: rotate(0deg) scaleX(1); }
}

@keyframes repair-bolt {
  0%, 9%      { transform: rotate(0deg); animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
  12%, 22%    { transform: rotate(-7deg); animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
  25%, 35%    { transform: rotate(-14deg); animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
  38%, 56%    { transform: rotate(-21deg); animation-timing-function: ease-in; }
  59.5%, 100% { transform: rotate(0deg); }
}

@keyframes repair-tile {
  0%, 9%    { transform: rotate(0deg); animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
  12%, 22%  { transform: rotate(-3deg); animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
  25%, 35%  { transform: rotate(-6deg); animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
  38%       { transform: rotate(-8.8deg); animation-timing-function: ease-in-out; }
  40%, 56%  { transform: rotate(-8deg); animation-timing-function: cubic-bezier(.5, 0, .9, .5); }
  59.5%     { transform: rotate(6.5deg); animation-timing-function: ease-in-out; }
  63%       { transform: rotate(-3deg); animation-timing-function: ease-in-out; }
  66.5%     { transform: rotate(2.4deg); animation-timing-function: ease-in-out; }
  69.5%     { transform: rotate(-1deg); animation-timing-function: ease-in-out; }
  73%, 100% { transform: rotate(0deg); }
}

@keyframes repair-sparks {
  0%, 10.5%, 23.5%, 36.5%, 57% { opacity: 0; transform: scale(.7); }
  12%, 25%, 38% { opacity: .9; transform: scale(1); }
  15%, 28%, 41% { opacity: 0; transform: scale(1.12); }
  59.5% { opacity: 1; transform: scale(1.1); }
  66%, 100% { opacity: 0; transform: scale(1.3); }
}

@keyframes repair-nut {
  0%, 58.5%, 63.5%, 65.5%, 100% { transform: translateY(0) rotate(0deg); }
  61% { transform: translateY(-7px) rotate(25deg); animation-timing-function: ease-in; }
  64.5% { transform: translateY(-1.5px) rotate(0deg); }
}

@keyframes repair-lean {
  0%, 9%, 20%, 22%, 33%, 35%, 57%, 66%, 100% { transform: rotate(0deg); }
  12%, 14%, 25%, 27% { transform: rotate(.8deg); }
  38%, 52% { transform: rotate(.9deg); }
  60% { transform: rotate(-.9deg); }
}

@keyframes repair-head {
  0%, 9%, 19%, 22%, 32%, 35%, 93%, 100% { transform: rotate(0deg); }
  12.5%, 25.5% { transform: rotate(1.6deg); }
  38.5% { transform: rotate(1.8deg); }
  43%, 53% { transform: rotate(-2deg); }
  56.5% { transform: rotate(-1deg); }
  59.5% { transform: rotate(-4.6deg); }
  64% { transform: rotate(-2.2deg); }
  70%, 86% { transform: rotate(-1.2deg); }
}

@keyframes repair-ear-l {
  0%, 56.5%, 73%, 80%, 84%, 100% { transform: rotate(0deg); }
  58.5%, 66% { transform: rotate(-14deg); }
  71% { transform: rotate(2deg); }
  81% { transform: rotate(-9deg); }
  82.5% { transform: rotate(2deg); }
}

@keyframes repair-ear-r {
  0%, 28.5%, 32.5%, 56.5%, 73%, 100% { transform: rotate(0deg); }
  29.5% { transform: rotate(11deg); }
  31% { transform: rotate(-3deg); }
  58.5%, 66% { transform: rotate(16deg); }
  71% { transform: rotate(-2deg); }
}

@keyframes repair-brows {
  0%, 56.5%, 67%, 100% { transform: translateY(0); }
  58.5%, 63% { transform: translateY(-1.8px); }
}

@keyframes repair-blink {
  0%, 4%, 6.6%, 43%, 49.5%, 56.5%, 66%, 76%, 80%, 100% { transform: scaleY(1); }
  5.2%, 45.5%, 47%, 77.5%, 78.5% { transform: scaleY(.1); }
  58.5%, 63% { transform: scaleY(1.45); }
}

@keyframes repair-pupil {
  0%, 56%, 90%, 100% { transform: translate(0, 0); }
  58.5%, 63% { transform: translate(1px, 0); }
  67%, 86% { transform: translate(-3.6px, .4px); }
}

@keyframes repair-whiskers {
  0%, 29%, 33%, 57%, 64%, 100% { transform: rotate(0deg); }
  30% { transform: rotate(-4deg); }
  31.5% { transform: rotate(2deg); }
  59% { transform: rotate(-6deg); }
  61% { transform: rotate(3deg); }
}

@keyframes repair-tail {
  0%, 6%, 88%, 100% { transform: rotate(0deg); }
  16% { transform: rotate(calc(var(--amp) * .6)); }
  26% { transform: rotate(calc(var(--amp) * -.3)); }
  36% { transform: rotate(calc(var(--amp) * .25)); }
  45%, 53% { transform: rotate(calc(var(--amp) * 1)); }
  57% { transform: rotate(calc(var(--amp) * .5)); }
  60% { transform: rotate(calc(var(--amp) * -1.4)); }
  63.5% { transform: rotate(calc(var(--amp) * 1.2)); }
  67% { transform: rotate(calc(var(--amp) * -.9)); }
  70.5% { transform: rotate(calc(var(--amp) * .6)); }
  76% { transform: rotate(calc(var(--amp) * -.2)); }
}

/* ---------- 2. Код: три очереди по четыре буквы, ввод, скобка, довольная пауза ---------- */

@keyframes code-tap {
  0%, 8%, 10.5%, 13%, 15.5%, 18%, 23%, 25.5%, 28%, 30.5%, 33%, 37%, 39.5%, 42%, 44.5%, 47.5%, 52.5%, 56.5%, 58%, 60.5%, 63.5%, 100% { transform: rotate(0deg); }
  9%, 11.5%, 14%, 16.5%, 24%, 26.5%, 29%, 31.5%, 38%, 40.5%, 43%, 45.5%, 59%, 61.5% { transform: rotate(-3deg); }
  54% { transform: rotate(-5deg); }
}

@keyframes code-type {
  0%     { transform: scaleX(1); }
  9%     { transform: scaleX(.9167); }
  11.5%  { transform: scaleX(.8333); }
  14%    { transform: scaleX(.75); }
  16.5%  { transform: scaleX(.6667); }
  24%    { transform: scaleX(.5833); }
  26.5%  { transform: scaleX(.5); }
  29%    { transform: scaleX(.4167); }
  31.5%  { transform: scaleX(.3333); }
  38%    { transform: scaleX(.25); }
  40.5%  { transform: scaleX(.1667); }
  43%    { transform: scaleX(.0833); }
  45.5%, 100% { transform: scaleX(0); }
}

@keyframes code-brace {
  0%   { transform: scaleX(1); }
  59%  { transform: scaleX(.5); }
  61.5%, 100% { transform: scaleX(0); }
}

@keyframes code-line-number {
  0% { opacity: 0; }
  54%, 100% { opacity: 1; }
}

@keyframes code-caret {
  0%     { transform: translate(-5px, -23px); }
  9%     { transform: translate(4.35px, -23px); }
  11.5%  { transform: translate(13.7px, -23px); }
  14%    { transform: translate(23.05px, -23px); }
  16.5%  { transform: translate(32.4px, -23px); }
  24%    { transform: translate(41.75px, -23px); }
  26.5%  { transform: translate(51.1px, -23px); }
  29%    { transform: translate(60.45px, -23px); }
  31.5%  { transform: translate(69.8px, -23px); }
  38%    { transform: translate(79.15px, -23px); }
  40.5%  { transform: translate(88.5px, -23px); }
  43%    { transform: translate(97.85px, -23px); }
  45.5%  { transform: translate(107.2px, -23px); }
  54%    { transform: translate(-23px, 0); }
  59%    { transform: translate(-13.65px, 0); }
  61.5%, 100% { transform: translate(0, 0); }
}

@keyframes caret-blink {
  0% { opacity: 1; }
  55% { opacity: .15; }
}

@keyframes code-head {
  0%, 46%, 50.5%, 58%, 62%, 95%, 100% { transform: rotate(0deg); }
  48% { transform: rotate(-.8deg); }
  54.5% { transform: rotate(-1.6deg); }
  68%, 88% { transform: rotate(2.6deg); }
}

@keyframes code-ear-l {
  0%, 18.5%, 22.5%, 34%, 37.5%, 100% { transform: rotate(0deg); }
  19.5% { transform: rotate(-10deg); }
  21% { transform: rotate(3deg); }
  35% { transform: rotate(-8deg); }
  36.2% { transform: rotate(2deg); }
}

@keyframes code-ear-r {
  0%, 54%, 58%, 81%, 85%, 100% { transform: rotate(0deg); }
  55% { transform: rotate(7deg); }
  56.5% { transform: rotate(-2deg); }
  82% { transform: rotate(10deg); }
  83.5% { transform: rotate(-3deg); }
}

@keyframes code-blink {
  0%, 5%, 7.6%, 33.5%, 36%, 67%, 75%, 89.5%, 92%, 100% { transform: scaleY(1); }
  6.2%, 34.7%, 69.5%, 72.5%, 90.7% { transform: scaleY(.1); }
}

@keyframes code-pupil {
  0%, 17.5%, 24%, 46%, 52.5%, 74%, 92%, 100% { transform: translate(0, 0); }
  19.5%, 22% { transform: translate(.6px, -1.2px); }
  49.5% { transform: translate(3px, 0); }
  77%, 88% { transform: translate(5px, .3px); }
}

@keyframes code-whiskers {
  0%, 19.5%, 23%, 54.5%, 58%, 100% { transform: rotate(0deg); }
  20.5% { transform: rotate(4deg); }
  21.8% { transform: rotate(-2deg); }
  55.5% { transform: rotate(-4deg); }
  56.8% { transform: rotate(2deg); }
}

@keyframes code-tail {
  0%, 12%, 50%, 56%, 100% { transform: rotate(0deg); }
  20% { transform: rotate(calc(var(--amp) * .5)); }
  30% { transform: rotate(calc(var(--amp) * -.3)); }
  40% { transform: rotate(calc(var(--amp) * .4)); }
  60% { transform: rotate(calc(var(--amp) * .8)); }
  63% { transform: rotate(calc(var(--amp) * .2)); }
  70%, 82% { transform: rotate(calc(var(--amp) * 1)); }
  85% { transform: rotate(calc(var(--amp) * .5)); }
  88% { transform: rotate(calc(var(--amp) * 1.1)); }
  93% { transform: rotate(calc(var(--amp) * .2)); }
}

/* ---------- 3. Проверка: курсор проходит за головой, дразнит, уворачивается и нажимает кнопку ---------- */

@keyframes inspect-pointer {
  0%, 6%     { transform: translate(194px, -25px); }
  14%, 18%   { transform: translate(204px, -5px); }
  30%        { transform: translate(34px, -35px); }
  33%        { transform: translate(41px, -28px); }
  36%        { transform: translate(30px, -31px); }
  42%, 48.5% { transform: translate(22px, -22px); animation-timing-function: cubic-bezier(.2, .8, .2, 1); }
  51.5%, 55% { transform: translate(-14px, -32px); animation-timing-function: ease-in-out; }
  63%, 100%  { transform: translate(0, 0); }
}

@keyframes inspect-press {
  0%, 64.5%, 68%, 100% { transform: scale(1); }
  65.8% { transform: scale(.8); }
}

@keyframes inspect-button {
  0%, 64.8%, 68.5%, 100% { transform: scale(1); }
  66% { transform: scale(.93); }
}

@keyframes inspect-sparkle {
  0%, 65.5% { opacity: 0; transform: scale(.2) rotate(-30deg); }
  68.5% { opacity: 1; transform: scale(1.25) rotate(8deg); }
  72%, 100% { opacity: 1; transform: scale(1) rotate(0deg); }
}

@keyframes inspect-wiggle {
  0%, 38%, 48%, 100% { transform: rotate(0deg); }
  39.5%, 42.5%, 45.5% { transform: rotate(1.1deg); }
  41%, 44%, 47% { transform: rotate(-1.1deg); }
}

@keyframes inspect-swat {
  0%, 47.5%   { opacity: 0; transform: scale(.25); }
  48%         { opacity: 1; transform: scale(.3); animation-timing-function: cubic-bezier(.2, .9, .2, 1); }
  50.5%, 53%  { opacity: 1; transform: scale(1); animation-timing-function: ease-in; }
  57%         { opacity: 1; transform: scale(.25); }
  57.5%, 100% { opacity: 0; transform: scale(.25); }
}

@keyframes inspect-head {
  0%, 6%     { transform: translate(3px, 0) rotate(5deg); }
  14%, 20%   { transform: translate(3.5px, 0) rotate(7deg); }
  27%        { transform: translate(0, 0) rotate(0deg); }
  31%        { transform: translate(-3.5px, 0) rotate(-8deg); }
  34.5%      { transform: translate(-3px, 0) rotate(-6deg); }
  42%, 47.5% { transform: translate(-3px, .5px) rotate(-7deg); animation-timing-function: cubic-bezier(.2, .9, .2, 1); }
  50.5%      { transform: translate(-6px, 2px) rotate(-11deg); animation-timing-function: ease-in-out; }
  55%, 58%   { transform: translate(-4.5px, 0) rotate(-10deg); }
  64%        { transform: translate(-3.5px, 1.5px) rotate(-8deg); }
  66.5%      { transform: translate(-3.5px, 0) rotate(-6.5deg); }
  72%, 100%  { transform: translate(-3px, .5px) rotate(-6deg); }
}

@keyframes inspect-ear-l {
  0%, 20.5%, 24.5%, 66%, 70%, 100% { transform: rotate(0deg); }
  21.5% { transform: rotate(-10deg); }
  23% { transform: rotate(3deg); }
  67% { transform: rotate(-9deg); }
  68.5% { transform: rotate(3deg); }
}

@keyframes inspect-ear-r {
  0%, 9%, 13%, 22.5%, 26.5%, 100% { transform: rotate(0deg); }
  10% { transform: rotate(9deg); }
  11.5% { transform: rotate(-3deg); }
  23.5% { transform: rotate(9deg); }
  25% { transform: rotate(-3deg); }
}

@keyframes inspect-tail {
  0%, 8%, 22%, 62%, 80%, 100% { transform: rotate(0deg); }
  16% { transform: rotate(calc(var(--amp) * .5)); }
  31% { transform: rotate(calc(var(--amp) * 1)); }
  33.5% { transform: rotate(calc(var(--amp) * -.4)); }
  36% { transform: rotate(calc(var(--amp) * .9)); }
  38.5% { transform: rotate(calc(var(--amp) * -.3)); }
  41% { transform: rotate(calc(var(--amp) * .8)); }
  43.5% { transform: rotate(calc(var(--amp) * -.5)); }
  46% { transform: rotate(calc(var(--amp) * 1)); }
  48% { transform: rotate(calc(var(--amp) * -.2)); }
  50.5% { transform: rotate(calc(var(--amp) * 1.3)); }
  54% { transform: rotate(calc(var(--amp) * .2)); }
  58% { transform: rotate(calc(var(--amp) * .6)); }
  67% { transform: rotate(calc(var(--amp) * .7)); }
  70% { transform: rotate(calc(var(--amp) * -.2)); }
  74% { transform: rotate(calc(var(--amp) * .3)); }
}

/* ---------- 4. Гравитация: пробный тычок, взгляд на зрителя, толчок, падение, новый блок ---------- */

@keyframes push-arm {
  0%, 6%    { transform: translate(-13px, 0); }
  9%        { transform: translate(-11px, 0); animation-timing-function: cubic-bezier(.3, .8, .3, 1); }
  11.5%     { transform: translate(-5px, 0); animation-timing-function: ease-in-out; }
  16%, 31%  { transform: translate(-13px, 0); }
  33%       { transform: translate(-15px, 0); animation-timing-function: cubic-bezier(.3, .8, .3, 1); }
  37%, 55%  { transform: translate(0, 0); animation-timing-function: ease-in-out; }
  64%, 100% { transform: translate(-13px, 0); }
}

/* Блок стоит на правом нижнем углу, вокруг него и опрокидывается; дальше падает и гаснет.
   Новый блок опускается сверху и встаёт на то же место. */
@keyframes push-tile {
  0%, 9%      { transform: translate(0, 0) rotate(-18deg); opacity: 1; animation-timing-function: cubic-bezier(.3, .8, .3, 1); }
  11.5%       { transform: translate(0, 0) rotate(-9deg); opacity: 1; animation-timing-function: ease-in; }
  15%         { transform: translate(0, 0) rotate(-18deg); opacity: 1; animation-timing-function: ease-out; }
  16.5%       { transform: translate(0, 0) rotate(-15.5deg); opacity: 1; animation-timing-function: ease-in; }
  18%         { transform: translate(0, 0) rotate(-18deg); opacity: 1; }
  19%         { transform: translate(0, 0) rotate(-17deg); opacity: 1; }
  20%, 33.5%  { transform: translate(0, 0) rotate(-18deg); opacity: 1; animation-timing-function: cubic-bezier(.3, .8, .3, 1); }
  37%         { transform: translate(0, 0) rotate(0deg); opacity: 1; animation-timing-function: cubic-bezier(.55, 0, .9, .5); }
  42.5%       { transform: translate(0, 0) rotate(52deg); opacity: 1; animation-timing-function: cubic-bezier(.4, .1, .9, .7); }
  47%         { transform: translate(-16px, 10px) rotate(98deg); opacity: 1; animation-timing-function: linear; }
  51%, 74.8%  { transform: translate(-17px, 37px) rotate(140deg); opacity: 0; animation-timing-function: step-end; }
  75%         { transform: translate(0, -200px) rotate(-18deg); opacity: 0; animation-timing-function: step-end; }
  75.4%       { transform: translate(0, -200px) rotate(-18deg); opacity: 1; animation-timing-function: cubic-bezier(.5, 0, 1, .6); }
  81%         { transform: translate(0, 0) rotate(-18deg); opacity: 1; animation-timing-function: ease-out; }
  83%         { transform: translate(0, -7px) rotate(-18deg); opacity: 1; animation-timing-function: ease-in; }
  85%         { transform: translate(0, 0) rotate(-18deg); opacity: 1; animation-timing-function: ease-out; }
  86%         { transform: translate(0, -2px) rotate(-18deg); opacity: 1; animation-timing-function: ease-in; }
  87%, 100%   { transform: translate(0, 0) rotate(-18deg); opacity: 1; }
}

@keyframes push-whoosh {
  0%, 35.5%, 44%, 100% { opacity: 0; }
  37.5%, 40% { opacity: 1; }
}

@keyframes push-head {
  0%, 9%, 17%, 91%, 100% { transform: rotate(0deg); }
  11.5% { transform: rotate(1.5deg); }
  22%, 30% { transform: rotate(-2.5deg); }
  33% { transform: rotate(-1deg); }
  37% { transform: rotate(2deg); }
  45%, 56% { transform: rotate(6deg); }
  64%, 74% { transform: rotate(-2deg); }
  78% { transform: rotate(-6deg); }
  82% { transform: rotate(1.5deg); }
  86% { transform: rotate(2.5deg); }
}

@keyframes push-ears {
  0%, 35%, 60%, 80.5%, 84.5%, 100% { transform: rotate(0deg); }
  38%, 54% { transform: rotate(6deg); }
  81.5% { transform: rotate(-9deg); }
  83% { transform: rotate(3deg); }
}

@keyframes push-blink {
  0%, 2%, 4.6%, 24%, 29%, 37%, 56%, 67%, 74%, 100% { transform: scale(1); }
  3.2%, 25.8%, 27%, 69%, 71.5% { transform: scale(1, .12); }
  40%, 52% { transform: scale(1.12, 1.18); }
}

@keyframes push-whiskers {
  0%, 11%, 14.5%, 36.5%, 41%, 100% { transform: rotate(0deg); }
  12% { transform: rotate(-5deg); }
  13.2% { transform: rotate(2deg); }
  38% { transform: rotate(-6deg); }
  39.5% { transform: rotate(3deg); }
}

@keyframes push-tail {
  0%, 8%, 50%, 94%, 100% { transform: rotate(0deg); }
  14% { transform: rotate(calc(var(--amp) * .5)); }
  20% { transform: rotate(calc(var(--amp) * -.2)); }
  24%, 30% { transform: rotate(calc(var(--amp) * .3)); }
  33% { transform: rotate(calc(var(--amp) * -.6)); }
  38% { transform: rotate(calc(var(--amp) * 1.2)); }
  42% { transform: rotate(calc(var(--amp) * -.4)); }
  46% { transform: rotate(calc(var(--amp) * .9)); }
  58% { transform: rotate(calc(var(--amp) * .6)); }
  66%, 72% { transform: rotate(calc(var(--amp) * 1)); }
  77% { transform: rotate(calc(var(--amp) * .2)); }
  82% { transform: rotate(calc(var(--amp) * 1.2)); }
  85% { transform: rotate(calc(var(--amp) * -.3)); }
  89% { transform: rotate(calc(var(--amp) * .3)); }
}

/* ---------- 5. Сон: ровное дыхание, ухо дёргается, один глаз приоткрылся и закрылся ---------- */

@keyframes nap-breathe {
  0%, 80%, 100% { transform: scale(1); }
  40% { transform: scale(1.012, 1.045); }
}

@keyframes nap-head {
  0%, 80%, 100% { transform: translateY(0) rotate(0deg); }
  40% { transform: translateY(-.7px) rotate(.5deg); }
}

@keyframes nap-ear-l {
  0%, 77%, 81%, 100% { transform: rotate(0deg); }
  78% { transform: rotate(-9deg); }
  79.5% { transform: rotate(2deg); }
}

@keyframes nap-ear-r {
  0%, 21%, 27.5%, 49%, 73%, 100% { transform: rotate(0deg); }
  22% { transform: rotate(9deg); }
  23.5% { transform: rotate(-2deg); }
  25% { transform: rotate(7deg); }
  26.5% { transform: rotate(-1deg); }
  50.5%, 68% { transform: rotate(7deg); }
}

@keyframes nap-whiskers {
  0%, 29%, 33%, 100% { transform: rotate(0deg); }
  30% { transform: rotate(5deg); }
  31.5% { transform: rotate(-2deg); }
}

@keyframes nap-peek {
  0%, 52.5%    { opacity: 0; transform: scaleY(0); }
  52.7%        { opacity: 1; transform: scaleY(0); }
  55.5%, 67.5% { opacity: 1; transform: scaleY(1); }
  70%          { opacity: 1; transform: scaleY(0); }
  70.2%, 100%  { opacity: 0; transform: scaleY(0); }
}

@keyframes nap-peek-pupil {
  0%, 57% { transform: translateX(-1.5px); }
  59.5%, 63% { transform: translateX(1.8px); }
  65.5%, 100% { transform: translateX(-.5px); }
}

/* Буквы сна поднимаются дважды за сцену; пока глаз открыт, их нет. */
@keyframes nap-zzz {
  0%         { opacity: 0; transform: translate(4px, 6px) scale(.7); }
  7%, 24%    { opacity: 1; }
  36%        { opacity: 0; transform: translate(-5px, -9px) scale(1.05); animation-timing-function: step-end; }
  36.1%, 72% { opacity: 0; transform: translate(4px, 6px) scale(.7); }
  79%        { opacity: 1; }
  100%       { opacity: 1; transform: translate(-3px, -5.5px) scale(.97); }
}

@keyframes nap-twinkle {
  0%, 100% { opacity: 1; transform: scale(1) rotate(0deg); }
  45% { opacity: .55; transform: scale(.55) rotate(25deg); }
  60% { opacity: 1; transform: scale(1.12) rotate(0deg); }
}

@keyframes nap-tail {
  0%, 20%, 36%, 68%, 84%, 100% { transform: rotate(0deg); }
  28% { transform: rotate(calc(var(--amp) * .5)); }
  73% { transform: rotate(calc(var(--amp) * 1)); }
  76% { transform: rotate(calc(var(--amp) * -.3)); }
  79% { transform: rotate(calc(var(--amp) * .8)); }
  92% { transform: rotate(calc(var(--amp) * .3)); }
}
