/* index-v1b/menu — ball-v3a's single-ball menu (its glass ball), copied in
   and fixed to the Index page's bottom-right corner. Classes are prefixed
   bm- so they don't clash with the page's. The page loads Cygnito Mono. */

:root {
  --bm-orange: #ff5b00;  /* the tube */
  --bm-label: #bababa;   /* page names on the tube */
  --bm-chip: #dfdfdf;    /* the filters' highlight */
  --bm-h: 58.336px;      /* tube height = one circle */
  --bm-ball: 47.62px;    /* the ball, in place of Figma's (S) badge */
  --bm-scale: 1.15;      /* the whole menu */
}

/* As wide as the widest item; the ball sits at the right end and the tube
   spreads out of it to the left. Fixed to the bottom-right corner (main.js
   moves it with translate when the ball's carried). Sized with a scale
   transform from that corner, not CSS zoom: under zoom the ball's canvas is
   drawn at its unzoomed size and comes out soft and clipped. */
.bm-menu {
  position: fixed;
  right: 20px;
  bottom: 20px;
  width: 545px; /* (index-v1c: the filter bar, with its "all") */
  height: var(--bm-h);
  scale: var(--bm-scale);
  transform-origin: 100% 100%;
  pointer-events: none; /* only the ball and the tube take the pointer */
  z-index: 20000;
}

.bm-tube {
  position: absolute;
  inset: 0;
}
/* One circle of the tube (placed by main.js). */
.bm-tube i {
  position: absolute;
  top: 0;
  right: 0;
  width: var(--bm-h);
  height: var(--bm-h);
  border-radius: 50%;
  background: var(--bm-orange);
  pointer-events: auto;
  cursor: pointer;
}

/* Figma: 29px in from the tube's full-width left end, line box 35px down. */
.bm-label {
  position: absolute;
  top: 35px;
  font: 12px/normal 'Cygnito Mono', ui-monospace, monospace;
  text-transform: uppercase;
  color: var(--bm-label);
  white-space: nowrap;
  text-decoration: none;
  pointer-events: none;
  visibility: hidden;
}
.bm-label.is-current { visibility: visible; pointer-events: auto; }
a.bm-label:hover { text-decoration: underline; }

/* Figma: the highlight bar 33px down, 18px between items. */
.bm-chips {
  top: 33px;
  display: flex;
  align-items: flex-end;
  gap: 18px;
  padding: 2px 4px;
  background: var(--bm-chip);
  color: var(--bm-orange);
  line-height: 1.5;
}
.bm-chip {
  font: inherit;
  color: inherit;
  text-transform: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.bm-chip:first-child { cursor: default; }
button.bm-chip:hover,
button.bm-chip[aria-pressed='true'] { text-decoration: underline; }

/* The ball sits where Figma's (S) badge was: 5.36px in from the right end.
   Its canvas is 12% bigger than the ball (main.js draws the ball inside that,
   so its rim is never cropped), centred on the same spot. */
.bm-ball {
  --pad: calc(var(--bm-ball) * 0.06);
  position: absolute;
  right: calc(5.36px - var(--pad));
  top: calc(5.36px - var(--pad));
  width: calc(var(--bm-ball) * 1.12);
  height: calc(var(--bm-ball) * 1.12);
  border-radius: 50%; /* the hit area is the ball, not its square */
  /* Scaled about its centre; main.js anchors the big shut size to the
     bottom-right corner with a translate. */
  transform-origin: 50% 50%;
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  outline: none;
  transition: filter 200ms ease;
}
.bm-ball.is-dragging { cursor: grabbing; }

/* The lens: under the glass, the page behind the ball, magnified and bent
   like through a glass sphere (an SVG displacement filter, built in main.js).
   Same box as the ball's canvas, clipped to the ball; main.js copies the
   ball's scale onto it every frame. Chromium only: elsewhere backdrop-filter
   url() is ignored and it's just the clear glass. */
.bm-lens {
  position: absolute;
  right: calc(5.36px - var(--bm-ball) * 0.06);
  top: calc(5.36px - var(--bm-ball) * 0.06);
  width: calc(var(--bm-ball) * 1.12);
  height: calc(var(--bm-ball) * 1.12);
  transform-origin: 50% 50%;
  clip-path: circle(44.64%); /* the ball: 0.5 / 1.12 of the box */
  backdrop-filter: url(#bm-lens-filter);
  pointer-events: none;
}

/* The glass ball: cut the ball's shape out of the tube, so through the glass
   you see the page, not orange. The ball's centre is 29.17px in from the
   right and down from the top (5.36px inset + its 23.81px radius). */
.bm-tube {
  --hole: calc(var(--bm-ball) / 2 - 0.5px);
  -webkit-mask-image: radial-gradient(circle at calc(100% - 29.17px) 29.17px, transparent var(--hole), #000 calc(var(--hole) + 0.75px));
  mask-image: radial-gradient(circle at calc(100% - 29.17px) 29.17px, transparent var(--hole), #000 calc(var(--hole) + 0.75px));
}

/* The big shut ball's footprint: an invisible hover area under the ball, so
   it stays open while the pointer is anywhere the big ball was. */
.bm-zone {
  --pad: calc(var(--bm-ball) * 0.06);
  --size: calc(var(--bm-ball) * 1.12);
  position: absolute;
  right: calc(5.36px - var(--pad));
  top: calc(5.36px - var(--pad) + var(--size) - var(--size) * var(--bm-rest, 1.9));
  width: calc(var(--size) * var(--bm-rest, 1.9));
  height: calc(var(--size) * var(--bm-rest, 1.9));
  border-radius: 50%;
  pointer-events: auto;
}

/* Picked up: a soft shadow under the ball. */
.bm-menu.is-lifted .bm-ball { filter: drop-shadow(0 10px 12px rgba(0, 0, 0, 0.22)); }

/* Phones: a little smaller, nearer the corner. */
@media (max-width: 700px) {
  :root { --bm-scale: 0.95; }
  .bm-menu { right: 12px; bottom: 12px; }
}

/* index-v1c: the ball has rolled off to filter; ours is gone for a moment. */
.bm-menu.is-ball-out .bm-ball,
.bm-menu.is-ball-out .bm-lens { opacity: 0; transition: none; }
.bm-ball, .bm-lens { transition: opacity 300ms ease-out, filter 200ms ease; }
