﻿/* ============================================================
   LIQUID GLASS  (lucasromerodb 4-layer adaptation, restored)

   Structure injected by liquid-glass.js — first children of every
   targeted glass surface, in this DOM order:

       <span class="lq-effect" aria-hidden="true"></span>  ← refractive lens (backdrop blur + SVG warp)
       <span class="lq-tint"   aria-hidden="true"></span>  ← legibility wash (the layer that hides
                                                              the turbulence ripple over empty areas)
       <span class="lq-shine"  aria-hidden="true"></span>  ← inset rim / specular highlight
       …original content…                                  ← lifted to z-index:3, never warped

   IMPORTANT — DO NOT add `position`, `isolation` or `overflow` to
   `.lq-glass` with !important. Each adopted surface in site.css
   already declares the correct positioning. Forcing
   `position: relative` on `.dropdown-menu` (which is `position:
   absolute`) collapses the menu back into its parent <li> and
   balloons the navbar.
   ============================================================ */

/* ---------- Wrapper ----------
   Defeat any pre-existing translucent fill / border / backdrop-filter /
   ::before / ::after on adopted surfaces — the four-layer primitive
   supplies its own visual chrome. We DO NOT touch position / isolation
   / overflow here. */
.lq-glass {
    background: transparent !important;
    -webkit-backdrop-filter: none !important;
            backdrop-filter: none !important;
    border-color: transparent !important;
    box-shadow:
        0 6px 24px rgba(15, 22, 38, 0.18),
        0 0 0 1px rgba(255, 255, 255, 0.10) inset,
        0 12px 48px rgba(15, 22, 38, 0.12);
}
.lq-glass::before,
.lq-glass::after { content: none !important; background: none !important; }

/* ---------- Layer 1: refractive lens ----------
   Owns BOTH the backdrop blur AND the SVG displacement filter, because
   `filter: url(#…)` works while `backdrop-filter: url(#…)` does NOT in
   any current browser. The blurred backdrop becomes the SourceGraphic
   that the displacement map then warps. */
.lq-glass > .lq-effect {
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    -webkit-backdrop-filter: blur(3px) saturate(140%);
            backdrop-filter: blur(3px) saturate(140%);
    /* NOTE: SVG displacement (`filter: url(#sl-glass-warp)`) is intentionally
       NOT applied here. The base `.lq-glass` only provides the blurred /
       tinted / shined glass surface. The actual liquid distortion is opt-in
       and only kicks in when the surface ALSO carries `.lq-dist`
       (see the `.lq-glass.lq-dist > .lq-effect` rule below). */
    /* Match the lucasromerodb sample: clip the displacement to the layer
       bounds and create an isolated stacking context so the warp acts
       only on the backdrop captured by this layer. */
    overflow: hidden;
    isolation: isolate;
    pointer-events: none;
}

/* ---------- Opt-in distortion ----------
   Add the `lq-dist` class alongside `lq-glass` (or any of the adopted
   surface classes) to enable the SVG displacement warp. Without it the
   surface stays as a plain frosted-glass plate. */
.lq-glass.lq-dist > .lq-effect {
    filter: url(#sl-glass-warp);
}

/* ---------- Layer 2: tint (legibility wash) ----------
   This is the layer that hides the turbulence ripple over flat /
   empty backgrounds. Without it the warp by itself produces visible
   noise on dark areas.
   注意: 値が濃すぎると navbar / floatingCartButton など \u201c透過させたい\u201d
   サーフェスが真っ白に曇って見える。可読性確保最低限まで薄くする。
   ホストごとに --lq-tint-alpha を上書きすればさらに微調整可能。 */
.lq-glass > .lq-tint {
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit;
    background: rgba(255, 255, 255, var(--lq-tint-alpha, 0.06));
    pointer-events: none;
}

/* ---------- Layer 3: shine (glass meniscus / specular rim) ---------- */
.lq-glass > .lq-shine {
    position: absolute;
    inset: 0;
    z-index: 2;
    border-radius: inherit;
    box-shadow:
        inset  2px  2px 1px 0 rgba(255, 255, 255, 0.55),
        inset -1px -1px 1px 1px rgba(255, 255, 255, 0.45);
    pointer-events: none;
}

/* ------------------------------------------------------------
   Hard-pin the three injected layer spans to absolute fill.

   Some hosts (notably `#floatingCartButton`) carry an ID-based
   rule like `#floatingCartButton > * { position: relative; ... }`
   in site.css that — because of ID specificity — wins against the
   plain `.lq-glass > .lq-tint` / `.lq-shine` rules above. When
   that happens the three layer spans become real flex/grid items
   inside `display: inline-flex` hosts and shove the actual icon
   sideways (visible misalignment of the cart icon).

   Re-assert the layer geometry with `!important` so per-host
   selectors can never accidentally promote a layer to a
   participating flow item.
   ------------------------------------------------------------ */
.lq-glass > .lq-effect,
.lq-glass > .lq-tint,
.lq-glass > .lq-shine {
    position: absolute !important;
    inset: 0 !important;
    pointer-events: none !important;
}

/* ---------- Layer 4: original content sits above all layers ---------- */
.lq-glass > :not(.lq-effect):not(.lq-tint):not(.lq-shine) {
    position: relative;
    z-index: 3;
}

/* ============================================================
   Per-surface overflow clipping
   Clip ONLY surfaces that are self-contained boxes.
   The navbar is intentionally excluded so its dropdown menu
   (position:absolute) can escape the pill.
   ============================================================ */
.modal-content.lq-glass,
.toast.lq-glass,
.hero.lq-glass,
.checkout-glass.lq-glass,
.dropdown-menu.lq-glass,
#floatingCartButton.lq-glass,
.card.lq-glass,
.alert.lq-glass,
.breadcrumb.lq-glass,
.feature-tile.lq-glass,
.news-panel.lq-glass,
.glass.lq-glass,
.glassmorphism.lq-glass {
    overflow: hidden;
}

/* ============================================================
   Per-surface adoptions (rounded corners etc.)
   ============================================================ */

/* Dropdown */
.dropdown-menu.lq-glass { padding: 8px; }

/* Modal */
.modal-content.lq-glass { border-radius: var(--r-lg, 22px); }

/* Toast */
.toast.lq-glass { border-radius: var(--r-xl, 28px); }

/* Floating cart button — circular droplet */
#floatingCartButton.lq-glass { border-radius: 50% !important; }
#floatingCartButton.lq-glass > i,
#floatingCartButton.lq-glass > #floatingCartIcon { position: relative; z-index: 3; }

/* Navbar — pill-shaped (NO overflow:hidden — dropdown must escape) */
.navbar.lq-glass { border-radius: var(--r-pill, 999px) !important; }

/* Hero */
.hero.lq-glass { border-radius: var(--r-2xl, 32px) !important; }
/* Re-instate the drifting aurora blobs that the wrapper's ::after reset
   would otherwise wipe out. They sit BEHIND every layer (z-index:-1) and
   read through the lens, contributing to the liquid feel. */
.hero.lq-glass::after {
    content: "" !important;
    position: absolute;
    inset: -10%;
    background:
        radial-gradient(28rem 22rem at 18% 30%, rgba(75,107,255,.30), transparent 60%),
        radial-gradient(24rem 20rem at 82% 80%, rgba(43,184,168,.28), transparent 60%),
        radial-gradient(20rem 16rem at 70% 12%, rgba(231,111,156,.22), transparent 60%);
    filter: blur(8px);
    z-index: -1;
    pointer-events: none;
    animation: liquidDrift 24s ease-in-out infinite alternate;
}

/* Checkout glass shell */
.checkout-glass.lq-glass { border-radius: var(--r-2xl, 32px) !important; }

/* Generic tile / panel — keep their existing radius */
.feature-tile.lq-glass,
.news-panel.lq-glass,
.glass.lq-glass,
.glassmorphism.lq-glass {
    border-radius: var(--r-lg, 22px);
}

/* ============================================================
   "Floating" surfaces — dropdown / modal / toast.

   Goal: same look as the navbar — actual refraction of whatever
   sits behind the surface (NOT a fake painted gradient).

   For that to work the lens layer must be able to sample the real
   page content as its backdrop. The only knob we touch here is the
   blur intensity (heavier blur → smoother source for the warp) and
   the tint alpha (light enough to let the warp read through).
   ============================================================ */
.dropdown-menu.lq-glass > .lq-effect,
.modal-content.lq-glass > .lq-effect,
.toast.lq-glass > .lq-effect {
    -webkit-backdrop-filter: blur(10px) saturate(160%);
            backdrop-filter: blur(10px) saturate(160%);
}

/* ------------------------------------------------------------
   Anti-flicker: also apply the blur to the HOST element itself.

   Why: while the host is mid-animation it carries either
   `transform != none` (dropdown/toast slide) or `opacity < 1`
   (fade-in/out). Both turn the host into a backdrop root, which
   silently disconnects any DESCENDANT `backdrop-filter` (i.e.
   `.lq-effect`) from the real page. The blur then only kicks in
   the moment the animation ends and `transform`/`opacity` snap
   back to neutral, producing:
     - "blur appears late" on open, and
     - "a frame of un-blurred flash" on close.

   An element's OWN `backdrop-filter` is not affected by it being
   a backdrop root — only descendants are. So mirroring the same
   blur onto the host eliminates the gap without needing to
   neutralize the open/close transform animation.
   ------------------------------------------------------------ */
.dropdown-menu.lq-glass,
.modal-content.lq-glass,
.toast.lq-glass {
    -webkit-backdrop-filter: blur(10px) saturate(160%) !important;
            backdrop-filter: blur(10px) saturate(160%) !important;
}

/* ------------------------------------------------------------
   Break backdrop-root barriers on adopted surfaces.

   Per W3C filter-effects-2, an element with `isolation: isolate`
   (and a few other properties) becomes a "backdrop root", which
   prevents any descendant's `backdrop-filter` from sampling
   pixels outside that element. site.css declares
   `isolation: isolate` on `.modal-content`, `.dropdown-menu`,
   `.navbar`, `.toast`, etc., so the injected `.lq-effect` child
   only saw the (transparent) parent box — which is why the SVG
   warp had nothing to displace and the lens looked dead.

   Clipping and stacking are still owned by `.lq-effect` itself
   (`overflow:hidden; isolation:isolate;` in its own rule), so it
   is safe to drop these on the wrapper.
   ------------------------------------------------------------ */
.navbar.lq-glass,
.dropdown-menu.lq-glass,
.modal-content.lq-glass,
.toast.lq-glass,
#floatingCartButton.lq-glass,
.hero.lq-glass,
.checkout-glass.lq-glass,
.feature-tile.lq-glass,
.news-panel.lq-glass,
.glass.lq-glass,
.glassmorphism.lq-glass {
    isolation: auto !important;
    -webkit-mask-image: none !important;
            mask-image: none !important;
}

/* ------------------------------------------------------------
   Suppress backdrop-root caused by `filter: blur(...)` left over
   from animations.

   site.css defines `liquidPopIn` (modal), `liquidToastIn` (toast)
   and `liquidDropdownIn` (dropdown) keyframes whose final frame
   sets `filter: blur(0)`. With `animation-fill-mode: both`, that
   computed `filter` value (≠ none) persists on `.modal-content`,
   `.toast`, `.dropdown-menu` even after the animation ends —
   which makes those hosts a backdrop root and leaves the inner
   `.lq-effect`'s `backdrop-filter` (and therefore the SVG warp's
   SourceGraphic) reading from an empty parent box. Result: no
   visible distortion despite all rules being applied.

   Author `!important` beats animation values per CSS Cascade L4,
   so we can force the host filter back to `none` here. The lens
   itself keeps its own `filter: url(#sl-glass-warp)` on the
   `.lq-effect` child, which is what we actually want to render.
   ------------------------------------------------------------ */
/* ------------------------------------------------------------
   Suppress backdrop-root caused by host `filter` / `transform`.

   An element becomes a "backdrop root" (and therefore severs
   its descendants' `backdrop-filter` from the real page) if it
   has — among others — `filter ≠ none`, `transform ≠ none`,
   `perspective ≠ none`, `will-change: transform|filter|...`,
   `mask`, `clip-path`, `opacity < 1`, or `isolation: isolate`.

   site.css declares the following on these hosts:
     .dropdown-menu : transform: translateY(-6px) scale(.96)
                     + isolation: isolate
                     + transition on transform
     .toast         : transform: translateY(-10px) scale(.96)
                     + isolation: isolate
     .modal-content : isolation: isolate
                     + liquidPopIn keyframes leave filter:blur(0)
                       and transform:scale(1,1) on the element
                       via animation-fill-mode: both.
     .navbar        : isolation: isolate (only — no transform,
                     no animation-driven filter; this is why the
                     navbar lens has always worked).

   To make the `.lq-effect` child see the real page again, force
   ALL these properties back to their root-neutral values on the
   host whenever it carries `.lq-dist`. Author `!important` beats
   animation values per CSS Cascade L4, and the host's own visual
   chrome is already taken over by the `.lq-glass` layer system,
   so we lose nothing by neutralizing them.

   NOTE: the open/close transform animation on dropdown / toast
   is intentionally sacrificed in favor of working refraction.
   The opacity / visibility transitions still fade them in.
   ------------------------------------------------------------ */
.navbar.lq-dist,
#floatingCartButton.lq-dist {
    filter: none !important;
    -webkit-filter: none !important;
    transform: none !important;
    perspective: none !important;
    -webkit-mask-image: none !important;
            mask-image: none !important;
    clip-path: none !important;
    will-change: auto !important;
    isolation: auto !important;
}

/* When the host is in its "shown" state, also force opacity:1 so
   it doesn't create a backdrop root via opacity<1. */
.navbar.lq-dist,
#floatingCartButton.lq-dist {
    opacity: 1 !important;
}

/* Floating cart button — small (60px) circular host. The shared
   `#sl-glass-warp` filter has `scale=80`, which is far too strong
   on a 60px box (displaced samples land outside the filter region
   and read as transparent → the lens looks empty). Switch the
   lens to the dedicated small-surface filter `#sl-glass-warp-sm`
   (defined in _Layout.cshtml, scale=22) so the same lucasromerodb
   pipeline still produces visible refraction at this size, and
   keep the button perfectly circular. */
#floatingCartButton.lq-glass.lq-dist > .lq-effect {
    filter: url(#sl-glass-warp-sm);
}
#floatingCartButton.lq-dist {
    /* Layer a softer blur on the host itself so the refraction has
       a smoother source even mid-animation. */
    -webkit-backdrop-filter: blur(8px) saturate(160%) !important;
            backdrop-filter: blur(8px) saturate(160%) !important;
}
#floatingCartButton.lq-glass > .lq-effect,
#floatingCartButton.lq-glass > .lq-tint,
#floatingCartButton.lq-glass > .lq-shine {
    border-radius: 50% !important;
}

.dropdown-menu.lq-glass {
    z-index: 1060;
}

/* Tints — keep them honest washes so the SVG warp of the real
   backdrop remains visible. */
.dropdown-menu.lq-glass > .lq-tint,
.modal-content.lq-glass > .lq-tint,
.toast.lq-glass > .lq-tint {
    background: rgba(255, 255, 255, 0.22);
}

@media (prefers-color-scheme: dark) {
    .dropdown-menu.lq-glass > .lq-tint,
    .modal-content.lq-glass > .lq-tint,
    .toast.lq-glass > .lq-tint {
        background: rgba(15, 22, 38, 0.34);
    }
}

/* ------------------------------------------------------------
   Bootstrap injects `.modal-backdrop` as a near-opaque dark sheet
   behind `.modal-content`. That sheet becomes the SourceGraphic
   for the lens, so the displacement has nothing real to refract —
   the modal ends up looking like a curved decoration on flat black.

   Make the backdrop transparent (only a faint dim + light blur)
   so the actual page content reaches the modal's lens. Bootstrap's
   "click-outside-to-dismiss" behavior is unaffected because the
   backdrop element itself is still present and clickable.
   ------------------------------------------------------------ */
.modal-backdrop,
.modal-backdrop.show,
.modal-backdrop.fade.show {
    background-color: rgba(15, 22, 38, 0.18) !important;
    opacity: 1 !important;
    -webkit-backdrop-filter: blur(2px) saturate(120%);
            backdrop-filter: blur(2px) saturate(120%);
}

/* ============================================================
   Press / hover micro-interactions (kept subtle)
   ============================================================ */
.lq-glass {
    transition:
        transform 320ms cubic-bezier(.34, 1.56, .64, 1),
        box-shadow 320ms cubic-bezier(.2, .8, .2, 1);
}
#floatingCartButton.lq-glass:hover { transform: scale(1.04); }
#floatingCartButton.lq-glass:active { transform: scale(0.94); }

/* ============================================================
   Dark mode — flip the tint and dim the shine
   ============================================================ */
@media (prefers-color-scheme: dark) {
    .lq-glass > .lq-tint {
        background: rgba(15, 22, 38, 0.42);
    }
    .lq-glass > .lq-shine {
        box-shadow:
            inset  2px  2px 1px 0 rgba(255, 255, 255, 0.30),
            inset -1px -1px 1px 1px rgba(255, 255, 255, 0.18);
    }
    .lq-glass {
        box-shadow:
            0 8px 28px rgba(0, 0, 0, 0.55),
            0 0 0 1px rgba(255, 255, 255, 0.06) inset,
            0 18px 60px rgba(0, 0, 0, 0.40);
    }
}

/* Per-element override: when liquid-glass.js detects a dark backdrop */
.lq-glass.is-on-dark > .lq-tint {
    background: rgba(15, 22, 38, 0.42);
}
.lq-glass.is-on-dark > .lq-shine {
    box-shadow:
        inset  2px  2px 1px 0 rgba(255, 255, 255, 0.30),
        inset -1px -1px 1px 1px rgba(255, 255, 255, 0.18);
}

/* ============================================================
   Accessibility / opt-out
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
    .lq-glass.lq-dist > .lq-effect { filter: none; }
}
body.no-refract .lq-glass.lq-dist > .lq-effect { filter: none; }

/* When Stripe iframe sits inside a .lq-glass wrapper we must NOT clip
   it inside the rounded glass; let .checkout-surface re-establish a
   non-overflowed surface for the iframe. */
.checkout-glass.lq-glass .checkout-surface { z-index: 3; position: relative; }
