/**
 * Page Designer — FX Block CSS  (pd-blk-fx-*)
 *
 * Styles the runtime-added canvas / scrim / fallback layers inside any
 * element that carries data-pd-fx-preset="...".
 *
 * NAMESPACE: pd-blk-fx-* only. No shared selectors with any other tool.
 * THEMING: This is layout-only CSS. Visual colors come from the active
 *          shader (via u_accent uniform bound to data-pd-fx-accent).
 *          Admin theme tokens are NOT used here — the effect IS the
 *          visual; the panel chrome handles all theme-aware UI.
 *
 * Loaded by BOTH editor.php (canvas iframe) and frontend_page.php (public).
 */

/* ── Root: any element carrying a NON-EMPTY data-pd-fx-preset ──────
   The :not([data-pd-fx-preset=""]) guard is essential: clearing FX to
   "No Preset" sets the attribute to "" but does NOT remove it, and a bare
   [data-pd-fx-preset] selector matches on attribute PRESENCE. Without the
   guard, a since-cleared host (e.g. one later switched to a Slider) keeps
   FX layout (overflow/isolation + the child position:relative rule below),
   which hijacks the slider's own slide positioning and breaks its height. */
[data-pd-fx-preset]:not([data-pd-fx-preset=""]) {
    position: relative;
    overflow: hidden;
    isolation: isolate;
}

/* ── Layer position modes ─────────────────────────────────────────
   In-flow (default): effect fills the block in normal layout.
       No special CSS — base rules already handle this.

   Fullwidth (attr value "fullbleed" kept for backward compat):
       Visible layers stretch edge-to-edge across the viewport WIDTH
       while their height stays bound to the block. Achieved via a
       break-out pattern: position:absolute + left:50% + translateX(-50%)
       + width:100vw. The root's overflow is loosened so the wider canvas
       can paint beyond the block's horizontal box. */
[data-pd-fx-preset][data-pd-fx-layer="fullbleed"] {
    overflow: visible;
}
[data-pd-fx-preset][data-pd-fx-layer="fullbleed"] > .pd-blk-fx-surface,
[data-pd-fx-preset][data-pd-fx-layer="fullbleed"] > .pd-blk-fx-accent-overlay,
[data-pd-fx-preset][data-pd-fx-layer="fullbleed"] > .pd-blk-fx-scrim,
[data-pd-fx-preset][data-pd-fx-layer="fullbleed"] > .pd-blk-fx-fallback {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 100vw;
    height: 100%;
    max-width: 100vw;
}

/* Admin override pages: the left sidebar offsets the content, so a viewport-
   wide (100vw) fullbleed spills back over the sidebar/chrome. `#wrapper` exists
   ONLY on admin (public pages have none), so scope the containment there —
   fill the block's own (content-area) box instead of the raw viewport. Public
   pages keep the true edge-to-edge bleed. Higher #id specificity beats the
   fullbleed rule above — no !important. */
#wrapper [data-pd-fx-preset][data-pd-fx-layer="fullbleed"] > .pd-blk-fx-surface,
#wrapper [data-pd-fx-preset][data-pd-fx-layer="fullbleed"] > .pd-blk-fx-accent-overlay,
#wrapper [data-pd-fx-preset][data-pd-fx-layer="fullbleed"] > .pd-blk-fx-scrim,
#wrapper [data-pd-fx-preset][data-pd-fx-layer="fullbleed"] > .pd-blk-fx-fallback {
    left: 0;
    transform: none;
    width: 100%;
    max-width: 100%;
}

/* Blend nested blocks — when data-pd-fx-blend-mode is anything except
   "off" (or absent), the NESTED CONTENT BLOCKS blend with the effect
   underneath them using the chosen CSS mix-blend-mode. The effect canvas
   stays at z:0 (background); only the content's stacking is touched.
   The JS runtime sets --pd-fx-blend-content-mode + opacity on the FX root
   and CSS picks them up via custom properties. */
[data-pd-fx-preset][data-pd-fx-blend-mode]:not([data-pd-fx-blend-mode=""]):not([data-pd-fx-blend-mode="off"])
    > *:not(.pd-blk-fx-surface):not(.pd-blk-fx-scrim):not(.pd-blk-fx-accent-overlay):not(.pd-blk-fx-fallback):not(.pd-blk-fx-click-burst) {
    mix-blend-mode: var(--pd-fx-blend-content-mode, normal);
    opacity: var(--pd-fx-blend-content-opacity, 1);
}

/* ── Canvas surface ───────────────────────────────────────────────── */
.pd-blk-fx-surface {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    z-index: 0;
    pointer-events: none;
    /* Block 0,0,0 stacking-context fallback (paint behind any user content) */
}

/* ── Accent overlay (colored layer that blends with the canvas) ───
   Sits at z:0 same as the canvas, but appended AFTER the canvas in the
   DOM so it paints on top of it. mix-blend-mode then blends it down
   into the canvas pixels. Controlled by:
       data-pd-fx-accent-blend     → CSS mix-blend-mode value
       data-pd-fx-accent-strength  → opacity 0..100
   Runtime sets inline style.background + style.mixBlendMode + style.opacity. */
.pd-blk-fx-accent-overlay {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    transition: opacity 0.2s ease, background-color 0.2s ease;
}

/* ── Scrim (legibility layer between canvas and content) ─────────── */
.pd-blk-fx-scrim {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    transition: opacity 0.2s ease, background-color 0.2s ease;
}

/* ── Click Burst overlay (Click Response = "Burst") ───────────────
   Expanding ring spawned by the runtime at the click point. Lives 750ms
   then auto-removes. Sits ABOVE the canvas + accent overlay (z:2) so
   the burst is visible. `color` is set inline from the accent hex; the
   border-color uses currentColor so a colour change re-tints the ring. */
.pd-blk-fx-click-burst {
    position: absolute;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 2px solid currentColor;
    pointer-events: none;
    z-index: 2;
    transform: translate(-50%, -50%) scale(0);
    opacity: 0.9;
    color: rgba(255, 255, 255, 0.9);
    animation: pd-blk-fx-burst 0.72s cubic-bezier(.16,.84,.44,1) forwards;
}
@keyframes pd-blk-fx-burst {
    0%   { transform: translate(-50%, -50%) scale(0);  opacity: 0.95; border-width: 2px; }
    60%  { opacity: 0.55; border-width: 1.5px; }
    100% { transform: translate(-50%, -50%) scale(28); opacity: 0; border-width: 0.5px; }
}

/* ── Fallback (CSS gradient / static image when WebGL unavailable) ─ */
.pd-blk-fx-fallback {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
}

/* ── Direct children of an FX root render ABOVE the canvas + scrim ─
   Guarded with :not([data-pd-fx-preset=""]) — see the root rule above. A
   cleared host ("No Preset" leaves data-pd-fx-preset="") must NOT force its
   children to position:relative; that (0,6,0) rule otherwise beats the
   slider's .pd-sl-rt-slide{position:absolute;inset:0} and collapses slides
   to content height (the "container too tall / white gap" bug). */
[data-pd-fx-preset]:not([data-pd-fx-preset=""]) > *:not(.pd-blk-fx-surface):not(.pd-blk-fx-scrim):not(.pd-blk-fx-fallback):not(.pd-blk-fx-accent-overlay):not(.pd-blk-fx-click-burst) {
    position: relative;
    z-index: 2;
}

/* ── Opacity control via attribute (data-pd-fx-opacity="0..100") ─── */
[data-pd-fx-preset] > .pd-blk-fx-surface,
[data-pd-fx-preset] > .pd-blk-fx-fallback {
    opacity: 1;
}

/* NOTE: The editor-only dashed outline that previously appeared on
   .gjs-frame [data-pd-fx-preset]:not(.pd-blk-fx-painted) has been removed
   — it manifested as faint side "borders" inside the rendered effect even
   at Border Strength = 0. GrapesJS's own hover/select highlight is enough
   to indicate the component in edit mode; the FX visual itself signals it
   has an effect applied. */

/* ════════════════════════════════════════════════════════════════
   FX EXTRAS — Rotation + Position + Gooey-surface layout
   Introduced alongside the Gooey FX preset family.
   Custom props are written by fx_extras.js (applyRotation / applyPosition).
   ════════════════════════════════════════════════════════════════ */

/* Continuous spin keyframes, applied by JS to .pd-blk-fx-surface inline
   style. Composes scale(--pd-blk-fx-cover-scale) ahead of the rotation so
   the rotated rectangle still fully covers the container at every angle
   (no underlying container-card showing through corners). Cover scale is
   computed in fx_extras.js applyRotation() from container W/H. Composes
   with the static rotate-angle via --pd-blk-fx-rot-start so the animation
   continues FROM the user-chosen angle rather than snapping to 0. */
@keyframes pd-blk-fx-spin-cw {
    from { transform: scale(var(--pd-blk-fx-cover-scale, 1)) rotate(var(--pd-blk-fx-rot-start, 0deg)); }
    to   { transform: scale(var(--pd-blk-fx-cover-scale, 1)) rotate(calc(var(--pd-blk-fx-rot-start, 0deg) + 360deg)); }
}
@keyframes pd-blk-fx-spin-ccw {
    from { transform: scale(var(--pd-blk-fx-cover-scale, 1)) rotate(var(--pd-blk-fx-rot-start, 0deg)); }
    to   { transform: scale(var(--pd-blk-fx-cover-scale, 1)) rotate(calc(var(--pd-blk-fx-rot-start, 0deg) - 360deg)); }
}

/* Rotation backdrop — sibling div mounted behind the FX surface when
   rotation is active for shader/iframe presets. Filled with the active
   preset's fallback_css so the container card never shows through the
   corners after rotation. fx_extras.js mounts/removes via
   manageRotationBackdrop(). */
[data-pd-fx-preset] > .pd-blk-fx-rot-bed {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    /* Ensure it's strictly behind every other FX layer; siblings without
       z-index already paint above this thanks to source order + z-index 0. */
}

/* Position — surface flexbox alignment. Has visible effect only when the
   surface is sized smaller than its FX root (the Gooey case). For
   fullbleed canvas / iframe surfaces, justify-content is a no-op. */
[data-pd-fx-preset] {
    --pd-blk-fx-justify: center;
}
[data-pd-fx-preset] > .pd-blk-fx-gooey-surface {
    display: flex;
    align-items: center;
    justify-content: var(--pd-blk-fx-justify, center);
    /* Gooey surface fills the FX root; the stage inside sizes itself via
       --pd-blk-fxg-size and is aligned by justify-content above. */
    position: absolute;
    inset: 0;
    pointer-events: none;
}

/* The gooey stage is the actual paint area; sized by gooey_lib.css. */
[data-pd-fx-preset] > .pd-blk-fx-gooey-surface > .pd-blk-fxg-stage {
    pointer-events: auto;
}
