/*
 * Klofy, the mascot. The parts (.kf-eye, .kf-grin, ...) are built by mascot.js
 * from the #face and #four symbols; this file decides how they move.
 *
 * Inside the SVG, px means one unit of the 96 × 96 drawing, so the same numbers
 * work for the 46 px logo and the 160 px hero. Big moves (jump, spin) are only
 * used on the hero; everything else gets the small hop.
 */

/* The hero mascot is a real button: it stays in place, only its artwork moves. */
.mascot-button{padding:0;border:0;background:transparent;cursor:pointer;border-radius:28%;-webkit-tap-highlight-color:transparent;touch-action:manipulation}
.mascot-button>svg{display:block;width:100%;height:100%;overflow:visible;animation:kf-enter .75s cubic-bezier(.3,.8,.4,1) .35s both}
.mascot-button:focus-visible{outline:3px solid var(--blue,#2e6bf0);outline-offset:5px}

.kf{overflow:visible}
.kf *{transform-box:fill-box}
.kf-tilt,.kf-eye,.kf-happy,.kf-wink,.kf-smile,.kf-grin,.kf-oh,.kf-block{transform-origin:center}
.kf-bob,.kf-hop{transform-origin:50% 100%}
.kf--symbol{cursor:pointer}

/* Expressions */
.kf-eye{transition:transform .09s ease,opacity .12s ease}
.kf-happy,.kf-wink,.kf-grin,.kf-oh{opacity:0;transition:opacity .12s ease,transform .22s cubic-bezier(.3,1.6,.5,1)}
.kf-smile{transition:opacity .12s ease,transform .22s cubic-bezier(.3,1.6,.5,1)}
.kf-grin{transform:scale(.55)}
.kf-oh{transform:scale(.35)}

.kf.is-blink .kf-eye{transform:scaleY(.1)}

.kf.is-excited .kf-eye{transform:scale(1.16)}
.kf.is-excited.is-blink .kf-eye{transform:scale(1.16,.1)}
.kf.is-excited .kf-smile{opacity:0;transform:scale(1.2)}
.kf.is-excited .kf-grin{opacity:1;transform:none}

.kf.is-joy .kf-eye{opacity:0;transform:scaleY(.2)}
.kf.is-joy .kf-happy{opacity:1}
.kf.is-joy .kf-smile{opacity:0;transform:scale(1.2)}
.kf.is-joy .kf-grin{opacity:1;transform:none}

.kf.is-wink .kf-eye-r{opacity:0;transform:scaleY(.2)}
.kf.is-wink .kf-wink{opacity:1}
.kf.is-wink .kf-smile{transform:scale(1.1)}

.kf.is-surprised .kf-eye{transform:scale(1.3)}
.kf.is-surprised.is-blink .kf-eye{transform:scale(1.3,.1)}
.kf.is-surprised .kf-smile{opacity:0;transform:scale(.5)}
.kf.is-surprised .kf-oh{opacity:1;transform:none}

/* Movement */
@keyframes kf-enter{
  0%{transform:translateY(26px) scale(.45) rotate(-14deg);opacity:0}
  55%{transform:translateY(-12px) scale(1.07) rotate(4deg);opacity:1}
  76%{transform:translateY(3px) scale(.97,1.02)}
  100%{transform:none}
}
@keyframes kf-bob{0%,100%{transform:none}50%{transform:translateY(-3px)}}
@keyframes kf-jump{
  0%{transform:none}
  14%{transform:translateY(3px) scale(1.12,.86)}
  40%{transform:translateY(-36px) scale(.93,1.09) rotate(-9deg)}
  58%{transform:translateY(-42px) rotate(7deg)}
  80%{transform:translateY(0) scale(1.14,.85)}
  91%{transform:translateY(-3px) scale(.97,1.03)}
  100%{transform:none}
}
@keyframes kf-spin{
  0%{transform:none}
  14%{transform:translateY(4px) scale(1.12,.86)}
  48%{transform:translateY(-50px) rotate(-200deg)}
  72%{transform:translateY(-18px) rotate(-360deg)}
  86%{transform:translateY(0) rotate(-360deg) scale(1.14,.85)}
  100%{transform:rotate(-360deg)}
}
@keyframes kf-hop{
  0%,100%{transform:none}
  20%{transform:translateY(1px) scale(1.07,.9)}
  50%{transform:translateY(-10px) scale(.96,1.05) rotate(-6deg)}
  78%{transform:translateY(0) scale(1.06,.94)}
}
@keyframes kf-drop{
  0%{transform:translateY(-72px) rotate(-30deg);opacity:0}
  30%{opacity:1}
  60%{transform:translateY(0) scale(1.16,.8)}
  78%{transform:translateY(-9px) scale(.95,1.06) rotate(5deg)}
  100%{transform:none;opacity:1}
}
@keyframes kf-block-pop{0%{transform:scale(.5);opacity:0}70%{transform:scale(1.08);opacity:1}100%{transform:none;opacity:1}}

.kf--hero .kf-bob{animation:kf-bob 3.4s ease-in-out infinite;animation-play-state:paused}
.kf--hero.is-onscreen .kf-bob{animation-play-state:running}
.kf.is-jump .kf-hop{animation:kf-jump .85s cubic-bezier(.3,.7,.4,1) both}
.kf.is-spin .kf-hop{transform-origin:center;animation:kf-spin 1.05s cubic-bezier(.3,.7,.4,1) both}
.kf.is-hop .kf-hop{animation:kf-hop .55s ease both}
.kf.is-waiting .kf-hop,.kf.is-waiting .kf-block{opacity:0}
.kf.is-drop .kf-hop{animation:kf-drop .8s cubic-bezier(.4,0,.3,1) .22s both}
.kf.is-drop .kf-block{animation:kf-block-pop .45s cubic-bezier(.3,1.4,.5,1) both}
.kf.is-drop .kf-block-1{animation-delay:.07s}
.kf.is-drop .kf-block-2{animation-delay:.14s}

/* Sparks from a jump, and the big sparkle in the hero joining in */
.kf-spark{position:absolute;z-index:6;width:var(--size);height:var(--size);margin:calc(var(--size) / -2) 0 0 calc(var(--size) / -2);pointer-events:none;opacity:0;animation:kf-spark .8s cubic-bezier(.2,.7,.3,1) both}
@keyframes kf-spark{
  0%{transform:translate(0,0) scale(.2);opacity:0}
  18%{opacity:1}
  70%{opacity:1}
  100%{transform:translate(var(--dx),var(--dy)) scale(1) rotate(var(--turn));opacity:0}
}
@keyframes kf-twinkle{0%,100%{transform:none}40%{transform:scale(1.25) rotate(45deg)}}
.spark.is-twinkle{animation:kf-twinkle .75s cubic-bezier(.3,1.4,.5,1)}

/* The dotted route in the hero slowly flows from the dead end to the better destination. */
@keyframes kf-route{to{stroke-dashoffset:-30}}
.hero-art .route path:first-child{animation:kf-route 2.4s linear infinite;animation-play-state:paused}
.hero-art.is-onscreen .route path:first-child{animation-play-state:running}

@media (prefers-reduced-motion:reduce){
  .mascot-button>svg,.kf .kf-bob,.kf .kf-hop,.kf .kf-block,.kf-spark,.spark.is-twinkle,.hero-art .route path:first-child{animation:none!important}
  .kf .kf-tilt,.kf .kf-look,.kf .kf-mouth{transform:none!important}
  .kf.is-waiting .kf-hop,.kf.is-waiting .kf-block{opacity:1}
}
