/* =============================================================================
   FRESHTECH LIQUID GLASS — v1.0 (2026-08-06)

   Apple-style liquid glass. Approved by Jase 2026-08-06: "Perfect... In the
   future, when I want Liquid Glass, this is what we want."

   Drop in two files and add two classes:

     <link rel="stylesheet" href="liquid-glass.css">
     <script src="liquid-glass.js" defer></script>

     <button class="lg lg--circle lg--bend-strong">…</button>
     <div    class="lg lg--card   lg--bend-soft">…</div>

   The JS injects the SVG lenses. Without it you still get frosted glass with a
   correct bevel — just no refraction.

   ---------------------------------------------------------------------------
   THE THREE INGREDIENTS (all three are needed; the bevel does most of the work)
     1. backdrop-filter: a whisper of blur + an SVG lens + saturation
     2. feDisplacementMap through a sphere map — the refraction (see the .js)
     3. a stack of inset shadows + a gradient rim — the bevel
   ---------------------------------------------------------------------------

   ⛔ BROWSERS. SVG filters inside backdrop-filter are CHROMIUM ONLY.
      Chrome / Edge → full effect, including the bend.
      Safari / iOS  → blur + saturate + bevel, NO bend. (WebKit bug 245510)
      Firefox       → same as Safari.
      It still reads as glass everywhere. Never promise the bend on iPhone.

   ⛔ IT NEEDS SOMETHING BEHIND IT. Glass over a flat colour looks like nothing.
      Put it on a photo, a gradient, or content.

   ⛔ SIZE CHANGES EVERYTHING. The bend is a fraction of the ELEMENT, but the
      detail behind it is fixed in pixels. The setting that looks elegant at
      160px turns a face to soup at 72px. Small element → lighter bend.
        ≥140px  →  lg--bend-strong
         80-140 →  lg--bend-medium
         <80px  →  lg--bend-soft
   ========================================================================== */

.lg {
  /* ---- the knobs ---------------------------------------------------------
     Tuned values, changed only with a reason. Jase's brief was "more
     transparent, more bend, less frosty" — the blur was hiding the very
     refraction it was supposed to support. */
  --lg-blur: .5px;        /* frost. Keep it tiny or you hide the bend.        */
  --lg-tint: .05;         /* white fill alpha. Higher = milkier.              */
  --lg-saturate: 175%;    /* lifts colour behind the glass.                   */
  --lg-radius: 999em;

  /* Reflex strength. Dial the light one DOWN and the dark one UP on dark
     surfaces, or the bevel disappears. */
  --lg-light: 1;
  --lg-dark: 1;

  position: relative;
  border: 0;
  border-radius: var(--lg-radius);
  background-color: rgba(255, 255, 255, var(--lg-tint));

  /* No url() on the -webkit line: Safari cannot do SVG filters here, and
     including it makes Safari drop the whole declaration. */
  backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
  -webkit-backdrop-filter: blur(calc(var(--lg-blur) * 5)) saturate(var(--lg-saturate));

  /* THE BEVEL. Light gathers top-left, shadow bottom-right, two outer shadows
     lift it off the surface. Nine layers — they are the effect, not decoration. */
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, calc(var(--lg-light) * .12)),
    inset 2px 3px 0 -2px rgba(255, 255, 255, calc(var(--lg-light) * .90)),
    inset -2px -2px 0 -2px rgba(255, 255, 255, calc(var(--lg-light) * .75)),
    inset -3px -8px 2px -7px rgba(255, 255, 255, calc(var(--lg-light) * .55)),
    inset -.3px -1px 5px 0 rgba(0, 0, 0, calc(var(--lg-dark) * .14)),
    inset -1.5px 2.5px 0 -2px rgba(0, 0, 0, calc(var(--lg-dark) * .20)),
    inset 0 3px 5px -2px rgba(0, 0, 0, calc(var(--lg-dark) * .22)),
    inset 2px -6.5px 1px -4px rgba(0, 0, 0, calc(var(--lg-dark) * .12)),
    0 2px 8px rgba(0, 0, 0, calc(var(--lg-dark) * .18)),
    0 10px 30px rgba(0, 0, 0, calc(var(--lg-dark) * .22));
}

/* THE RIM. A gradient ring masked to a hairline band — brightest top-left and
   bottom-right, where a real glass edge catches light. This is the single
   detail that most separates "glass" from "translucent rectangle". */
.lg::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1.5px;
  background: linear-gradient(145deg,
    rgba(255, 255, 255, calc(var(--lg-light) * .95)) 0%,
    rgba(255, 255, 255, calc(var(--lg-light) * .25)) 32%,
    rgba(255, 255, 255, calc(var(--lg-light) * .06)) 52%,
    rgba(255, 255, 255, calc(var(--lg-light) * .35)) 74%,
    rgba(255, 255, 255, calc(var(--lg-light) * .90)) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}

/* ------------------------------------------------------------------ shapes -- */

.lg--circle { border-radius: 50%; aspect-ratio: 1; display: grid; place-items: center; }
.lg--pill   { border-radius: 999em; }
.lg--card   { --lg-radius: 26px; }

/* ------------------------------------------------------------- bend levels -- */
/* The lenses live in liquid-glass.js. Without that script these classes are
   inert and the element stays frosted-but-flat, which is a safe fallback.

   ⛔ PICK BY SIZE **AND** SHAPE.

     shape / size                     use
     ------------------------------   ----------------
     round or square, >=140px         lg--bend-strong
     round or square, 80-140px        lg--bend-medium
     round or square, <80px           lg--bend-soft
     WIDE RECTANGLE (card, bar, pill) lg--bend-soft   <- always

   Two independent traps, both seen for real:

   (a) SIZE. The bend is a fraction of the ELEMENT but the detail behind it is
       fixed in pixels, so the same setting bends far harder on a small element.
       strong on a 72px button turns a face to soup.

   (b) SHAPE. The lens map is a SPHERE. Stretched across a wide rectangle it
       becomes an ellipse and the far edges displace so hard the backdrop
       MIRRORS AND REPEATS - a hand appeared twice, flipped, on a test card.
       Soft is clean on wide shapes; medium and strong are not. */

.lg--bend-soft   { backdrop-filter: blur(var(--lg-blur)) url(#lg-bend-soft)   saturate(var(--lg-saturate)); }
.lg--bend-medium { backdrop-filter: blur(var(--lg-blur)) url(#lg-bend-medium) saturate(var(--lg-saturate)); }
.lg--bend-strong { backdrop-filter: blur(var(--lg-blur)) url(#lg-bend-strong) saturate(var(--lg-saturate)); }

/* ------------------------------------------------------------- interaction -- */

.lg--press {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 320ms cubic-bezier(.2, .9, .25, 1), box-shadow 320ms ease;
}
.lg--press:hover  { transform: scale(1.04); }
.lg--press:active { transform: scale(.97); }
.lg--press:focus-visible { outline: 3px solid #fff; outline-offset: 6px; }

/* --------------------------------------------------------------- contents --- */

/* Anything sitting ON the glass needs grounding — it floats over whatever is
   behind, which may be light or dark. */
.lg-mark {
  position: relative;
  filter:
    drop-shadow(0 0 10px rgba(255, 255, 255, .5))
    drop-shadow(0 2px 5px rgba(0, 0, 0, .45));
}

/* --------------------------------------------------------------- on dark ---- */

.lg--on-dark { --lg-light: .35; --lg-dark: 2; }

/* -------------------------------------------------------------- fallbacks --- */

@media (prefers-reduced-transparency: reduce) {
  .lg {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background-color: rgba(255, 255, 255, .86);
  }
  .lg--on-dark { background-color: rgba(20, 20, 24, .9); }
}

@media (prefers-reduced-motion: reduce) {
  .lg--press { transition: none; }
  .lg--press:hover, .lg--press:active { transform: none; }
}
