/* ═══════════════════════════════════════════════════════════════
   Glass effects: sitewide cursor spotlight + scroll reveal + squash
   ═══════════════════════════════════════════════════════════════ */

/* Sitewide cursor spotlight - GPU-positioned fixed blob */
.lg-spotlight {
  position: fixed;
  left: 0;
  top: 0;
  width: 720px;
  height: 720px;
  margin-left: -360px;
  margin-top: -360px;
  pointer-events: none;
  z-index: -5;
  background: radial-gradient(
    circle,
    rgba(255, 255, 255, 0.06),
    rgba(255, 255, 255, 0.02) 45%,
    transparent 72%
  );
  transform: translate3d(var(--cx, 50vw), var(--cy, 50vh), 0);
  transition: opacity 0.3s var(--ease-apple-out);
  will-change: transform;
}
html.over-glass .lg-spotlight { opacity: 0.55; }
html:not(.dark) .lg-spotlight {
  background: radial-gradient(
    circle,
    rgba(0, 0, 0, 0.04),
    rgba(0, 0, 0, 0.015) 45%,
    transparent 72%
  );
}

/* Scroll reveal entrance — compositor-driven transform + opacity transition.
   (v1.1.0) Replaces the old @property --lg-reveal-y / --lg-reveal-scale
   registered-custom-property interpolation, which recomputed the composed
   transform on the main thread every frame and silently no-op'd in Firefox
   <128 (no @property support). Same 16px / 0.96 / eases → a pixel-identical
   pop, now run off the main thread by the compositor. The revealed ("in")
   state keeps an explicit identity transform (not `none`) so the element's
   compositing layer matches exactly. */
.liquid-glass[data-reveal] {
  opacity: 0;
  transform-origin: center;
  transform: translateY(16px) scale(0.96);
  backface-visibility: hidden;
  transition:
    transform 0.85s cubic-bezier(0.22, 1.12, 0.4, 1),
    opacity 0.65s cubic-bezier(0.25, 0.8, 0.25, 1);
}
.liquid-glass[data-reveal="in"] {
  transform: translateY(0) scale(1);
  opacity: 1;
}

/* Scroll-velocity squash (macro only) - subtle liquid motion. Default on.
   Lives on the individual `translate`/`scale` properties (NOT `transform`) so
   it composes WITH the reveal's `transform` transition but is timed completely
   independently: the reveal eases over 0.85s on the compositor, while these
   have no transition and so track --sv/--svmag instantly, per frame, exactly
   like v1.0.1. No reveal-state dependency is needed — at rest --sv/--svmag are
   0 → `translate: 0 0; scale: 1 1` (identity) → inert, composing to just the
   reveal transform. To turn the squash off, pass `scroll:false` to
   useLiquidGlassEffects: --sv/--svmag go unset → var(...,0) fallbacks →
   identity, no CSS change required.
   (Individual translate/scale: Chrome 104+ / Firefox 72+ / Safari 14.1+;
   older engines just no-op the squash and the reveal still works.) */
.liquid-glass.lg-macro {
  translate: 0 calc(var(--sv, 0) * -2px);
  scale: calc(1 - var(--svmag, 0) * 0.012) calc(1 + var(--svmag, 0) * 0.006);
}

/* ── Scroll edge effects ────────────────────────────────────────────
   Apple's companion system to Liquid Glass (WWDC 219/356): content
   scrolling under floating glass progressively dissolves near the
   screen edge so the glass stays legible without a bar background.
   `soft` = progressive fade (iOS default), `hard` = uniform, more
   opaque boundary (pinned accessories / macOS).
   Place as a fixed/sticky sibling under your floating glass:
     <div class="lg-scroll-edge lg-scroll-edge-top" aria-hidden="true"></div> */
.lg-scroll-edge {
  position: fixed;
  left: 0;
  right: 0;
  height: 88px;
  pointer-events: none;
  z-index: 30;
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
}
.lg-scroll-edge-top {
  top: 0;
  mask-image: linear-gradient(to bottom, black 0%, black 25%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, black 0%, black 25%, transparent 100%);
}
.lg-scroll-edge-bottom {
  bottom: 0;
  mask-image: linear-gradient(to top, black 0%, black 25%, transparent 100%);
  -webkit-mask-image: linear-gradient(to top, black 0%, black 25%, transparent 100%);
}
/* Hard style: uniform boundary, slight dim for contrast */
.lg-scroll-edge-hard {
  backdrop-filter: blur(16px) saturate(140%) brightness(0.96);
  -webkit-backdrop-filter: blur(16px) saturate(140%) brightness(0.96);
  mask-image: linear-gradient(to bottom, black 0%, black 72%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, black 0%, black 72%, transparent 100%);
}
html.glass-off .lg-scroll-edge { display: none; }

/* Touch devices skip velocity squash */
@media (hover: none), (pointer: coarse) {
  .lg-spotlight { display: none; }
  .liquid-glass[data-reveal],
  .liquid-glass[data-reveal="in"] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  /* transform:none above does NOT affect the individual translate/scale
     properties — neutralize the macro velocity squash explicitly. */
  .liquid-glass.lg-macro {
    translate: none !important;
    scale: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  .liquid-glass[data-reveal],
  .liquid-glass[data-reveal="in"] {
    opacity: 1;
    transform: none;
    transition: none;
  }
  /* Disable the individual-property velocity squash under reduced motion too. */
  .liquid-glass.lg-macro {
    translate: none;
    scale: none;
  }
}
