/**
 * Border Effects — Animated Borders
 *
 * Uses @property for smooth angle interpolation.
 * Pseudo-element approach keeps gradient behind content.
 *
 * NOTE: Animated borders on bg-layers elements are limited.
 * See plan 04 Section 5.6 for pseudo-element budget.
 */

/* ==========================================================================
   Animated Border Base
   ========================================================================== */

[class*="border-fx-animated"]:not(.border-fx-animated-pulse) {
    position: relative;
}

[class*="border-fx-animated"]:not(.border-fx-animated-pulse)::before {
    content: '';
    position: absolute;
    inset: calc(var(--border-fx-width, 2px) * -1);
    border-radius: inherit;
    z-index: -1;
    pointer-events: none;
}

/* ==========================================================================
   Animated Presets (4)
   ========================================================================== */

/* Spin — rotating conic gradient around border */
.border-fx-animated-spin::before {
    background: conic-gradient(
        from var(--border-fx-angle, 0deg),
        var(--color-primary),
        var(--color-secondary),
        var(--color-accent),
        var(--color-primary)
    );
    animation: border-fx-spin var(--border-fx-duration, 3s) linear infinite;
}

/* Pulse — glow intensity cycles */
.border-fx-animated-pulse {
    box-shadow:
        0 0 var(--border-fx-glow-spread, 8px) color-mix(in oklch, var(--color-primary) 40%, transparent),
        0 0 calc(var(--border-fx-glow-spread, 8px) * 2) color-mix(in oklch, var(--color-primary) 15%, transparent);
    animation: border-fx-pulse 2s ease-in-out infinite;
}

/* Dash — marching dashes effect using background gradient */
.border-fx-animated-dash::before {
    background: repeating-linear-gradient(
        90deg,
        var(--color-primary) 0,
        var(--color-primary) 8px,
        transparent 8px,
        transparent 16px
    );
    background-size: 200% 100%;
    animation: border-fx-shimmer 2s linear infinite;
}

/* Shimmer — light sweep across border */
.border-fx-animated-shimmer::before {
    background: linear-gradient(
        90deg,
        transparent 0%,
        color-mix(in oklch, var(--color-primary) 60%, transparent) 25%,
        color-mix(in oklch, var(--color-secondary) 80%, transparent) 50%,
        color-mix(in oklch, var(--color-primary) 60%, transparent) 75%,
        transparent 100%
    );
    background-size: 200% 100%;
    animation: border-fx-shimmer 3s ease-in-out infinite;
}

/* ==========================================================================
   @supports Fallback
   ========================================================================== */

@supports not (background: conic-gradient(from 0deg, red, blue)) {
    .border-fx-animated-spin::before {
        background: linear-gradient(135deg, var(--color-primary), var(--color-secondary));
        animation: none;
    }
}

/* ==========================================================================
   Animated presets on a bg-layers__border layer (sections, page header)
   The element technique above assumes an opaque host with the ring behind
   it. On a transparent layer the ring is cut out of the ::before with the
   same mask the gradient technique in base.css uses.
   ========================================================================== */

.bg-layers__border[class*="border-fx-animated"]:not(.border-fx-animated-pulse) {
    position: absolute;
}

.bg-layers__border[class*="border-fx-animated"]:not(.border-fx-animated-pulse)::before {
    inset: 0;
    z-index: auto;
    padding: var(--border-fx-width, 2px);
    -webkit-mask:
        linear-gradient(#fff 0 0) content-box,
        linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask:
        linear-gradient(#fff 0 0) content-box,
        linear-gradient(#fff 0 0);
    mask-composite: exclude;
}

/* ==========================================================================
   ...and on a TRANSPARENT PART, which is the third case and was missed.

   Found 2026-09-14 on ?wip=media-media-text-1: `border_effect:
   animated-shimmer` on a Media_Text laid over a ground painted a full
   green-to-blue gradient RECTANGLE across the whole section instead of a
   border.

   The cause is written in the comment above this block and was simply never
   carried to its third case. The element technique at the top of this file
   "assumes an opaque host with the ring behind it": ::before is a full-size
   gradient at `inset: -2px; z-index: -1`, and it LOOKS like a border only
   because the host paints an opaque background over its middle and leaves a
   2px rim showing. Take the opaque background away and the whole rectangle is
   what you see. `.bg-layers__border` already had the mask; a part with
   `mode: transparent` is neither opaque nor a bg-layers border, so it had
   neither.

   It needed a part to be transparent OVER A GROUND to appear — an opaque part
   hides it and a part on a plain ground hides it. That combination is exactly
   what the step 7 test pages were built to produce, and varying one property
   at a time against a fixed ground would never have shown it.

   Same mask, same reason: cut the ring out of the rectangle rather than rely
   on something else to cover its middle.
   ========================================================================== */

/* There is no DOM marker for a transparent part — `mode: transparent` returns
   the PARENT's mode and emits no data-theme and no class of its own — so no
   selector can target the broken case. The fix is therefore not a new selector
   but the base rule telling the truth: mask the ring out of the rectangle
   ALWAYS, instead of leaving a filled rectangle and relying on the host to
   cover its middle.

   On an opaque host this is a no-op by construction: the masked-away middle is
   exactly the region the host's own background was already painting over. On a
   transparent host it is the difference between a border and a gradient block.
   The ring stays OUTSIDE the element, as `inset: calc(width * -1)` puts it, so
   no existing composition moves. */
[class*="border-fx-animated"]:not(.border-fx-animated-pulse):not(.bg-layers__border)::before {
    padding: var(--border-fx-width, 2px);
    -webkit-mask:
        linear-gradient(#fff 0 0) content-box,
        linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask:
        linear-gradient(#fff 0 0) content-box,
        linear-gradient(#fff 0 0);
    mask-composite: exclude;
}
