@keyframes grow-x {
    from {
        transform: scaleX(0);
    }
    to {
        transform: scaleX(1);
    }
}

@keyframes shrink-x {
    from {
        transform: scaleX(1);
    }
    to {
        transform: scaleX(0);
    }
}

@keyframes skew-x-shaking {
    0% { transform: skewX(-15deg); }
    5% { transform: skewX(15deg); }
    10% { transform: skewX(-15deg); }
    15% { transform: skewX(15deg); }
    20% { transform: skewX(0deg); }
    100% { transform: skewX(0deg); }
}

@keyframes punch-left {
    0% { transform: translateX(0px); }
    5% { transform: translateX(-20px); }
    10% { transform: translateX(-40px); }
    15% { transform: translateX(-60px); }
    20% { transform: translateX(-80px); }
    100% { transform: translateX(0px); }
}

@keyframes punch-right {
    0% { transform: translateX(0px); }
    5% { transform: translateX(20px); }
    10% { transform: translateX(40px); }
    15% { transform: translateX(60px); }
    20% { transform: translateX(80px); }
    100% { transform: translateX(0px); }
}

/* A move that never reaches the opponent — a self-buff, a heal, a status.
   The user stays put and gathers itself: a crouch, then a rise that peaks
   on a flash of light, rather than the lunge an attack gets. */
@keyframes gather-up {
    0%   { transform: translateY(0) scale(1, 1);          filter: brightness(1); }
    18%  { transform: translateY(5px) scale(1.08, 0.9);   filter: brightness(1); }
    50%  { transform: translateY(-12px) scale(0.94, 1.1); filter: brightness(1.8); }
    72%  { transform: translateY(-3px) scale(1.02, 0.98); filter: brightness(1.25); }
    100% { transform: translateY(0) scale(1, 1);          filter: brightness(1); }
}

@keyframes jump-up-twice {
    0% { transform: translateY(0px); }
    15% { transform: translateY(-8px); }
    20% { transform: translateY(-16px); }
    35% { transform: translateY(-8px); }
    50% { transform: translateY(0px); }
    65% { transform: translateY(-8px); }
    75% { transform: translateY(-16px); }
    85% { transform: translateY(-8px); }
    100% { transform: translateY(0px); }
}

/* Two-turn moves. Dig/Dive drop through the floor and burst back out of it;
   Fly climbs out of frame and stoops back in. Each pair is the reverse of the
   other so the pokemon leaves and returns the same way. */
@keyframes burrow-down {
    0%   { transform: translateY(0) scaleY(1);      opacity: 1; }
    35%  { transform: translateY(-6px) scaleY(1.1); opacity: 1; }
    100% { transform: translateY(28px) scaleY(0.4); opacity: 0; }
}

@keyframes burst-from-below {
    0%   { transform: translateY(28px) scaleY(0.4); opacity: 0; }
    60%  { transform: translateY(-10px) scaleY(1.1); opacity: 1; }
    100% { transform: translateY(0) scaleY(1);      opacity: 1; }
}

@keyframes soar-up {
    0%   { transform: translateY(0);      opacity: 1; }
    25%  { transform: translateY(8px);    opacity: 1; }
    100% { transform: translateY(-110px); opacity: 0; }
}

@keyframes stoop-from-above {
    0%   { transform: translateY(-110px); opacity: 0; }
    70%  { transform: translateY(6px);    opacity: 1; }
    100% { transform: translateY(0);      opacity: 1; }
}

@keyframes fade-out-top {
    0% { opacity: 1; transform: translateY(-40px); }
    100% { opacity: 0; transform: translateY(-80px); }
}

/*.character-card {*/
/*    view-transition-name: character-card;*/
/*}*/

/*::view-transition-old(character-card) {*/
/*    animation: 0.25s linear both shrink-x;*/
/*}*/

/*::view-transition-new(character-card) {*/
/*    animation: 0.25s 0.25s linear both grow-x;*/
/*}*/

/*::view-transition-old(character-card) {*/
/*    animation: 0.25s linear both shrink-x;*/
/*}*/

/*::view-transition-new(character-card) {*/
/*    animation: 0.25s 0.25s linear both grow-x;*/
/*}*/

.character-card-hit {
    animation: 0.5s linear both skew-x-shaking;
}

.character-card-attack-right {
    animation: 0.5s linear both punch-right;
}

.character-card-attack-left {
    animation: 0.5s linear both punch-left;
}

.character-card-focus {
    animation: 0.7s ease-out both gather-up;
}

.character-card-vanish-down {
    animation: 0.6s ease-in both burrow-down;
}

.character-card-reappear-down {
    animation: 0.5s ease-out both burst-from-below;
}

.character-card-vanish-up {
    animation: 0.7s ease-in both soar-up;
}

.character-card-reappear-up {
    animation: 0.6s ease-out both stoop-from-above;
}

/* Off the field between the two halves of the move: no animation left to
   run, just gone. Hidden rather than removed so the battle-anim layer keeps
   its anchor point for anything that can still reach it (Earthquake). */
.combat-sprite--off-field {
    opacity: 0;
}

.damage-number {
  animation: 2s linear both fade-out-top;
  text-align: center;
  width: 48px;
  position: absolute;
}

.character-icon-moving {
    animation: 0.4s linear both jump-up-twice;
}

/* mount point for the battle-anim controller; the sprites themselves are
   drawn into a .battle-anim-layer appended to the .battlefield */
.battle-anim-overlay {
    display: none;
}

.battle-anim-layer {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 30;
}

.battle-anim-sprite {
    position: absolute;
    left: 0;
    top: 0;
    width: 96px;
    height: 96px;
    background-repeat: no-repeat;
    image-rendering: pixelated;
    will-change: transform, opacity;
}

/*.health-bar .progress-content {*/
/*    transition: width 2s ease;*/
/*    view-transition-name: health-bar;*/
/*}*/

::view-transition-old(*),::view-transition-new(*) {
    /*mix-blend-mode: normal;*/
    height: 100%; /* WTF why?! This took me forever to figure out! */
}

/*::view-transition-group(*){*/
/*    animation-duration: 0.05s;*/
/*}*/

.exp-bar .progress-content {
    /*animation-duration: 5s;*/
    /*transition: width 2s ease-out;*/
    /*animation: 0.25s linear both ;*/
    /*view-transition-name: exp-bar;*/
}

.health-bar .progress-content {
    /*animation-duration: 5s;*/
    /*transition: width 2s ease-out;*/
    /*animation: 0.25s linear both ;*/
    /*view-transition-name: health-bar;*/
}
