/*
 * The Nandi bison, alive: a port of the app's mascot (BisonPose and
 * bison-pose.css in the Nandi app) for the site. A brand asset of VaultDB.ai.
 *
 * Each pose image (img/nandi-bison-<pose>.webp) is stacked: the body, and
 * copies cut to the parts that move (head, tail, crates, the badge), each
 * turning a few degrees about its joint. The body leaves the parts out, and
 * each part is a little larger than the hole it fills, so a turn never shows
 * a gap. The head's edge is feathered (a mask), so there's no seam.
 *
 * - rest: breathes; dozes off and looks up; now and then gets up, stretches
 *   and lies down again (crossfading to the standing pose)
 * - wait: shifts its weight; lifts its head to look at you, then nods;
 *   swishes its tail; the ! pulses
 * - carry: walks with a bob, the crates rocking half a step behind
 * - done: the check pops in, two nods, the tail flicks
 *
 * Markup (js/nandi-bison.js switches poses):
 *   <span class="bison" data-pose="wait">
 *     <span class="bp-group">
 *       <img class="bp-part bp-base" ...> <img class="bp-part bp-head" ...>
 *       <img class="bp-part bp-tail" ...> <img class="bp-part bp-badge" ...>
 *       <img class="bp-part bp-crates" ...>
 *     </span>
 *     <img class="bp-part bp-stand" src="img/nandi-bison-wait.webp" ...>
 *   </span>
 * Every part image shows the same pose file. It holds still under the
 * system's "reduce motion".
 */
.bison {
  position: relative;
  display: inline-block;
  flex: none;
}
.bison .bp-group,
.bison .bp-part {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.bison .bp-part {
  display: block;
  user-select: none;
  pointer-events: none;
}
.bison .bp-group,
.bison .bp-head,
.bison .bp-tail,
.bison .bp-crates,
.bison .bp-badge,
.bison .bp-stand {
  will-change: transform, opacity;
}

/* Shapes: generated from the 384 px poses (see the header) */
.bison[data-pose='rest'] .bp-base {
  clip-path: polygon(
    evenodd,
    0% 0%,
    100% 0%,
    100% 100%,
    0% 100%,
    0% 0%,
    100.9% 49%,
    100% 55.7%,
    97.5% 62%,
    93.4% 67.4%,
    88.2% 71.6%,
    82.1% 74.2%,
    75.5% 75.1%,
    69% 74.2%,
    62.9% 71.6%,
    57.6% 67.4%,
    53.6% 62%,
    51.1% 55.7%,
    50.2% 49%,
    51.1% 42.2%,
    53.6% 35.9%,
    57.6% 30.5%,
    62.9% 26.3%,
    69% 23.7%,
    75.5% 22.8%,
    82.1% 23.7%,
    88.2% 26.3%,
    93.4% 30.5%,
    97.5% 35.9%,
    100% 42.2%,
    100.9% 49%,
    0% 0%
  );
}
.bison[data-pose='rest'] .bp-head {
  -webkit-mask-image: radial-gradient(
    ellipse 33.3% 34.4% at 75.5% 49%,
    #000 80%,
    transparent 100%
  );
  mask-image: radial-gradient(
    ellipse 33.3% 34.4% at 75.5% 49%,
    #000 80%,
    transparent 100%
  );
  transform-origin: 62% 65.6%;
}
.bison[data-pose='rest'] .bp-stand {
  clip-path: polygon(
    evenodd,
    0% 0%,
    100% 0%,
    100% 100%,
    0% 100%,
    0% 0%,
    14.6% 7.3%,
    33.9% 7.3%,
    33.9% 26%,
    14.6% 26%,
    14.6% 7.3%,
    0% 0%
  );
}

.bison[data-pose='wait'] .bp-base {
  clip-path: polygon(
    evenodd,
    0% 0%,
    100% 0%,
    100% 100%,
    0% 100%,
    0% 0%,
    102.8% 47.4%,
    101.8% 55.6%,
    99.2% 63.2%,
    94.9% 69.8%,
    89.4% 74.8%,
    83% 78%,
    76% 79.1%,
    69.1% 78%,
    62.7% 74.8%,
    57.1% 69.8%,
    52.9% 63.2%,
    50.2% 55.6%,
    49.3% 47.4%,
    50.2% 39.2%,
    52.9% 31.6%,
    57.1% 25%,
    62.7% 20%,
    69.1% 16.8%,
    76% 15.7%,
    83% 16.8%,
    89.4% 20%,
    94.9% 25%,
    99.2% 31.6%,
    101.8% 39.2%,
    102.8% 47.4%,
    0% 0%,
    0% 45.6%,
    9.4% 45.6%,
    10.4% 68.2%,
    0% 68.2%,
    0% 45.6%,
    0% 0%,
    14.6% 7.3%,
    33.9% 7.3%,
    33.9% 26%,
    14.6% 26%,
    14.6% 7.3%,
    0% 0%
  );
}
.bison[data-pose='wait'] .bp-head {
  -webkit-mask-image: radial-gradient(
    ellipse 35.2% 41.7% at 76% 47.4%,
    #000 80%,
    transparent 100%
  );
  mask-image: radial-gradient(
    ellipse 35.2% 41.7% at 76% 47.4%,
    #000 80%,
    transparent 100%
  );
  transform-origin: 62% 62.5%;
}
.bison[data-pose='wait'] .bp-tail {
  clip-path: polygon(0% 45.6%, 9.4% 45.6%, 10.4% 68.2%, 0% 68.2%);
  transform-origin: 8.9% 46.4%;
}
.bison[data-pose='wait'] .bp-badge {
  clip-path: polygon(14.6% 7.3%, 33.9% 7.3%, 33.9% 26%, 14.6% 26%);
  transform-origin: 24.2% 16.7%;
}

.bison[data-pose='carry'] .bp-base {
  clip-path: polygon(
    evenodd,
    0% 0%,
    100% 0%,
    100% 100%,
    0% 100%,
    0% 0%,
    102.8% 46.9%,
    101.8% 53.4%,
    99.2% 59.5%,
    94.9% 64.8%,
    89.4% 68.8%,
    83% 71.3%,
    76% 72.2%,
    69.1% 71.3%,
    62.7% 68.8%,
    57.1% 64.8%,
    52.9% 59.5%,
    50.2% 53.4%,
    49.3% 46.9%,
    50.2% 40.3%,
    52.9% 34.2%,
    57.1% 29%,
    62.7% 24.9%,
    69.1% 22.4%,
    76% 21.5%,
    83% 22.4%,
    89.4% 24.9%,
    94.9% 29%,
    99.2% 34.2%,
    101.8% 40.3%,
    102.8% 46.9%,
    0% 0%,
    0% 45.6%,
    9.4% 45.6%,
    10.4% 68.2%,
    0% 68.2%,
    0% 45.6%,
    0% 0%,
    19.8% 19.8%,
    49% 19.8%,
    49% 41.7%,
    19.8% 41.7%,
    19.8% 19.8%,
    0% 0%
  );
}
.bison[data-pose='carry'] .bp-head {
  -webkit-mask-image: radial-gradient(
    ellipse 35.2% 33.3% at 76% 46.9%,
    #000 80%,
    transparent 100%
  );
  mask-image: radial-gradient(
    ellipse 35.2% 33.3% at 76% 46.9%,
    #000 80%,
    transparent 100%
  );
  transform-origin: 62% 62.5%;
}
.bison[data-pose='carry'] .bp-tail {
  clip-path: polygon(0% 45.6%, 9.4% 45.6%, 10.4% 68.2%, 0% 68.2%);
  transform-origin: 8.9% 44.8%;
}
.bison[data-pose='carry'] .bp-crates {
  clip-path: polygon(18.2% 18.2%, 50.5% 18.2%, 50.5% 46.4%, 18.2% 46.4%);
  transform-origin: 34.4% 43.8%;
}

.bison[data-pose='done'] .bp-base {
  clip-path: polygon(
    evenodd,
    0% 0%,
    100% 0%,
    100% 100%,
    0% 100%,
    0% 0%,
    102.8% 47.4%,
    101.8% 55.6%,
    99.2% 63.2%,
    94.9% 69.8%,
    89.4% 74.8%,
    83% 78%,
    76% 79.1%,
    69.1% 78%,
    62.7% 74.8%,
    57.1% 69.8%,
    52.9% 63.2%,
    50.2% 55.6%,
    49.3% 47.4%,
    50.2% 39.2%,
    52.9% 31.6%,
    57.1% 25%,
    62.7% 20%,
    69.1% 16.8%,
    76% 15.7%,
    83% 16.8%,
    89.4% 20%,
    94.9% 25%,
    99.2% 31.6%,
    101.8% 39.2%,
    102.8% 47.4%,
    0% 0%,
    0% 26%,
    13% 26%,
    13% 44.8%,
    0% 44.8%,
    0% 26%,
    0% 0%,
    14.6% 7.3%,
    33.9% 7.3%,
    33.9% 26%,
    14.6% 26%,
    14.6% 7.3%,
    0% 0%
  );
}
.bison[data-pose='done'] .bp-head {
  -webkit-mask-image: radial-gradient(
    ellipse 35.2% 41.7% at 76% 47.4%,
    #000 80%,
    transparent 100%
  );
  mask-image: radial-gradient(
    ellipse 35.2% 41.7% at 76% 47.4%,
    #000 80%,
    transparent 100%
  );
  transform-origin: 62% 62.5%;
}
.bison[data-pose='done'] .bp-tail {
  clip-path: polygon(0% 26%, 13% 26%, 13% 44.8%, 0% 44.8%);
  transform-origin: 12% 43.8%;
}
.bison[data-pose='done'] .bp-badge {
  clip-path: polygon(14.6% 7.3%, 33.9% 7.3%, 33.9% 26%, 14.6% 26%);
  transform-origin: 24.2% 17.2%;
}

/* --- rest ------------------------------------------------------------- */
.bison[data-pose='rest'] .bp-group {
  transform-origin: 50% 85%;
  animation:
    bp-breathe 3.5s ease-in-out infinite,
    bp-lie 24s ease-in-out -6.5s infinite;
}
.bison[data-pose='rest'] .bp-head {
  animation: bp-doze 9s ease-in-out -2s infinite;
}
.bison[data-pose='rest'] .bp-stand {
  opacity: 0;
  transform-origin: 50% 92%;
  animation: bp-stand 24s ease-in-out -6.5s infinite;
}
@keyframes bp-breathe {
  0%,
  100% {
    transform: scaleY(1);
  }
  45% {
    transform: scaleY(1.04);
  }
}
/* Lying, until it gets up (44-47%) and after it lies down (60-63%) */
@keyframes bp-lie {
  0%,
  44% {
    opacity: 1;
  }
  47%,
  60% {
    opacity: 0;
  }
  63%,
  100% {
    opacity: 1;
  }
}
/* Nods off, jerks awake, looks round */
@keyframes bp-doze {
  0%,
  52% {
    transform: rotate(0deg);
  }
  60%,
  66% {
    transform: rotate(7deg);
  }
  70% {
    transform: rotate(-3deg);
  }
  74% {
    transform: rotate(0deg);
  }
  82% {
    transform: rotate(-5deg) translateX(1.5%);
  }
  88%,
  100% {
    transform: rotate(0deg);
  }
}
/* Rises from low, stretches with a shake, settles back down */
@keyframes bp-stand {
  0%,
  43% {
    opacity: 0;
    transform: translateY(7%) scaleY(0.9);
  }
  47% {
    opacity: 1;
    transform: translateY(0) scaleY(1);
  }
  50% {
    transform: rotate(-2.5deg);
  }
  51.5% {
    transform: rotate(2.5deg);
  }
  53% {
    transform: rotate(-1.5deg);
  }
  54.5%,
  59% {
    opacity: 1;
    transform: rotate(0deg);
  }
  63%,
  100% {
    opacity: 0;
    transform: translateY(7%) scaleY(0.9);
  }
}

/* --- wait ------------------------------------------------------------- */
.bison[data-pose='wait'] .bp-group {
  transform-origin: 50% 95%;
  animation: bp-shift 7s ease-in-out infinite;
}
.bison[data-pose='wait'] .bp-head {
  animation: bp-look 5s ease-in-out infinite;
}
.bison[data-pose='wait'] .bp-tail {
  animation: bp-swish 3.7s ease-in-out infinite;
}
.bison[data-pose='wait'] .bp-badge {
  animation: bp-pulse 2.4s ease-in-out infinite;
}
@keyframes bp-shift {
  0%,
  100% {
    transform: translateX(0) rotate(0deg);
  }
  30%,
  45% {
    transform: translateX(1.5%) rotate(1deg);
  }
  70% {
    transform: translateX(-1%) rotate(-0.6deg);
  }
}
/* Lifts its head to look at you, holds, nods */
@keyframes bp-look {
  0%,
  38% {
    transform: rotate(0deg);
  }
  46%,
  68% {
    transform: rotate(-6deg);
  }
  75% {
    transform: rotate(3deg);
  }
  81%,
  100% {
    transform: rotate(0deg);
  }
}
/* Still, then a quick double swish */
@keyframes bp-swish {
  0%,
  68% {
    transform: rotate(0deg);
  }
  73% {
    transform: rotate(14deg);
  }
  78% {
    transform: rotate(-9deg);
  }
  83% {
    transform: rotate(10deg);
  }
  88%,
  100% {
    transform: rotate(0deg);
  }
}
@keyframes bp-pulse {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.12);
  }
}

/* --- carry ------------------------------------------------------------ */
.bison[data-pose='carry'] .bp-group {
  animation: bp-walk 1.8s ease-in-out infinite;
}
.bison[data-pose='carry'] .bp-head {
  animation: bp-step 0.9s ease-in-out infinite;
}
.bison[data-pose='carry'] .bp-crates {
  animation: bp-rock 0.9s ease-in-out -0.45s infinite;
}
.bison[data-pose='carry'] .bp-tail {
  animation: bp-sway 1.8s ease-in-out infinite;
}
@keyframes bp-walk {
  0%,
  100% {
    transform: translateY(0);
  }
  25% {
    transform: translateY(-3%);
  }
  50% {
    transform: translateY(0);
  }
  75% {
    transform: translateY(-2%);
  }
}
@keyframes bp-step {
  0%,
  100% {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(2.5deg);
  }
}
@keyframes bp-rock {
  0%,
  100% {
    transform: rotate(-1.5deg);
  }
  50% {
    transform: rotate(1.5deg);
  }
}
@keyframes bp-sway {
  0%,
  100% {
    transform: rotate(-6deg);
  }
  50% {
    transform: rotate(6deg);
  }
}

/* --- done ------------------------------------------------------------- */
.bison[data-pose='done'] .bp-badge {
  animation: bp-pop 0.6s cubic-bezier(0.3, 1.6, 0.6, 1) both;
}
.bison[data-pose='done'] .bp-head {
  animation: bp-nod 0.7s ease-in-out 0.3s 2;
}
.bison[data-pose='done'] .bp-tail {
  animation: bp-flick 1.6s ease-in-out 0.6s infinite;
}
@keyframes bp-pop {
  0% {
    transform: scale(0);
  }
  100% {
    transform: scale(1);
  }
}
@keyframes bp-nod {
  0%,
  100% {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(4deg);
  }
}
@keyframes bp-flick {
  0%,
  30% {
    transform: rotate(0deg);
  }
  42% {
    transform: rotate(-14deg);
  }
  56% {
    transform: rotate(10deg);
  }
  70%,
  100% {
    transform: rotate(0deg);
  }
}

/* Only the parts each pose moves are shown (BisonPose's PARTS) */
.bison .bp-tail,
.bison .bp-badge,
.bison .bp-crates,
.bison .bp-stand {
  display: none;
}
.bison[data-pose='wait'] .bp-tail,
.bison[data-pose='wait'] .bp-badge,
.bison[data-pose='carry'] .bp-tail,
.bison[data-pose='carry'] .bp-crates,
.bison[data-pose='done'] .bp-tail,
.bison[data-pose='done'] .bp-badge,
.bison[data-pose='rest'] .bp-stand {
  display: block;
}

/* Still when the system asks for less motion: lying down at rest */
@media (prefers-reduced-motion: reduce) {
  .bison,
  .bison * {
    animation: none !important;
  }
}

/* The companion bison: the app's own companion animation (lying down,
   breathing in a 4-second loop, `src/assets/brand/mascot/companion-bison.webp`
   in the app). The corner companion on the home page. The still frame shows
   when the system asks for less motion */
.nandi_companion {
  display: block;
  width: 100%;
  height: 100%;
}
.nandi_companion img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.nandi_companion .nandi_companion_still {
  display: none;
}
@media (prefers-reduced-motion: reduce) {
  .nandi_companion .nandi_companion_moving {
    display: none;
  }
  .nandi_companion .nandi_companion_still {
    display: block;
  }
}
.bison_companion .nandi_companion {
  filter: drop-shadow(0 10px 18px rgba(0, 0, 0, 0.45));
}
