/* bob-callout: a small label (speech bubble with a tail, a pill, a badge) that bobs in place on a two-leg loop:
   down to --bob-to over the first leg, up past rest to --bob-back over the second, and round again. The overshoot
   above rest (-2px after a 6px drop) is what makes it read as a bob, not a slide. Measured from heyjay.studio IX2:
   a-71 "Bounce 3" (label), a-76 (tooltip), a-66 (preloader badge), a-11 (hero card float).

   <span class="bob" data-bob="label">Kind words</span>            part.js drives it (exact legs, any knob)
   <span class="bob bob--label">Kind words</span>                  CSS only (the four presets, no JS needed)
   Tail: add .bob--tail-bottom | -top | -left | -right (none by default); tilt with --bob-tilt. */

.bob {
  --bob-to: 6px;                    /* first leg ends here (down = positive) */
  --bob-back: -2px;                 /* second leg ends here: the overshoot above rest */
  --bob-dur: 1500ms;                /* both legs (CSS-only presets keep their own leg ratio) */
  --bob-tilt: -3deg;                /* static tilt (the source label sits at rotate(-3deg)) */
  --bob-fill: #fff;
  --bob-ink: #000;
  --bob-rule: #000;
  --bob-radius: 100px;
  --bob-pad: 4px 28px 2px;
  --bob-font: 400 24px/1.4 "Instrument Serif", "Editorial New", Georgia, serif;
  --bob-tail: 10px;                 /* tail size */
  --bob-tail-pos: 50%;              /* where along its edge the tail sits */

  position: relative;
  display: inline-block;
  box-sizing: border-box;
  padding: var(--bob-pad);
  border: 1px solid var(--bob-rule);
  border-radius: var(--bob-radius);
  background: var(--bob-fill);
  color: var(--bob-ink);
  font: var(--bob-font);
  letter-spacing: -.03em;
  white-space: nowrap;
  rotate: var(--bob-tilt);
  translate: 0 0;
  will-change: translate;
}
.bob--plain { padding: 0; border: 0; background: none; border-radius: 0; font: inherit; letter-spacing: inherit; white-space: normal; }

/* ---- CSS-only presets (part.js takes over when present: it adds .bob--js and runs the exact legs) ---- */
/* label: a-71, 0 -> 6px (750ms) -> -2px (750ms), linear, loop */
.bob--label { animation: bob-even var(--bob-dur) linear infinite; animation-delay: calc(var(--bob-dur) * -0.125); }
/* tooltip: a-76, same distances over 1000 + 1000ms */
.bob--tooltip { --bob-dur: 2000ms; animation: bob-even var(--bob-dur) linear infinite; animation-delay: calc(var(--bob-dur) * -0.125); }
/* badge: a-66, 0 -> 16px (750ms) -> -8px (1000ms), linear: the second leg is longer, so it floats up slower than it drops */
.bob--badge { --bob-to: 16px; --bob-back: -8px; --bob-dur: 1750ms; animation: bob-badge var(--bob-dur) linear infinite; animation-delay: calc(var(--bob-dur) * -0.142857); }
/* float: a-11, 0 -> 14px (1000ms outSine) -> 0 (1500ms outSine) */
.bob--float { --bob-to: 14px; --bob-back: 0px; --bob-dur: 2500ms; animation: bob-float var(--bob-dur) linear infinite; }

@keyframes bob-even { 0%, 100% { translate: 0 var(--bob-back); } 50% { translate: 0 var(--bob-to); } }
/* 750 / 1750 = 42.857% */
@keyframes bob-badge { 0%, 100% { translate: 0 var(--bob-back); } 42.857% { translate: 0 var(--bob-to); } }
/* 1000 / 2500 = 40%; Webflow outSine = cubic-bezier(.39,.575,.565,1), written out per leg */
@keyframes bob-float {
  0% { translate: 0 var(--bob-back); animation-timing-function: cubic-bezier(.39, .575, .565, 1); }
  40% { translate: 0 var(--bob-to); animation-timing-function: cubic-bezier(.39, .575, .565, 1); }
  100% { translate: 0 var(--bob-back); }
}
.bob--js { animation: none; }

/* ---- tails: an outlined triangle (rule colour underneath, fill colour 1px inside) ---- */
.bob[class*="bob--tail-"]::before, .bob[class*="bob--tail-"]::after { content: ""; position: absolute; width: 0; height: 0; border-style: solid; }
.bob--tail-bottom::before { top: 100%; left: var(--bob-tail-pos); translate: -50% 0; border-width: calc(var(--bob-tail) + 1px) calc(var(--bob-tail) + 1px) 0; border-color: var(--bob-rule) transparent transparent; }
.bob--tail-bottom::after  { top: calc(100% - 1px); left: var(--bob-tail-pos); translate: -50% 0; border-width: var(--bob-tail) var(--bob-tail) 0; border-color: var(--bob-fill) transparent transparent; }
.bob--tail-top::before    { bottom: 100%; left: var(--bob-tail-pos); translate: -50% 0; border-width: 0 calc(var(--bob-tail) + 1px) calc(var(--bob-tail) + 1px); border-color: transparent transparent var(--bob-rule); }
.bob--tail-top::after     { bottom: calc(100% - 1px); left: var(--bob-tail-pos); translate: -50% 0; border-width: 0 var(--bob-tail) var(--bob-tail); border-color: transparent transparent var(--bob-fill); }
.bob--tail-left::before   { right: 100%; top: var(--bob-tail-pos); translate: 0 -50%; border-width: calc(var(--bob-tail) + 1px) calc(var(--bob-tail) + 1px) calc(var(--bob-tail) + 1px) 0; border-color: transparent var(--bob-rule) transparent transparent; }
.bob--tail-left::after    { right: calc(100% - 1px); top: var(--bob-tail-pos); translate: 0 -50%; border-width: var(--bob-tail) var(--bob-tail) var(--bob-tail) 0; border-color: transparent var(--bob-fill) transparent transparent; }
.bob--tail-right::before  { left: 100%; top: var(--bob-tail-pos); translate: 0 -50%; border-width: calc(var(--bob-tail) + 1px) 0 calc(var(--bob-tail) + 1px) calc(var(--bob-tail) + 1px); border-color: transparent transparent transparent var(--bob-rule); }
.bob--tail-right::after   { left: calc(100% - 1px); top: var(--bob-tail-pos); translate: 0 -50%; border-width: var(--bob-tail) 0 var(--bob-tail) var(--bob-tail); border-color: transparent transparent transparent var(--bob-fill); }

@media (prefers-reduced-motion: reduce) {
  .bob { animation: none; translate: 0 0; }
}
