/* ------------------------------------------------------------------
   Agentic Solar — hero (full-bleed video -> five-image collage)
   Static, self-contained. Lives outside the Framer React root so it is
   never touched by hydration. Baseline (no JS) renders a full-bleed
   video hero with the headline and CTA visible; JS only adds the
   scroll-linked assembly.
   ------------------------------------------------------------------ */

.as-hero,
.as-problem,
.as-mission {
    --as-bg: #0b2242;
    --as-ink: #10305a;
    --as-accent: #4a86d0;
    --as-tint: #edf2f9;
    --as-radius: 28px;
    --as-card-w: min(27vw, 400px);
    --as-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ---------- mission statement, between the hero and the problem ---------- */

.as-mission {
    background: #fff;
}

.as-mission__inner {
    max-width: 900px;
    margin: 0 auto;
    padding: 128px 64px;
    text-align: center;
}

.as-mission__text {
    margin: 0;
    font-family: "Fraunces Variable", "Fraunces", "Fraunces Variable Placeholder", serif;
    font-variation-settings: "opsz" 56, "wght" 350, "SOFT" 100, "WONK" 1;
    font-feature-settings: "ss01" on;
    font-size: clamp(26px, 3.2vw, 42px);
    line-height: 1.28;
    letter-spacing: -0.03em;
    color: var(--as-ink);
}

@media (max-width: 809px) {
    .as-mission__inner {
        padding: 88px 24px;
    }
}

.as-hero {
    position: relative;
    width: 100%;
    background: var(--as-bg);
    isolation: isolate;
}

.as-hero__scroll {
    position: relative;
    height: 100vh;
    height: 100dvh;
}

.as-hero.as-js .as-hero__scroll {
    height: 320vh;
}

.as-hero__stage {
    position: relative;
    top: 0;
    height: 100vh;
    height: 100dvh;
    width: 100%;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
}

.as-hero.as-js .as-hero__stage {
    position: sticky;
}

/* ---------- cards ---------- */

.as-collage {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.as-card {
    position: absolute;
    top: 50%;
    left: 50%;
    margin: 0;
    width: var(--as-card-w);
    aspect-ratio: 3 / 4;
    overflow: hidden;
    border-radius: var(--as-radius);
    background: #08192f;
    box-shadow: 0 24px 60px rgba(3, 12, 26, 0.38);
    transform: translate(-50%, -50%);
    will-change: transform, opacity;
    backface-visibility: hidden;
}

.as-card img,
.as-card video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* the swapping photo layers of a slot */
.as-card img {
    opacity: 0;
    transition: opacity 900ms ease;
}

.as-card img.is-shown {
    opacity: 1;
}

.as-card__scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(6, 18, 38, 0.55) 0%, rgba(6, 18, 38, 0.35) 45%, rgba(6, 18, 38, 0.62) 100%);
    opacity: var(--as-scrim, 0.15);
    pointer-events: none;
}

/* stacking of the fan — the resting x/scale live on the cards as
   data-x / data-s and are applied by hero.js, so there is one source of
   truth for positions that both the flight and the resting state share. */
.as-card--center {
    z-index: 5;
}

.as-card--in-l,
.as-card--in-r {
    z-index: 4;
}

.as-card--out-l,
.as-card--out-r {
    z-index: 3;
}

/* side cards start off-stage once the script is driving the timeline */
.as-hero.as-js .as-card:not(.as-card--center) {
    opacity: 0;
}

/* ---------- baseline: no JS -> full-bleed video hero ---------- */

.as-hero:not(.as-js) .as-card--center {
    position: absolute;
    inset: 0;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
    transform: none;
    border-radius: 0;
    box-shadow: none;
    --as-scrim: 0.5;
}

.as-hero:not(.as-js) .as-card:not(.as-card--center) {
    display: none;
}

/* ---------- headline + CTA ---------- */

.as-hero__content {
    position: relative;
    z-index: 10;
    width: 100%;
    max-width: 1560px;
    padding: 0 64px;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 40px;
    will-change: opacity, transform;
}

.as-hero__title {
    margin: 0;
    max-width: 18ch;
    color: #fff;
    font-family: "Fraunces Variable", "Fraunces", "Fraunces Variable Placeholder", serif;
    font-variation-settings: "opsz" 72, "wght" 350, "SOFT" 100, "WONK" 1;
    font-feature-settings: "ss01" on;
    font-size: clamp(38px, 5.2vw, 76px);
    line-height: 1.06;
    letter-spacing: -0.04em;
    font-weight: 400;
    text-wrap: balance;
    text-shadow: 0 2px 40px rgba(4, 14, 30, 0.45);
}

.as-hero__cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 48px;
    padding: 0 28px;
    border-radius: 100px;
    background: #ffffff;
    color: var(--as-bg);
    font-family: Inter, "Inter Placeholder", sans-serif;
    font-size: 15px;
    font-weight: 500;
    letter-spacing: -0.02em;
    text-decoration: none;
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.12), 0 1.5px 3px rgba(0, 0, 0, 0.2), 0 4px 8px rgba(0, 0, 0, 0.2);
    transition: transform 220ms var(--as-ease), background-color 220ms var(--as-ease);
}

.as-hero__cta:hover {
    transform: translateY(-2px);
    background: var(--as-tint);
}

/* ---------- the problem, directly under the collage ---------- */

.as-problem {
    background: var(--as-bg);
    color: #fff;
}

.as-problem__inner {
    max-width: 1560px;
    margin: 0 auto;
    padding: 96px 64px 120px;
}

.as-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 28px;
    font-family: Inter, "Inter Placeholder", sans-serif;
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.62);
}

.as-eyebrow::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 100px;
    background: var(--as-accent);
}

.as-problem__title {
    margin: 0 0 48px;
    max-width: 16ch;
    font-family: "Fraunces Variable", "Fraunces", "Fraunces Variable Placeholder", serif;
    font-variation-settings: "opsz" 56, "wght" 350, "SOFT" 100, "WONK" 1;
    font-feature-settings: "ss01" on;
    font-size: clamp(32px, 4vw, 56px);
    line-height: 1.07;
    letter-spacing: -0.04em;
    font-weight: 400;
    color: #fff;
}

.as-problem__body {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 32px 64px;
    max-width: 1120px;
}

.as-problem__body p {
    margin: 0;
    font-family: Inter, "Inter Placeholder", sans-serif;
    font-size: 17px;
    line-height: 1.65;
    letter-spacing: -0.01em;
    color: rgba(255, 255, 255, 0.72);
}

/* ---------- platform walkthrough (Wistia) ---------- */

.as-walkthrough {
    background: var(--as-bg, #0b2242);
}

.as-walkthrough__inner {
    width: 100%;
    text-align: center;
    max-width: 1560px;
    margin: 0 auto;
    padding: 96px 64px 120px;
}

.as-walkthrough__title {
    margin: 0 auto 48px;
    max-width: 22ch;
    font-family: "Fraunces Variable", "Fraunces", "Fraunces Variable Placeholder", serif;
    font-variation-settings: "opsz" 56, "wght" 350, "SOFT" 100, "WONK" 1;
    font-feature-settings: "ss01" on;
    font-size: clamp(30px, 3.4vw, 48px);
    line-height: 1.08;
    letter-spacing: -0.04em;
    font-weight: 400;
    color: #fff;
}

.as-walkthrough__player {
    max-width: 900px;
    margin: 0 auto;
    border-radius: 24px;
    overflow: hidden;
    background: #08192f;
    box-shadow: 0 30px 80px rgba(3, 12, 26, 0.45);
}

.as-walkthrough__player wistia-player {
    display: block;
    width: 100%;
}

/* Wistia's own placeholder while the custom element is still upgrading */
wistia-player[media-id="rqnxd8xza8"]:not(:defined) {
    display: block;
    padding-top: 56.25%;
    background: center / contain no-repeat url("https://fast.wistia.com/embed/medias/rqnxd8xza8/swatch");
    filter: blur(5px);
}

/* ---------- how it works: section header above the dial ---------- */

.as-steps-head {
    width: 100%;
    max-width: 1560px;
    margin: 0 auto 8px;
    padding: 0 64px;
}

.as-eyebrow--dark {
    color: rgba(11, 34, 66, 0.55);
}

.as-steps-head__title {
    margin: 0 0 20px;
    max-width: 18ch;
    font-family: "Fraunces Variable", "Fraunces", "Fraunces Variable Placeholder", serif;
    font-variation-settings: "opsz" 56, "wght" 350, "SOFT" 100, "WONK" 1;
    font-feature-settings: "ss01" on;
    font-size: clamp(30px, 3.6vw, 52px);
    line-height: 1.07;
    letter-spacing: -0.04em;
    font-weight: 400;
    color: #0b2242;
}

.as-steps-head__lede {
    margin: 0;
    max-width: 60ch;
    font-family: Inter, "Inter Placeholder", sans-serif;
    font-size: 17px;
    line-height: 1.6;
    color: rgba(11, 34, 66, 0.62);
}

/* ---------- responsive ---------- */

@media (max-width: 1199px) {
    .as-hero {
        --as-card-w: min(34vw, 340px);
    }

    .as-hero__content,
    .as-problem__inner,
    .as-walkthrough__inner {
        padding-left: 40px;
        padding-right: 40px;
    }
}

@media (max-width: 809px) {
    .as-hero {
        --as-card-w: min(58vw, 320px);
        --as-radius: 20px;
    }

    .as-card--out-l,
    .as-card--out-r {
        display: none;
    }

    .as-hero__content {
        padding: 0 24px;
        gap: 28px;
    }

    .as-hero__title {
        max-width: none;
    }

    .as-problem__inner,
    .as-walkthrough__inner {
        padding: 72px 24px 88px;
    }

    .as-problem__body {
        grid-template-columns: minmax(0, 1fr);
        gap: 24px;
    }
}

/* ---------- how it works: step image stuck mid scroll-in animation ----------
   The step image sits inside a Framer "appear" animation (fade + scale
   from 0.5 up to 1 the first time it scrolls into view). On phones that
   animation was getting stuck at its opening frame — opacity: 0.001,
   transform: scale(0.5) translate(-50%,-50%) — set directly on
   .framer-1df48sy by Framer's own JS, which read as "the image is
   missing" (it is there, just five hundredths of a percent visible and
   half size). Most likely cause: loadStepShots() in hero.js force-loads
   these images by re-assigning img.src, and that extra load event fires
   before Framer's own IntersectionObserver decides the element has
   "appeared", so the appear animation never gets told to finish.
   Forcing the resting state directly is more reliable than chasing that
   race — Framer keeps re-writing the same inline style, but an
   !important rule in the stylesheet still wins over it. */
.framer-180p5lq {
    position: relative;
}

.framer-1df48sy {
    opacity: 1 !important;
    transform: none !important;
    position: absolute !important;
    inset: 0 !important;
    width: 100% !important;
    height: 100% !important;
}

.framer-1df48sy > div,
.framer-1df48sy img {
    position: absolute !important;
    inset: 0 !important;
    width: 100% !important;
    height: 100% !important;
    object-fit: cover;
}

/* the Worldwide section's three icon badges (sweep/region/globe) sit in
   the same kind of stuck Framer "appear" wrapper -- opacity: 0 and a
   small leftover translateY, which read as the icon sitting off-center
   in its circle rather than simply not being there yet. */
.framer-tdz3p4-container,
.framer-lj0q2h-container,
.framer-1yfkyqj-container {
    opacity: 1 !important;
    transform: none !important;
}

/* ...and the icon renders larger than the box it is placed in (a 46px
   image in a 36px box), so it starts at that box's top-left corner and
   overflows down and to the right rather than sitting centred in the
   circle. `width: 100%` cannot fix it: these SVGs carry a viewBox but
   no intrinsic width/height, so the percentage never resolves against
   the small box. Sizing the box itself to match the icon is what
   actually re-centres it. */
.framer-q4ngqo {
    display: flex;
    align-items: center;
    justify-content: center;
}

.framer-q4ngqo .framer-1ixwhcw {
    width: 46px !important;
    height: 46px !important;
}

.framer-q4ngqo img {
    width: 46px !important;
    height: 46px !important;
    object-fit: contain !important;
}

/* ---------- how it works: laggy pinned scroll on phones ----------
   The step-by-step dial pins itself full-height and drives its own
   scroll-linked transforms while it is stuck (native Framer component,
   compiled — not something rebuildable by hand the way the hero was).
   Disabling that pin outright breaks it: only the current step's DOM
   is mounted at a time, so an unpinned section just leaves ~3.7k px of
   blank space where the unmounted next steps would have appeared.
   Short of rewriting Framer's compiled scroll handler, the safe lever
   left is compositor hints — telling the browser which layers move so
   it can promote them to their own GPU layer instead of repainting
   the pinned stage on every scroll tick. */
@media (max-width: 809px) {
    .framer-hbnb15 {
        will-change: transform;
        contain: layout paint;
    }

    .framer-180p5lq,
    .framer-1df48sy,
    .framer-1rijmqp {
        will-change: transform, opacity;
    }
}

/* ---------- template chrome we don't use ---------- */

/* the template's own hero */
.framer-mv0q0g {
    display: none !important;
}

/* template/marketplace furniture: Awwwards badge, "only $99" promo,
   "Made in Framer" badge. #__framer-badge-container is the actual
   floating pill (the :has() selectors above never matched it — :has()
   support is inconsistent enough not to rely on for something this
   visible), and .framer-1rbcj3r is a separate "Powered by Framer" text
   credit lower on the page. */
body > div:has(> a[href*="awwwards.com"]),
.framer-abmnlp-container,
.__framer-badge,
body > div:has(> .__framer-badge),
#__framer-badge-container,
.framer-1rbcj3r {
    display: none !important;
}

/* sections carrying template content we have nothing real to put in yet:
   client-logo wall, studio testimonials, portfolio, blog, FAQ.
   Delete a line here to bring one back. */
#logos,
.framer-1j2drky,
.framer-tejpcc,
.framer-15bkp47,
.framer-4p2e98 {
    display: none !important;
}

/* the native Pricing section is replaced by our own static .as-pricing
   block (see script_main.vGoRmafi.mjs), which we can position wherever
   the page needs it rather than wherever Framer's canvas put it */
.framer-k816n8 {
    display: none !important;
}

/* pricing: two plans, not three — drop the third card and let the
   remaining pair share the row */
.framer-1vwvmq7-container {
    display: none !important;
}

.framer-1i7rok2 {
    justify-content: center;
}

.framer-n30ole-container,
.framer-74h80d-container {
    flex: 0 1 520px !important;
    width: 520px !important;
}

/* socials we don't run: Behance, Dribbble */
.framer-ldvp8v-container,
.framer-e2h041-container {
    display: none !important;
}

/* nav dropdowns with no Agentic Solar counterpart: Services, Pages */
.framer-1nmpt6z-container,
.framer-18c8pfg-container {
    display: none !important;
}

/* the Agentic Solar lockup, in navy on light sections and white on the video.
   The template renders its logo tile with image-rendering: pixelated and a
   stretched background — both have to go or the wordmark turns to mush. */
[data-framer-name="Logo"] {
    background-image: url("img/logo-navy.png") !important;
    background-size: contain !important;
    background-position: left center !important;
    background-repeat: no-repeat !important;
    image-rendering: auto !important;
    width: 148px !important;
    height: 34px !important;
    flex: none !important;
}

/* while the video is still full bleed, the nav has to read on top of it:
   white type and logo, and none of the template's frosted backdrop, which
   turns near-white over bright sky */
html.as-hero-dark nav .framer-text {
    color: #fff !important;
}

html.as-hero-dark nav,
html.as-hero-dark nav > div,
html.as-hero-dark nav > div > div {
    background-color: transparent !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    border-color: transparent !important;
}

html.as-hero-dark .framer-13nr5y8-container::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 160px;
    background: linear-gradient(180deg, rgba(6, 18, 38, 0.55), rgba(6, 18, 38, 0));
    pointer-events: none;
    z-index: -1;
}

html.as-hero-dark [data-framer-name="Logo"] {
    background-image: url("img/logo-white.png") !important;
}

/* ---------- mobile nav drawer ----------
   The native dropdown ships transparent with unstyled link-blue text
   and template labels, so it is replaced outright — see initMobileNav
   in sections.js. */
.framer-15igyxo {
    display: none !important;
}

.as-mnav {
    position: fixed;
    inset: 0;
    /* has to clear Framer's own fixed nav container, which sits in a
       stacking context we do not control — z-index 40 was losing to it,
       leaving the template's transparent menu visible over the hero
       video instead of this panel */
    z-index: 2147483000;
    display: flex;
    flex-direction: column;
    padding: 104px 28px 40px;
    background: #fff;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-12px);
    transition: opacity 220ms ease, transform 220ms ease, visibility 0s linear 220ms;
    overflow-y: auto;
}

.as-mnav.is-open {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition: opacity 220ms ease, transform 220ms ease;
}

.as-mnav a {
    padding: 20px 2px;
    border-bottom: 1px solid var(--as-line, rgba(11, 34, 66, 0.12));
    font-family: "Fraunces Variable", "Fraunces", serif;
    font-variation-settings: "opsz" 32, "wght" 400;
    font-size: 26px;
    letter-spacing: -0.02em;
    color: var(--as-ink, #10305a);
    text-decoration: none;
}

@media (min-width: 810px) {
    .as-mnav {
        display: none !important;
    }
}

/* while the drawer is open the nav rides above it, so the logo and the
   close button stay visible and tappable — and it has to use its light
   styling there, since over the hero video the nav goes white and a
   white logo on the white drawer is invisible */
html.as-mnav-open .framer-13nr5y8-container {
    z-index: 2147483001 !important;
}

html.as-mnav-open nav .framer-text {
    color: var(--as-ink, #10305a) !important;
}

html.as-mnav-open [data-framer-name="Logo"] {
    background-image: url("img/logo-navy.png") !important;
}

html.as-mnav-open .framer-13nr5y8-container::before {
    display: none !important;
}

/* React no longer sees the tap on the hamburger (sections.js stops it in
   the capture phase so the template menu can never open), which means it
   also never swaps the icon to a close control. These two bars are that
   icon: 16px and 9px, sitting 4px either side of the button's centre.
   Crossing them here gives the drawer its close affordance back. */
.framer-b8dmt9,
.framer-rivbz3 {
    transition: transform 220ms ease, width 220ms ease;
}

html.as-mnav-open .framer-b8dmt9 {
    transform: translateY(4px) rotate(45deg) !important;
}

html.as-mnav-open .framer-rivbz3 {
    width: 16px !important;
    transform: translateY(-4px) rotate(-45deg) !important;
}

/* ---------- reduced motion: skip the scroll choreography ---------- */

@media (prefers-reduced-motion: reduce) {
    .as-hero.as-js .as-hero__scroll {
        height: 100vh;
    }

    .as-card,
    .as-hero__content {
        transition: none !important;
    }
}

/* ---------- footer ---------- */

/* the pre-footer CTA card carries the solar farm, not an abstract render */
.framer-xnc2k1 {
    background-image:
        linear-gradient(100deg, rgba(11, 34, 66, 0.97) 0%, rgba(11, 34, 66, 0.9) 42%, rgba(11, 34, 66, 0.35) 100%),
        url("img/solar-farm.webp") !important;
    background-size: cover, cover !important;
    background-position: center, center right !important;
    background-repeat: no-repeat, no-repeat !important;
}

/* the template's abstract 3D loop inside that card */
.framer-1429ia4 {
    display: none !important;
}

/* the template's oversized word-art — replaced by the real lockup in the
   footer sitemap block */
.framer-1dtdtyp,
.framer-1hpq1ay {
    display: none !important;
}

.as-legal-wrap {
    margin-top: 6px;
}

/* the Worldwide card icons want a little more presence */
img[src*="/img/icons/"] {
    width: 46px !important;
    height: 46px !important;
}

/* the pre-footer card breathes: a slow drift on the solar farm behind it */
.framer-xnc2k1 {
    background-size: cover, 112% auto !important;
    animation: as-cta-drift 26s ease-in-out infinite alternate;
}

@keyframes as-cta-drift {
    from {
        background-position: center, 58% 50%;
    }

    to {
        background-position: center, 42% 46%;
    }
}

@media (prefers-reduced-motion: reduce) {
    .framer-xnc2k1 {
        animation: none;
    }
}
