/* =============================================================================
   AIS PREMIUM EFFECTS - the shared motion / depth / light vocabulary.

   Loaded after site.css and canopy.css so it may refine both. Implemented in
   tandem with assets/js/effects.js. Every rule here follows two hard bars:

     1. prefers-reduced-motion: reduce  =>  nothing moves, everything visible.
     2. No layout shift: animations use transform / opacity only.

   The class list is documented in assets/css/EFFECTS.md - page templates use
   THESE classes and invent nothing structural of their own.
   ========================================================================== */

:root {
    --fx-blue:      #4080C0;
    --fx-green:     #45A845;
    --fx-navy:      #0E2C48;
    --fx-ease:      cubic-bezier(.22, 1, .36, 1);
    --fx-grad:      linear-gradient(96deg, #4080C0, #45A845);
}

/* =============================================================================
   1. SCROLL REVEAL  -  [data-reveal] (+ "left" | "right" | "zoom")
   -----------------------------------------------------------------------------
   Default state is VISIBLE. effects.js adds .js-reveal to <html> before first
   paint (skipped under reduced motion); only then is the hidden state applied,
   so content is never lost when JS fails or motion is unwelcome.
   ========================================================================== */

html.js-reveal [data-reveal] {
    opacity: 0;
    transform: translateY(24px);
    transition:
        opacity   .65s var(--fx-ease),
        transform .65s var(--fx-ease);
    will-change: opacity, transform;
}
html.js-reveal [data-reveal="left"]  { transform: translateX(-28px); }
html.js-reveal [data-reveal="right"] { transform: translateX(28px); }
html.js-reveal [data-reveal="zoom"]  { transform: scale(.94); }

html.js-reveal [data-reveal].is-revealed {
    opacity: 1;
    transform: none;
}

/* stagger: delay steps of 90ms */
html.js-reveal [data-reveal-delay="1"] { transition-delay: .09s; }
html.js-reveal [data-reveal-delay="2"] { transition-delay: .18s; }
html.js-reveal [data-reveal-delay="3"] { transition-delay: .27s; }
html.js-reveal [data-reveal-delay="4"] { transition-delay: .36s; }
html.js-reveal [data-reveal-delay="5"] { transition-delay: .45s; }
html.js-reveal [data-reveal-delay="6"] { transition-delay: .54s; }

/* =============================================================================
   2. COUNTERS  -  .counter[data-count-to][data-count-suffix]
   effects.js counts 0 -> target over ~1.4s when scrolled into view.
   ========================================================================== */

.counter {
    font-variant-numeric: tabular-nums;
    display: inline-block;
}

/* =============================================================================
   3. HEADER  -  .site-header.is-scrolled (added by effects.js after 24px)
   Glass blur, tighter padding, soft shadow; the logo eases down a touch.
   ========================================================================== */

.site-header {
    transition:
        background-color .25s ease,
        box-shadow       .25s ease,
        border-color     .25s ease;
}
.site-header .navbar { transition: padding .25s ease; }
.site-header .brand-logo {
    transition: transform .25s ease;
    transform-origin: left center;
}
.site-header.is-scrolled {
    background: rgba(255, 255, 255, .85);
    -webkit-backdrop-filter: saturate(170%) blur(14px);
    backdrop-filter: saturate(170%) blur(14px);
    border-bottom-color: rgba(221, 229, 236, .7);
    box-shadow: 0 8px 30px -12px rgba(14, 44, 72, .18);
}
.site-header.is-scrolled .navbar {
    padding-top: .25rem !important;
    padding-bottom: .25rem !important;
}
.site-header.is-scrolled .brand-logo { transform: scale(.88); }

/* =============================================================================
   4. GLASS PANELS  -  .glass / .glass-dark
   ========================================================================== */

.glass {
    background: rgba(255, 255, 255, .72);
    -webkit-backdrop-filter: blur(14px) saturate(150%);
    backdrop-filter: blur(14px) saturate(150%);
    border: 1px solid rgba(255, 255, 255, .5);
    box-shadow: 0 18px 44px -24px rgba(14, 44, 72, .35);
}
.glass-dark {
    background: rgba(14, 44, 72, .58);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    backdrop-filter: blur(14px) saturate(140%);
    border: 1px solid rgba(255, 255, 255, .16);
    color: #fff;
    box-shadow: 0 18px 44px -24px rgba(0, 0, 0, .5);
}
/* browsers without backdrop-filter get a solid, still-AA ground */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .glass      { background: rgba(255, 255, 255, .96); }
    .glass-dark { background: rgba(14, 44, 72, .96); }
}

/* =============================================================================
   5. GRADIENT TEXT  -  .grad-text
   ========================================================================== */

.grad-text { color: var(--fx-blue); }              /* solid fallback */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
    .grad-text {
        background: var(--fx-grad);
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
        -webkit-text-fill-color: transparent;
    }
}

/* =============================================================================
   6. BUTTON SHEEN  -  .btn-primary / .btn-gold light sweep + lift on hover
   ========================================================================== */

.btn-primary,
.btn-gold {
    position: relative;
    overflow: hidden;
    transition:
        transform    .22s var(--fx-ease),
        box-shadow   .22s var(--fx-ease),
        background-color .18s ease,
        border-color .18s ease;
}
.btn-primary::after,
.btn-gold::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 55%;
    background: linear-gradient(105deg,
        transparent 18%, rgba(255, 255, 255, .38) 50%, transparent 82%);
    transform: translateX(-130%) skewX(-14deg);
    pointer-events: none;
}
.btn-primary:hover::after,
.btn-primary:focus-visible::after,
.btn-gold:hover::after,
.btn-gold:focus-visible::after {
    transform: translateX(240%) skewX(-14deg);
    transition: transform .6s ease;
}
.btn-primary:hover,
.btn-primary:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 14px 28px -12px rgba(44, 98, 153, .65);
}
.btn-gold:hover,
.btn-gold:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 14px 28px -12px rgba(48, 144, 48, .7);
}

/* =============================================================================
   7. MARQUEE  -  .marquee > .marquee-track (track content duplicated once in
   markup; mark the duplicate aria-hidden="true"). ~40s loop, pauses on
   hover / keyboard focus, wraps to a static grid under reduced motion.
   ========================================================================== */

.marquee {
    overflow: hidden;
    position: relative;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee-track {
    display: flex;
    align-items: center;
    gap: clamp(2rem, 5vw, 4rem);
    width: max-content;
    padding-right: clamp(2rem, 5vw, 4rem); /* keeps the -50% seam gap even */
    animation: fx-marquee 40s linear infinite;
    will-change: transform;
}
.marquee:hover .marquee-track,
.marquee:focus-within .marquee-track { animation-play-state: paused; }

@keyframes fx-marquee {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

/* =============================================================================
   8. CANOPY DRAW  -  .canopy path stroke draw-in (lengths measured by
   effects.js) + a slow breathing drift on the whole arc. Runs once.
   ========================================================================== */

html.js-reveal .canopy.fx-drawing path {
    transition: stroke-dashoffset 1.6s ease-out;
}
.canopy.fx-breathe {
    animation: fx-canopy-breathe 14s ease-in-out infinite alternate;
}
@keyframes fx-canopy-breathe {
    from { transform: translateX(-50%) translateY(0); }
    to   { transform: translateX(-50%) translateY(10px); }
}

/* =============================================================================
   9. AURORA  -  .aurora  drifting radial-gradient blobs for dark bands.
   Parent must be position:relative with overflow:hidden; content above it
   needs position:relative / z-index. Pure CSS, no canvas.
   ========================================================================== */

.aurora {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 0;
}
.aurora::before,
.aurora::after {
    content: "";
    position: absolute;
    width: 46vw;
    min-width: 420px;
    aspect-ratio: 1;
    border-radius: 50%;
    filter: blur(90px);
    opacity: .35;
    will-change: transform;
}
.aurora::before {
    background: radial-gradient(circle at 50% 50%, #4080C0, transparent 65%);
    top: -22%;
    left: -8%;
    animation: fx-aurora-a 22s ease-in-out infinite alternate;
}
.aurora::after {
    background: radial-gradient(circle at 50% 50%, #45A845, transparent 65%);
    bottom: -28%;
    right: -10%;
    animation: fx-aurora-b 26s ease-in-out infinite alternate;
}
@keyframes fx-aurora-a {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(9vw, 6vh, 0) scale(1.18); }
}
@keyframes fx-aurora-b {
    from { transform: translate3d(0, 0, 0) scale(1.1); }
    to   { transform: translate3d(-8vw, -7vh, 0) scale(.92); }
}

/* =============================================================================
   10. CANOPY DIVIDER  -  .divider-canopy   curved seam between sections.
   Colour the SVG with the NEXT section's ground via `color` (currentColor).
   Markup example lives in EFFECTS.md.
   ========================================================================== */

.divider-canopy {
    display: block;
    line-height: 0;
    margin-bottom: -1px;   /* kill sub-pixel seams */
    position: relative;
    z-index: 1;
    pointer-events: none;
}
.divider-canopy svg {
    display: block;
    width: 100%;
    height: clamp(30px, 6vw, 84px);
}

/* =============================================================================
   11. TILT  -  .tilt  pointer-tracking 3D tilt (max 6deg, JS-driven,
   desktop pointer:fine only). Hero card + photo figures only.
   ========================================================================== */

.tilt {
    transform-style: preserve-3d;
    transition: transform .3s var(--fx-ease);
}
.tilt.fx-tilting { transition: transform .08s linear; }

/* =============================================================================
   12. CARD HOVER GLOW  -  .card-glow  (also wired onto the existing card
   family so current markup benefits immediately): gradient border fade-in.
   ========================================================================== */

.card-glow,
.svc-card,
.service-card,
.feature-card,
.why-card,
.compliance-card {
    position: relative;
}
.card-glow::before,
.svc-card::before,
.service-card::before,
.feature-card::before,
.why-card::before,
.compliance-card::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(120deg, rgba(64, 128, 192, .9), rgba(69, 168, 69, .9));
    -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;
    opacity: 0;
    transition: opacity .3s ease;
    pointer-events: none;
    z-index: 1;
}
.card-glow:hover::before,
.card-glow:focus-within::before,
.svc-card:hover::before,
.svc-card:focus-within::before,
.service-card:hover::before,
.service-card:focus-within::before,
.feature-card:hover::before,
.feature-card:focus-within::before,
.why-card:hover::before,
.why-card:focus-within::before,
.compliance-card:hover::before,
.compliance-card:focus-within::before {
    opacity: 1;
}

/* =============================================================================
   13. SCROLL PROGRESS  -  .scroll-progress  3px gradient bar fixed to the top.
   effects.js drives transform: scaleX(0..1) - zero layout cost.
   ========================================================================== */

.scroll-progress {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    z-index: 2000;
    background: linear-gradient(90deg, var(--fx-blue), var(--fx-green));
    transform: scaleX(0);
    transform-origin: left center;
    pointer-events: none;
}

/* =============================================================================
   14. BACK TO TOP  -  .back-to-top  (markup in the layout; site.css holds the
   base plate). Upgrade the show/hide to a fade + rise, add a brand hover.
   ========================================================================== */

.back-to-top {
    display: inline-flex;              /* always in the tree, faded out      */
    opacity: 0;
    visibility: hidden;
    transform: translateY(14px);
    transition:
        opacity    .3s ease,
        visibility .3s ease,
        transform  .3s var(--fx-ease),
        color      .2s ease,
        background-color .2s ease;
}
.back-to-top.show {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}
.back-to-top:hover,
.back-to-top:focus-visible {
    background: var(--fx-blue);
    border-color: var(--fx-blue);
    color: #fff;
}

/* =============================================================================
   15. NAV UNDERLINES  -  animated scaleX underline from the left on
   hover / focus / .active (replaces the static active bar from site.css).
   Applies to the layout's .navbar-nav links and the generic .site-nav a hook.
   ========================================================================== */

.site-nav a,
.navbar-nav .nav-link {
    position: relative;
}
.site-nav a::after,
.navbar-nav .nav-link::after,
.navbar-nav .nav-link.active::after {
    content: "";
    position: absolute;
    left: .8rem;
    right: .8rem;
    bottom: .28rem;
    height: 3px;
    margin: 0;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--fx-blue), var(--fx-green));
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform .28s var(--fx-ease);
    display: block;
    pointer-events: none;
}
.site-nav a::after { left: 0; right: 0; bottom: -.2rem; }
.site-nav a:hover::after,
.site-nav a:focus-visible::after,
.site-nav a.active::after,
.navbar-nav .nav-link:hover::after,
.navbar-nav .nav-link:focus-visible::after,
.navbar-nav .nav-link.active::after {
    transform: scaleX(1);
}

@media (max-width: 991.98px) {
    /* collapsed mobile menu: links are full-width rows - no underline there */
    .navbar-nav .nav-link::after,
    .navbar-nav .nav-link.active::after { display: none; }
}

/* =============================================================================
   16. REDUCED MOTION  -  the master off-switch. Content visible, nothing moves.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    html.js-reveal [data-reveal] {
        opacity: 1;
        transform: none;
        transition: none;
    }
    .marquee {
        -webkit-mask-image: none;
        mask-image: none;
    }
    .marquee-track {
        animation: none;
        width: auto;
        flex-wrap: wrap;
        justify-content: center;
    }
    /* the duplicated half exists only to make the loop seamless - hide it
       when the track wraps to a static grid so logos don't appear twice */
    .marquee-track > [aria-hidden="true"] { display: none; }
    .aurora::before,
    .aurora::after,
    .canopy.fx-breathe { animation: none; }
    html.js-reveal .canopy.fx-drawing path { transition: none; }
    .site-header,
    .site-header .navbar,
    .site-header .brand-logo,
    .btn-primary,
    .btn-gold,
    .tilt,
    .back-to-top,
    .site-nav a::after,
    .navbar-nav .nav-link::after { transition: none; }
    .btn-primary::after,
    .btn-gold::after { display: none; }
    .btn-primary:hover,
    .btn-gold:hover,
    .tilt,
    .back-to-top { transform: none !important; }
    .scroll-progress { display: none; }
}
