/* ========================================================================
   Leadnox brand layer, loaded after style.css
   Dark (night) + light (day) themes, driven by `.lightmode` on <body>.
   Section effects adapted from 21st.dev patterns:
     glowing-orb hero · blur-out-up text · blurred marquee · border beam ·
     3D tilt card · spotlight card · shine sweep · bento grid · magnetic CTA
   ======================================================================== */

/* ---------------- 01. Theme tokens ---------------- */
:root {
    --lx-indigo: #4F46E5;
    --lx-violet: #7C3AED;
    --lx-purple: #C82AEF;
    --lx-gradient: linear-gradient(100deg, #4F46E5 0%, #7C3AED 35%, #C82AEF 70%, #8B5CF6 100%);

    /* night (default) */
    --lx-surface: rgba(255, 255, 255, 0.045);
    --lx-surface-solid: #100E18;
    --lx-card-bg: #100E18;
    --lx-section-tint: transparent;
    --lx-border: rgba(255, 255, 255, 0.10);
    --lx-border-strong: rgba(200, 42, 239, 0.42);
    --lx-shadow: 0 30px 80px -34px rgba(0, 0, 0, 0.9);
    --lx-orb-opacity: 0.5;
    --lx-glow-tint: rgba(200, 42, 239, 0.16);
    --lx-panel-blur: rgba(10, 8, 14, 0.97);
    --lx-hairline: rgba(255, 255, 255, 0.07);
}

/* Day theme. Surfaces carry a soft lavender gradient (as in the Marko
   reference) so every section still reads as a distinct block on a light page
   instead of dissolving into flat white. */
body.lightmode {
    --lx-surface: rgba(124, 58, 237, 0.06);
    --lx-surface-solid: #FFFFFF;
    --lx-card-bg: linear-gradient(158deg, #FFFFFF 0%, #F4E8FD 100%);
    --lx-section-tint: linear-gradient(180deg, rgba(200, 42, 239, 0.045), rgba(79, 70, 229, 0.05));
    --lx-border: rgba(124, 58, 237, 0.20);
    --lx-border-strong: rgba(200, 42, 239, 0.55);
    --lx-shadow: 0 22px 50px -28px rgba(79, 70, 229, 0.42);
    --lx-orb-opacity: 0.34;
    --lx-glow-tint: rgba(200, 42, 239, 0.14);
    --lx-panel-blur: rgba(255, 255, 255, 0.98);
    --lx-hairline: rgba(124, 58, 237, 0.18);

    --secondary: #FFFAFA;
    --primary: #16121F;
    --text-color: #55506B;
    background-color: var(--secondary);
}

/* Alternate sections get a faint tinted band so the page has rhythm in
   daylight rather than one continuous white sheet. */
body.lightmode main > .section:nth-of-type(even) {
    background-image: var(--lx-section-tint);
    border-top: 1px solid var(--lx-hairline);
    border-bottom: 1px solid var(--lx-hairline);
}

/* ---------------- 02. Global cleanups ---------------- */

/* Kill the template's tiled grid-line background in BOTH themes */
body::before { display: none !important; content: none !important; }

/* Remove the little circle-dot markers above section headings */
.sub-heading > i,
.lx-eyebrow > i { display: none !important; }
.sub-heading { gap: 0 !important; }

/* No scroll-progress bar */
#lx-progress { display: none !important; }

/* ---------------- 03. Fluid cursor canvas ----------------
   Sits behind ALL page content so text and cards stay legible.
   Light mode multiplies so the ink tints the page instead of glowing. */
#fluid-canvas {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    pointer-events: none;
    z-index: 0;
    opacity: 0.5;
    transition: opacity 0.4s ease;
}
body.lightmode #fluid-canvas {
    opacity: 0.42;
    mix-blend-mode: multiply;
}
header, main, footer, aside { position: relative; z-index: 2; }
header { z-index: 20; }
aside  { z-index: 30; }

/* Content surfaces stay opaque so smoke never washes out text */
.card, .lx-stat-card, .lx-h3-card, .lx-bento-card, .lx-panel, .form-layout, .contact-title {
    background: var(--lx-card-bg) !important;
    backdrop-filter: none;
}

/* ---------------- 04. Header / navigation ---------------- */
.navbar-nav {
    flex-wrap: nowrap !important;
    align-items: center;
}
.navbar-nav .nav-link {
    font-size: 14.5px;
    white-space: nowrap;
    padding: 8px 9px !important;
}
.navbar-collapse { flex: 1 1 auto; min-width: 0; }
@media (min-width: 1400px) {
    .navbar-nav .nav-link { font-size: 15.5px; padding: 8px 13px !important; }
}
/* Header CTA stays compact so the menu never wraps */
.navbar-action-container .btn-accent { padding: 6px 6px 6px 20px; }
.navbar-action-container .btn-accent .icon-circle { width: 38px; height: 38px; }

.lx-logo {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    text-decoration: none;
    white-space: nowrap;
}
.lx-logo img { height: 42px; width: auto; }
.lx-wordmark {
    font-weight: 800;
    font-size: 1.35rem;
    letter-spacing: 0.11em;
    color: var(--primary);
    line-height: 1;
}
.lx-wordmark em {
    font-style: normal;
    background: var(--lx-gradient);
    background-size: 200% auto;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: lx-grad-shift 6s ease-in-out infinite;
}
.logo-container-footer .lx-logo img { height: 50px; }

/* Day / night toggle */
.lx-theme-btn {
    width: 42px;
    height: 42px;
    flex: 0 0 42px;
    border-radius: 50%;
    border: 1px solid var(--lx-border);
    background: var(--lx-surface);
    color: var(--primary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: border-color 0.3s ease, transform 0.3s ease;
}
.lx-theme-btn:hover {
    border-color: var(--lx-border-strong);
    transform: rotate(-18deg);
}
.lx-theme-btn i {
    font-size: 15px;
    transition: opacity 0.35s ease, transform 0.45s ease;
}
.lx-theme-btn .lx-icon-sun { position: absolute; opacity: 0; transform: scale(0.4) rotate(-90deg); }
body.lightmode .lx-theme-btn .lx-icon-sun  { opacity: 1; transform: scale(1) rotate(0); color: var(--lx-purple); }
body.lightmode .lx-theme-btn .lx-icon-moon { opacity: 0; transform: scale(0.4) rotate(90deg); }

/* The template pins these to width:30% each, which squeezes the menu onto
   a second line, size them to their content instead. */
.navbar-action-container {
    width: auto !important;
    flex: 0 0 auto;
    gap: 0.7rem;
    align-items: center;
    display: flex;
}
.logo-container-header {
    width: auto !important;
    flex: 0 0 auto;
    flex-direction: row !important;
}
.logo-container-header img { width: auto !important; }
.navbar-action-container .btn-title,
.navbar-action-container .btn-title span { white-space: nowrap; }

/* ---------------- Nav: sliding pill + rich dropdowns ----------------
   Ported from a framer-motion nav. The pill is framer's `layoutId` shared
   element done in CSS: one absolutely positioned node whose transform and
   width transition to whichever item is hovered, so it appears to glide
   between them instead of fading in place. Driven by initNavPill(). */
.navbar-nav { position: relative; }
.navbar-nav .nav-item { position: relative; z-index: 1; }
.lx-nav-pill {
    position: absolute;
    top: 50%;
    left: 0;
    width: var(--pill-w, 0);
    height: var(--pill-h, 34px);
    transform: translate(var(--pill-x, 0), -50%);
    border-radius: 99px;
    background: var(--lx-glow-tint);
    border: 1px solid var(--lx-border);
    opacity: 0;
    pointer-events: none;
    z-index: 0;
    transition: transform 0.38s cubic-bezier(0.4, 1.25, 0.35, 1),
                width 0.38s cubic-bezier(0.4, 1.25, 0.35, 1),
                height 0.38s cubic-bezier(0.4, 1.25, 0.35, 1),
                opacity 0.22s ease;
}
.navbar-nav.is-pill-on .lx-nav-pill { opacity: 1; }
/* First reveal should fade in place, not fly in from the left. */
.lx-nav-pill.no-slide { transition: opacity 0.22s ease; }

/* Chevrons flip when their menu is open or hovered. */
.nav-link .fa-angle-down {
    transition: transform 0.3s ease;
    font-size: 0.8em;
}
.nav-item:hover > .nav-link .fa-angle-down,
.nav-item.show > .nav-link .fa-angle-down { transform: rotate(180deg); }

/* Panels */
.dropdown-menu {
    border-radius: 16px !important;
    border: 1px solid var(--lx-border) !important;
    background: var(--lx-panel-blur) !important;
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    box-shadow: var(--lx-shadow);
    padding: 0.6rem !important;
}
.lx-drop-rich { min-width: 20rem; }
.lx-drop-item {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.6rem;
    border-radius: 11px;
    text-decoration: none;
    transition: background 0.28s ease;
}
.lx-drop-item:hover { background: var(--lx-surface); }
.lx-drop-icon {
    flex: none;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--lx-border);
    border-radius: 9px;
    color: var(--primary);
    font-size: 0.9rem;
    transition: background 0.28s ease, color 0.28s ease, border-color 0.28s ease;
}
.lx-drop-item:hover .lx-drop-icon {
    background: var(--lx-gradient);
    border-color: transparent;
    color: #fff;
}
.lx-drop-text { display: flex; flex-direction: column; line-height: 1.35; }
.lx-drop-label { font-size: 0.9rem; font-weight: 600; color: var(--primary); }
.lx-drop-desc {
    font-size: 0.76rem;
    color: var(--text-color);
    transition: color 0.28s ease;
}
.lx-drop-item:hover .lx-drop-desc { color: var(--primary); }

/* Desktop: open dropdowns on hover so the parent link stays clickable
   (Services goes straight to the all-services page). */
@media (min-width: 992px) {
    /* display toggling cannot transition, so the panel stays laid out and is
       hidden with visibility/opacity instead. */
    .lx-hover-drop > .dropdown-menu {
        display: block;
        visibility: hidden;
        opacity: 0;
        transform: translateY(-8px) scale(0.98);
        transform-origin: top center;
        transition: opacity 0.22s ease,
                    transform 0.3s cubic-bezier(0.4, 1.25, 0.35, 1),
                    visibility 0s linear 0.22s;
        margin-top: 0;
    }
    .lx-hover-drop > .dropdown-menu.lx-mega { display: grid; }
    .lx-hover-drop:hover > .dropdown-menu,
.lx-hover-drop:focus-within > .dropdown-menu {
        visibility: visible;
        opacity: 1;
        transform: none;
        transition-delay: 0s, 0s, 0s;
    }
    .lx-hover-drop::after {
        content: "";
        position: absolute;
        left: 0; right: 0; top: 100%;
        height: 18px;
    }
    .lx-hover-drop { position: relative; }
}
/* Mobile: hamburger sits last, next to the theme toggle */
@media (max-width: 991px) {
    .navbar-container { align-items: center; }
    .nav-btn { order: 3; margin-left: 0.5rem; }
    .navbar-action-container { order: 2; margin-left: auto; }
    .lx-wordmark { font-size: 1.15rem; letter-spacing: 0.08em; }
    .lx-logo img { height: 36px; }
    .lx-theme-btn { width: 38px; height: 38px; flex-basis: 38px; }
}

/* ---------------- 05. Shared text / gradient ---------------- */
.lx-gradient-text {
    background: var(--lx-gradient);
    background-size: 220% auto;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: lx-grad-shift 7s ease-in-out infinite;
}
@keyframes lx-grad-shift {
    0%, 100% { background-position: 0% center; }
    50%      { background-position: 100% center; }
}

.lx-eyebrow, .sub-heading span {
    color: var(--lx-purple);
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}

/* ---------------- 06. Hero (21st.dev: glowing orb + grain) ---------------- */
.lx-hero { position: relative; overflow: hidden; }
.lx-orb {
    position: absolute;
    border-radius: 50%;
    filter: blur(90px);
    opacity: var(--lx-orb-opacity);
    pointer-events: none;
    animation: lx-orb-float 14s ease-in-out infinite alternate;
}
.lx-orb-1 {
    width: 480px; height: 480px; top: -140px; right: -80px;
    background: radial-gradient(circle, rgba(200,42,239,0.55), transparent 65%);
}
.lx-orb-2 {
    width: 420px; height: 420px; bottom: -160px; left: -120px;
    background: radial-gradient(circle, rgba(79,70,229,0.5), transparent 65%);
    animation-delay: -7s;
}
.lx-orb-3 {
    width: 300px; height: 300px; top: 30%; left: 38%;
    background: radial-gradient(circle, rgba(124,58,237,0.35), transparent 65%);
    animation-duration: 18s;
}
@keyframes lx-orb-float {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(40px, -50px, 0) scale(1.12); }
}
/* Hero video plate: a rounded, inset panel of footage behind the hero copy,
   adapted from a Tailwind/React hero block into this site's vanilla stack.
   The clip is dark violet aerial footage, so rather than inverting it in day
   mode (which would drag the brand hues toward green) each theme sets its own
   scrim and opacity, keeping the headline legible either way. */
.lx-hero-video {
    position: absolute;
    /* Starts BELOW the fixed nav (as in the Marko reference) so the header
       floats over the page background, not over this dark plate. That is what
       lets the logo and the right-hand controls follow the page theme and stay
       legible in day mode. */
    inset: var(--lx-nav-h, 5.5rem) 0.4rem 0.4rem;
    border-radius: 28px;
    overflow: hidden;
    /* Same still as the video poster, so the panel is never blank: it covers
       the load gap, a blocked autoplay, and the reduced-motion case where the
       video element is removed entirely. */
    background: #050507 url("../image/brand/hero-plate.webp") center / cover no-repeat;
    border: 1px solid rgba(255, 255, 255, 0.06);
    pointer-events: none;
    z-index: 0;
    --lx-video-op: 0.75;
}
/* Once frames are actually rendering, drop the still. Leaving it behind a
   translucent video ghosts frame one over everything that follows. */
.lx-hero-video.is-playing { background-image: none; }
/* Two players are stacked so the loop point can crossfade rather than cut. */
.lx-hero-video video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    opacity: 0;
    transition: opacity 1s linear;
}
.lx-hero-video video.is-front { opacity: var(--lx-video-op); }
/* Scrim: darkens the left side, where the headline sits, and feathers the
   bottom edge into the section below. */
.lx-hero-video::after {
    content: "";
    position: absolute;
    inset: 0;
    background:
        /* Corner vignette. The source clip carries a generator watermark in the
           bottom right, and masking it costs nothing here, where the layout is
           empty, versus upscale-cropping a 720p plate. */
        radial-gradient(ellipse 26% 30% at 97% 90%, rgba(5, 5, 7, 0.99) 40%, rgba(5, 5, 7, 0.7) 68%, transparent 100%),
        linear-gradient(100deg, rgba(5, 5, 7, 0.94) 0%, rgba(5, 5, 7, 0.72) 38%, rgba(5, 5, 7, 0.18) 68%, rgba(5, 5, 7, 0.05) 100%),
        linear-gradient(to bottom, rgba(5, 5, 7, 0.55) 0%, transparent 22%, transparent 62%, rgba(5, 5, 7, 0.85) 100%);
}
/* Day mode keeps the hero as a DARK panel floating on the light page, the way
   the Marko reference does. Washing the plate out to white made the footage
   invisible, so instead the hero becomes its own dark context: the theme
   tokens are re-pointed at their night values for everything inside it, and
   the copy flips to light. */
body.lightmode .lx-hero-home {
    /* The template's own `.keep-dark` (on the hero element) re-points its
       token set to the night values, which is what keeps the buttons and copy
       correct. These are the Leadnox brand-layer tokens it does not know
       about. */
    --lx-card-bg: rgba(255, 255, 255, 0.06);
    --lx-surface: rgba(255, 255, 255, 0.06);
    --lx-surface-solid: rgba(255, 255, 255, 0.06);
    --lx-border: rgba(255, 255, 255, 0.14);
    --lx-border-strong: rgba(200, 42, 239, 0.5);
    --lx-hairline: rgba(255, 255, 255, 0.10);
    --lx-glow-tint: rgba(200, 42, 239, 0.20);
}
body.lightmode .lx-hero-home .lx-stat-card { backdrop-filter: blur(14px); }
@media (min-width: 992px) {
    .lx-hero-video { inset: var(--lx-nav-h, 5.5rem) 0.5rem 0.5rem; border-radius: 44px; }
}
@media (max-width: 767px) {
    .lx-hero-video { inset: 5.5rem 0.25rem 0.25rem; border-radius: 20px; }
    /* Portrait viewports crop the 16:9 plate hard, and copy runs the full
       width rather than sitting in a left column, so the scrim becomes an
       even wash instead of a left-weighted one. */
    .lx-hero-video { --lx-video-op: 0.62; }
    .lx-hero-video::after {
        background:
            radial-gradient(ellipse 34% 22% at 97% 92%, rgba(5, 5, 7, 0.99) 40%, rgba(5, 5, 7, 0.7) 70%, transparent 100%),
            linear-gradient(to bottom, rgba(5, 5, 7, 0.72) 0%, rgba(5, 5, 7, 0.62) 45%, rgba(5, 5, 7, 0.78) 78%, rgba(5, 5, 7, 0.92) 100%);
    }
}

/* Glow horizon: layered blurred arcs that converge into a glowing line at
   the top edge of the hero. Adapted from a framer-motion 21st.dev component
   into pure CSS so it fits this site's vanilla stack; gated on
   prefers-reduced-motion rather than JS so there is no hidden-tab risk (the
   unconditional base state below is already the fully-formed, fully visible
   look, the animation only ever runs on top of it). */
.lx-glow-horizon {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 46%;
    min-height: 260px;
    overflow: hidden;
    pointer-events: none;
    isolation: isolate;
    z-index: 1;
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,0.85) 22%, transparent 94%);
            mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,0.85) 22%, transparent 94%);
}
.lx-glow-arc {
    position: absolute;
    left: 50%;
    bottom: 100%;
    width: 150%;
    aspect-ratio: 3 / 1;
    border-radius: 50%;
    transform: translate(-50%, 42%);
}
.lx-glow-arc-black  { background: #000;    filter: blur(60px); opacity: 0.9; }
.lx-glow-arc-indigo { background: #4922E5; filter: blur(36px); opacity: 0.42; width: 140%; }
.lx-glow-arc-purple { background: #A558FB; filter: blur(42px); opacity: 0.32; width: 132%; }
.lx-glow-arc-white  {
    background: #fff;
    opacity: 0.3;
    width: 118%;
    filter: blur(6px);
    box-shadow: 0 -4px 34px 0 rgba(255, 255, 255, 0.45);
}
body.lightmode .lx-glow-arc-black  { opacity: 0.12; }
body.lightmode .lx-glow-arc-indigo { opacity: 0.32; }
body.lightmode .lx-glow-arc-purple { opacity: 0.26; }
body.lightmode .lx-glow-arc-white  { opacity: 0.6; }

@media (prefers-reduced-motion: no-preference) {
    .lx-glow-horizon {
        opacity: 0;
        animation: lx-glow-in 2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    }
    .lx-glow-arc-indigo { animation: lx-glow-slide 2s cubic-bezier(0.16, 1, 0.3, 1) 0s backwards; }
    .lx-glow-arc-black  { animation: lx-glow-slide 2s cubic-bezier(0.16, 1, 0.3, 1) 0s backwards; }
    .lx-glow-arc-purple { animation: lx-glow-slide 2s cubic-bezier(0.16, 1, 0.3, 1) 0.6s backwards; }
}
@keyframes lx-glow-in {
    from { opacity: 0; filter: blur(15px); transform: translateY(-30%) scaleY(1.4); }
    to   { opacity: 1; filter: blur(0);    transform: translateY(0)    scaleY(1); }
}
@keyframes lx-glow-slide {
    from { transform: translate(-50%, 30%); }
    to   { transform: translate(-50%, 42%); }
}

.lx-grain::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0.45;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.06'/%3E%3C/svg%3E");
}
body.lightmode .lx-grain::after { opacity: 0.22; }

.lx-hero-home {
    min-height: 92vh;
    display: flex;
    align-items: center;
    padding: 10rem 0 5rem 0;
}
.lx-hero-home .hero-container { width: 100%; }
.lx-hero-kicker {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 1.1rem;
    border: 1px solid var(--lx-border-strong);
    border-radius: 100px;
    background: var(--lx-glow-tint);
    color: var(--primary);
    font-size: 0.85rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    align-self: flex-start;
}
.lx-hero-kicker i { color: var(--lx-purple); }
.lx-hero-title {
    font-size: clamp(2.4rem, 5.2vw, 4.4rem);
    line-height: 1.08;
    font-weight: 800;
    color: var(--primary);
}
.lx-hero-sub { max-width: 640px; font-size: 1.05rem; }

/* Hero words: blur-out-up (21st.dev).
   Deliberately a TRANSITION, not an animation: a transition always lands on
   its final value even if the tab never paints it, so the headline can never
   be left invisible. The hidden start state is only applied once JS has armed
   the element, so with JS off the text simply shows. */
.lx-word { display: inline-block; }
.lx-words.is-armed .lx-word {
    /* Starts visible rather than at zero. The previous values (opacity 0,
       blur 10px) meant that on a long headline the later words were fully
       invisible for over a second while the stagger caught up, so the
       headline read as broken on first paint. This is now a mild settle:
       the word is always legible, it just arrives. */
    opacity: 0.32;
    filter: blur(3px);
    transform: translateY(0.16em);
    transition: opacity 0.5s ease, filter 0.5s ease,
                transform 0.5s cubic-bezier(0.22, 0.68, 0.24, 1);
}
.lx-words.is-armed .lx-word.is-in {
    opacity: 1;
    /* `none`, not blur(0). A filter of blur(0) is still a filter, and in WebKit
       any non-none filter on a descendant establishes a rendering context that
       breaks an ancestor's -webkit-background-clip: text. .title-heading is
       exactly that, so on iOS Safari the headline painted nothing at all while
       still occupying its space. */
    filter: none;
    transform: none;
}

/* ---------------- 07. Section reveal (21st.dev: blur reveal) ----------------
   The hidden start state only applies once JS marks the document ready, so a
   script failure leaves the page fully readable instead of blank. */
body.lx-js .lx-reveal {
    opacity: 0;
    filter: blur(14px);
    transform: translateY(26px);
    transition: opacity 0.85s ease, filter 0.85s ease, transform 0.85s cubic-bezier(0.22, 0.68, 0.24, 1);
}
body.lx-js .lx-reveal.is-in { opacity: 1; filter: blur(0); transform: none; }

body.lx-js .lx-wipe { clip-path: inset(0 100% 0 0); transition: clip-path 1.05s cubic-bezier(0.22, 0.68, 0.24, 1); }
body.lx-js .lx-wipe.is-in { clip-path: inset(0 0 0 0); }

/* ---------------- 08. Stat cards + border beam (21st.dev) ---------------- */
.lx-stat-row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
}
@media (max-width: 991px) { .lx-stat-row { grid-template-columns: repeat(2, 1fr); } }
.lx-stat-card {
    position: relative;
    border: 1px solid var(--lx-border);
    border-radius: 18px;
    padding: 1.6rem 1.4rem;
    overflow: hidden;
    box-shadow: var(--lx-shadow);
}
.lx-stat-value {
    font-size: clamp(1.7rem, 2.6vw, 2.4rem);
    font-weight: 800;
    color: var(--primary);
    white-space: nowrap;
}
.lx-stat-label { color: var(--text-color); font-size: 0.9rem; margin: 0; }

.lx-beam { position: relative; }
.lx-beam::before {
    content: "";
    position: absolute;
    inset: -140%;
    background: conic-gradient(from 0deg, transparent 0deg, var(--lx-purple) 26deg, var(--lx-indigo) 46deg, transparent 76deg);
    animation: lx-beam-spin 5.5s linear infinite;
    z-index: 0;
    opacity: 0.85;
}
.lx-beam::after {
    content: "";
    position: absolute;
    inset: 1px;
    border-radius: inherit;
    background: var(--lx-card-bg);
    z-index: 0;
}
.lx-beam > * { position: relative; z-index: 1; }
.lx-beam:nth-child(2n)::before { animation-duration: 7s;   animation-direction: reverse; }
.lx-beam:nth-child(3n)::before { animation-duration: 8.5s; }
@keyframes lx-beam-spin { to { transform: rotate(1turn); } }

/* ---------------- 09. Spotlight card (21st.dev) ---------------- */
.lx-spot { position: relative; overflow: hidden; }
.lx-spot::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.35s ease;
    background: radial-gradient(320px circle at var(--lx-mx, 50%) var(--lx-my, 50%), var(--lx-glow-tint), transparent 65%);
    z-index: 0;
}
.lx-spot:hover::before { opacity: 1; }
.lx-spot > * { position: relative; z-index: 1; }

/* ---------------- 10. 3D tilt card (21st.dev) ---------------- */
.lx-tilt {
    transform-style: preserve-3d;
    transition: transform 0.35s cubic-bezier(0.22, 0.68, 0.24, 1), box-shadow 0.35s ease, border-color 0.35s ease;
    will-change: transform;
}
.lx-tilt:hover {
    box-shadow: 0 40px 90px -40px rgba(124, 58, 237, 0.55);
    border-color: var(--lx-border-strong);
}
.lx-tilt-inner { transform: translateZ(38px); }

/* ---------------- 11. Shine sweep (bento / location cards) ---------------- */
.lx-shine { position: relative; overflow: hidden; }
.lx-shine::after {
    content: "";
    position: absolute;
    top: 0;
    left: -70%;
    width: 55%;
    height: 100%;
    background: linear-gradient(100deg, transparent, rgba(255,255,255,0.12), transparent);
    transform: skewX(-18deg);
    transition: left 0.75s cubic-bezier(0.22, 0.68, 0.24, 1);
    pointer-events: none;
    z-index: 2;
}
body.lightmode .lx-shine::after { background: linear-gradient(100deg, transparent, rgba(124,58,237,0.13), transparent); }
.lx-shine:hover::after { left: 125%; }

/* ---------------- 12. Marquee (21st.dev: blurred marquee) ---------------- */
.lx-marquee {
    overflow: hidden;
    padding: 1.2rem 0;
    border-top: 1px solid var(--lx-hairline);
    border-bottom: 1px solid var(--lx-hairline);
    -webkit-mask-image: linear-gradient(to right, transparent, black 12%, black 88%, transparent);
    mask-image: linear-gradient(to right, transparent, black 12%, black 88%, transparent);
}
.lx-marquee-track {
    display: flex;
    gap: 3.2rem;
    width: max-content;
    animation: lx-marquee-scroll 34s linear infinite;
}
.lx-marquee:hover .lx-marquee-track { animation-play-state: paused; }
.lx-marquee-item {
    display: inline-flex;
    align-items: center;
    gap: 0.8rem;
    white-space: nowrap;
    font-weight: 700;
    font-size: 1.1rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-color);
}
.lx-marquee-item i { color: var(--lx-purple); font-size: 0.55rem; }
@keyframes lx-marquee-scroll {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

/* ---------------- 13. Magnetic CTA + gradient ring ---------------- */
.lx-magnetic { transition: transform 0.25s cubic-bezier(0.22, 0.68, 0.24, 1); }
.lx-pulse { position: relative; }
.lx-pulse::after {
    content: "";
    position: absolute;
    inset: -3px;
    border-radius: inherit;
    background: var(--lx-gradient);
    background-size: 200% auto;
    opacity: 0.35;
    filter: blur(9px);
    z-index: -1;
    animation: lx-grad-shift 5s ease-in-out infinite;
}

/* ---------------- 14. Mega dropdown ---------------- */
.dropdown-menu.lx-mega {
    min-width: 560px;
    display: none;
    grid-template-columns: 1fr 1fr;
    gap: 0 1.5rem;
    padding: 1.2rem 1.4rem;
    background: var(--lx-panel-blur) !important;
    backdrop-filter: blur(14px);
    border: 1px solid var(--lx-border-strong);
    border-radius: 16px;
    box-shadow: var(--lx-shadow);
}
.dropdown-menu.lx-mega.show { display: grid; }
.lx-mega-group-title {
    font-size: 0.76rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--lx-purple);
    font-weight: 700;
    padding: 0.5rem 1rem 0.3rem 1rem;
}
.dropdown-menu.lx-mega .dropdown-item { font-size: 0.9rem; }
@media (max-width: 1200px) { .dropdown-menu.lx-mega { min-width: 420px; } }
.dropdown-menu { background: var(--lx-panel-blur) !important; border: 1px solid var(--lx-border); }

/* ---------------- 15. Content sections ---------------- */
.lx-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3.5rem;
    /* Start, not stretch: forcing a landscape photo to fill a 1000px column
       kept only ~40% of its width and sliced the subject. The image column is
       sticky instead (below), so it stays beside the copy the whole way down
       without dead space and without a brutal crop. */
    align-items: start;
}
@media (max-width: 991px) {
    /* Single column: nothing to stick to. */
    .lx-split { grid-template-columns: 1fr; gap: 2rem; align-items: start; }
    .lx-split-img, .lx-illus { position: static; }
    .lx-split-img img, .lx-illus img { height: auto; max-height: 24rem; }
}

/* Image reveal: clip-path wipe on scroll */
.lx-split-img {
    border-radius: 22px;
    overflow: hidden;
    border: 1px solid var(--lx-border);
    box-shadow: var(--lx-shadow);
    clip-path: inset(0 0 0 0);
    position: sticky;
    top: 2rem;                /* nav is in flow now, no bar to clear */
    align-self: start;
}
.lx-split-img img {
    width: 100%;
    /* Tall enough to hold its own beside a long column, shallow enough to keep
       roughly 60% of the frame's width. */
    height: clamp(22rem, 46vh, 34rem);
    object-fit: cover;
    display: block;
    transition: transform 0.8s cubic-bezier(0.22, 0.68, 0.24, 1);
}
.lx-split-img:hover img { transform: scale(1.05); }

/* Service illustration panels (SVG). The art is drawn portrait and keeps its
   subject in the middle band, so filling the column crops gracefully. */
.lx-illus {
    border-radius: 22px;
    overflow: hidden;
    border: 1px solid var(--lx-border);
    box-shadow: var(--lx-shadow);
    background: #0B0912;
    position: sticky;
    top: 6.5rem;
    align-self: start;
}
.lx-illus img {
    width: 100%;
    height: clamp(22rem, 46vh, 34rem);
    object-fit: cover;
    object-position: center;
    display: block;
}

.lx-prose p { margin-bottom: 1rem; }
.lx-prose p:last-child { margin-bottom: 0; }

.lx-h3-card {
    border: 1px solid var(--lx-border);
    border-radius: 18px;
    padding: 1.8rem;
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    transition: transform 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
}
.lx-h3-card:hover {
    transform: translateY(-6px);
    border-color: var(--lx-border-strong);
    box-shadow: var(--lx-shadow);
}
.lx-h3-card h3, .lx-h3-card h4 { font-size: 1.15rem; color: var(--primary); margin: 0; }
.lx-h3-card p { font-size: 0.95rem; margin: 0; }
.lx-card-icon {
    width: 46px; height: 46px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 12px;
    background: var(--lx-glow-tint);
    color: var(--lx-purple);
    font-size: 1.15rem;
    transition: transform 0.45s cubic-bezier(0.22, 0.68, 0.24, 1), background 0.35s ease;
}
.lx-h3-card:hover .lx-card-icon,
.card-service:hover .lx-card-icon {
    transform: rotate(-8deg) scale(1.1);
    background: var(--lx-gradient);
    color: #FFFFFF;
}

/* ---------------- 3D coverflow (home services section) -------------
   Ported from a React coverflow carousel. Five cards on a shared
   perspective stage: the centre one flat and nearest, its neighbours pushed
   out, scaled down and rotated away, with an ambient blur of the active
   photo behind everything. Positions are applied by initCoverflow() in
   leadnox.js; the offsets scale off the card width so the same geometry
   works at every breakpoint. */
.lx-cf {
    position: relative;
    border-radius: 28px;
    overflow: hidden;
    padding: clamp(2rem, 4vw, 3.25rem) 0 clamp(1.75rem, 3vw, 2.5rem);
    background: #0B0912;
    isolation: isolate;
}

/* Ambient backdrop: the active photo, heavily blurred and dimmed. */
.lx-cf-bg { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.lx-cf-bg-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transform: scale(1.15);
    filter: brightness(0.22) blur(32px);
    transition: opacity 0.6s ease;
}
.lx-cf-bg-veil {
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at center, rgba(11,9,18,0.30) 0%, rgba(11,9,18,0.94) 100%);
}

/* Stage */
.lx-cf-stage {
    position: relative;
    z-index: 2;
    height: clamp(24rem, 52vw, 31.25rem);
    display: flex;
    align-items: center;
    justify-content: center;
    perspective: 1400px;
}
.lx-cf-card {
    position: absolute;
    width: clamp(13.5rem, 26vw, 20.625rem);   /* 216px -> 330px */
    height: clamp(20rem, 40vw, 31.25rem);     /* 320px -> 500px */
    border-radius: 18px;
    overflow: hidden;
    background: #171120;
    border: 1px solid rgba(255, 255, 255, 0.12);
    transform-origin: center center;
    transition: transform 0.8s cubic-bezier(0.25, 1, 0.5, 1),
                opacity 0.8s cubic-bezier(0.25, 1, 0.5, 1),
                filter 0.8s cubic-bezier(0.25, 1, 0.5, 1),
                box-shadow 0.8s ease;
    box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5);
    cursor: pointer;
    /* Without JS the first card still shows, flat and readable. */
    opacity: 0;
}
.lx-cf-card.is-center {
    opacity: 1;
    z-index: 30;
    cursor: default;
    box-shadow: 0 25px 60px rgba(0, 0, 0, 0.9), 0 0 40px rgba(200, 42, 239, 0.28);
}
.lx-cf-photo {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.lx-cf-veil {
    position: absolute;
    inset: 0;
    z-index: 1;
    /* Heavier through the lower half: the title and body sit there, and a
       bright patch of photo behind them washed the text out. */
    background: linear-gradient(180deg, rgba(0,0,0,0.45) 0%, rgba(0,0,0,0.10) 20%,
                rgba(11,9,18,0.55) 42%, rgba(11,9,18,0.88) 60%,
                rgba(11,9,18,0.97) 78%, rgba(11,9,18,0.99) 100%);
}

/* Card content. Only the centre card shows it, exactly as in the source. */
.lx-cf-body {
    position: relative;
    z-index: 2;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    text-align: center;
    padding: 1.15rem 1.1rem 1.35rem;
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 0.5s ease, transform 0.5s ease;
    pointer-events: none;
}
.lx-cf-card.is-center .lx-cf-body { opacity: 1; transform: none; pointer-events: auto; }
.lx-cf-main {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.3rem;
    margin-top: auto;
    width: 100%;
}
.lx-cf .lx-cf-main h3 {
    margin: 0;
    font-size: clamp(1.05rem, 2vw, 1.35rem);
    font-weight: 800;
    line-height: 1.15;
    color: #fff;
    text-shadow: 0 3px 12px rgba(0, 0, 0, 0.95);
}
.lx-cf-rule {
    width: 34px;
    height: 2px;
    border-radius: 2px;
    margin: 0.35rem 0 0.25rem;
    background: var(--lx-gradient);
    box-shadow: 0 0 8px rgba(200, 42, 239, 0.7);
}
.lx-cf .lx-cf-main p {
    margin: 0 0 0.6rem;
    font-size: 0.8rem;
    line-height: 1.45;
    color: rgba(255, 255, 255, 0.88);
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.9);
    /* Descriptions vary in length; clamp so every card reads the same height. */
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.lx-cf-logos {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.7rem;
    margin-bottom: 0.75rem;
    font-size: 1.05rem;
    color: #fff;
    filter: drop-shadow(0 3px 8px rgba(0, 0, 0, 0.6));
}
.lx-cf-cta {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.5rem 1.1rem;
    border-radius: 999px;
    background: var(--lx-gradient);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4), 0 0 16px rgba(200, 42, 239, 0.35);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.lx-cf-cta:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0,0,0,0.5), 0 0 22px rgba(200,42,239,0.5); }
.lx-cf-cta i { font-size: 0.7rem; }

/* Arrows sit against the panel edges. */
.lx-cf-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 40;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.2);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: #fff;
    cursor: pointer;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
    transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}
.lx-cf-arrow:hover { background: var(--lx-gradient); border-color: transparent; transform: translateY(-50%) scale(1.06); }
.lx-cf-arrow:focus-visible { outline: 2px solid var(--lx-purple); outline-offset: 3px; }
.lx-cf-prev { left: clamp(0.5rem, 2vw, 1.5rem); }
.lx-cf-next { right: clamp(0.5rem, 2vw, 1.5rem); }

.lx-cf-dots {
    position: relative;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-top: clamp(1.25rem, 3vw, 2rem);
}
.lx-cf-dot {
    height: 8px;
    width: 8px;
    padding: 0;
    border: none;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.25);
    cursor: pointer;
    transition: width 0.3s ease, background 0.3s ease, box-shadow 0.3s ease;
}
.lx-cf-dot.is-active {
    width: 28px;
    background: var(--lx-purple);
    box-shadow: 0 0 10px rgba(200, 42, 239, 0.7);
}
.lx-cf-dot:focus-visible { outline: 2px solid var(--lx-purple); outline-offset: 3px; }

/* No JS, or reduced motion: fall back to a readable single card. */
.lx-cf:not(.is-live) .lx-cf-card:not(.is-center) { display: none; }
@media (prefers-reduced-motion: reduce) {
    .lx-cf-card, .lx-cf-body { transition: none; }
}

.lx-carousel-cta {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.1rem;
    margin-top: clamp(2.5rem, 5vw, 4rem);
    padding-top: clamp(2rem, 4vw, 3rem);
    border-top: 1px solid var(--lx-hairline);
}
.lx-carousel-cta p {
    max-width: 44rem;
    margin: 0;
    font-size: 1.02rem;
    text-align: center;
}

@media (prefers-reduced-motion: reduce) {
    .lx-carousel-card { transition: none; }
    .lx-carousel-word { opacity: 1; filter: none; transform: none; }
}

.lx-quote {
    border-left: 3px solid var(--lx-purple);
    background: var(--lx-glow-tint);
    border-radius: 0 16px 16px 0;
    padding: 1.4rem 1.7rem;
    color: var(--primary);
    font-size: 1.02rem;
}

.lx-chip-row { display: flex; flex-wrap: wrap; gap: 0.7rem; }
.lx-chip {
    padding: 0.45rem 1rem;
    border-radius: 100px;
    border: 1px solid var(--lx-border);
    background: var(--lx-surface);
    color: var(--primary);
    font-size: 0.85rem;
    transition: border-color 0.3s ease, transform 0.3s ease;
}
.lx-chip:hover { border-color: var(--lx-border-strong); transform: translateY(-3px); }
.lx-chip i { color: var(--lx-purple); margin-right: 0.4rem; }

/* ---------------- 16. Bento locations grid ----------------
   Gradient panel with the icon tile floating half outside the left edge.
   The tile is a sibling of the card, not a child: the card keeps
   `overflow: hidden` for its shine sweep, which would otherwise clip it. */
.lx-bento {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.6rem;
}
@media (max-width: 991px) { .lx-bento { grid-template-columns: 1fr; } }

.lx-bento-item {
    position: relative;
    padding-left: 2.7rem;      /* room for the tile's overhang */
}
.lx-bento-item > .lx-card-icon {
    position: absolute;
    left: 0;
    top: 2.6rem;
    z-index: 2;
    width: 5.4rem;
    height: 5.4rem;
    border-radius: 22px;
    font-size: 1.55rem;
    background: #FFFFFF;
    color: var(--lx-purple);
    border: 1px solid rgba(255, 255, 255, 0.7);
    box-shadow: 0 0 0 7px rgba(200, 42, 239, 0.07),
                0 14px 34px -10px rgba(200, 42, 239, 0.45);
    transition: transform 0.45s cubic-bezier(0.22, 0.68, 0.24, 1),
                box-shadow 0.4s ease;
}
.lx-bento-item:hover > .lx-card-icon {
    transform: translateY(-4px) rotate(-6deg);
    box-shadow: 0 0 0 9px rgba(200, 42, 239, 0.10),
                0 18px 42px -10px rgba(200, 42, 239, 0.6);
}

.lx-bento-card {
    /* The global surface rule sets `background: var(--lx-card-bg) !important`,
       so the panel gradient is set through that token rather than fought. */
    --lx-card-bg: linear-gradient(115deg, #17131F 0%, #1B1430 48%, #2A1642 100%);
    border: 1px solid var(--lx-border);
    border-radius: 26px;
    padding: 2.4rem 2.2rem 2.4rem 4.4rem;
    height: 100%;
    position: relative;
    overflow: hidden;
    transition: border-color 0.35s ease, transform 0.35s ease, box-shadow 0.35s ease;
}
/* Mirror the sweep on the second card so the pair reads as a set. */
.lx-bento-item:nth-child(even) .lx-bento-card {
    --lx-card-bg: linear-gradient(295deg, #17131F 0%, #1B1430 48%, #2A1642 100%);
}
.lx-bento-item:hover .lx-bento-card {
    border-color: var(--lx-border-strong);
    transform: translateY(-4px);
    box-shadow: var(--lx-shadow);
}
.lx-bento-card h3 { color: var(--primary); margin: 0 0 0.6rem; font-size: 1.6rem; }
.lx-bento-card > p {
    margin: 0 0 1.1rem;
    font-size: 0.95rem;
    line-height: 1.65;
    color: var(--text-color);
}

body.lightmode .lx-bento-card {
    --lx-card-bg: linear-gradient(115deg, #F7F6F9 0%, #F2EBFB 52%, #E7D8FA 100%);
    border-color: rgba(124, 58, 237, 0.14);
}
body.lightmode .lx-bento-item:nth-child(even) .lx-bento-card {
    --lx-card-bg: linear-gradient(295deg, #F7F6F9 0%, #F2EBFB 52%, #E7D8FA 100%);
}

@media (max-width: 575px) {
    /* Too narrow for an overhang. The tile moves fully inside the card rather
       than going static, which would leave it floating above the panel. */
    .lx-bento-item { padding-left: 0; }
    .lx-bento-item > .lx-card-icon {
        left: 1.6rem;
        top: 1.6rem;
        width: 4rem;
        height: 4rem;
        font-size: 1.2rem;
        border-radius: 18px;
    }
    .lx-bento-card { padding: 6.4rem 1.6rem 1.8rem; }
}

.lx-loc-cloud { display: flex; flex-wrap: wrap; gap: 0.35rem 0; }
.lx-loc-cloud a {
    color: var(--text-color);
    font-size: 0.85rem;
    text-decoration: none;
    transition: color 0.25s ease;
}
.lx-loc-cloud a:hover { color: var(--lx-purple); }
.lx-loc-cloud a:not(:last-child)::after {
    content: "·";
    margin: 0 0.55rem;
    color: var(--lx-purple);
    opacity: 0.55;
}

/* ---------------- 17. Footer ---------------- */
.lx-footer-locations {
    border-top: 1px solid var(--lx-hairline);
    padding-top: 1.6rem;
    margin-top: 0.4rem;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2rem;
}
@media (max-width: 767px) { .lx-footer-locations { grid-template-columns: 1fr; } }
.lx-footer-locations h4 {
    font-size: 0.78rem;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--lx-purple);
    margin-bottom: 0.7rem;
}

/* ---------------- 18. Inner page hero ---------------- */
.lx-inner-hero {
    position: relative;
    padding: 11rem 0 5rem 0;
    overflow: hidden;
}
.lx-inner-hero .breadcrumb { justify-content: flex-start; }
.lx-inner-hero h1 {
    font-size: clamp(2rem, 3.8vw, 3.2rem);
    line-height: 1.12;
    max-width: 900px;
}
.lx-inner-hero .lx-hero-sub { max-width: 780px; }

/* ---------------- 19. Light-mode contrast repairs ---------------- */
body.lightmode .card,
body.lightmode .lx-stat-card,
body.lightmode .lx-h3-card,
body.lightmode .lx-bento-card {
    box-shadow: 0 18px 44px -28px rgba(31, 25, 60, 0.30);
}
body.lightmode .title-heading,
body.lightmode h1, body.lightmode h2, body.lightmode h3,
body.lightmode h4, body.lightmode h5, body.lightmode h6 { color: var(--primary); }
body.lightmode p, body.lightmode .lx-stat-label { color: var(--text-color); }
body.lightmode .lx-marquee-item { color: #6A6383; }
body.lightmode .breadcrumb .current-page { color: var(--text-color); }
body.lightmode .check-list li { color: var(--text-color); }
body.lightmode .footer-list a,
body.lightmode .contact-list li,
body.lightmode .copyright,
body.lightmode .legal-link { color: var(--text-color); }
/* Footer follows the theme: light plate + dark type in day mode */
body.lightmode .bg-footer {
    background-image: radial-gradient(at top left, #EDE4FB, #FBFAFD 55%);
}
body.lightmode footer .lx-wordmark,
body.lightmode footer h2, body.lightmode footer h3, body.lightmode footer h4 { color: var(--primary); }
body.lightmode footer p,
body.lightmode footer .footer-list a,
body.lightmode footer .contact-list li,
body.lightmode footer .copyright,
body.lightmode footer .legal-link,
body.lightmode footer .lx-loc-cloud a { color: var(--text-color); }
body.lightmode footer .footer-list a:hover,
body.lightmode footer .lx-loc-cloud a:hover { color: var(--lx-purple); }
body.lightmode footer .social-item { color: var(--primary); }

/* ---------------- 20. Reduced motion ---------------- */
@media (prefers-reduced-motion: reduce) {
    .lx-orb, .lx-marquee-track, .lx-pulse::after, .lx-gradient-text,
    .lx-wordmark em, .lx-beam::before { animation: none !important; }
    .lx-word { animation-duration: 0.01s; }
    .lx-reveal, .lx-wipe { transition: none; opacity: 1; filter: none; transform: none; clip-path: none; }
}

/* ---------------- 18. Rhythm & alignment pass ----------------
   Consolidated spacing/alignment optimization, patterned on current
   21st.dev section conventions: fluid section padding, tight eyebrow ->
   heading -> lead groups, readable lead measure, and a brand CTA band
   instead of the template's leftover stock-photo banner. Loaded after
   style.css, so plain rules here override it by order. */

/* Fluid vertical rhythm: 120px on desktop easing to ~72px on phones.
   Fixed 120px reads as a chasm on a 375px viewport. */
.section { padding: clamp(4.5rem, 4vw + 3rem, 7.5rem) 20px; }
.lx-hero-home { padding: clamp(7.5rem, 16vh, 10rem) 0 clamp(3.25rem, 7vh, 5rem) 0; }
.lx-inner-hero { padding: clamp(8rem, 15vh, 11rem) 0 clamp(3.25rem, 7vh, 5rem) 0; }
.bg-footer { padding-top: clamp(4.5rem, 8vw, 7.5rem); }

/* Header groups: the eyebrow belongs to its heading (list-style proximity),
   so the stack tightens from a uniform 20px to 12px between eyebrow and
   title. Browsers without :has() simply keep the template's 20px. */
main div.gspace-2:has(> .sub-heading) { gap: 12px 12px; }
main div.gspace-2:has(> .sub-heading) > p { margin-top: 6px; }

/* Lead paragraphs under section headings: cap at a readable measure
   (~65ch) instead of 75% of a 1280px container. Headings keep the wide
   container; only body copy narrows. */
p.heading-container-medium { max-width: min(100%, 46rem); }

/* Stat row joins the same 20px gutter grid every other card row uses. */
.lx-stat-row { gap: 1.25rem; }

/* Card interiors: one padding family across the board (bento already sits
   at 2.2-2.4rem). */
.lx-h3-card { padding: 2rem; }

/* ---- CTA band: brand panel, not the template's stock-photo banner ---- */
.guide-banner {
    background-image:
        radial-gradient(ellipse 60% 90% at 85% 10%, rgba(200, 42, 239, 0.16), transparent 70%),
        radial-gradient(ellipse 55% 90% at 10% 95%, rgba(79, 70, 229, 0.20), transparent 70%),
        linear-gradient(120deg, #14101E 0%, #1A1230 55%, #241238 100%);
    background-attachment: scroll;      /* `fixed` janks on scroll + iOS */
    padding: clamp(4rem, 7vw, 6.5rem) clamp(1.5rem, 4vw, 4rem);
    border-color: var(--lx-border-strong);
}
.guide-banner::before { display: none; }   /* old scrim for the stock photo */
.guide-content { max-width: min(100%, 46rem); gap: 1.6rem; }
.guide-content h3 { color: #F7F5FC; }
.guide-content p { color: rgba(244, 242, 250, 0.78); }
body.lightmode .guide-banner {
    background-image:
        radial-gradient(ellipse 60% 90% at 85% 10%, rgba(200, 42, 239, 0.10), transparent 70%),
        radial-gradient(ellipse 55% 90% at 10% 95%, rgba(79, 70, 229, 0.12), transparent 70%),
        linear-gradient(120deg, #FBFAFE 0%, #F3ECFC 55%, #EADAF9 100%);
    border-color: rgba(124, 58, 237, 0.22);
}
body.lightmode .guide-content h3 { color: var(--primary); }
body.lightmode .guide-content p { color: var(--text-color); }

@media (max-width: 767px) {
    .guide-content { max-width: 100%; }
}

/* ---------------- 19. Notch navigation (sticky) ----------------
   Ported from a React "adaptive notch navigation bar". Only the CENTER menu
   is a notch: a dark island carved into the top edge of the viewport, joined
   to the edge by concave corner fillets. The component draws those fillets as
   SVG "wings"; here they are radial-gradient pseudo-elements, which need no
   extra DOM and inherit the notch color for free.

   The logo and the right-hand controls are deliberately NOT notched, so they
   carry no island background and follow the page theme. `keep-dark` sits on
   the menu island itself (not the header) so only that island stays dark in
   day mode, the way the reference renders dark notches on a light page. */
header.lx-notch {
    --lx-notch-bg: #0E0B17;
    --lx-wing: 18px;
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 60;
}
header.lx-notch .navbar-wrapper { padding: 0; }
header.lx-notch .navbar {
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 0;
}

@media (min-width: 992px) {
    header.lx-notch .navbar-container {
        position: relative;
        align-items: flex-start;
    }

    /* ---- Logo: no island. A soft, theme-aware plate keeps the wordmark
       legible while it floats over whatever scrolls beneath it. ---- */
    /* Logo sits in a pill that matches the Free Audit button: same surface,
       radius, accent border and purple glow, reusing the button's own tokens
       so the two stay in sync if the theme changes. */
    header.lx-notch .logo-container-header {
        display: flex;
        align-items: center;
        align-self: center;
        margin: 12px 0 0 30px;
        padding: 8px 22px;
        border-radius: 100px;
        background-color: var(--accent-color-4);
        box-shadow: var(--box-shadow-top-left);
        transition: box-shadow 0.6s, transform 0.35s ease;
    }
    body.lightmode header.lx-notch .logo-container-header {
        border: 1px solid var(--accent-color);
    }
    header.lx-notch .logo-container-header:hover {
        box-shadow: var(--box-shadow-top-left-wide);
    }

    /* ---- Center menu: the notch. ---- */
    header.lx-notch .navbar-collapse {
        position: absolute;
        left: 50%; top: 0;
        transform: translateX(-50%);
        flex: none;
        width: auto;
        min-width: 0;
        background: var(--lx-notch-bg);
        height: 66px;
        display: flex;
        align-items: center;
        padding: 0 20px;
        border-radius: 0 0 26px 26px;
    }
    header.lx-notch .navbar-collapse::before {
        content: "";
        position: absolute;
        right: 100%; top: 0;
        width: var(--lx-wing); height: var(--lx-wing);
        background: radial-gradient(circle at 0 100%,
            transparent calc(var(--lx-wing) - 0.5px), var(--lx-notch-bg) var(--lx-wing));
    }
    header.lx-notch .navbar-collapse::after {
        content: "";
        position: absolute;
        left: 100%; top: 0;
        width: var(--lx-wing); height: var(--lx-wing);
        background: radial-gradient(circle at 100% 100%,
            transparent calc(var(--lx-wing) - 0.5px), var(--lx-notch-bg) var(--lx-wing));
    }
    /* Dropdown panels hang off a taller bar now; close the hover gap. */
    header.lx-notch .lx-hover-drop::after { height: 26px; }

    /* ---- Right controls: no island either. The toggle and the CTA already
       carry their own shapes, so they only need breathing room. ---- */
    header.lx-notch .navbar-action-container {
        height: 66px;
        margin-right: 30px;
        padding: 0;
    }
}

/* The menu island keeps night styling in BOTH modes by design (the user's
   call: the dark notch is part of the brand look, like the dark hero plate).
   `keep-dark` on the markup re-points the template tokens; these are the
   Leadnox brand-layer tokens it does not know about, so the pill, dropdown
   panels and hairlines inside the island stay correct in day mode. */
body.lightmode header.lx-notch .navbar-collapse {
    --lx-surface: rgba(255, 255, 255, 0.045);
    --lx-border: rgba(255, 255, 255, 0.10);
    --lx-border-strong: rgba(200, 42, 239, 0.42);
    --lx-glow-tint: rgba(200, 42, 239, 0.16);
    --lx-panel-blur: rgba(10, 8, 14, 0.97);
    --lx-hairline: rgba(255, 255, 255, 0.07);
    --lx-card-bg: #100E18;
    --lx-shadow: 0 30px 80px -34px rgba(0, 0, 0, 0.9);
}

/* Mobile / tablet: the site map lives in the slide-in sidebar, so there is no
   notch to draw. The bar returns to the template's floating rounded style,
   still fixed to the top. */
@media (max-width: 991px) {
    header.lx-notch .navbar-wrapper { padding: 14px 16px 0; }
    header.lx-notch .navbar {
        background: var(--lx-card-bg);
        border: 1px solid var(--lx-border);
        border-radius: 22px;
        padding: 10px 18px;
    }
    /* The sidebar must stack above the fixed bar. */
    aside { z-index: 70; }
}

/* ---------------- 20. Alignment & breathing room ----------------
   One gutter for every full-width band, so panel edges and section content
   land on the same vertical axis. Auditing services.html found four different
   gutters on a single page (0, 20px, 42px, 45px), which is what made the page
   read as misaligned. */
:root { --lx-gutter: clamp(1.25rem, 3vw, 2.5rem); }

.section,
.section-guide,
.section-footer,
.section-banner,
.section-partner {
    padding-left: var(--lx-gutter);
    padding-right: var(--lx-gutter);
}
.lx-hero-home .hero-container,
.lx-inner-hero .hero-container {
    padding-left: var(--lx-gutter);
    padding-right: var(--lx-gutter);
}
/* Panels that sit inside an already-guttered band must not add a second one. */
.guide-banner > .hero-container,
.bg-footer > .hero-container { padding-left: 0; padding-right: 0; }

/* ---- Body copy: 18px with no declared line-height inherits a ~1.2 default,
   which is what made paragraphs feel cramped. ---- */
p { line-height: 1.75; }
.lx-prose p, .check-list li, .lx-h3-card p, .card p { line-height: 1.75; }
.check-list li { margin-bottom: 0.65rem; }
h1, h2, h3, h4, .title-heading { text-wrap: balance; }
p { text-wrap: pretty; }

/* ---- CTA band: the copy was capped at 46rem inside a full-width panel,
   leaving the right half empty. Side by side on wide screens instead. ---- */
@media (min-width: 992px) {
    .guide-content {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: clamp(2rem, 5vw, 4.5rem);
        max-width: 100%;
    }
    .guide-content > .d-flex.flex-column { max-width: 44rem; }
    .guide-content > .d-flex.align-items-center { flex: none; }
}

/* ---- The notch nav is transparent between its islands, so page content
   scrolled visibly through the gaps and collided with the menu. A soft scrim
   mutes what passes underneath without filling the gaps in. ---- */
header.lx-notch::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 118px;
    z-index: -1;
    pointer-events: none;
    background: linear-gradient(to bottom, var(--secondary) 42%, transparent 100%);
}

/* Anchor jumps must clear the fixed nav. */
html { scroll-padding-top: 7rem; }

@media (max-width: 991px) {
    header.lx-notch::before { height: 96px; }
}

/* Blog post byline strip. */
.lx-post-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem 1.6rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--lx-hairline);
    font-size: 0.9rem;
    color: var(--text-color);
}
.lx-post-meta i { margin-right: 0.4rem; }

/* ---------------- 21. Blog listing (BLOG-SYSTEM-GUIDE.md §3) ----------------
   Tokens taken from the guide. Cards carry NO photographs by design: the
   thumbnail is a CSS gradient with a text label, which keeps the listing fast
   and on-brand. Colours are mapped onto the theme tokens so the grid works in
   both day and night. */
.blog-filter-bar {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    justify-content: center;
    margin-bottom: 48px;
}
.blog-filter-pill {
    padding: 8px 20px;
    border-radius: 100px;
    font-size: 13px;
    font-weight: 600;
    border: 2px solid var(--lx-border);
    background: var(--lx-card-bg);
    color: var(--text-color);
    cursor: pointer;
    transition: all 0.2s;
}
.blog-filter-pill:hover { border-color: var(--lx-border-strong); color: var(--primary); }
.blog-filter-pill.active {
    background: var(--lx-gradient);
    border-color: transparent;
    color: #fff;
}
.blog-filter-pill:focus-visible { outline: 2px solid var(--lx-purple); outline-offset: 3px; }

.blog-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 28px;
    margin-bottom: 64px;
}
@media (max-width: 991px) { .blog-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .blog-grid { grid-template-columns: 1fr; } }

.blog-card {
    background: var(--lx-card-bg);
    border-radius: 20px;
    overflow: hidden;
    border: 1px solid var(--lx-border);
    display: flex;
    flex-direction: column;
    transition: box-shadow .3s, transform .3s, opacity .2s;
}
.blog-card:hover { transform: translateY(-6px); box-shadow: var(--lx-shadow); border-color: var(--lx-border-strong); }
/* The card thumb is the post's own photograph. It used to be a gradient
   plate with the headline printed on it, which repeated the title sitting
   directly underneath it. */
.blog-card-thumb {
    height: 200px;
    overflow: hidden;
    background: var(--lx-surface);
}
.blog-card-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform .5s cubic-bezier(0.22, 0.68, 0.24, 1);
}
.blog-card:hover .blog-card-thumb img { transform: scale(1.045); }
.blog-card-body { display: flex; flex-direction: column; gap: 12px; padding: 22px 24px 24px; flex: 1; }
.blog-card-meta { display: flex; align-items: center; gap: 12px; }
.blog-cat-pill {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    padding: 4px 10px;
    border-radius: 100px;
}
.pill-ads      { background: rgba(124, 92, 245, 0.16); color: #a78bfa; }
.pill-seo      { background: rgba(16, 185, 129, 0.16); color: #34d399; }
.pill-ai       { background: rgba(249, 115, 22, 0.16); color: #fb923c; }
.pill-strategy { background: rgba(56, 189, 248, 0.16); color: #38bdf8; }
.pill-social   { background: rgba(34, 197, 94, 0.16);  color: #4ade80; }
body.lightmode .pill-ads      { background: rgba(124, 92, 245, 0.12); color: #6d3fe0; }
body.lightmode .pill-seo      { background: rgba(16, 185, 129, 0.12); color: #0f7a5a; }
body.lightmode .pill-ai       { background: rgba(249, 115, 22, 0.12); color: #b45309; }
body.lightmode .pill-strategy { background: rgba(56, 189, 248, 0.14); color: #0369a1; }
body.lightmode .pill-social   { background: rgba(34, 197, 94, 0.14);  color: #15803d; }
.blog-read-time { font-size: 12px; color: var(--text-color); }
.blog-card-title {
    font-size: 17px;
    font-weight: 700;
    line-height: 1.45;
    color: var(--primary);
    text-decoration: none;
    transition: color .25s ease;
}
.blog-card-title:hover { color: var(--lx-purple); }
.blog-card-excerpt { font-size: 14.5px; line-height: 1.7; color: var(--text-color); margin: 0; }
.blog-card-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: auto;
    padding-top: 16px;
    border-top: 1px solid var(--lx-hairline);
}
.blog-author { font-size: 13px; color: var(--text-color); }
.blog-read-link {
    font-size: 13px;
    font-weight: 700;
    color: var(--lx-purple);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.blog-read-link i { font-size: 11px; transition: transform .25s ease; }
.blog-read-link:hover i { transform: translateX(3px); }

/* Content pillars */
.pillar-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.6rem; }
@media (max-width: 767px) { .pillar-grid { grid-template-columns: 1fr; } }
.pillar-card { border-radius: 20px; padding: 2rem; border: 1px solid var(--lx-border); }
.pillar-card.dark  { background: linear-gradient(150deg, #14101E 0%, #241238 100%); }
.pillar-card.light { background: var(--lx-card-bg); }
.pillar-card.dark h3 { color: #fff; }
.pillar-card h3 { margin: 0 0 1.1rem; font-size: 1.3rem; color: var(--primary); }
.pillar-topics { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.pillar-topic-tag {
    font-size: 0.8rem;
    padding: 0.4rem 0.85rem;
    border-radius: 100px;
    border: 1px solid var(--lx-border);
    color: var(--text-color);
}
.pillar-card.dark .pillar-topic-tag { border-color: rgba(255,255,255,0.16); color: rgba(255,255,255,0.82); }

/* Ported post pages carry their own <style> block; these only bridge the post
   layout to the fixed nav and the themed page background. */
.lnx-post-sidebar { top: 7rem !important; }
.lnx-post-body { background: var(--secondary); }

/* ---------------------------------------------------------------
   22. Post CTA plates vs. day mode
   The post hero now uses the site's standard inner hero, so it follows the
   page background in both themes and needs no overrides. The two CTA plates
   are still saturated brand gradients with white type on them, and section
   1256's day-mode rules would otherwise repaint their headings and copy with
   the near-black ink tokens. Specificity (0,3,1) clears the (0,2,1) blanket.
   --------------------------------------------------------------- */
body.lightmode .lnx-post-cta h2,
body.lightmode .lnx-post-cta h3,
body.lightmode .lnx-sidebar-cta .lnx-sidebar-cta-title { color: #ffffff; }

body.lightmode .lnx-post-cta p,
body.lightmode .lnx-sidebar-cta p { color: rgba(255, 255, 255, 0.88); }

/* ---------------------------------------------------------------
   23. Blog listing rhythm + empty state
   The listing used to zero its own top padding, so the filter bar butted
   straight into the hero with no breathing room. It now keeps the site's
   normal section rhythm, slightly tightened at the top because the inner
   hero already carries its own bottom space.
   --------------------------------------------------------------- */
.lx-blog-listing { padding-top: clamp(3.5rem, 6vw, 5.5rem); }

.blog-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 1.25rem;
    max-width: 620px;
    margin: 0 auto;
    padding: clamp(2.5rem, 5vw, 4rem) clamp(1.5rem, 4vw, 3rem);
    background: var(--lx-card-bg);
    border: 1px solid var(--lx-border);
    border-radius: 24px;
    box-shadow: var(--lx-shadow);
}
.blog-empty-icon {
    display: grid;
    place-items: center;
    width: 64px;
    height: 64px;
    border-radius: 50%;
    font-size: 22px;
    color: #fff;
    background: var(--lx-gradient);
}
.blog-empty h2 { font-size: clamp(22px, 3vw, 30px); line-height: 1.25; margin: 0; }
.blog-empty p  { margin: 0; max-width: 52ch; }
.blog-empty .btn { margin-top: .5rem; }

/* Filter visibility is a single class with no timers, so clicking pills
   quickly can never leave a card half-hidden. See js/blog-filter.js. */
.blog-card.is-filtered-out { display: none; }

/* ---------------------------------------------------------------
   24. Hero gutter alignment + CTA band / footer separation
   --------------------------------------------------------------- */

/* The inner hero put its gutter on the inner .hero-container, while .section
   puts the gutter on the section itself and leaves the container flush. At a
   1440px viewport that pushed hero text ~40px further in than every section
   below it, so the H1 never lined up with the content underneath. Moving the
   hero gutter out to the band makes both resolve to the same content edge at
   every width. */
.lx-inner-hero {
    padding-left: var(--lx-gutter);
    padding-right: var(--lx-gutter);
}
.lx-inner-hero .hero-container {
    padding-left: 0;
    padding-right: 0;
}

/* The CTA band and the footer are both rounded panels, and the band's section
   ended at padding-bottom 0 with the footer starting at margin-top 0, so the
   two cards touched. Separate them with the same rhythm the rest of the page
   uses between blocks. */
.section-guide { padding-bottom: clamp(3rem, 6vw, 5rem); }

/* ---------------------------------------------------------------
   25. Case study cards
   Real engagements with client-reported figures. The head is a tinted brand
   plate carrying the headline metric, the body carries the narrative, the
   stat row, an optional callout and an optional client quote. Everything is
   token-driven so the cards follow day and night mode like the rest of the
   site.
   --------------------------------------------------------------- */
.lx-cs-grid {
    display: grid;
    /* Four studies now. Three columns left the fourth stranded alone on a
       second row; two columns gives a clean 2x2 and wider, more readable cards. */
    grid-template-columns: repeat(2, 1fr);
    gap: 28px;
    align-items: start;
    max-width: 1080px;
    margin: 0 auto;
}
@media (max-width: 760px)  { .lx-cs-grid { grid-template-columns: 1fr; } }

.lx-cs-card {
    display: flex;
    flex-direction: column;
    background: var(--lx-card-bg);
    border: 1px solid var(--lx-border);
    border-radius: 22px;
    overflow: hidden;
    transition: box-shadow .3s, transform .3s, border-color .3s;
}
.lx-cs-card:hover {
    transform: translateY(-6px);
    box-shadow: var(--lx-shadow);
    border-color: var(--lx-border-strong);
}

/* Head plate stays dark in both themes so the metric always reads as a
   highlight rather than as body text. */
.lx-cs-head {
    padding: 26px 26px 30px;
    background:
        radial-gradient(ellipse 70% 100% at 85% 0%, rgba(200, 42, 239, 0.20), transparent 70%),
        linear-gradient(140deg, #14101E 0%, #1A1230 55%, #241238 100%);
    border-bottom: 1px solid var(--lx-border);
}
.lx-cs-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 22px; }
.lx-cs-tag {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    padding: 6px 13px;
    border-radius: 100px;
    color: #E9D5FF;
    background: rgba(200, 42, 239, 0.16);
    border: 1px solid rgba(200, 42, 239, 0.40);
}
.lx-cs-metric {
    font-size: clamp(38px, 4.6vw, 54px);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.02em;
    background: var(--lx-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    margin-bottom: 10px;
}
.lx-cs-metric-label {
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.62);
}

.lx-cs-body { display: flex; flex-direction: column; gap: 16px; padding: 26px; flex: 1; }
.lx-cs-body h3 { font-size: 19px; line-height: 1.4; margin: 0; }
.lx-cs-body > p { margin: 0; font-size: 15px; line-height: 1.75; }

.lx-cs-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 2px; }
.lx-cs-stat {
    text-align: center;
    padding: 14px 8px;
    border-radius: 14px;
    background: var(--lx-surface);
    border: 1px solid var(--lx-hairline);
}
.lx-cs-stat .num {
    font-size: 19px;
    font-weight: 800;
    line-height: 1.15;
    margin-bottom: 5px;
    background: var(--lx-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}
.lx-cs-stat .label { font-size: 11.5px; line-height: 1.45; }

.lx-cs-callout {
    padding: 16px 18px;
    border-radius: 14px;
    border-left: 3px solid var(--lx-purple);
    background: var(--lx-glow-tint);
}
.lx-cs-callout-title { font-weight: 700; font-size: 15px; line-height: 1.4; margin-bottom: 5px; }
.lx-cs-callout p { margin: 0; font-size: 13.5px; line-height: 1.6; }

.lx-cs-quote {
    margin: 0;
    padding: 0 0 0 18px;
    border-left: 3px solid var(--lx-violet);
}
.lx-cs-quote p { margin: 0 0 10px; font-size: 14.5px; line-height: 1.7; font-style: italic; }
.lx-cs-quote cite { font-size: 13px; font-style: normal; font-weight: 700; color: var(--lx-purple); }

/* ---------------------------------------------------------------
   26. Hero measure and vertical rhythm
   The inner hero capped its H1 at 900px and its standfirst at 780px inside a
   1280px container, so headline text stopped ~380px short of the right edge
   and the standfirst ~500px short. It read as a narrow left-hand column
   rather than a hero that runs the width of the page. Both now run the full
   container, and the block gets more room above and below so the type is not
   pinned against the nav or the section that follows.
   --------------------------------------------------------------- */
.lx-inner-hero h1,
.lx-inner-hero .lx-hero-sub { max-width: none; }

.lx-inner-hero {
    padding-top: clamp(9.5rem, 16vh, 12.5rem);
    padding-bottom: clamp(4.5rem, 9vh, 7rem);
}

/* Headline to standfirst needs more air once the lines run full width. */
.lx-inner-hero .hero-container .gspace-2 { gap: clamp(1.15rem, 1.8vw, 1.75rem); }

/* `text-wrap: balance` (set site-wide on headings) evens the line lengths,
   which is what kept the hero headline breaking early and sitting in a narrow
   column even after the max-width cap came off. The hero headline fills each
   line before wrapping instead; balance stays on for every other heading. */
.lx-inner-hero h1,
.lx-inner-hero h1.title-heading { text-wrap: wrap; }

/* The home hero keeps a tighter measure on purpose: its copy sits beside the
   video panel rather than running the full page width. */

/* ---------------------------------------------------------------
   27. Section rhythm
   A heading and the card grid that belongs to it used to be two sibling
   sections, so the alternating day-mode band could draw its hairline border
   straight between them and split the group. They are now one section with
   two containers (see merge_subsections in build_core.py); this restores the
   gap between the heading and its cards, which the old `pt-0` used to get
   from the previous section's bottom padding.
   --------------------------------------------------------------- */
.hero-container + .hero-container.lx-subgroup { margin-top: clamp(2.25rem, 3.5vw, 3.25rem); }

/* Give genuinely separate sections a slightly more generous, consistent
   rhythm so the page breathes between blocks rather than between a heading
   and its own content. */
.section { padding-top: clamp(5rem, 4.5vw + 3.25rem, 8.5rem); padding-bottom: clamp(5rem, 4.5vw + 3.25rem, 8.5rem); }

/* A section that opens straight after the hero does not need a full band of
   space above it; the hero already carries its own bottom padding. */
.lx-inner-hero + .section { padding-top: clamp(3.5rem, 5vw, 5.5rem); }

/* ---------------------------------------------------------------
   28. Non-sticky navigation
   The notch nav was position:fixed, which took it out of flow and required
   compensating hacks everywhere: a tall scrim so content did not scroll
   visibly through the gaps between its islands, extra hero top padding to
   clear it, and scroll offsets on anchors. It now sits in normal flow and
   scrolls away with the page, so all of that compensation is unwound.
   --------------------------------------------------------------- */
header.lx-notch {
    position: static;
    padding-top: 1.25rem;
}

/* No fixed bar for content to pass beneath, so the scrim has nothing to mute. */
header.lx-notch::before { display: none; }

/* The hero no longer has to reserve space for an overlaid bar. */
.lx-inner-hero { padding-top: clamp(3.25rem, 5vw, 4.75rem); }
.lx-hero-home { padding-top: clamp(2.5rem, 4vw, 4rem); }

/* Anchor jumps and sticky offsets were sized against the fixed bar. */
html { scroll-padding-top: 1.5rem; }
.lnx-post-sidebar { top: 2rem !important; }

/* ---------------------------------------------------------------
   29. Contact: qualification form + what-happens-next sidebar
   Two columns: the form carries labelled fields and a qualification note so
   the visitor knows it is reviewed by a person, and the sidebar sets the
   expectation for what follows. All token-driven for both themes.
   --------------------------------------------------------------- */
.lx-contact-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
    gap: 32px;
    align-items: start;
}
@media (max-width: 991px) { .lx-contact-grid { grid-template-columns: 1fr; } }

/* ---- Form card ---- */
.lx-form-card {
    background: var(--lx-card-bg);
    border: 1px solid var(--lx-border);
    border-radius: 24px;
    padding: clamp(1.75rem, 3vw, 2.75rem);
}
.lx-form-card h2 { font-size: clamp(22px, 2.6vw, 30px); line-height: 1.25; margin: 0 0 14px; }
.lx-form-intro { margin: 0 0 24px; line-height: 1.75; }

.lx-form-note {
    display: flex;
    gap: 14px;
    padding: 18px 20px;
    border-radius: 14px;
    background: var(--lx-glow-tint);
    border: 1px solid var(--lx-border);
    margin-bottom: 30px;
}
.lx-form-note i { color: var(--lx-purple); margin-top: 3px; }
.lx-form-note p { margin: 0; font-size: 14.5px; line-height: 1.65; }

.lx-form { display: flex; flex-direction: column; gap: 20px; }
.lx-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
@media (max-width: 640px) { .lx-field-row { grid-template-columns: 1fr; } }

.lx-field { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.lx-field label {
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    opacity: .82;
}
.lx-field label .req { color: #E0457B; }

.lx-form input,
.lx-form select,
.lx-form textarea {
    width: 100%;
    padding: 14px 16px;
    border-radius: 12px;
    border: 1px solid var(--lx-border);
    background: var(--lx-surface-solid);
    color: inherit;
    font-size: 15px;
    font-family: inherit;
    transition: border-color .2s, box-shadow .2s;
}
.lx-form textarea { resize: vertical; min-height: 130px; line-height: 1.7; }
.lx-form input::placeholder,
.lx-form textarea::placeholder { opacity: .55; }
.lx-form input:focus,
.lx-form select:focus,
.lx-form textarea:focus {
    outline: none;
    border-color: var(--lx-border-strong);
    box-shadow: 0 0 0 3px var(--lx-glow-tint);
}

/* The submit uses the site's standard .btn.btn-accent component so it matches
   every other CTA; it only needs to span the form width. */
.lx-form-submit {
    width: 100%;
    justify-content: center;
    gap: 14px;
    margin-top: 4px;
    border: none;
    font-family: inherit;
    cursor: pointer;
}
body.lightmode .lx-form-submit { border: 1px solid var(--accent-color); }
.lx-form-submit .btn-title { padding-left: 18px; }

.lx-form-footnote { margin: 0; text-align: center; font-size: 13px; opacity: .72; }
.lx-form-consent { margin: 10px 0 0; text-align: center; font-size: 12px; line-height: 1.5; opacity: .6; }
.lx-form-consent a { color: inherit; text-decoration: underline; text-underline-offset: 2px; font: inherit; letter-spacing: inherit; }

/* ---- Sidebar ---- */
.lx-contact-side { display: flex; flex-direction: column; gap: 20px; }
.lx-side-card {
    background: var(--lx-card-bg);
    border: 1px solid var(--lx-border);
    border-radius: 20px;
    padding: 24px 22px;
}
.lx-side-title { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; }
.lx-side-title h3 { font-size: 17px; margin: 0; line-height: 1.35; }

.lx-side-step { display: flex; gap: 13px; margin-bottom: 20px; }
.lx-side-step:last-child { margin-bottom: 0; }
.lx-side-step h4 { font-size: 14.5px; margin: 0 0 5px; line-height: 1.4; }
.lx-side-step p { margin: 0; font-size: 13.5px; line-height: 1.65; opacity: .85; }

.lx-side-step-icon {
    flex: none;
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 10px;
    font-size: 13px;
    color: var(--lx-purple);
    background: var(--lx-glow-tint);
    border: 1px solid var(--lx-border);
}
.lx-side-step-icon.star { color: #F5A524; background: rgba(245, 165, 36, 0.14); }

.lx-whatsapp-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 16px 22px;
    border-radius: 14px;
    background: #25D366;
    color: #fff;
    font-weight: 700;
    font-size: 15px;
    transition: transform .2s, filter .2s;
}
.lx-whatsapp-btn:hover { transform: translateY(-2px); filter: brightness(1.05); color: #fff; }

.lx-side-contact { list-style: none; margin: 0; padding: 0; }
.lx-side-contact li {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 0;
    font-size: 14.5px;
    border-bottom: 1px solid var(--lx-hairline);
}
.lx-side-contact li:last-child { border-bottom: none; padding-bottom: 0; }
.lx-side-contact i { color: var(--lx-purple); width: 16px; text-align: center; }

.lx-side-quote { margin: 0; }
.lx-side-quote p { margin: 0 0 12px; font-size: 14px; line-height: 1.7; font-style: italic; }
.lx-side-quote cite { font-size: 12.5px; font-style: normal; opacity: .78; }

/* ---------------------------------------------------------------
   30. Home hero plate vs. the in-flow nav
   The video plate was inset 5.5rem from the top so the fixed nav floated over
   the page background rather than over the dark plate. The nav is in normal
   flow now and already sits above the hero, so that inset pushed the plate
   down and left the headline stranded on the page background above it. The
   plate now starts at the top of the hero like its other three edges.
   --------------------------------------------------------------- */
.lx-hero-home { --lx-nav-h: 0.4rem; }
.lx-hero-home { padding-top: clamp(3.25rem, 5vw, 5rem); }

@media (min-width: 992px) {
    .lx-hero-home { --lx-nav-h: 0.5rem; }
}
@media (max-width: 767px) {
    .lx-hero-video { inset: 0.25rem 0.25rem 0.25rem; }
}

/* ---------------------------------------------------------------
   31. Notch island polish
   The island stays dark in both themes (deliberate, it is part of the brand
   look like the hero plate), so instead of theme-flipping it gets depth and
   finish: a hairline inner highlight along its top edge, a soft violet drop
   shadow so it reads as an object sitting on the light page rather than a
   flat slab, a brand-gradient hover pill, and a marked current page.
   --------------------------------------------------------------- */
@media (min-width: 992px) {
    header.lx-notch .navbar-collapse {
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, 0.05),
            0 22px 44px -30px rgba(0, 0, 0, 0.85);
    }
    body.lightmode header.lx-notch .navbar-collapse {
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, 0.06),
            0 24px 48px -26px rgba(79, 70, 229, 0.55);
    }
}

/* Hover pill: the sliding highlight picks up the brand ramp instead of a
   flat tint, and a faint outer glow so it reads on the dark plate. */
.lx-nav-pill {
    background: linear-gradient(120deg, rgba(79, 70, 229, 0.30), rgba(200, 42, 239, 0.26));
    border-color: rgba(200, 42, 239, 0.38);
    box-shadow: 0 0 18px -6px rgba(200, 42, 239, 0.45);
}

/* Phone field: country code select sits inline with the number, sized to its
   content so the number keeps the rest of the row. Defaults to +1 because the
   site serves US roofing and HVAC contractors. */
.lx-phone-group { display: flex; gap: 10px; min-width: 0; }
.lx-phone-group select { flex: 0 0 auto; width: auto; min-width: 108px; }
.lx-phone-group input { flex: 1 1 auto; min-width: 0; }

/* ---------------------------------------------------------------
   32. Founding Client offer
   Scarcity block shown on the home and contact pages. Filled slots are drawn
   as filled rather than removed, so the remaining count is legible at a
   glance. Slot count comes from FOUNDING_TAKEN in build_core.py.
   --------------------------------------------------------------- */
.lx-founding-inner {
    max-width: 900px;
    margin: 0 auto;
    text-align: center;
    padding: clamp(2.5rem, 5vw, 4rem) clamp(1.5rem, 4vw, 3.5rem);
    border-radius: 28px;
    background: var(--lx-card-bg);
    border: 1px solid var(--lx-border-strong);
    box-shadow: var(--lx-shadow);
}
.lx-founding-title {
    font-size: clamp(26px, 3.6vw, 44px);
    line-height: 1.18;
    letter-spacing: -0.02em;
    margin: 0 0 .85rem;
    text-wrap: balance;
}
/* The scarcity line is the hook under the headline: still large and still
   carrying the gradient emphasis, but it is not the heading itself. */
.lx-founding-hook {
    font-size: clamp(19px, 2.5vw, 30px);
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: -0.01em;
    margin: 0 0 1.25rem;
    text-wrap: balance;
}
.lx-founding-lead { max-width: 62ch; margin: 0 auto 2.25rem; line-height: 1.75; }

.lx-slot-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: clamp(10px, 1.6vw, 16px);
    margin-bottom: 1.5rem;
}
.lx-slot {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    width: clamp(78px, 9vw, 104px);
    aspect-ratio: 1;
    border-radius: 18px;
    border: 2px dashed var(--lx-border-strong);
    background: var(--lx-surface);
}
.lx-slot-num { font-size: clamp(19px, 2.1vw, 25px); font-weight: 800; color: var(--lx-purple); }
.lx-slot-state { font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; opacity: .7; }

/* Taken slots: solid, desaturated, struck through. Reads as "gone". */
.lx-slot.is-taken {
    border-style: solid;
    border-color: var(--lx-hairline);
    background: transparent;
    opacity: .45;
}
.lx-slot.is-taken .lx-slot-num { color: inherit; text-decoration: line-through; }

.lx-founding-count { font-size: clamp(17px, 2vw, 21px); margin: 0 0 .5rem; }
.lx-founding-count strong {
    background: var(--lx-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}
.lx-founding-note { font-size: 14px; opacity: .8; margin: 0 0 2rem; }

@media (max-width: 560px) {
    .lx-slot { width: clamp(62px, 17vw, 78px); border-radius: 14px; }
}

/* ---------------------------------------------------------------
   33. One button treatment everywhere
   The button used to follow the theme: dark plate on the hero, but pale grey
   on light pages, so the same CTA looked like two different components
   depending on where it sat. It is now pinned to the dark hero treatment on
   every page and in both themes, with the brand glow that previously only
   `.lx-pulse` buttons carried.
   --------------------------------------------------------------- */
.btn-accent,
body.lightmode .btn-accent,
body.lightmode .keep-dark .btn-accent {
    /* Was #0E0E0E, which is all but pure black and reads as a hole in the page.
       This is a violet-tinted dark surface: still dark enough for white text at
       AA, but it now belongs to the brand palette instead of sitting under it. */
    background-color: #1B1526;
    border: 1px solid rgba(200, 42, 239, 0.32);
    position: relative;
}
.btn-accent .btn-title,
body.lightmode .btn-accent .btn-title,
.btn-accent .btn-title span,
body.lightmode .btn-accent .btn-title span { color: #F4F2FA; }

/* The glow every hero button had; now standard, so buttons read the same on a
   white card as they do on the dark video plate. */
.btn-accent {
    position: relative;
    box-shadow: 0 0 18px -6px rgba(200, 42, 239, 0.34),
                0 0 38px -16px rgba(124, 58, 237, 0.30);
    transition: box-shadow .3s ease, background-color .6s ease, transform .15s ease;
}
.btn-accent:hover,
body.lightmode .btn-accent:hover {
    background-color: #241C31;
    box-shadow: 0 0 24px -5px rgba(200, 42, 239, 0.48),
                0 0 50px -14px rgba(124, 58, 237, 0.40);
}
.btn-accent:active { transform: scale(.97); }

/* `.lx-pulse` draws its own blurred ::after. Every button now carries the glow
   as a box-shadow, so that would double up and make pulse buttons brighter
   than the rest. Suppressed to keep all buttons identical. */
.btn-accent.lx-pulse::after { display: none; }

/* ---------------------------------------------------------------
   35. FAQ blocks on service and location pages
   Static, non-collapsing Q&A cards: every answer stays in the DOM as plain
   text, which is what retrieval engines extract. Two columns on desktop.
   --------------------------------------------------------------- */
.lx-faq-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
    max-width: 1080px;
    margin: 0 auto;
}
@media (max-width: 860px) { .lx-faq-grid { grid-template-columns: 1fr; } }
.lx-faq-card {
    background: var(--lx-card-bg);
    border: 1px solid var(--lx-border);
    border-radius: 18px;
    padding: 24px 26px;
}
.lx-faq-card .lx-faq-q {
    font-size: 16.5px;
    line-height: 1.4;
    margin: 0 0 10px;
}
.lx-faq-card .lx-faq-a {
    margin: 0;
    font-size: 14.5px;
    line-height: 1.75;
    color: var(--text-color);
}

/* ---------------------------------------------------------------
   36. FAQ accordion
   Ported from the supplied Radix/shadcn accordion. The panel animates with
   grid-template-rows 0fr to 1fr rather than max-height, so it opens to the
   content's true height with no JS measurement and no clipped answers.

   The answers are in the HTML and ship open; js/leadnox.js collapses them on
   init. That ordering is what keeps the block fully readable to crawlers and
   to anyone whose JS fails.
   --------------------------------------------------------------- */
.lx-faq-layout {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    gap: clamp(2rem, 5vw, 4rem);
    align-items: start;
}
@media (max-width: 860px) { .lx-faq-layout { grid-template-columns: 1fr; } }

.lx-faq-intro .title-heading { margin: .5rem 0 1rem; }
.lx-faq-note { font-size: 14.5px; line-height: 1.7; margin: 0; }
.lx-faq-note a { color: var(--lx-purple); font-weight: 600; }
.lx-faq-note a:hover { text-decoration: underline; }

.lx-acc {
    background: var(--lx-card-bg);
    border: 1px solid var(--lx-border);
    border-radius: 20px;
    padding: 6px clamp(1.25rem, 2.5vw, 2rem);
    box-shadow: var(--lx-shadow);
}
.lx-acc-item + .lx-acc-item { border-top: 1px dotted var(--lx-border); }
.lx-acc-head { margin: 0; }

.lx-acc-btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    width: 100%;
    padding: 20px 0;
    background: none;
    border: none;
    text-align: left;
    font-family: inherit;
    font-size: 16px;
    font-weight: 700;
    line-height: 1.45;
    color: inherit;
    cursor: pointer;
}
.lx-acc-btn:focus-visible {
    outline: 2px solid var(--lx-purple);
    outline-offset: 3px;
    border-radius: 8px;
}
.lx-acc-q { flex: 1 1 auto; }

.lx-acc-chev {
    flex: none;
    font-size: 13px;
    color: var(--lx-purple);
    transition: transform .25s ease;
}
.lx-acc-btn[aria-expanded="true"] .lx-acc-chev { transform: rotate(180deg); }

/* 0fr to 1fr opens to the real content height without measuring it. */
.lx-acc-panel {
    display: grid;
    grid-template-rows: 1fr;
    transition: grid-template-rows .28s ease;
}
.lx-acc-panel[data-collapsed] { grid-template-rows: 0fr; }
.lx-acc-inner { overflow: hidden; }
.lx-acc-a {
    margin: 0;
    padding: 0 0 22px;
    font-size: 14.5px;
    line-height: 1.8;
    color: var(--text-color);
}

@media (prefers-reduced-motion: reduce) {
    .lx-acc-panel, .lx-acc-chev { transition: none; }
}

/* ============================================================
   37. Touch targets and mobile weight
   Scoped to coarse pointers so the desktop design is untouched.
   Targets: 44px where the control stands alone, never under 40px.
   ============================================================ */
img { height: auto; }                       /* width/height attrs = aspect ratio only */
.lx-slot-state { font-size: 12px; }        /* was 10px, unreadable on a phone */

@media (hover: none) and (pointer: coarse) {
    .lx-theme-btn, .nav-btn { min-width: 44px; min-height: 44px; }
    .sidebar-dropdown-btn { min-height: 44px; min-width: 60px; padding: 8px 18px; }
    .lx-cf-cta { min-height: 44px; padding: 0.75rem 1.3rem; font-size: 0.78rem; }
    .lx-cf-dots { gap: 1rem; }
    .lx-cf-dot { position: relative; height: 12px; width: 12px; }
    .lx-cf-dot.is-active { width: 32px; }
    .lx-cf-dot::before { content: ""; position: absolute; inset: -16px -8px; }   /* 44px tall hit box */
    .lx-loc-cloud a, .lx-footer-locations a, .legal-link, .social-item-wrapper a, .footer-list a, footer li a {
        display: inline-block; padding: 0.6rem 0.15rem; min-height: 40px; line-height: 1.4;
    }
    .lx-acc-btn, .blog-filter-pill { min-height: 44px; }
    a, button, [role="button"], input, select, textarea { touch-action: manipulation; }
}

/* Contact form on phones: 16px controls stop iOS zooming the page on focus;
   the card gutter shrinks so the fields use the width the screen has. */
.lx-form-after { margin: 0.75rem 0 0; font-size: 0.85rem; opacity: 0.7; text-align: center; }
@media (max-width: 767px) {
    .lx-form input, .lx-form select, .lx-form textarea { font-size: 16px; }
    .lx-form-card { padding-left: 18px; padding-right: 18px; }
    .lx-form-submit { width: 100%; }
}

/* ============================================================
   38. Legal pages (privacy policy)
   Long-form reading layout: narrower measure, generous rhythm,
   and a table that scrolls on its own rather than pushing the
   page sideways on a phone.
   ============================================================ */
.lx-legal-meta { max-width: 60rem; margin: 0 auto 2.5rem; }
.lx-legal-meta p { font-size: 1.05rem; line-height: 1.8; }

.lx-legal-summary {
    max-width: 60rem; margin: 0 auto 2.5rem; padding: 1.75rem 1.9rem;
    background: var(--lx-card-bg); border: 1px solid rgba(255,255,255,.10);
    border-left: 3px solid var(--lx-purple); border-radius: 18px;
}
.lx-legal-summary h2 { font-size: 1.05rem; margin: 0 0 1.1rem; }
.lx-legal-summary dl { margin: 0; display: grid; grid-template-columns: 12rem 1fr; gap: .7rem 1.4rem; }
.lx-legal-summary dt { font-weight: 700; font-size: .93rem; }
.lx-legal-summary dd { margin: 0; font-size: .93rem; line-height: 1.65; opacity: .9; }
.lx-legal-summary-note { margin: 1.2rem 0 0; font-size: .85rem; opacity: .65; }
body.lightmode .lx-legal-summary { border-color: rgba(0,0,0,.10); border-left-color: var(--lx-purple); }
@media (max-width: 640px) {
    .lx-legal-summary dl { grid-template-columns: 1fr; gap: .25rem; }
    .lx-legal-summary dd { margin: 0 0 .8rem; }
}

.lx-legal-toc {
    max-width: 60rem; margin: 0 auto 3.5rem; padding: 1.5rem 1.75rem;
    background: var(--lx-card-bg); border: 1px solid rgba(255,255,255,.10);
    border-radius: 18px;
}
.lx-legal-toc h2 { font-size: 0.78rem; letter-spacing: .14em; text-transform: uppercase; opacity: .7; margin: 0 0 .9rem; }
.lx-legal-toc ul { margin: 0; padding: 0; list-style: none; columns: 2; column-gap: 2rem; }
.lx-legal-toc li { break-inside: avoid; margin: 0 0 .5rem; }
.lx-legal-toc a { color: inherit; text-decoration: none; opacity: .85; font-size: .93rem; }
.lx-legal-toc a:hover { color: var(--lx-purple); opacity: 1; }

.lx-legal-section { max-width: 60rem; margin: 0 auto 2.75rem; scroll-margin-top: 2rem; }
.lx-legal-section h2 { font-size: clamp(1.25rem, 2.2vw, 1.6rem); margin: 0 0 1rem; }
.lx-legal-section p { line-height: 1.85; margin: 0 0 1rem; }
.lx-legal-section a { color: var(--lx-purple); }
.lx-legal-section code {
    font-size: .88em; padding: .12em .4em; border-radius: 5px;
    background: rgba(255,255,255,.08);
}
.lx-legal-list { margin: 0 0 1rem; padding-left: 1.15rem; }
.lx-legal-list li { line-height: 1.85; margin: 0 0 .6rem; }

.lx-legal-tablewrap { overflow-x: auto; margin: 0 0 1.25rem; -webkit-overflow-scrolling: touch; }
.lx-legal-table { width: 100%; min-width: 34rem; border-collapse: collapse; font-size: .92rem; }
.lx-legal-table th, .lx-legal-table td {
    text-align: left; padding: .7rem .8rem; vertical-align: top;
    border-bottom: 1px solid rgba(255,255,255,.10);
}
.lx-legal-table th { font-size: .76rem; letter-spacing: .1em; text-transform: uppercase; opacity: .75; }
body.lightmode .lx-legal-toc { border-color: rgba(0,0,0,.10); }
body.lightmode .lx-legal-section code { background: rgba(0,0,0,.06); }
body.lightmode .lx-legal-table th,
body.lightmode .lx-legal-table td { border-bottom-color: rgba(0,0,0,.10); }

@media (max-width: 767px) {
    .lx-legal-toc ul { columns: 1; }
    /* Long-form legal copy at 14px is a squint on a phone. */
    .lx-legal-section p, .lx-legal-list li { font-size: 1rem; }
    .lx-legal-meta p { font-size: 1rem; }
}

/* ============================================================
   37b. Locations mega menu overflow
   The only mega menu belongs to "Locations", a right-hand nav
   item. It was anchored left:0 and is 560px wide, so between
   roughly 992px and 1350px it ran past the right edge of the
   viewport: a horizontal scrollbar on every page, and the menu
   itself was cut off when opened. Anchoring it to the item's
   right edge keeps it on screen at every width. Safe to pin
   right because this menu never belongs to a left-hand item.
   ============================================================ */
.dropdown-menu.lx-mega { left: auto; right: 0; }

/* ============================================================
   39. Hero headline gradient fade
   style.css fills .title-heading with
     linear-gradient(284deg, var(--accent-transparent) 3%, var(--primary) 100%)
   and --accent-transparent is #00000000, i.e. FULLY transparent. At 284deg the
   0% stop lands at the lower right, so the end of a long headline faded to
   nothing and became unreadable on the dark theme. (Light mode already
   overrides the gradient to solid, which is why it only showed in dark.)

   This keeps the fade, and makes it smoother by adding a mid stop, but floors
   it at 42% opacity so the last words stay legible instead of disappearing.
   Loaded after style.css, so it wins without editing the base file.
   ============================================================ */
.title-heading {
    background-image: linear-gradient(284deg,
        rgba(209, 209, 209, 0.42) 0%,
        rgba(209, 209, 209, 0.72) 38%,
        rgba(209, 209, 209, 0.92) 70%,
        var(--primary) 100%);
}

/* ============================================================
   40. Mobile stacking for split sections
   The @media (max-width: 991px) block up at section ~24 already tried to
   unstick these, but it is written BEFORE the base `.lx-split-img` and
   `.lx-illus` rules. Media queries add no specificity, so those later base
   declarations won at every width and the image stayed `position: sticky`
   on phones. The pinned image then held its place while the copy scrolled
   up over it, which is why the heading was printed across the photo.

   Re-declared here, at the end of the file, so source order is on our side.
   DOM order is already image then text in all 54 split sections, so once the
   sticky is gone the natural single-column flow is image first, copy second.
   ============================================================ */
@media (max-width: 991px) {
    .lx-split-img, .lx-illus {
        position: static;
        top: auto;
        align-self: stretch;
    }
    /* Let the photo size to its own aspect ratio instead of the fixed
       desktop height, so nothing is cropped to a letterbox on a phone. */
    .lx-split-img img, .lx-illus img {
        height: auto;
        max-height: 24rem;
        object-fit: cover;
    }
    /* Same trap, same fix: the FAQ heading is sticky on desktop. */
    .faq-title-container { position: static; top: auto; }

    /* Desktop alternates the columns, so some sections have the copy first in
       the DOM and the photo second. Stacked on a phone that reads as a wall of
       text with the picture stranded underneath. `order` puts the image first
       in every section regardless of source order; grid items honour it just
       like flex items do. */
    .lx-split-img, .lx-illus { order: -1; }
    .lx-split > *:not(.lx-split-img):not(.lx-illus) { order: 0; }
}

/* ============================================================
   41. Headline legibility guarantee
   .title-heading paints its text by clipping a gradient to the glyphs
   (-webkit-background-clip: text + -webkit-text-fill-color: transparent).
   That technique fails silently: when it breaks, the text does not fall back
   to a colour, it simply disappears, which is what happened on iOS Safari.

   The audience for this site is overwhelmingly on phones, so below 991px the
   headline is painted as ordinary solid text with no clipping involved. It
   cannot vanish. The gradient is kept on wider screens where it is verified
   to render.
   ============================================================ */
@media (max-width: 991px) {
    .title-heading {
        background-image: none;
        background-color: transparent;
        -webkit-text-fill-color: var(--primary);
        color: var(--primary);
    }
}
body.lightmode .title-heading { -webkit-text-fill-color: var(--primary); }

/* ============================================================
   42. Curved mobile menu
   Port of a React/framer-motion "curved menu". No React, no
   framer-motion: the panel slides on a CSS transform and the curved edge is a
   single <svg> whose quadratic control point is tweened in leadnox.js.

   Deliberately reuses the EXISTING .sidebar markup rather than adding a second
   menu, so the links, the three dropdowns and the jQuery open/close in
   script.js all keep working. Only the presentation changes, and only below
   991px. Declared at the end of the file because the base .sidebar rules come
   later in source order than the old media query (see section 40).
   ============================================================ */
@media (max-width: 991px) {
    .sidebar {
        left: auto;
        right: 0;
        width: min(86vw, 440px);
        max-width: none;
        padding: 0;
        border-left: none;
        /* Matches the original: the panel parks 100px beyond its own width so
           the curve has somewhere to live while closed. */
        transform: translateX(calc(100% + 100px));
        transition: transform 0.8s cubic-bezier(0.76, 0, 0.24, 1);
    }
    .sidebar.active { transform: translateX(0); width: min(86vw, 440px); }

    /* The curve is a fixed sibling rather than a child, so the panel keeps
       overflow-y:auto for long menus without clipping it. */
    .lx-curve {
        position: fixed;
        top: 0;
        right: min(86vw, 440px);
        width: 100px;
        height: 100dvh;
        z-index: 1000;
        pointer-events: none;
        /* Must travel the SAME absolute distance as the panel. `100%` here is
           the curve's own 100px width, which left it parked mid-screen and
           painting a black wedge across the page while the menu was CLOSED.
           The panel moves by its own width + 100px, so match that literally. */
        transform: translateX(calc(min(86vw, 440px) + 100px));
        transition: transform 0.8s cubic-bezier(0.76, 0, 0.24, 1);
    }
    body.lx-menu-open .lx-curve { transform: translateX(0); }

    .sidebar-header { padding: 26px 28px 10px; }

    .sidebar .menu {
        counter-reset: lxnav;
        padding: 0 28px 28px;
        margin: 0;
        list-style: none;
    }
    .sidebar .menu > li {
        counter-increment: lxnav;
        border-bottom: 1px solid var(--lx-hairline, rgba(255,255,255,.16));
        padding: 0;
    }
    .sidebar .menu > li > a,
    .sidebar .menu > li .dropdown-header > a {
        display: block;
        padding: 18px 0;
        min-width: 0;                 /* let it shrink inside the flex header */
        overflow-wrap: break-word;
        /* "Roofing Locations" plus its chevron ran past the panel edge at the
           original size, so this is scaled to the longest label rather than to
           the shortest. */
        font-size: clamp(0.98rem, 4.5vw, 1.4rem);
        font-weight: 300;
        letter-spacing: -0.01em;
        text-transform: uppercase;
        line-height: 1.1;
    }
    /* The numbered index from the original, without touching the markup. */
    .sidebar .menu > li > a::before,
    .sidebar .menu > li .dropdown-header > a::before {
        content: counter(lxnav, decimal-leading-zero) ".";
        display: inline-block;
        margin-right: 0.6rem;
        font-size: 0.85rem;
        font-weight: 400;
        vertical-align: middle;
        opacity: 0.5;
        letter-spacing: 0.06em;
    }
    .sidebar .menu > li > a:active,
    .sidebar .menu > li .dropdown-header > a:active { transform: translateX(6px); }
    .sidebar .menu > li > a,
    .sidebar .menu > li .dropdown-header > a { transition: transform 0.25s ease, color 0.25s ease; }

    .sidebar .dropdown-header {
        display: flex; align-items: center; justify-content: space-between; gap: .85rem;
        min-width: 0;
    }
    .sidebar .dropdown-header > a { flex: 1 1 auto; }
    .sidebar .sidebar-dropdown-btn { flex: 0 0 auto; }
    /* Nothing in the panel may push it sideways. */
    .sidebar { overflow-x: hidden; }
    .sidebar .menu > li { max-width: 100%; }
    .sidebar .sidebar-dropdown-menu { padding-left: 2.1rem; }
    .sidebar .sidebar-dropdown-menu a { font-size: 0.95rem; text-transform: none; padding: 9px 0; display: block; }

    /* The backdrop was the second animation. style.css parks it at
       `left: -100%` with `transition: left 0.4s`, so it SWEPT IN FROM THE LEFT
       while the panel slid in from the right, reading as two conflicting
       movements. It should not travel at all: pin it in place and fade it, so
       the only thing that moves is the panel coming from the right.
       visibility is delayed out so it stays clickable through the fade. */
    .sidebar-overlay {
        left: 0;
        right: auto;
        background: rgba(0,0,0,.55);
        opacity: 0;
        visibility: hidden;
        pointer-events: none;
        transition: opacity 0.5s ease, visibility 0s linear 0.5s;
    }
    .sidebar-overlay.active {
        left: 0;
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
        transition: opacity 0.5s ease, visibility 0s linear 0s;
    }
}

@media (prefers-reduced-motion: reduce) {
    .sidebar, .lx-curve { transition: none; }
}

/* ============================================================
   43. CTA button: the icon crosses the button on hover
   Port of a React/shadcn "button with icon". No React, no Tailwind, no lucide:
   the markup is untouched (.btn-title + .icon-circle, 83 CTAs across the site)
   and only CSS changes, so nothing had to be regenerated per button.

   At rest the circle sits right, as before. On hover it travels to the left
   edge and rotates, while the label's padding swaps so the text slides the
   other way. The circle is taken out of flow and positioned absolutely to make
   that possible; the label's right padding replaces the space it used to
   occupy, so the button's width does not change.

   Scoped to `hover: hover` and `pointer: fine`. On a touch screen :hover
   sticks after a tap, which would leave the arrow stranded on the wrong side.
   ============================================================ */
.btn-accent { overflow: hidden; }

@media (hover: hover) and (pointer: fine) {
    .btn-accent .icon-circle {
        position: absolute;
        right: 5px;                       /* matches .btn's 5px padding */
        top: 50%;
        transform: translateY(-50%);
        transition: right .5s cubic-bezier(.65, 0, .35, 1),
                    transform .5s cubic-bezier(.65, 0, .35, 1);
    }
    .btn-accent .btn-title {
        /* 5px button padding + 59px circle + 30px gap = the space the circle
           used to take up in flow. */
        padding-left: 30px;
        padding-right: 94px;
        transition: padding .5s cubic-bezier(.65, 0, .35, 1);
    }
    .btn-accent:hover .icon-circle {
        right: calc(100% - 64px);         /* lands 5px from the left edge */
        transform: translateY(-50%) rotate(-45deg);
    }
    .btn-accent:hover .btn-title {
        padding-left: 94px;
        padding-right: 30px;
    }
    @media (prefers-reduced-motion: reduce) {
        .btn-accent .icon-circle,
        .btn-accent .btn-title { transition: none; }
        .btn-accent:hover .icon-circle { right: 5px; transform: translateY(-50%); }
        .btn-accent:hover .btn-title { padding-left: 30px; padding-right: 94px; }
    }
}

/* ============================================================
   44. Carousel CTA block
   `.btn` carries `align-self: stretch`, which beat the parent's
   `align-items: center` and stretched this button the full width of the
   section while the paragraph above it stayed centred. Sizing the button to
   its content puts the two back on the same axis.
   ============================================================ */
.lx-carousel-cta .btn {
    align-self: center;
    width: auto;
    align-self: center;
}
.lx-carousel-cta p {
    max-width: 40rem;
    line-height: 1.7;
    text-wrap: balance;                   /* keeps the two lines even */
    opacity: .88;
}
.lx-carousel-cta { gap: 1.6rem; }

/* ============================================================
   45. Rectangular CTAs
   style.css gives `.btn` a 100px radius, which makes every call to action a
   pill. Rectangles instead, at 14px so they sit in the same family as the
   site's cards and panels (18px to 22px) rather than looking like a different
   component. For hard 90 degree corners, set these to 0.

   Only genuine calls to action change. `.lx-chip`, `.blog-filter-pill`,
   `.blog-cat-pill`, `.pillar-topic-tag`, `.lx-cs-tag` and `.lx-hero-kicker`
   stay pills on purpose: those are labels, tags and filters, not buttons, and
   the pill is what distinguishes them from something clickable.

   `.icon-circle` deliberately stays a circle. It is the accent inside the
   rectangle, and it is what the hover animation in section 43 moves.
   ============================================================ */
.btn,
.btn-accent,
body.lightmode .btn-accent,
body.lightmode .keep-dark .btn-accent {
    border-radius: 14px;
}
/* The small "View Details" action on the coverflow cards, kept proportional
   to its size rather than given the full 14px. */
.lx-cf-cta { border-radius: 10px; }

/* ============================================================
   46. Accessibility hardening (keyboard + screen readers)
   The base theme sets `outline: none` on several controls and never restores
   a focus indicator, so a keyboard user could not see where they were.
   :focus-visible only fires for keyboard focus, so mouse users see no change.
   ============================================================ */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, summary:focus-visible, [tabindex]:not([tabindex="-1"]):focus-visible,
.nav-btn:focus-visible, .form select:focus-visible, .lx-form textarea:focus-visible,
.lx-form input:focus-visible, .lx-form select:focus-visible {
    outline: 3px solid var(--lx-purple, #C82AEF);
    outline-offset: 3px;
    border-radius: 6px;
}
body.lightmode :focus-visible { outline-color: #7c3aed; }
#main:focus { outline: none; }               /* programmatic target of the skip link */

/* Skip link: off-screen until it receives keyboard focus, then pinned top-left
   above the notch nav. */
.lx-skip {
    position: fixed; top: 12px; left: 12px; z-index: 10000;
    padding: 12px 18px; border-radius: 10px;
    background: var(--lx-purple, #C82AEF); color: #fff !important;
    font-weight: 700; text-decoration: none;
    transform: translateY(-200%); opacity: 0;
    transition: transform .15s ease, opacity .15s ease;
}
.lx-skip:focus, .lx-skip:focus-visible {
    transform: translateY(0); opacity: 1; outline: 3px solid #fff; outline-offset: 2px;
}

/* The desktop Services / Locations menus opened on hover only, which a
   keyboard user can never trigger. `:focus-within` (added to the hover rule
   above) opens them when a link inside gains focus via Tab. */
.lx-hover-drop > .dropdown-menu a:focus-visible { outline-offset: -3px; }

/* ============================================================
   47. Leadnox AI chat widget (js/chatbot.js)
   Vanilla port of a React/framer-motion chat component, in the brand
   violet-to-magenta instead of the original indigo. Launcher bottom-right,
   panel above it; a full-screen sheet on phones. Every animation is switched
   off under prefers-reduced-motion.
   ============================================================ */
.lx-chat { --chat-grad: linear-gradient(135deg, #7c5cf5 0%, #C82AEF 100%); }
.lx-chat-launcher {
    position: fixed; right: 24px; bottom: 24px; z-index: 900;
    width: 64px; height: 64px; border-radius: 50%; cursor: pointer;
    display: grid; place-items: center; color: #fff; font-size: 22px;
    /* Dark disc with a brand-gradient rim: the mark reads clearly on it. */
    border: 2px solid transparent;
    background: radial-gradient(circle at 30% 25%, #2a1d3d 0%, #120c1a 70%) padding-box, var(--chat-grad) border-box;
    box-shadow: 0 12px 32px -8px rgba(200, 42, 239, .6), 0 0 0 6px rgba(124, 92, 245, .10);
    transition: transform .25s ease, box-shadow .25s ease;
}
.lx-chat-launcher:hover {
    transform: translateY(-3px) scale(1.05);
    box-shadow: 0 16px 40px -8px rgba(200, 42, 239, .75), 0 0 0 8px rgba(124, 92, 245, .16);
}
.lx-chat-launcher::before {          /* slow glowing halo behind the disc */
    content: ""; position: absolute; inset: -10px; border-radius: 50%; z-index: -1;
    background: conic-gradient(from 0deg, #7c5cf5, #C82AEF, #5b8cff, #7c5cf5);
    filter: blur(12px); opacity: .5;
    /* Glow outside the rim only; the launcher is its own stacking context,
       so without the mask the halo would paint over the dark disc. */
    -webkit-mask: radial-gradient(closest-side, transparent 72%, #000 82%);
    mask: radial-gradient(closest-side, transparent 72%, #000 82%);
    animation: lxChatSpin 6s linear infinite;
}
.lx-chat-launcher::after {           /* soft "I am here" ring */
    content: ""; position: absolute; inset: -6px; border-radius: 50%;
    border: 2px solid rgba(200, 42, 239, .5); opacity: 0;
    animation: lxChatPing 2.8s ease-out 1.5s 3;
}
@keyframes lxChatSpin { to { transform: rotate(360deg); } }
@keyframes lxChatPing { 0% { transform: scale(.85); opacity: .9; } 100% { transform: scale(1.3); opacity: 0; } }
.lx-chat-launcher > * { grid-area: 1 / 1; }
.lx-chat-launcher .lx-chat-mark { width: 34px; height: 34px; transition: transform .3s ease, opacity .3s ease; }
.lx-chat-launcher i { transition: transform .3s ease, opacity .3s ease; }
.lx-chat-ico-close { opacity: 0; transform: rotate(-90deg) scale(.6); }
.lx-chat.is-open .lx-chat-ico-open { opacity: 0; transform: rotate(90deg) scale(.6); }
.lx-chat.is-open .lx-chat-ico-close { opacity: 1; transform: none; }
.lx-chat.is-open .lx-chat-launcher::after { animation: none; }
.lx-chat-online {                    /* green "online" dot on the launcher */
    position: absolute; right: 3px; bottom: 3px; width: 13px; height: 13px; border-radius: 50%;
    background: #22c55e; border: 2px solid #120c1a; box-shadow: 0 0 8px rgba(34, 197, 94, .7);
}
.lx-chat.is-open .lx-chat-online { opacity: 0; }

/* One-time teaser bubble beside the launcher. */
.lx-chat-teaser {
    position: fixed; right: 100px; bottom: 30px; z-index: 900;
    display: flex; align-items: flex-start; gap: 4px; max-width: 260px;
    padding: 12px 8px 12px 16px; border-radius: 16px 16px 4px 16px;
    background: rgba(23, 17, 31, .96); border: 1px solid rgba(200, 42, 239, .35);
    box-shadow: 0 16px 40px -12px rgba(0,0,0,.6), 0 0 30px -14px rgba(200,42,239,.6);
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
    animation: lxChatTease .45s cubic-bezier(.22, 1, .36, 1);
}
.lx-chat-teaser[hidden] { display: none !important; }
@keyframes lxChatTease { from { opacity: 0; transform: translateX(12px) scale(.95); } to { opacity: 1; transform: none; } }
.lx-chat-teaser-open {
    border: 0; background: none; padding: 0; cursor: pointer; text-align: left; color: #ECEAF2;
    display: flex; flex-direction: column; gap: 3px; font-size: 13px; line-height: 1.4;
}
.lx-chat-teaser-open strong { font-size: 14px; color: #fff; }
.lx-chat-teaser-open span { opacity: .7; }
.lx-chat-teaser-x {
    border: 0; background: none; color: rgba(255,255,255,.5); cursor: pointer;
    width: 26px; height: 26px; border-radius: 8px; flex: 0 0 auto; font-size: 12px;
}
.lx-chat-teaser-x:hover { background: rgba(255,255,255,.08); color: #fff; }
.lx-chat.is-open .lx-chat-teaser { display: none; }

.lx-chat-panel {
    position: fixed; right: 24px; bottom: 96px; z-index: 950;
    width: min(390px, calc(100vw - 32px)); height: min(620px, calc(100dvh - 120px));
    display: flex; flex-direction: column; overflow: hidden;
    border-radius: 22px; border: 1px solid rgba(200, 42, 239, .22);
    background:
        radial-gradient(120% 60% at 100% 0%, rgba(200, 42, 239, .14) 0%, transparent 60%),
        radial-gradient(90% 50% at 0% 100%, rgba(124, 92, 245, .10) 0%, transparent 60%),
        linear-gradient(180deg, #17111f 0%, #0c0913 100%);
    box-shadow: 0 24px 64px -16px rgba(0,0,0,.65), 0 0 40px -18px rgba(200,42,239,.45);
    color: #ECEAF2; font-size: 15px;
    transform-origin: bottom right;
    animation: lxChatOpen .32s cubic-bezier(.22, 1, .36, 1);
}
.lx-chat-panel[hidden] { display: none !important; }
@keyframes lxChatOpen { from { opacity: 0; transform: translateY(14px) scale(.96); } to { opacity: 1; transform: none; } }

.lx-chat-head {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 14px 14px 13px 16px; border-bottom: 1px solid rgba(255,255,255,.07);
    background: linear-gradient(135deg, rgba(124, 92, 245, .20) 0%, rgba(200, 42, 239, .12) 100%);
}
.lx-chat-who { display: flex; align-items: center; gap: 10px; min-width: 0; flex: 1 1 auto; }
.lx-chat-who > div:last-child { min-width: 0; }
.lx-chat-avatar {
    width: 40px; height: 40px; border-radius: 50%; flex: 0 0 auto;
    display: grid; place-items: center; border: 1.5px solid transparent;
    background: radial-gradient(circle at 30% 25%, #2a1d3d 0%, #120c1a 75%) padding-box, var(--chat-grad) border-box;
}
.lx-chat-avatar .lx-chat-mark { width: 58%; height: 58%; }
.lx-chat-avatar.is-small { width: 30px; height: 30px; }
.lx-chat-mark { display: block; object-fit: contain; }
.lx-chat-name { font-weight: 700; font-size: 15px; line-height: 1.2; color: #fff; }
.lx-chat-sub {
    display: flex; align-items: center; gap: 6px; margin-top: 2px;
    font-size: 12px; color: rgba(236, 234, 242, .65); line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lx-chat-dot {
    width: 7px; height: 7px; border-radius: 50%; background: #22c55e; flex: 0 0 auto;
    box-shadow: 0 0 0 0 rgba(34, 197, 94, .6); animation: lxChatLive 2.4s ease-out infinite;
}
@keyframes lxChatLive { 0% { box-shadow: 0 0 0 0 rgba(34,197,94,.55); } 70%, 100% { box-shadow: 0 0 0 7px rgba(34,197,94,0); } }
.lx-chat-tools { display: flex; gap: 6px; flex: 0 0 auto; }
.lx-chat-tool {
    display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 11px;
    border-radius: 10px; border: 0; cursor: pointer; font-size: 12.5px; white-space: nowrap;
    background: rgba(255,255,255,.06); color: rgba(255,255,255,.72);
    transition: background .2s ease, color .2s ease;
}
.lx-chat-tool:hover { background: rgba(255,255,255,.12); color: #fff; }
.lx-chat-tool { width: 34px; padding: 0; justify-content: center; }

/* Welcome card at the top of every conversation. */
.lx-chat-welcome { text-align: center; padding: 8px 12px 4px; }
.lx-chat-welcome-mark {
    width: 64px; height: 64px; margin: 0 auto 12px; border-radius: 20px;
    display: grid; place-items: center; border: 1.5px solid transparent;
    background: radial-gradient(circle at 30% 25%, #2a1d3d 0%, #120c1a 75%) padding-box, var(--chat-grad) border-box;
    box-shadow: 0 12px 30px -10px rgba(200, 42, 239, .6);
}
.lx-chat-welcome-mark .lx-chat-mark { width: 38px; height: 38px; }
.lx-chat-welcome-title {
    font-weight: 800; font-size: 18px; line-height: 1.25; margin-bottom: 6px;
    background: linear-gradient(90deg, #fff 0%, #E4D6FF 55%, #F0B8FF 100%);
    -webkit-background-clip: text; background-clip: text; color: transparent;
}
.lx-chat-welcome-text { margin: 0 auto; max-width: 290px; font-size: 13.5px; line-height: 1.5; color: rgba(236, 234, 242, .68); }

/* "Fill in the contact form" button inside a reply. */
.lx-chat-cta {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    margin-top: 12px; padding: 11px 14px; border-radius: 10px;
    background: var(--chat-grad); color: #fff !important; text-decoration: none !important;
    font-weight: 700; font-size: 14px; box-shadow: 0 10px 24px -10px rgba(200, 42, 239, .8);
    transition: transform .2s ease, box-shadow .2s ease;
}
.lx-chat-cta:hover { transform: translateY(-1px); box-shadow: 0 14px 30px -10px rgba(200, 42, 239, .95); }
.lx-chat-cta i { transition: transform .2s ease; }
.lx-chat-cta:hover i { transform: translateX(3px); }

.lx-chat-log {
    flex: 1 1 auto; overflow-y: auto; padding: 16px 14px; display: flex; flex-direction: column; gap: 12px;
    scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.12) transparent; overscroll-behavior: contain;
}
.lx-chat-row { display: flex; align-items: flex-end; gap: 8px; }
.lx-chat-row.is-user { justify-content: flex-end; }
.lx-chat-bubble {
    max-width: 82%; padding: 10px 14px; border-radius: 18px; line-height: 1.55; font-size: 14.5px;
    overflow-wrap: anywhere;
}
.lx-chat-row.is-bot .lx-chat-bubble {
    border-top-left-radius: 6px; background: rgba(39, 36, 48, .92);
    border: 1px solid rgba(255,255,255,.08); color: #ECEAF2;
    box-shadow: 0 4px 12px -2px rgba(0,0,0,.3);
}
.lx-chat-row.is-user .lx-chat-bubble {
    border-top-right-radius: 6px; background: var(--chat-grad); color: #fff;
    box-shadow: 0 8px 24px -6px rgba(200, 42, 239, .45);
}
.lx-chat-bubble p { margin: 0 0 8px; }
.lx-chat-bubble p:last-child { margin-bottom: 0; }
.lx-chat-bubble ul, .lx-chat-bubble ol { margin: 4px 0 8px; padding-left: 20px; }
.lx-chat-bubble ul { list-style: disc; }      /* the theme resets list-style globally */
.lx-chat-bubble ol { list-style: decimal; }
.lx-chat-bubble li::marker { color: #C79BFF; }
.lx-chat-bubble li { margin: 0 0 4px; }
.lx-chat-bubble a { color: #D9B8FF; text-decoration: underline; text-underline-offset: 2px; }
.lx-chat-row.is-user .lx-chat-bubble a { color: #fff; }
.lx-chat-bubble strong { color: #fff; font-weight: 700; }
.lx-chat-sources { margin-top: 10px; padding-top: 8px; border-top: 1px solid rgba(255,255,255,.08); display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; }
.lx-chat-sources-label { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; opacity: .5; }
.lx-chat-sources a { text-decoration: none; }
.lx-chat-sources a::before { content: "\2192  "; opacity: .6; }
.lx-chat-sources a:hover { text-decoration: underline; }
.lx-chat-row.is-new { animation: lxChatIn .35s cubic-bezier(.22, 1, .36, 1) both; }
.lx-chat-row.is-new.is-user { animation-name: lxChatInUser; }
@keyframes lxChatIn { from { opacity: 0; transform: translate(-20px, 12px) scale(.96); } to { opacity: 1; transform: none; } }
@keyframes lxChatInUser { from { opacity: 0; transform: translate(20px, 12px) scale(.96); } to { opacity: 1; transform: none; } }

.lx-chat-typing { display: inline-flex; gap: 5px; padding: 13px 16px; }
.lx-chat-typing span {
    width: 7px; height: 7px; border-radius: 50%; background: rgba(255,255,255,.6);
    animation: lxChatDot .8s ease-in-out infinite;
}
.lx-chat-typing span:nth-child(2) { animation-delay: .15s; }
.lx-chat-typing span:nth-child(3) { animation-delay: .3s; }
@keyframes lxChatDot { 0%, 100% { opacity: .4; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-4px); } }

.lx-chat-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; padding: 4px 4px 0; }
.lx-chat-chip {
    border: 1px solid rgba(200, 42, 239, .38); background: rgba(124, 92, 245, .10); color: #E4D6FF;
    border-radius: 999px; padding: 8px 13px; font-size: 13px; cursor: pointer; min-height: 36px;
    transition: background .2s ease, border-color .2s ease;
}
.lx-chat-chip:hover { background: rgba(124, 92, 245, .22); border-color: rgba(200, 42, 239, .7); }

.lx-chat-form { padding: 10px 12px 12px; border-top: 1px solid rgba(255,255,255,.06); }
.lx-chat-box {
    display: flex; align-items: center; gap: 8px; padding: 6px 6px 6px 14px;
    border-radius: 14px; border: 1px solid rgba(255,255,255,.10); background: rgba(39, 36, 48, .55);
    transition: border-color .2s ease, background .2s ease;
}
.lx-chat-box:focus-within {
    border-color: rgba(200, 42, 239, .75); background: rgba(39, 36, 48, .8);
    box-shadow: 0 0 0 3px rgba(200, 42, 239, .22);
}
/* The box's own ring is the focus indicator; drop the site-wide outline on the
   bare input so keyboard users see one clear ring, not two stacked ones. */
.lx-chat-input:focus, .lx-chat-input:focus-visible { outline: none; }
.lx-chat-input {
    flex: 1 1 auto; min-width: 0; border: 0; outline: 0; background: transparent;
    color: #fff; font-size: 16px; padding: 8px 0;       /* 16px: iOS will not zoom the page */
}
.lx-chat-input::placeholder { color: rgba(255,255,255,.38); }
.lx-chat-send {
    width: 38px; height: 38px; border-radius: 11px; border: 0; cursor: pointer; flex: 0 0 auto;
    display: grid; place-items: center; color: #fff; background: var(--chat-grad);
    transition: opacity .2s ease, transform .15s ease;
}
.lx-chat-send:disabled { opacity: .3; cursor: not-allowed; }
.lx-chat-send:not(:disabled):active { transform: scale(.92); }
.lx-chat-form.is-busy .lx-chat-send { opacity: .3; }
.lx-chat-note { margin: 8px 2px 0; font-size: 11.5px; line-height: 1.45; opacity: .5; text-align: center; }
.lx-chat-note a { color: inherit; text-decoration: underline; font: inherit; letter-spacing: inherit; }

/* Phones: a full-screen sheet; the header's close button replaces the launcher. */
@media (max-width: 560px) {
    .lx-chat-launcher { right: 16px; bottom: 16px; width: 58px; height: 58px; }
    .lx-chat-launcher .lx-chat-mark { width: 30px; height: 30px; }
    .lx-chat-teaser { right: 16px; bottom: 88px; max-width: min(270px, calc(100vw - 32px)); border-radius: 16px 16px 4px 16px; }
    .lx-chat-panel {
        inset: 0; width: 100%; height: 100dvh; border-radius: 0; border: 0;
        padding-bottom: env(safe-area-inset-bottom);
    }
    .lx-chat.is-open .lx-chat-launcher { display: none; }
    html.lx-chat-lock, html.lx-chat-lock body { overflow: hidden; }
    .lx-chat-bubble { max-width: 86%; }
}
@media (prefers-reduced-motion: reduce) {
    .lx-chat-panel, .lx-chat-row.is-new, .lx-chat-typing span, .lx-chat-launcher::before, .lx-chat-launcher::after,
    .lx-chat-teaser, .lx-chat-dot { animation: none !important; }
    .lx-chat-launcher, .lx-chat-launcher i { transition: none; }
}
@media print { .lx-chat { display: none !important; } }

/* ============================================================
   48. Cookie consent banner (js/consent.js)
   Accept and Decline are deliberately the same size and weight: a
   consent choice nudged by design is not valid consent. Bottom-left on
   desktop so it never covers the chat launcher; a full-width sheet on
   phones, with the launcher lifted above it while it is open.
   ============================================================ */
.lx-consent {
    position: fixed; left: 24px; bottom: 24px; z-index: 960;
    width: min(440px, calc(100vw - 48px));
    padding: 18px 18px 16px; border-radius: 16px;
    background: rgba(23, 17, 31, .97); color: #ECEAF2;
    border: 1px solid rgba(200, 42, 239, .28);
    box-shadow: 0 20px 50px -16px rgba(0, 0, 0, .7), 0 0 36px -18px rgba(200, 42, 239, .5);
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
    animation: lxConsentIn .4s cubic-bezier(.22, 1, .36, 1);
}
.lx-consent[hidden] { display: none !important; }
@keyframes lxConsentIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.lx-consent-text { margin: 0 0 14px; font-size: 13.5px; line-height: 1.55; color: rgba(236, 234, 242, .82); }
.lx-consent-text strong { color: #fff; }
.lx-consent-text a { color: #D9B8FF; text-decoration: underline; text-underline-offset: 2px; font: inherit; }
.lx-consent-actions { display: flex; gap: 10px; }
.lx-consent-btn {
    flex: 1 1 0; min-height: 44px; padding: 0 16px; border-radius: 8px; cursor: pointer;
    font: inherit; font-size: 14px; font-weight: 700; color: #fff;
    background: rgba(124, 92, 245, .22); border: 1px solid rgba(200, 42, 239, .55);
    transition: background .2s ease, border-color .2s ease;
}
.lx-consent-btn:hover { background: rgba(124, 92, 245, .38); border-color: rgba(200, 42, 239, .85); }
body.lightmode .lx-consent { background: rgba(255, 255, 255, .98); color: #1d1628; border-color: rgba(124, 92, 245, .35); }
body.lightmode .lx-consent-text { color: #3b3348; }
body.lightmode .lx-consent-text strong { color: #1d1628; }
body.lightmode .lx-consent-text a { color: #6d3fd6; }
body.lightmode .lx-consent-btn { color: #1d1628; background: rgba(124, 92, 245, .10); }
@media (max-width: 560px) {
    .lx-consent { left: 12px; right: 12px; bottom: 12px; width: auto; padding: 16px; }
    html.lx-consent-open .lx-chat-launcher { bottom: 236px; }
    html.lx-consent-open .lx-chat-teaser { display: none !important; }
}
@media (prefers-reduced-motion: reduce) { .lx-consent { animation: none; } }
@media print { .lx-consent { display: none !important; } }
