/* ===== Liquid bubble cursor =====
   Replaces the arrow on devices with a real mouse (js/modules/cursor-bubble.js
   adds .has-bubble). A drop of liquid metal: it refracts the page behind it and
   a slow iridescent sheet turns inside it. Moving, it draws out a little into a
   capsule, round at both ends; stopped, it closes back into a circle.

   The shape is drawn by JS every frame, one outline used three ways: as the
   clip-path of the glass body, and as the inner depth and the shadow in the two SVGs.
   A clip-path cuts off box-shadow, which is why those are paths. All of it is
   what a CSS cursor image cannot do, so this is an element, not `cursor: url()`. */
@media (min-width: 769px) {
  html.has-bubble,
  html.has-bubble * { cursor: none !important; }
  /* typing needs a caret, the bubble steps aside for it */
  html.has-bubble input,
  html.has-bubble textarea { cursor: text !important; }
}
/* Never at phone width, whatever the device reports about its pointer: some
   phones claim a fine pointer, and the JS check alone would let the drop through. */
@media (max-width: 768px) {
  .cursor-bubble { display: none; }
}

.cursor-bubble {
  --box: 240px;           /* the stage the outline is drawn on, centred on the head */
  position: fixed;
  left: 0;
  top: 0;
  z-index: var(--z-cursor);
  width: 0;
  height: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 200ms var(--ease-out);
  will-change: transform;
}
.cursor-bubble.is-on { opacity: 1; }
.cursor-bubble.is-text { opacity: 0; }

.cursor-bubble__shadow,
.cursor-bubble__body,
.cursor-bubble__rim {
  position: absolute;
  left: calc(var(--box) / -2);
  top: calc(var(--box) / -2);
  width: var(--box);
  height: var(--box);
  max-width: none;        /* the reset caps svg at its parent, and this parent is 0 wide */
  overflow: visible;
}
.cursor-bubble__shadow {
  fill: rgb(18 48 140 / .5);
  filter: blur(7px);
  transform: translateY(7px);
  transition: opacity 320ms var(--ease-out);
}
.is-hot .cursor-bubble__shadow,
.is-lens .cursor-bubble__shadow { opacity: .4; }

.cursor-bubble__body {
  overflow: hidden;
  -webkit-backdrop-filter: blur(2px) saturate(190%) brightness(1.12);
          backdrop-filter: blur(2px) saturate(190%) brightness(1.12);
}
/* the iridescent sheet: dock blues, lilac and bright silver, turning slowly */
.cursor-bubble__body::before {
  content: "";
  position: absolute;
  inset: -20%;
  background: conic-gradient(from 0deg,
    #57b2f4, #e6efff 12%, #6997ff 26%, #b7a9ff 40%, #3264e8 54%,
    #dfe9ff 66%, #8fcbfb 80%, #a9b8ff 90%, #57b2f4);
  filter: blur(3px);
  opacity: .78;
  animation: bubble-turn 14s linear infinite;
  transition: opacity 320ms var(--ease-out);
}
/* the specular: a soft window of light near the head, --r is its radius */
.cursor-bubble__body::after {
  content: "";
  position: absolute;
  top: calc(50% - var(--r, 15px) * .78);
  left: calc(50% - var(--r, 15px) * .68);
  width: calc(var(--r, 15px) * .84);
  height: calc(var(--r, 15px) * .6);
  border-radius: 50%;
  background: radial-gradient(closest-side, rgb(255 255 255 / .95), rgb(255 255 255 / 0));
  transform: rotate(-24deg);
}
/* See-through: over something clickable, and from a click on empty space until
   the next click. No blur, what is under the drop has to stay sharp. */
.is-hot .cursor-bubble__body::before,
.is-lens .cursor-bubble__body::before { opacity: .2; }
.is-hot .cursor-bubble__body,
.is-lens .cursor-bubble__body {
  -webkit-backdrop-filter: saturate(170%) brightness(1.1);
          backdrop-filter: saturate(170%) brightness(1.1);
}

.cursor-bubble__rim { fill: none; }
/* light from above, deep blue from below, held inside by the body's outline */
.cursor-bubble__depth { stroke-width: 9; filter: blur(2.5px); }

@keyframes bubble-turn { to { transform: rotate(360deg); } }
