/* Pixel-block fill button. Rewritten from Sadewa's button (teardown 09-30): on hover a 7 x 2 grid of big cells
   flips to the hover colour one block at a time in random order (hard flips, no fade), the label inverts, and the
   arrow tile swaps arrows: the old one flies out top-right while a new one flies in from bottom-left over a
   blurred dot that blooms to fill the tile. Leaving runs it backwards: cells un-flip at random. part.js deals the
   random timings; without JS the colours still swap on :hover.
   Markup (part.js builds the cells and tile if they are missing):
     <a class="pxbf" href="#"><span class="pxbf__label">Start a project</span></a>
   Variants: .pxbf--light (light button, dark fill), .pxbf--ghost (no tile, outline). */
.pxbf {
  --pxbf-bg: #151515;              /* resting button */
  --pxbf-fg: #ffffff;              /* resting label */
  --pxbf-fill: #ff6a3d;            /* hover fill (the cells) */
  --pxbf-fill-fg: #151515;         /* hover label */
  --pxbf-tile: var(--pxbf-fill);   /* resting arrow tile */
  --pxbf-tile-fg: var(--pxbf-bg);  /* resting arrow */
  --pxbf-tile-on: var(--pxbf-bg);  /* the bloom that fills the tile on hover */
  --pxbf-tile-fg-on: var(--pxbf-fill);
  --pxbf-cols: 7;
  --pxbf-rows: 2;
  --pxbf-fly: 32px;                /* arrow travel, diagonal */
  --pxbf-dot-scale: 8;             /* 10px dot -> covers the 40px tile from its right edge */
  --pxbf-icon-dur: .4s;
  --pxbf-ink-dur: .25s;
  /* Framer spring, duration .4 s, bounce 0 (baked by ../spring-to-linear) */
  --pxbf-ease: linear(0, 0.0229, 0.0788, 0.1532, 0.2361, 0.3208, 0.403, 0.4802, 0.5509, 0.6146, 0.6711, 0.7207, 0.7638, 0.801, 0.8329, 0.8601, 0.8832, 0.9027, 0.9191, 0.9329, 0.9445, 0.9541, 0.9621, 0.9688, 0.9743, 0.9789, 0.9827, 0.9858, 0.9884, 0.9905, 0.9922, 0.9936, 0.9948, 0.9958, 0.9965, 0.9972, 0.9977, 0.9981, 0.9985, 0.9988, 1);
  --pxbf-h: 52px;
  --pxbf-pad: 6px 6px 6px 16px;
  --pxbf-radius: 4px;
  --pxbf-tile-size: 40px;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  box-sizing: border-box;
  height: var(--pxbf-h);
  padding: var(--pxbf-pad);
  border-radius: var(--pxbf-radius);
  background: var(--pxbf-bg);
  color: var(--pxbf-fg);
  font: 500 18px/1.4 ui-sans-serif, system-ui, sans-serif;
  letter-spacing: -.02em;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
@supports not (transition-timing-function: linear(0, 1)) { .pxbf { --pxbf-ease: cubic-bezier(.22, 1, .36, 1); } }

/* the cells: big, stretched to the button (not square), hard on/off */
.pxbf__cells {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  display: grid;
  grid-template-columns: repeat(var(--pxbf-cols), minmax(0, 1fr));
  grid-template-rows: repeat(var(--pxbf-rows), minmax(0, 1fr));
}
.pxbf__cells i { background: var(--pxbf-fill); opacity: 0; }
.pxbf.is-hov .pxbf__cells i.is-on { opacity: 1; }
.pxbf.is-done { background: var(--pxbf-fill); }       /* all cells landed: hand the colour to the button itself */
.pxbf.is-done .pxbf__cells i { opacity: 0; }

.pxbf__label { position: relative; z-index: 2; transition: color var(--pxbf-ink-dur); }
.pxbf.is-ink .pxbf__label { color: var(--pxbf-fill-fg); }

/* the arrow tile */
.pxbf__tile {
  position: relative; z-index: 2; flex: none; overflow: hidden;
  width: var(--pxbf-tile-size); height: var(--pxbf-tile-size); border-radius: 2px;
  background: var(--pxbf-tile);
}
.pxbf__dot {
  position: absolute; right: 0; top: 50%; width: 10px; height: 10px; margin-top: -5px;
  background: var(--pxbf-tile-on);
  opacity: 0; filter: blur(5px); transform: scale(0);
  transition: opacity var(--pxbf-icon-dur) var(--pxbf-ease), filter var(--pxbf-icon-dur) var(--pxbf-ease), transform var(--pxbf-icon-dur) var(--pxbf-ease);
}
.pxbf__arrow {
  position: absolute; left: 20%; top: 20%; width: 60%; height: 60%;
  background: var(--pxbf-tile-fg);
  -webkit-mask: var(--pxbf-arrow) center / contain no-repeat; mask: var(--pxbf-arrow) center / contain no-repeat;
  transition: transform var(--pxbf-icon-dur) var(--pxbf-ease), opacity var(--pxbf-icon-dur) var(--pxbf-ease), background-color var(--pxbf-ink-dur);
}
.pxbf__arrow--in { transform: translate(calc(-1 * var(--pxbf-fly)), var(--pxbf-fly)); opacity: 0; }
.pxbf.is-ink .pxbf__dot { opacity: 1; filter: blur(0); transform: scale(var(--pxbf-dot-scale)); }
.pxbf.is-ink .pxbf__arrow { background: var(--pxbf-tile-fg-on); transform: translate(var(--pxbf-fly), calc(-1 * var(--pxbf-fly))); opacity: 0; }
.pxbf.is-ink .pxbf__arrow--in { transform: none; opacity: 1; }
:root { --pxbf-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 17 17 7M8 7h9v9' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='square'/%3E%3C/svg%3E"); }

/* no JS: plain colour swap on hover */
.pxbf:not(.pxbf--js):hover { background: var(--pxbf-fill); color: var(--pxbf-fill-fg); }

/* variants */
.pxbf--light { --pxbf-bg: #ffffff; --pxbf-fg: #151515; --pxbf-fill: #151515; --pxbf-fill-fg: #ffffff; --pxbf-tile: #151515; --pxbf-tile-fg: #ffffff; --pxbf-tile-on: #ff6a3d; --pxbf-tile-fg-on: #151515; }
.pxbf--ghost { --pxbf-h: 40px; --pxbf-pad: 6px 16px; --pxbf-bg: transparent; --pxbf-fg: currentColor; font-size: 16px; letter-spacing: -.01em; box-shadow: inset 0 0 0 1px rgba(127, 127, 127, .45); }
.pxbf:focus-visible { outline: 2px solid var(--pxbf-fill); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
  .pxbf__dot, .pxbf__arrow { transition-duration: 1ms; }
}
