/* Spin fill badge: a round outlined badge that, when pointed at, makes one full turn with a wind-up and an overshoot
   and floods with its ink colour while its label turns light; leaving runs it back. part.js plays it (Web Animations,
   so leaving mid-spin retraces the same curve); without JS, :hover / :focus-visible run the same move as a CSS transition.
   Knobs (custom properties on .sfb; measured defaults from the source):
     --sfb-size   120px   diameter
     --sfb-ink    border + resting label colour (and the flood, via --sfb-fill)
     --sfb-bg     resting face colour
     --sfb-fill   face colour once pointed at (the ink)
     --sfb-on     label colour once pointed at (a light grey)
     --sfb-tilt   15deg   resting tilt; the badge comes back to it after its full turn
     --sfb-spin   360deg  turn added on hover (the source's absolute 375deg = 15deg tilt + one full turn)
     --sfb-dur    .5s     play time each way (IX3's default; measured .5 s on the live hover)
     --sfb-back   2.5     back.inOut overshoot: 2.5 winds back 34deg first and overshoots 34deg past the end
     --sfb-border 2px · --sfb-font label face */
.sfb {
  --sfb-size: 120px; --sfb-ink: #c2412d; --sfb-bg: #f2dcd2; --sfb-fill: var(--sfb-ink); --sfb-on: #f1ede9;
  --sfb-tilt: 15deg; --sfb-spin: 360deg; --sfb-dur: .5s; --sfb-back: 2.5; --sfb-border: 2px;
  --sfb-font: "Courier New", ui-monospace, monospace;
  /* back.inOut(2.5) sampled for the no-JS fallback (part.js builds its own from --sfb-back) */
  --sfb-ease: linear(0, -0.0029, -0.0108, -0.0222, -0.036, -0.0508, -0.0653, -0.0781, -0.088, -0.0937, -0.0938, -0.087, -0.072, -0.0475, -0.0123, 0.0352, 0.096, 0.1716, 0.2632, 0.3723, 0.5, 0.6277, 0.7368, 0.8284, 0.904, 0.9648, 1.0123, 1.0475, 1.072, 1.087, 1.0938, 1.0937, 1.088, 1.0781, 1.0653, 1.0508, 1.036, 1.0222, 1.0108, 1.0029, 1);
  box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: var(--sfb-size); aspect-ratio: 1; border-radius: 50%; padding: calc(var(--sfb-size) * .08);
  border: var(--sfb-border) solid var(--sfb-ink); background-color: var(--sfb-bg); color: var(--sfb-ink);
  rotate: var(--sfb-tilt);
  font: 700 calc(var(--sfb-size) * .175)/.85 var(--sfb-font); text-transform: uppercase; text-align: center; text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
.sfb:focus-visible { outline: 2px solid var(--sfb-ink); outline-offset: 5px; }
/* no-JS fallback: the same move as a transition (an interrupted leave restarts the curve instead of retracing it) */
.sfb:not(.sfb-js) { transition: rotate var(--sfb-dur) var(--sfb-ease), background-color var(--sfb-dur) var(--sfb-ease), color var(--sfb-dur) var(--sfb-ease); }
@media (hover: hover) { .sfb:not(.sfb-js):hover { rotate: calc(var(--sfb-tilt) + var(--sfb-spin)); background-color: var(--sfb-fill); color: var(--sfb-on); } }
.sfb:not(.sfb-js):focus-visible { rotate: calc(var(--sfb-tilt) + var(--sfb-spin)); background-color: var(--sfb-fill); color: var(--sfb-on); }
@media (prefers-reduced-motion: reduce) { .sfb:not(.sfb-js) { transition: background-color .2s, color .2s; } .sfb:not(.sfb-js):hover, .sfb:not(.sfb-js):focus-visible { rotate: var(--sfb-tilt); } }
