/* ============================================================
   ElectricBorder — an animated, noise-displaced glowing outline.

   Vanilla port of the React Bits <ElectricBorder /> component.
   Component inspired by @BalintFerenczy on X
   https://codepen.io/BalintFerenczy/pen/KwdoyEN

   The inner markup is built by static/js/electric-border.js from
   any element carrying [data-electric-border]. Without JS the host
   stays a plain box and none of these rules ever match.
   ============================================================ */

.electric-border {
    /* Overridden per instance from the data-eb-* attributes. */
    --eb-color:     #5227FF;
    --eb-thickness: 2px;
    --eb-radius:    24px;

    position: relative;
    border-radius: var(--eb-radius);
    overflow: visible;
    isolation: isolate;
}

/* The canvas is drawn larger than the host on every side so the displaced
   stroke has room to wander past the true edge without being cut off.
   The overhang is EB_OFFSET in electric-border.js. */
.eb-canvas-container {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
    z-index: 2;
}

.eb-canvas { display: block; }

/* The host's original children, lifted above the glow layers but below
   the stroke — so the arc crackles over the top of the content's edge. */
.eb-content {
    position: relative;
    border-radius: inherit;
    z-index: 1;
}

.eb-layers {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    z-index: 0;
}

.eb-glow-1,
.eb-glow-2,
.eb-background-glow {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    box-sizing: border-box;
}

/* Upstream reaches for `oklch(from … l c h / .6)` to fade the colour.
   color-mix() lands on the same place with wider browser support. */
.eb-glow-1 {
    border: var(--eb-thickness) solid color-mix(in srgb, var(--eb-color) 60%, transparent);
    filter: blur(1px);
}

.eb-glow-2 {
    border: var(--eb-thickness) solid var(--eb-color);
    filter: blur(4px);
}

.eb-background-glow {
    z-index: -1;
    transform: scale(1.1);
    filter: blur(32px);
    opacity: .3;
    background: linear-gradient(-30deg, var(--eb-color), transparent, var(--eb-color));
}

/* A .cf-card lifts 4px on hover. Inside an electric border that would slide
   the card out from under its own outline, so the host keeps it planted —
   the crackling border is the hover affordance here. */
.electric-border .cf-card:hover {
    transform: none;
}

/* The canvas and the scaled background glow both overhang the host, and those
   boxes still count toward scrollable overflow — without this the landing page
   drags ~48px sideways on a phone.

   It has to be `hidden`, not `clip`: overflow on <body> is what reaches the
   viewport here (the root's own overflow is `visible`, so <body>'s propagates
   up), and `clip` is excluded from that propagation — it would silently do
   nothing. Because the value propagates, body's *used* overflow stays
   `visible`, so body never becomes a scroll container and the sticky navbar and
   .cf3d-sticky scenes keep pinning to the viewport.

   :has() keeps the whole thing off pages that don't use the effect. */
body:has(.electric-border) {
    overflow-x: hidden;
}
