/**
 * Effects Accessibility, Responsive Degradation & Print
 *
 * Centralized policies for ALL effect systems. Loaded after individual
 * effect CSS files. Uses pattern selectors to cover current and future
 * effect classes without enumeration.
 *
 * Sections:
 * 1. Reduced Motion
 * 2. High Contrast
 * 3. Reduced Transparency
 * 4. Touch / Hover Fallback
 * 5. Tablet Responsive Degradation (768–1023px)
 * 6. Mobile Responsive Degradation (< 768px)
 * 7. Schema Override Classes (fx-responsive-full, fx-responsive-minimal)
 * 8. Containment & Off-Screen Optimization
 * 9. Print
 */

/* ==========================================================================
   1. Reduced Motion — disable all decorative motion
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {

    /* Image: Ken Burns, hover zoom transitions */
    [class*="img-anim-"] .img-effect__img {
        animation: none !important;
        transform: scale(1) !important;
    }
    [class*="img-hover-"] .img-effect__img {
        transition: none !important;
    }

    /* Border: spinning, pulsing, dashing, shimmering */
    [class*="border-fx-animated"]::before,
    [class*="border-fx-animated"] {
        animation: none !important;
    }

    /* Text: CSS animated effects */
    .text-fx-gradient-flow,
    .text-fx-gradient-rotate,
    .text-fx-shimmer,
    .text-fx-glow-pulse,
    .text-fx-color-cycle,
    .text-fx-blur-in,
    .text-fx-reveal-right,
    .text-fx-reveal-up {
        animation: none !important;
    }

    /* Ensure reveal effects are visible */
    .text-fx-blur-in {
        filter: none !important;
        opacity: 1 !important;
    }
    .text-fx-reveal-right,
    .text-fx-reveal-up {
        clip-path: none !important;
    }

    /* Entry animations — show immediately */
    [class*="animate-"] {
        opacity: 1 !important;
        transform: none !important;
        animation: none !important;
        transition: none !important;
    }

    /* Shadow hover transitions */
    [class*="shadow-fx-"] {
        transition: none !important;
    }

    /* Background: particles, mesh drift, noise film-grain */
    .bg-layers__particles {
        animation-play-state: paused !important;
    }
    /* 3D scene layer: bg-scenes.js already refuses to run under reduced
       motion, so the canvas never gets its .is-ready class — this is the
       CSS-side belt-and-suspenders in case it was somehow left visible. */
    .bg-layers__scene {
        display: none !important;
    }
    [data-bg-mesh] .bg-layers__base::before {
        animation: none !important;
    }
    [data-bg-noise="film-grain"] .bg-layers__noise::before {
        animation: none !important;
    }

    /* Cursor effects — no lerp animation visible */
    .plexa-cursor {
        display: none !important;
    }
    body.has-custom-cursor,
    body.has-custom-cursor a,
    body.has-custom-cursor button,
    body.has-custom-cursor [role="button"] {
        cursor: auto !important;
    }

    /* View transitions — instant swap */
    ::view-transition-old(root),
    ::view-transition-new(root) {
        animation-duration: 0s !important;
    }

    /* Scroll progress bar — no transition */
    .scroll-progress-bar {
        transition: none !important;
    }

    /* GSAP: handled in JS via gsap.matchMedia(), not CSS.
       JS sets opacity:1 and skips SplitText initialization. */
}

/* ==========================================================================
   2. High Contrast — remove decorative effects that reduce clarity
   ========================================================================== */

@media (prefers-contrast: more) {

    /* Image: remove filters, overlays, blends */
    [class*="img-fx-"] img {
        filter: none !important;
    }
    .img-effect::before,
    .img-effect::after {
        display: none !important;
    }

    /* Border: remove gradient/glow decorations, keep solid borders */
    [class*="border-fx-gradient"],
    [class*="border-fx-animated"] {
        background: none !important;
        border-color: currentColor !important;
    }
    [class*="border-fx-glow"] {
        box-shadow: none !important;
    }

    /* Text: remove gradients, glows, strokes — restore plain text */
    [class*="text-fx-"] {
        -webkit-text-fill-color: unset !important;
        background: none !important;
        -webkit-background-clip: unset !important;
        background-clip: unset !important;
        text-shadow: none !important;
        -webkit-text-stroke: 0 !important;
        filter: none !important;
    }

    /* Shadows: simplify to single minimal shadow */
    [class*="shadow-fx-"] {
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3) !important;
    }

    /* Glass: replace with solid opaque background */
    [class*="glass-fx-"] {
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        background: var(--color-base-100) !important;
        border: 2px solid var(--color-base-content) !important;
    }
}

/* ==========================================================================
   3. Reduced Transparency — replace translucent with opaque
   ========================================================================== */

@media (prefers-reduced-transparency: reduce) {

    /* Glass: solid opaque background */
    [class*="glass-fx-"] {
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        background: var(--color-base-100) !important;
        opacity: 1 !important;
    }

    /* Overlay opacity → near-opaque */
    .bg-layers__overlay {
        opacity: 0.9 !important;
    }

    /* Image overlays — opaque */
    .img-effect::before {
        opacity: 0.9 !important;
    }
}

/* ==========================================================================
   4. Touch / Hover Fallback — suppress hover on touch-only devices
   ========================================================================== */

@media (hover: none) {

    /* Image hover: show at default state (no zoom on tap) */
    [class*="img-hover-"] .img-effect__img {
        transform: none !important;
        transition: none !important;
    }

    /* Border hover: show static border (no animation trigger) */
    .border-fx-on-hover {
        animation-play-state: paused;
    }

    /* Text hover effects: no transitions */
    [class*="text-fx-hover-"] {
        transition: none !important;
    }

    /* Shadow hover effects: static */
    [class*="shadow-fx-"][class*="hover"] {
        transition: none !important;
    }
}

/* ==========================================================================
   5. Tablet Degradation (768–1023px) — reduced animation
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

    /* Image: Ken Burns disabled */
    :not(.fx-responsive-full) [class*="img-anim-ken-burns"] .img-effect__img {
        animation: none !important;
        transform: scale(1) !important;
    }

    /* Border: animated → static; glow intensity reduced */
    :not(.fx-responsive-full) [class*="border-fx-animated"]::before,
    :not(.fx-responsive-full) [class*="border-fx-animated"] {
        animation: none !important;
    }
    :not(.fx-responsive-full) [class*="border-fx-glow"] {
        --border-fx-glow-spread: calc(var(--border-fx-glow-spread, 8px) * 0.7);
    }

    /* Text: GSAP animations disabled via JS matchMedia.
       CSS animated text effects preserved. */

    /* Glass: reduced blur */
    :not(.fx-responsive-full) [class*="glass-fx-"] {
        --glass-blur: 10px;
    }

    /* Scroll UX: dot nav hidden */
    .section-dot-nav {
        display: none !important;
    }

    /* Background: mesh limited speed */
    :not(.fx-responsive-full) [data-bg-mesh] .bg-layers__base::before {
        --mesh-speed: 40s;
    }
}

/* ==========================================================================
   6. Mobile Degradation (< 768px) — static only
   ========================================================================== */

@media (max-width: 767px) {

    /* Image: disable Ken Burns and hover effects */
    :not(.fx-responsive-full) [class*="img-anim-"] .img-effect__img {
        animation: none !important;
        transform: scale(1) !important;
    }

    /* Border: disable continuous animations, reduce glow */
    :not(.fx-responsive-full) [class*="border-fx-animated"]::before,
    :not(.fx-responsive-full) [class*="border-fx-animated"] {
        animation: none !important;
    }
    :not(.fx-responsive-full) [class*="border-fx-glow"] {
        --border-fx-glow-spread: calc(var(--border-fx-glow-spread, 8px) * 0.5);
    }

    /* Text: disable CSS animated effects */
    :not(.fx-responsive-full) .text-fx-shimmer,
    :not(.fx-responsive-full) .text-fx-gradient-flow,
    :not(.fx-responsive-full) .text-fx-gradient-rotate,
    :not(.fx-responsive-full) .text-fx-glow-pulse,
    :not(.fx-responsive-full) .text-fx-color-cycle {
        animation: none !important;
    }

    /* Text: reduce glow size */
    :not(.fx-responsive-full) [class*="text-fx-glow"] {
        --text-fx-glow-size: calc(var(--text-fx-glow-size, 20px) * 0.6);
    }

    /* Glass: disabled on mobile — solid fallback */
    :not(.fx-responsive-full) [class*="glass-fx-"] {
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
    }

    /* Shadows: capped at simpler presets */
    :not(.fx-responsive-full) [class*="shadow-fx-"] {
    }

    /* Background: particles disabled, mesh static, noise reduced */
    :not(.fx-responsive-full) .bg-layers__particles {
        display: none !important;
    }
    /* 3D scene layer: same tablet/mobile degrade as particles — the poster
       underneath (part of the normal background stack) stays visible. */
    :not(.fx-responsive-full) .bg-layers__scene {
        display: none !important;
    }
    :not(.fx-responsive-full) [data-bg-mesh] .bg-layers__base::before {
        animation: none !important;
    }
    :not(.fx-responsive-full) [data-bg-noise] .bg-layers__noise::before {
        opacity: 0.04 !important;
    }

    /* Scroll UX: dot nav hidden, progress bar thin, scroll-to-top touch target */
    .section-dot-nav {
        display: none !important;
    }
    .scroll-progress-bar {
        height: 2px !important;
    }
    .scroll-to-top {
        min-width: 44px !important;
        min-height: 44px !important;
    }

    /* Cursor effects: always hidden on mobile (also handled in cursor-effects.css) */
    .plexa-cursor {
        display: none !important;
    }
}

/* ==========================================================================
   7. Schema Override Classes
   ========================================================================== */

/**
 * .fx-responsive-full — disable responsive degradation.
 * Applied to section elements via effects_responsive: "full" schema property.
 * The :not(.fx-responsive-full) guards in §5/§6 above exclude these sections.
 * No additional CSS needed here.
 */

/**
 * .fx-responsive-minimal — force mobile-tier effects at all viewports.
 * Applied to section elements via effects_responsive: "minimal".
 */
.fx-responsive-minimal [class*="border-fx-animated"],
.fx-responsive-minimal [class*="border-fx-animated"]::before {
    animation: none !important;
}

.fx-responsive-minimal .text-fx-shimmer,
.fx-responsive-minimal .text-fx-gradient-flow,
.fx-responsive-minimal .text-fx-gradient-rotate,
.fx-responsive-minimal .text-fx-glow-pulse,
.fx-responsive-minimal .text-fx-color-cycle {
    animation: none !important;
}

.fx-responsive-minimal [class*="animate-"] {
    animation: none !important;
    transition: none !important;
}

.fx-responsive-minimal [class*="glass-fx-"] {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
}

.fx-responsive-minimal .bg-layers__particles {
    display: none !important;
}

.fx-responsive-minimal .bg-layers__scene {
    display: none !important;
}

.fx-responsive-minimal [data-bg-mesh] .bg-layers__base::before {
    animation: none !important;
}

.fx-responsive-minimal [class*="img-anim-"] .img-effect__img {
    animation: none !important;
    transform: scale(1) !important;
}

/* ==========================================================================
   8. Containment & Off-Screen Optimization
   ========================================================================== */

/* REMOVED 2026-09-15 — content-visibility: auto on .plexa-content-section.
   Approved by Rick after measurement.

   It read as a free performance win and was the single cause of step 10's
   "nothing plays". With contain-intrinsic-size: auto 600px every off-screen
   section is a 600px guess, so the document has no settled height: the same
   page measured 7,469 / 12,123 / 14,186 / 23,062px on four consecutive loads,
   depending only on which sections happened to have rendered. With this rule
   gone it measures 7,549px on every load.

   Nothing that reads a scroll position survives that. ScrollTrigger caches each
   trigger's start/end at creation against placeholder geometry and leaves the
   heading in its gsap.from() state — opacity 0 — believing it is far below the
   fold. The heading is then not un-animated, it is INVISIBLE, and stays so
   because the sections keep expanding as you scroll and move the target again.
   section-parallax's cached offsetTop and section-reveal's thresholds fail the
   same way from the same cause.

   This was worked around once (ee497c6) with ScrollTrigger.refresh() on load,
   resize and first scroll. A refresh cannot win a race against geometry that
   changes every time a section scrolls into view, and the pages stayed broken.
   Do not reintroduce it. If off-screen cost ever needs addressing it has to be
   on sections carrying no scroll-driven effect, with a measured
   contain-intrinsic-size rather than a guess. */

/* Paint containment for overflow-hidden effect containers.

   NOT ON CHROME. `contain: paint` clips every descendant to the element's own
   box — overflow: hidden, but stronger and not overridable from inside. The
   site header carries `glass-fx-frosted-nav`, so this rule was clipping the
   header to itself, and with it every dropdown the nav opens.

   Measured on the live page 2026-09-16, because four hypotheses had already
   been wrong: on hover the mega panel is display: block, 264px tall, correctly
   positioned at x=0 w=1920 with its full contents — and
   document.elementFromPoint() in the middle of it returns the page content
   behind, because the panel never paints. The menu was not failing to open. It
   was opening inside a box that refused to show it.

   Glass is a surface treatment, not a container: `backdrop-filter` already
   makes its own containing block and needs no help clipping. The two cases
   this rule exists for both genuinely overflow — a ken-burns image scales past
   its frame, a section shape clips to a path — and neither is chrome. The
   three chrome levels are excluded by name because CSS cannot say "an element
   that contains a menu". */
[class*="glass-fx-"]:not(.site-header):not(.header-bars):not(.bar),
.img-anim-ken-burns,
[class*="section-shape-"] {
    contain: paint;
}

/* ==========================================================================
   9. Print — strip all decorative effects, save ink
   ========================================================================== */

@media print {

    /* ── Animations & Transitions ── */
    [class*="img-fx-"],
    [class*="border-fx-"],
    [class*="text-fx-"],
    [class*="shadow-fx-"],
    [class*="glass-fx-"],
    [class*="animate-"] {
        animation: none !important;
        transition: none !important;
    }

    /* ── Shadows (ink saving) ── */
    [class*="shadow-fx-"] {
        box-shadow: none !important;
    }
    .text-fx-glow,
    .text-fx-glow-intense,
    .text-fx-glow-pulse,
    [class*="text-fx-shadow"] {
        text-shadow: none !important;
    }

    /* ── Image filters ── */
    [class*="img-fx-"] img {
        filter: none !important;
    }
    .img-effect {
        transform: none !important;
    }

    /* ── Image overlays & gradients ── */
    .img-effect::before,
    .img-effect::after {
        display: none !important;
    }

    /* ── Glassmorphism ── */
    [class*="glass-fx-"] {
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        background: white !important;
        border: 1px solid #ccc !important;
    }

    /* ── Borders: no gradients, glows, animations ── */
    [class*="border-fx-gradient"],
    [class*="border-fx-animated"] {
        background: none !important;
        border-color: currentColor !important;
    }
    [class*="border-fx-glow"] {
        box-shadow: none !important;
        border: 1px solid currentColor !important;
    }
    [class*="border-fx-"]::before,
    [class*="border-fx-"]::after {
        display: none !important;
    }

    /* ── Text effects — restore readability ── */
    [class*="text-fx-"] {
        -webkit-text-fill-color: unset !important;
        background: none !important;
        -webkit-background-clip: unset !important;
        background-clip: unset !important;
        text-shadow: none !important;
        -webkit-text-stroke: 0 !important;
        filter: none !important;
        animation: none !important;
        clip-path: none !important;
        color: black !important;
    }

    /* ── Decorative pseudo-elements ── */
    .border-fx-animated::before,
    .border-fx-animated::after,
    .bg-layers__noise,
    .bg-layers__particles,
    .bg-layers__scene,
    .bg-layers__overlay,
    .bg-layers__pattern {
        display: none !important;
    }

    /* ── Background effects (ink saving) ── */
    [data-bg-mesh] .bg-layers__base::before {
        display: none !important;
    }
    .bg-layers__base {
        background: white !important;
    }

    /* ── Cursor & scroll UX ── */
    .plexa-cursor,
    .section-dot-nav,
    .scroll-to-top,
    .scroll-progress-bar {
        display: none !important;
    }

}
