/* ==========================================================================
   hero-enhance.css — homepage hero background enhancement layer
   Created 12/08/2026 by Vivek Singh.

   Loaded on index.php ONLY, AFTER style.css / custom.css / colors/default.css.
   The vendor theme (assets_v4/css/style.css) is left untouched — everything
   here is additive and scoped to `.hero-enhanced` / `.hero-fx`, so removing
   the one <link> in index.php reverts the hero exactly to its old look.

   Design notes
   ------------
   * Pure CSS: no JS, no extra images, no new HTTP requests, so LCP is
     unaffected — the browser paints these layers, it does not fetch them.
   * Only `transform` and `opacity` are animated, both GPU-composited, so the
     effects never trigger layout or paint on the main thread.
   * The FX layer is `pointer-events: none` and `aria-hidden`, so it can never
     intercept a click on the "Get Started" form or be read by a screen reader.
   * Honours `prefers-reduced-motion` — motion stops, the gradients stay.

   Brand palette: primary #2f55d4 · deep #2443ac · accent #2eca8b
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Base
   --------------------------------------------------------------------------
   Deliberately does NOT touch background-size/repeat/position. The inline
   `style="background: url(...) center center"` leaves the artwork at natural
   size, and that framing is what puts the rocket / gears / megaphone details
   in view — forcing `cover` scales them out of frame. Enhancement only: the
   original background rendering is preserved exactly.

   No `overflow: hidden` here either: `.home-dashboard img` is pushed down 60px
   and is meant to spill past the hero over the white wedge below. Clipping the
   section cuts that illustration off. The FX layer does its own clipping.

   And deliberately NO `isolation: isolate`: that would open a new stacking
   context, trapping `.home-dashboard img`'s `z-index: 1` inside the section so
   it could no longer paint above the `.shape.integration-hero` white wedge that
   follows the section in the DOM — the illustration would end up buried behind
   the wedge. The FX layers are ordered by plain z-index instead.
   -------------------------------------------------------------------------- */
.hero-enhanced {
    position: relative;
}

/* Brand wash for depth. Kept deliberately light — this paints OVER the bg.png
   artwork, so high opacity here would bury it. It deepens toward the bottom so
   the hero copy and the white wedge below both gain contrast. */
.hero-enhanced::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    background:
        radial-gradient(120% 90% at 50% -10%, rgba(47, 85, 212, .16) 0%, rgba(36, 67, 172, .30) 45%, rgba(18, 34, 88, .46) 100%);
    pointer-events: none;
}

/* Keep the real content above every decorative layer. */
.hero-enhanced>.container {
    position: relative;
    z-index: 3;
}

/* --------------------------------------------------------------------------
   2. The FX layer
   -------------------------------------------------------------------------- */
.hero-fx {
    position: absolute;
    inset: 0;
    /* 0, not 1: `.home-dashboard img` is z-index 1 and must stay above the FX. */
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
    /* layout+paint+style, deliberately NOT `strict` — `strict` adds size
       containment, which this inset:0 layer does not need and which bites if
       the markup ever changes to a non-absolute box. */
    contain: layout paint style;
}

/* --- 2a. Aurora — two large, slowly drifting colour fields ---------------- */
.hero-fx .hero-aurora {
    position: absolute;
    inset: -30%;
    background:
        radial-gradient(38% 44% at 22% 32%, rgba(46, 202, 139, .30) 0%, transparent 62%),
        radial-gradient(42% 48% at 78% 26%, rgba(88, 132, 255, .34) 0%, transparent 64%),
        radial-gradient(46% 40% at 60% 82%, rgba(47, 85, 212, .30) 0%, transparent 66%);
    filter: blur(28px);
    will-change: transform;
    animation: heroAurora 26s ease-in-out infinite alternate;
}

@keyframes heroAurora {
    0% {
        transform: translate3d(-2.5%, -1.5%, 0) scale(1);
    }

    50% {
        transform: translate3d(2%, 2.5%, 0) scale(1.08);
    }

    100% {
        transform: translate3d(3%, -2%, 0) scale(1.04);
    }
}

/* --- 2b. Grid mesh — a faint technical lattice, fades out at the edges ---- */
.hero-fx .hero-grid {
    position: absolute;
    inset: -10% -10% 0;
    background-image:
        linear-gradient(rgba(255, 255, 255, .07) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, .07) 1px, transparent 1px);
    background-size: 54px 54px;
    -webkit-mask-image: radial-gradient(72% 62% at 50% 38%, #000 0%, transparent 78%);
    mask-image: radial-gradient(72% 62% at 50% 38%, #000 0%, transparent 78%);
    will-change: transform;
    animation: heroGridPan 34s linear infinite;
}

@keyframes heroGridPan {
    from {
        transform: translate3d(0, 0, 0);
    }

    to {
        transform: translate3d(54px, 54px, 0);
    }
}

/* --- 2c. Glow orbs — soft floating spheres ------------------------------- */
.hero-fx .hero-orb {
    position: absolute;
    border-radius: 50%;
    filter: blur(2px);
    opacity: .5;
    will-change: transform;
}

.hero-fx .hero-orb-1 {
    width: 320px;
    height: 320px;
    top: 4%;
    left: -70px;
    background: radial-gradient(circle at 32% 30%, rgba(255, 255, 255, .32), rgba(47, 85, 212, 0) 68%);
    animation: heroFloat 18s ease-in-out infinite;
}

.hero-fx .hero-orb-2 {
    width: 240px;
    height: 240px;
    top: 46%;
    right: -50px;
    background: radial-gradient(circle at 62% 38%, rgba(46, 202, 139, .34), rgba(46, 202, 139, 0) 70%);
    animation: heroFloat 22s ease-in-out infinite reverse;
    animation-delay: -6s;
}

.hero-fx .hero-orb-3 {
    width: 180px;
    height: 180px;
    top: 12%;
    right: 22%;
    background: radial-gradient(circle at 45% 45%, rgba(255, 255, 255, .22), rgba(255, 255, 255, 0) 72%);
    animation: heroFloat 15s ease-in-out infinite;
    animation-delay: -3s;
}

@keyframes heroFloat {

    0%,
    100% {
        transform: translate3d(0, 0, 0) scale(1);
    }

    33% {
        transform: translate3d(22px, -26px, 0) scale(1.07);
    }

    66% {
        transform: translate3d(-16px, 18px, 0) scale(.95);
    }
}

/* --- 2d. Storm: drifting clouds, falling rain, lightning ------------------
   Replaces the old left-to-right light sweep. Still pure CSS — the clouds are
   blurred radial gradients, the rain is two repeating-linear-gradient sheets
   translated on the Y axis, and the lightning is an opacity flicker. Nothing
   here loads a file or touches the DOM.
   -------------------------------------------------------------------------- */

/* Clouds — a cumulus silhouette: several overlapping circular lobes sitting on
   a common baseline, so the top is lumpy and the base roughly flat.

   Two things the first version got wrong, both avoided here:
     - `border-radius: 50%` clipped the box to an ellipse, shearing the outer
       lobes off and leaving a smooth blob. The gradients define the shape, so
       the box must NOT be clipped.
     - `blur(18px)` on a ~120px-tall element is more than the lobe radii, so it
       dissolved the silhouette into fog. Blur is now well under lobe size and
       only softens the edges.

   Lobe radii are given in PIXELS, not percentages. A percentage stop in a
   `circle` gradient resolves against the farthest-corner radius, so on a
   340x130 box `0 44%` is a ~126px circle — five of those overlap into a filled
   rectangle, which is exactly what the percentage version rendered. Explicit
   radii keep each lobe the size it looks like.

   Each lobe holds solid to ~96% then falls off over the last 4%, so the union
   of the lobes keeps a defined silhouette; `filter: blur()` (kept well under
   the lobe radii) does the softening. A soft falloff across the whole radius
   instead just sums back into one featureless mound. */
.hero-fx .hero-cloud {
    position: absolute;
    will-change: transform;
    background-repeat: no-repeat;
}

.hero-fx .hero-cloud-1 {
    width: 340px;
    height: 130px;
    top: 5%;
    left: -20%;
    filter: blur(9px);
    background:
        /* lobes, left to right, centres sitting on a common baseline */
        radial-gradient(circle 34px at 62px 92px, rgba(232, 240, 255, .26) 0 96%, transparent 100%),
        radial-gradient(circle 46px at 118px 70px, rgba(232, 240, 255, .28) 0 96%, transparent 100%),
        radial-gradient(circle 40px at 182px 80px, rgba(226, 236, 255, .26) 0 96%, transparent 100%),
        radial-gradient(circle 30px at 240px 94px, rgba(220, 231, 255, .23) 0 96%, transparent 100%),
        radial-gradient(circle 24px at 286px 100px, rgba(220, 231, 255, .20) 0 96%, transparent 100%),
        /* base slab that ties the lobes together and flattens the underside */
        radial-gradient(ellipse 140px 24px at 170px 104px, rgba(226, 236, 255, .24) 0 92%, transparent 100%);
    animation: heroCloudDrift 48s linear infinite;
}

.hero-fx .hero-cloud-2 {
    width: 260px;
    height: 104px;
    top: 19%;
    left: -16%;
    filter: blur(8px);
    background:
        radial-gradient(circle 28px at 52px 74px, rgba(214, 227, 255, .21) 0 96%, transparent 100%),
        radial-gradient(circle 36px at 104px 56px, rgba(214, 227, 255, .23) 0 96%, transparent 100%),
        radial-gradient(circle 30px at 158px 68px, rgba(206, 221, 255, .20) 0 96%, transparent 100%),
        radial-gradient(circle 22px at 206px 78px, rgba(206, 221, 255, .17) 0 96%, transparent 100%),
        radial-gradient(ellipse 105px 19px at 130px 84px, rgba(210, 224, 255, .20) 0 92%, transparent 100%);
    animation: heroCloudDrift 66s linear infinite;
    animation-delay: -22s;
}

.hero-fx .hero-cloud-3 {
    width: 420px;
    height: 150px;
    top: 1%;
    left: -24%;
    filter: blur(11px);
    background:
        radial-gradient(circle 38px at 70px 106px, rgba(196, 212, 246, .17) 0 96%, transparent 100%),
        radial-gradient(circle 52px at 140px 80px, rgba(196, 212, 246, .19) 0 96%, transparent 100%),
        radial-gradient(circle 44px at 214px 92px, rgba(190, 207, 244, .17) 0 96%, transparent 100%),
        radial-gradient(circle 36px at 286px 84px, rgba(190, 207, 244, .18) 0 96%, transparent 100%),
        radial-gradient(circle 28px at 350px 104px, rgba(184, 202, 242, .15) 0 96%, transparent 100%),
        radial-gradient(ellipse 175px 27px at 210px 118px, rgba(192, 209, 245, .16) 0 92%, transparent 100%);
    animation: heroCloudDrift 82s linear infinite;
    animation-delay: -50s;
}

@keyframes heroCloudDrift {
    from {
        transform: translate3d(0, 0, 0);
    }

    to {
        transform: translate3d(calc(100vw + 460px), 0, 0);
    }
}

/* Rain — two sheets at different angles/speeds so it reads as depth rather
   than a flat texture. The gradient is 1px hairlines on a transparent field;
   the sheet is oversized and rotated, then translated straight down. */
.hero-fx .hero-rain {
    position: absolute;
    top: -60%;
    left: -30%;
    width: 160%;
    height: 220%;
    transform: rotate(14deg);
    will-change: transform;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 18%, #000 72%, transparent 96%);
    mask-image: linear-gradient(to bottom, transparent 0%, #000 18%, #000 72%, transparent 96%);
}

/* Each sheet is built from TWO gradients on different axes:
     - background = continuous 1px vertical hairlines, spaced along X
     - mask       = horizontal dashes along Y, which chops those hairlines into
                    individual streaks
   Doing the spacing on X and the dashes on Y is what makes this read as rain.
   A single `repeating-linear-gradient(to bottom, …)` cannot: it has no
   horizontal variation, so every column carries the same band and the result is
   solid diagonal stripes, not droplets.

   Because the background has no vertical period, a seamless loop only needs the
   translate distance to equal the MASK period. */
.hero-fx .hero-rain::before,
.hero-fx .hero-rain::after {
    content: "";
    position: absolute;
    inset: -50% 0;
    will-change: transform;
}

/* Far layer — sparse, faint, slower. Mask period 68px.
   Kept deliberately low-contrast: this is atmosphere behind the headline, not
   weather. Widening the X spacing thins the rain out more cleanly than dropping
   opacity alone, which just greys the streaks without reducing the clutter. */
.hero-fx .hero-rain::before {
    background-image: repeating-linear-gradient(to right,
            rgba(255, 255, 255, .20) 0 1px,
            transparent 1px 42px);
    -webkit-mask-image: repeating-linear-gradient(to bottom, #000 0 14px, transparent 14px 68px);
    mask-image: repeating-linear-gradient(to bottom, #000 0 14px, transparent 14px 68px);
    opacity: .26;
    animation: heroRainFar 1.1s linear infinite;
}

/* Near layer — slightly brighter, longer streaks, faster. Mask period 92px. */
.hero-fx .hero-rain::after {
    background-image: repeating-linear-gradient(to right,
            rgba(226, 238, 255, .26) 0 1px,
            transparent 1px 62px);
    -webkit-mask-image: repeating-linear-gradient(to bottom, #000 0 22px, transparent 22px 92px);
    mask-image: repeating-linear-gradient(to bottom, #000 0 22px, transparent 22px 92px);
    opacity: .30;
    animation: heroRainNear .68s linear infinite;
}

@keyframes heroRainFar {
    from {
        transform: translate3d(0, 0, 0);
    }

    to {
        transform: translate3d(0, 68px, 0);
    }
}

@keyframes heroRainNear {
    from {
        transform: translate3d(0, 0, 0);
    }

    to {
        transform: translate3d(0, 92px, 0);
    }
}

/* Lightning — a full-hero flash on a long, irregular cycle. Real lightning
   double-strikes, so the keyframes fire a short flash, a dimmer echo, then go
   dark for the rest of the loop. Only `opacity` animates. */
.hero-fx .hero-lightning {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(58% 46% at 72% 8%, rgba(226, 238, 255, .85) 0%, rgba(198, 216, 255, .34) 34%, rgba(255, 255, 255, 0) 72%);
    opacity: 0;
    mix-blend-mode: screen;
    /* POSITIVE delay: the storm holds off until 5s after load, so the hero does
       not flash in the visitor's face while the page is still settling. During
       the delay `animation-fill-mode` stays `none`, so the element just uses its
       own `opacity: 0` — nothing is painted. The strike sits at 4% of the cycle,
       so the first one lands at ~5.4s, then every 9s after that.
       (The old `-5s` here was a NEGATIVE delay, which did the opposite — it
       started the animation already 5s in, firing almost immediately on load.) */
    animation: heroLightning 9s linear 5s infinite;
}

/* Second strike, offset in time and position so the storm never looks
   metronomic: first flash at ~11.6s, then every 14s. */
.hero-fx .hero-lightning-2 {
    background:
        radial-gradient(52% 42% at 22% 12%, rgba(226, 238, 255, .70) 0%, rgba(190, 210, 255, .28) 32%, rgba(255, 255, 255, 0) 70%);
    animation-duration: 14s;
    animation-delay: 11s;
}

@keyframes heroLightning {

    0%,
    3% {
        opacity: 0;
    }

    /* strike */
    4% {
        opacity: 1;
    }

    6% {
        opacity: .12;
    }

    /* echo */
    8% {
        opacity: .72;
    }

    11% {
        opacity: 0;
    }

    100% {
        opacity: 0;
    }
}

/* --- 2e. Bottom fade — blends the hero into the white wedge below --------- */
.hero-fx .hero-fade {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 34%;
    background: linear-gradient(to bottom, rgba(18, 34, 88, 0) 0%, rgba(18, 34, 88, .38) 100%);
}

/* --------------------------------------------------------------------------
   3. Hero copy
   --------------------------------------------------------------------------
   NOTE: no border-radius / box-shadow on `.home-dashboard img`. hero.png is a
   transparent-background PNG, so a box-shadow traces the element's rectangle
   rather than the illustration inside it — it renders as a visible grey slab
   behind the artwork. Leave the image unstyled.
   -------------------------------------------------------------------------- */
.hero-enhanced .title-heading .heading {
    text-shadow: 0 2px 18px rgba(10, 20, 60, .35);
}

/* --------------------------------------------------------------------------
   4. Responsive — lighten the work on small screens
   -------------------------------------------------------------------------- */
@media (max-width: 768px) {
    .hero-fx .hero-grid {
        background-size: 38px 38px;
    }

    /* A 28px blur over a viewport-sized box is the most expensive thing here;
       halve it on phones where the GPU budget is tightest. */
    .hero-fx .hero-aurora {
        filter: blur(14px);
    }

    .hero-fx .hero-orb-1 {
        width: 210px;
        height: 210px;
    }

    .hero-fx .hero-orb-2 {
        width: 160px;
        height: 160px;
    }

    /* Reads as noise at phone width, and the orb is the cheapest thing to drop. */
    .hero-fx .hero-orb-3,
    .hero-fx .hero-cloud-3 {
        display: none;
    }

    /* Keep the rain, but one sheet only — two full-bleed scrolling layers is the
       heaviest part of the storm on a low-end GPU. */
    .hero-fx .hero-rain::before {
        display: none;
    }

    .hero-fx .hero-rain::after {
        opacity: .26;
    }
}

/* --------------------------------------------------------------------------
   5. Accessibility — respect a reduced-motion preference
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {

    .hero-fx .hero-aurora,
    .hero-fx .hero-grid,
    .hero-fx .hero-orb,
    .hero-fx .hero-cloud,
    .hero-fx .hero-rain::before,
    .hero-fx .hero-rain::after,
    .hero-fx .hero-lightning {
        animation: none !important;
    }

    /* Falling rain and a strobing flash are exactly what this preference exists
       to stop, so drop them entirely rather than freezing them mid-frame — a
       static lightning flash would just look like a blown-out highlight. */
    .hero-fx .hero-rain,
    .hero-fx .hero-lightning {
        display: none;
    }

    .hero-enhanced .title-heading .heading {
        transition: none !important;
    }
}
