/* ============================================================
   GLASS ENGINE v5 — CSS wave background + real backdrop-filter glass
   ------------------------------------------------------------
   Site-wide glass design system. Ported from design-preview/.
   No WebGL, no canvas, no shader — two things make this work:

     1. Background: pure inline SVG <path> wave strokes (markup
        lives in src/Views/partials/wave-background.php), rotated
        45deg via .wave-diagonal-rotor and scrolled with CSS only.
     2. Glass: real backdrop-filter blur (macOS/Windows Mica-style,
        genuine live blur of real pixels, not a fake effect), with
        a second heavier-blurred, edge-masked pseudo-element so the
        panel reads as glass-with-thickness instead of a flat
        uniform blur (see .glass::after comment below).

   Panels are tinted NEUTRAL BLACK (rgba(10,12,16,...)), not white/
   blue, so they look like tinted glass sitting over the blue wave
   background rather than a milky overlay recoloring it.
   ============================================================ */

:root {
    --glass-border: rgba(255, 255, 255, 0.14);
    --glass-shadow: 0 30px 80px -12px rgba(0, 0, 0, 0.6);
    --glass-radius: 22px;
}

/* IMPORTANT: do NOT put an opaque background on html/body.
   .bg-scene paints the full backdrop (gradient + waves) at
   z-index:-1. An opaque body background paints ABOVE that in
   normal stacking order and hides it completely.

   !important is required here: the existing layouts put a
   Tailwind utility class (bg-background) directly on <body>,
   and a class selector (bg-background) outranks a bare type
   selector (html, body) in specificity regardless of stylesheet
   order. Without !important, Tailwind's opaque background would
   silently win and hide the wave background again. */
html, body { background: transparent !important; }

/* -------------------------- wave-lines background --------------------- */

.bg-scene {
    position: fixed;
    inset: 0;
    z-index: -1;
    overflow: hidden;
    background: linear-gradient(180deg, #030b1e 0%, #05162f 55%, #071f42 100%);
}

/* Full-page 45deg diagonal wave field. .wave-diagonal-rotor is an
   oversized SQUARE (side = 100vw + 100vh, always >= the viewport
   diagonal) centered and rotated once (static rotation). Inside,
   one wide SVG scrolls horizontally forever; because the rotor is
   rotated, that horizontal scroll reads as diagonal motion. */

.wave-diagonal-rotor {
    position: absolute;
    top: 50%;
    left: 50%;
    width: calc(100vw + 100vh);
    height: calc(100vw + 100vh);
    transform: translate(-50%, -50%) rotate(45deg);
    transform-origin: center center;
    overflow: hidden;
}

.wave-diagonal-svg {
    display: block;
    width: 200%;
    height: 100%;
    animation: wave-diagonal-scroll 26s linear infinite;
}

@keyframes wave-diagonal-scroll {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
    .wave-diagonal-svg { animation: none !important; }
}

.bg-glow {
    position: absolute;
    inset: 0;
    background: radial-gradient(60% 45% at 50% 15%, rgba(120, 190, 255, 0.14), transparent 70%);
    pointer-events: none;
}

.bg-grain {
    position: absolute;
    inset: 0;
    opacity: 0.05;
    mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* -------------------------- core glass panel ------------------------- */

.glass {
    --mx: 30%;
    --my: 20%;
    --rx: 0deg;
    --ry: 0deg;
    position: relative;
    border-radius: var(--glass-radius);
    /* Lowered from 0.32/0.14 to 0.18/0.07 per feedback that panels
       read as too opaque/milky — wave background behind the glass
       should stay clearly visible through the tint. */
    background: linear-gradient(160deg, rgba(10, 12, 16, 0.18), rgba(10, 12, 16, 0.07) 65%);
    border: 1px solid var(--glass-border);
    box-shadow:
        var(--glass-shadow),
        inset 0 1px 0 rgba(255, 255, 255, 0.16),
        inset 0 -20px 34px -20px rgba(0, 0, 0, 0.35);
    backdrop-filter: blur(4px) saturate(100%) brightness(0.96);
    -webkit-backdrop-filter: blur(4px) saturate(100%) brightness(0.96);
    overflow: hidden;
    isolation: isolate;
    transform: perspective(900px) rotateX(var(--rx)) rotateY(var(--ry));
    transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.4s ease, border-color 0.3s ease;
}

/* Edge-only heavy blur ring — gives the panel a sense of thickness
   (center stays comparatively clear, edges go hazy) instead of a
   flat uniform blur across the whole surface. Fixed-pixel mask
   stops so the ring width stays constant regardless of panel size.

   BUG FIX: this pseudo-element used to have no z-index. A ::after
   is conceptually the LAST child of its element, and per CSS paint
   order, stacked children at the same stack level (z-index:auto)
   paint in tree order — so this ::after (which triggers its own
   stacking context via backdrop-filter) was painting ON TOP of the
   real content inside .glass (buttons, text, icons), not behind it.
   That's why buttons nested in a .glass panel (navbar "Go to
   gallery", view.php action buttons, the contact form submit
   button, etc.) looked smeared/blurred and visually sat "behind"
   the ring instead of being crisp glass buttons on top of it.

   z-index:-1 forces it into the negative-stack-level paint step,
   which happens BEFORE normal in-flow content — i.e. behind real
   children, in front of only the panel's own background/border.
   .glass has isolation:isolate, so this is scoped inside the panel
   and can't affect anything outside it. */
.glass::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    backdrop-filter: blur(24px) saturate(105%) brightness(0.85);
    -webkit-backdrop-filter: blur(24px) saturate(105%) brightness(0.85);
    -webkit-mask-image: radial-gradient(ellipse closest-side,
        transparent 0,
        transparent calc(100% - 34px),
        rgba(0, 0, 0, 0.4) calc(100% - 16px),
        black 100%);
    mask-image: radial-gradient(ellipse closest-side,
        transparent 0,
        transparent calc(100% - 34px),
        rgba(0, 0, 0, 0.4) calc(100% - 16px),
        black 100%);
}

.glass-strong {
    background: linear-gradient(160deg, rgba(10, 12, 16, 0.26), rgba(10, 12, 16, 0.11) 65%);
    backdrop-filter: blur(12px) saturate(100%) brightness(0.92);
    -webkit-backdrop-filter: blur(12px) saturate(100%) brightness(0.92);
}
.glass-subtle {
    background: linear-gradient(160deg, rgba(10, 12, 16, 0.10), rgba(10, 12, 16, 0.04) 65%);
    backdrop-filter: blur(6px) saturate(100%) brightness(0.97);
    -webkit-backdrop-filter: blur(6px) saturate(100%) brightness(0.97);
}
.glass-flat   { transform: none !important; }

/* Explicit overrides for pre-existing components that carry their own
   opaque background from legacy stylesheets (dashboard.css, landing.css)
   and also have .glass applied. Two-class selectors here (.sidebar.glass)
   are more specific than the legacy single-class rule (.sidebar), so this
   wins regardless of <link> tag order — the site's layout/spacing rules
   in those legacy files are left completely untouched, only `background`
   is retaken here so the glass panel underneath can show through. */
/* Bug fix: this used to be written as `nav.glass, footer.glass, ...`
   which — being !important and appearing after .glass-strong in this
   file — clobbered .glass-strong's intentionally MORE opaque
   background whenever an element had both classes (e.g. the landing
   navbar is `class="glass glass-strong"`). That silently made the
   navbar/footer LESS opaque than intended and is part of why the
   navbar didn't visually match design-preview/landing.html. Scoped
   the selector to only fire when .glass-strong is NOT also present. */
.sidebar.glass:not(.glass-strong),
nav.glass:not(.glass-strong),
footer.glass:not(.glass-strong),
header.glass:not(.glass-strong),
.builder-nav.glass:not(.glass-strong) {
    background: linear-gradient(160deg, rgba(10, 12, 16, 0.20), rgba(10, 12, 16, 0.09) 65%) !important;
}

/* Same pattern for dashboard/gallery-panel/legacy-style surfaces that
   also get .glass added in markup: two-class selectors always outrank
   the legacy single-class rule regardless of <link> load order (e.g.
   gallery-panel.css is loaded from gallery.php's own head section,
   which prints AFTER this stylesheet in dashboard.php — without this
   explicit override, .gp-panel's own opaque background would win on
   source-order alone despite identical specificity). Only `background`
   is retaken; padding/position/sizing rules in the legacy files are
   untouched. */
.stat-card.glass,
.masonry-card.glass,
.gp-panel.glass,
.empty-state.glass,
.glass-panel.glass,
.view-shell.glass,
.share-card.glass,
.ocr-section.glass,
.organize-card.glass,
.modal-content.glass {
    background: linear-gradient(160deg, rgba(10, 12, 16, 0.18), rgba(10, 12, 16, 0.07) 65%) !important;
}

/* view.php uses Tailwind CDN utility classes (bg-surface-200/40 etc.)
   directly alongside .glass on the same element. Tailwind's utilities
   are also single-class selectors of equal specificity, injected via
   <style type="text/tailwindcss"> in tailwind-config.php which loads
   BEFORE glass.css in base.php's <head> — so source order alone would
   already make glass.css win, but !important here makes that explicit
   and not dependent on remembering the include order. */
.glass[class*="bg-surface"],
.glass[class*="bg-primary-500/"] {
    background: linear-gradient(160deg, rgba(10, 12, 16, 0.17), rgba(10, 12, 16, 0.06) 65%) !important;
}

/* home.php's landing bento/hero panels (landing-home.css .lp-* classes)
   also carry their own semi-opaque rgba(14,14,20,...) backgrounds.
   Same two-class-selector override pattern as above. */
.lp-stat.glass,
.lp-step.glass,
.lp-card.glass,
.lp-mock.glass,
.lp-pricing-teaser.glass,
.lp-faq-item.glass,
.lp-cta-band.glass {
    background: linear-gradient(160deg, rgba(10, 12, 16, 0.17), rgba(10, 12, 16, 0.06) 65%) !important;
}

/* .gp-panel specifically also sets its own background-image gradient
   with `background:` shorthand at nearly-opaque values (gallery-panel.css)
   — the rule above already retakes that. It also relies on its own
   ::before for a border-gradient mask; left untouched since that's a
   decorative border effect, not the panel's opacity/fill. */

/* legacy attribute from earlier markup — no-op, harmless if left in HTML */
.glass-refract { }

/* specular highlight, tracked to pointer via --mx/--my */
.glass::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at var(--mx) var(--my), rgba(255, 255, 255, 0.28), transparent 45%);
    opacity: 0;
    mix-blend-mode: overlay;
    pointer-events: none;
    transition: opacity 0.35s ease;
    z-index: 2;
}

.glass:hover::before,
.glass:focus-within::before { opacity: 0.55; }

.glass:hover { box-shadow: var(--glass-shadow), inset 0 1px 0 rgba(255,255,255,0.55), 0 0 0 1px rgba(255,255,255,0.14); }

/* static rim highlight on the bevel edge — fixed, no rotation */
.glass-rim {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(155deg, rgba(255,255,255,.4), rgba(255,255,255,0) 40%, rgba(255,255,255,0) 70%, rgba(255,255,255,.2));
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    opacity: 0.6;
    pointer-events: none;
    z-index: 3;
}

/* one-shot click ripple, not a loop */
.glass-ripple-fx {
    position: absolute;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255,255,255,.85), rgba(255,255,255,0) 70%);
    transform: translate(-50%, -50%) scale(0);
    pointer-events: none;
    z-index: 4;
    animation: glass-ripple 0.75s ease-out forwards;
}

@keyframes glass-ripple {
    0%   { transform: translate(-50%, -50%) scale(0);  opacity: .9; }
    100% { transform: translate(-50%, -50%) scale(26); opacity: 0; }
}

/* --------------------------- glass controls --------------------------- */

.glass-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 11px 20px;
    border-radius: 14px;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: #f2f2f7;
    cursor: pointer;
    border: 1px solid var(--glass-border);
    background: linear-gradient(155deg, rgba(10,12,16,0.28), rgba(10,12,16,0.10));
    backdrop-filter: blur(10px) saturate(100%) brightness(0.92);
    -webkit-backdrop-filter: blur(10px) saturate(100%) brightness(0.92);
    box-shadow: inset 0 1px 0 rgba(255,255,255,.16), 0 8px 24px rgba(0,0,0,.35);
    transition: transform .18s ease, box-shadow .25s ease, border-color .25s ease;
    overflow: hidden;
    isolation: isolate;
    text-decoration: none;
}

.glass-btn::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at var(--mx, 50%) var(--my, 0%), rgba(255,255,255,.5), transparent 55%);
    opacity: 0.5;
    mix-blend-mode: overlay;
    pointer-events: none;
}

.glass-btn:hover  { transform: translateY(-2px); box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 14px 30px rgba(0,0,0,.4); }
.glass-btn:active { transform: translateY(0) scale(.97); }

/* Fixed to match the site's actual brand indigo (#6366f1/#818cf8,
   same as .btn-primary in style.css and .lp-btn-primary in
   landing-home.css) — this was previously copied straight from the
   design-preview mockup's cyan-blue accent without checking it
   against the real site palette, which is why the navbar's
   "Go to gallery" button rendered a completely different color
   than every other primary button on the site. */
.glass-btn-primary {
    color: #fff;
    background: linear-gradient(155deg, rgba(129,140,248,.55), rgba(99,102,241,.28));
    border-color: rgba(165, 180, 252, .5);
    box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 10px 26px rgba(99,102,241,.35);
}

.glass-btn-primary:hover:not(:active) {
    box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 14px 32px rgba(99,102,241,.5);
    border-color: rgba(165, 180, 252, .7);
}

.glass-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 13px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    color: #e4e6ea;
    border: 1px solid rgba(255,255,255,.14);
    background: rgba(10,12,16,.22);
    backdrop-filter: blur(8px) saturate(100%) brightness(0.94);
    -webkit-backdrop-filter: blur(8px) saturate(100%) brightness(0.94);
}

.glass-input {
    width: 100%;
    padding: 11px 14px;
    border-radius: 12px;
    color: #f2f2f7;
    border: 1px solid rgba(255,255,255,.14);
    background: rgba(6, 7, 10, 0.32);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    outline: none;
    font-size: 13px;
    transition: border-color .2s ease, box-shadow .2s ease;
}

.glass-input:focus {
    border-color: rgba(165, 180, 252, .6);
    box-shadow: 0 0 0 3px rgba(99,102,241,.25);
}

.glass-input::placeholder { color: rgba(214, 228, 236, .45); }

/* utility */
.glass-scrollbar::-webkit-scrollbar { width: 6px; }
.glass-scrollbar::-webkit-scrollbar-thumb { background: rgba(255,255,255,.18); border-radius: 999px; }
.glass-scrollbar::-webkit-scrollbar-track { background: transparent; }

@media (prefers-reduced-motion: reduce) {
    .glass { transition: none !important; }
}
