/* ============================================================
   BLUEGRID LAND SOLUTIONS — HOMEPAGE STYLES
   Flagship Nulo Studio build — reusable systems are marked.
============================================================ */

/* ============================================================
   VARIABLES
============================================================ */

:root
{

    --colorSky: #5B9BD5;

    --colorSkyDeep: #3E7CB8;

    --colorSkyLight: #A9D2F0;

    --colorCharcoal: #1C1F22;

    --colorNearBlack: #101214;

    --colorInk: #232A30;

    --colorSteel: #7C8894;

    --colorOffWhite: #F7F9FB;

    --colorWhite: #FFFFFF;

    --colorGold: #E8B64C;

    --colorDanger: #D96A5B;

    --colorLineLight: rgba(16, 18, 20, 0.10);

    --colorLineDark: rgba(247, 249, 251, 0.14);

    --fontDisplay: 'Rokkitt', 'Georgia', serif;

    --fontBody: 'Inter', 'Segoe UI', sans-serif;

    --easePremium: cubic-bezier(0.22, 1, 0.36, 1);

    --durationReveal: 650ms;

    --durationRevealShort: 420ms;

    --durationHeroReveal: 560ms;

    --maxWidth: 1220px;

    --radiusCard: 14px;

    --radiusPill: 999px;

    /* ── Header layout ──
       The header morphs through three states: full desktop, compact
       desktop (≤1360px), and mobile (≤1200px). Every dimension that
       differs between them lives here and is overridden in those two
       media queries; the header rules themselves only ever read these,
       so retuning the spacing is one edit in one place rather than a
       hunt through the stylesheet.

       --headerTransition puts every one of those changes on the same
       curve, matching the 0.35s the header already uses for its
       scrolled background, so a resize morphs rather than snaps. */

    --headerHeight: 78px;

    --headerPadX: 1.5rem;

    --headerGap: 1.6rem;

    --headerBrandGap: 1rem;

    --headerBadgeSize: 69px;

    --headerBrandNameSize: 1.7rem;

    --headerNavGap: 0.4rem;

    --headerNavLinkPadX: 0.95rem;

    --headerNavChevronGap: 0.4rem;

    --headerActionsGap: 0.9rem;

    --headerPhonePadX: 1rem;

    /* Deliberately constant at every width — the primary CTA keeps its
       prominence while everything around it gives ground. */

    --headerCtaPadX: 1.3rem;

    --headerTransition: 0.35s var(--easePremium);

    /* ── Mega menu surface (reusable Nulo Studio pattern) ──
       Every mega panel on the site reads these, so a panel added for
       another section inherits the surface for free and the three
       that exist today cannot drift apart. The values are the ones
       the panels already shipped with — this is the vocabulary being
       named, not the look being changed. */

    --megaPanelPad: 1.4rem;

    --megaPanelSurface: rgba(16, 18, 20, 0.97);

    --megaPanelShadow: 0 30px 70px rgba(0, 0, 0, 0.5);

    /* The hairline that separates a panel's regions, and the one that
       catches the light along its top edge. */

    --megaRule: var(--colorLineDark);

    --megaTopEdge: inset 0 1px 0 rgba(255, 255, 255, 0.07);

    --megaRowRadius: 10px;

    --megaRowTint: rgba(91, 155, 213, 0.14);

    --megaLabelColor: rgba(247, 249, 251, 0.42);

    --megaCopyColor: rgba(247, 249, 251, 0.6);

    --shadowCard: 0 18px 45px rgba(16, 18, 20, 0.14);

    --shadowCardHover: 0 26px 60px rgba(16, 18, 20, 0.22);

}

/* ============================================================
   RESET & BASE
============================================================ */

*,
*::before,
*::after
{

    box-sizing: border-box;

}

[hidden]
{

    display: none !important;

}

html
{

    overflow-x: hidden;

    scroll-behavior: smooth;

    scroll-padding-top: calc(var(--headerHeight) + 12px);

}

body
{

    margin: 0;

    overflow-x: hidden;

    font-family: var(--fontBody);

    font-size: 1rem;

    line-height: 1.65;

    color: var(--colorInk);

    background-color: var(--colorOffWhite);

    -webkit-font-smoothing: antialiased;

}

img
{

    max-width: 100%;

    height: auto;

    display: block;

}

a
{

    color: var(--colorSkyDeep);

    text-decoration: none;

}

button
{

    font-family: inherit;

    cursor: pointer;

}

/* ── Utilities ── */

.visuallyHidden
{

    position: absolute;

    width: 1px;

    height: 1px;

    margin: -1px;

    padding: 0;

    overflow: hidden;

    clip: rect(0 0 0 0);

    white-space: nowrap;

    border: 0;

}

.skipLink
{

    position: absolute;

    top: -60px;

    left: 16px;

    z-index: 400;

    padding: 0.6rem 1.1rem;

    background-color: var(--colorSky);

    color: var(--colorNearBlack);

    font-weight: 600;

    border-radius: 6px;

    transition: top 0.25s var(--easePremium);

}

.skipLink:focus
{

    top: 12px;

}

.honeypotField
{

    position: absolute;

    left: -9999px;

    opacity: 0;

    pointer-events: none;

}

:focus-visible
{

    outline: 3px solid var(--colorSky);

    outline-offset: 2px;

}

/* ============================================================
   TYPOGRAPHY & SECTION SHELL
============================================================ */

.sectionInner
{

    max-width: var(--maxWidth);

    margin: 0 auto;

    padding: 6.5rem 1.5rem;

}

.sectionKicker
{

    margin: 0 0 0.9rem;

    font-family: var(--fontDisplay);

    font-size: 1.05rem;

    font-weight: 600;

    letter-spacing: 0.22em;

    text-transform: uppercase;

    color: var(--colorSkyDeep);

}

.darkSection .sectionKicker
{

    color: var(--colorSky);

}

.sectionHeading
{

    margin: 0 0 1.1rem;

    font-family: var(--fontDisplay);

    font-size: clamp(2.3rem, 4.5vw, 3.4rem);

    font-weight: 700;

    line-height: 1.06;

    letter-spacing: 0.01em;

    text-transform: uppercase;

    color: var(--colorCharcoal);

}

.sectionLede
{

    max-width: 620px;

    margin: 0 0 3.2rem;

    font-size: 1.1rem;

    color: var(--colorSteel);

}

/* ── Dark section variant ── */

.darkSection
{

    background-color: var(--colorCharcoal);

    color: var(--colorOffWhite);

}

.darkSection .sectionHeading
{

    color: var(--colorWhite);

}

.darkSection .sectionLede
{

    color: rgba(247, 249, 251, 0.72);

}

/* ============================================================
   BUTTONS  (reusable CTA system)
============================================================ */

.buttonPrimary
{

    display: inline-flex;

    align-items: center;

    justify-content: center;

    gap: 0.55rem;

    padding: 0.85rem 1.7rem;

    background-color: var(--colorSky);

    color: var(--colorNearBlack);

    font-family: var(--fontBody);

    font-size: 1rem;

    font-weight: 700;

    border: none;

    border-radius: 8px;

    transition:
        background-color 0.25s var(--easePremium),
        transform 0.25s var(--easePremium),
        box-shadow 0.25s var(--easePremium);

}

.buttonPrimary:hover
{

    background-color: var(--colorSkyLight);

    transform: translateY(-2px);

    box-shadow: 0 12px 28px rgba(91, 155, 213, 0.35);

}

.buttonGhost
{

    display: inline-flex;

    align-items: center;

    justify-content: center;

    gap: 0.55rem;

    padding: 0.85rem 1.7rem;

    background-color: transparent;

    color: var(--colorWhite);

    font-family: var(--fontBody);

    font-size: 1rem;

    font-weight: 600;

    border: 1.5px solid rgba(247, 249, 251, 0.55);

    border-radius: 8px;

    transition:
        border-color 0.25s var(--easePremium),
        background-color 0.25s var(--easePremium),
        transform 0.25s var(--easePremium);

}

.buttonGhost:hover
{

    border-color: var(--colorSky);

    background-color: rgba(91, 155, 213, 0.12);

    transform: translateY(-2px);

}

.buttonLarge
{

    padding: 1.05rem 2.1rem;

    font-size: 1.08rem;

}

/* Icon slot for any button in the system above. It inherits the
   button's own text colour rather than carrying one, so the same
   glyph works on the solid primary and the outlined ghost, and it
   rides the gap the buttons already declare — dimensions unchanged. */

.buttonIcon
{

    width: 17px;

    height: 17px;

    flex-shrink: 0;

    fill: currentColor;

}

/* ============================================================
   ANIMATION ENGINE  (reusable — load sequence + viewport reveal)
============================================================ */

html.jsEnabled [data-animate]
{

    opacity: 0;

    transition:
        opacity var(--durationReveal) var(--easePremium),
        transform var(--durationReveal) var(--easePremium),
        clip-path var(--durationReveal) var(--easePremium);

    transition-delay: var(--animateDelay, 0ms);

    will-change: opacity, transform;

}

html.jsEnabled [data-animate="fadeUp"]
{

    transform: translate3d(0, 24px, 0);

}

html.jsEnabled [data-animate="fadeIn"]
{

    transform: none;

}

html.jsEnabled [data-animate="slideLeft"]
{

    transform: translate3d(-32px, 0, 0);

}

html.jsEnabled [data-animate="slideRight"]
{

    transform: translate3d(32px, 0, 0);

}

html.jsEnabled [data-animate="scaleIn"]
{

    transform: translate3d(0, 14px, 0) scale(0.97);

}

html.jsEnabled [data-animate="clipReveal"]
{

    clip-path: inset(0 0 100% 0);

    transform: translate3d(0, 14px, 0);

}

html.jsEnabled .sectionKicker[data-animate="fadeUp"],
html.jsEnabled .sectionHeading[data-animate="fadeUp"],
html.jsEnabled .sectionLede[data-animate="fadeUp"]
{

    transform: translate3d(-30px, 0, 0);

}

html.jsEnabled .whyContent .sectionKicker[data-animate="fadeUp"],
html.jsEnabled .whyContent .sectionHeading[data-animate="fadeUp"]
{

    transform: translate3d(30px, 0, 0);

}

html.jsEnabled .facebookPosts .postCard[data-animate="fadeUp"]
{

    transform: translate3d(14px, 24px, 0);

}

html.jsEnabled .servicesGrid .serviceCard:nth-child(3n + 1)[data-animate="fadeUp"],
html.jsEnabled .transformationStories .storyCard:nth-child(3n + 1)[data-animate="fadeUp"]
{

    transform: translate3d(-14px, 24px, 0);

}

html.jsEnabled .servicesGrid .serviceCard:nth-child(3n)[data-animate="fadeUp"],
html.jsEnabled .transformationStories .storyCard:nth-child(3n)[data-animate="fadeUp"]
{

    transform: translate3d(14px, 24px, 0);

}

html.jsEnabled .comparisonSlider[data-animate] .comparisonTag,
html.jsEnabled .comparisonSlider[data-animate] .comparisonHandle
{

    opacity: 0;

    transition:
        opacity var(--durationRevealShort) var(--easePremium),
        transform var(--durationRevealShort) var(--easePremium);

}

html.jsEnabled .comparisonSlider[data-animate] .comparisonTagBefore
{

    transform: translate3d(-12px, 0, 0);

}

html.jsEnabled .comparisonSlider[data-animate] .comparisonTagAfter
{

    transform: translate3d(12px, 0, 0);

}

html.jsEnabled .comparisonSlider[data-animate] .comparisonHandle
{

    transform: translate3d(-50%, 12px, 0);

}

html.jsEnabled .comparisonSlider[data-animate].isAnimated .comparisonTag,
html.jsEnabled .comparisonSlider[data-animate].isAnimated .comparisonHandle
{

    opacity: 1;

    transform: none;

    transition-delay: 260ms;

}

html.jsEnabled .comparisonSlider[data-animate].isAnimated .comparisonHandle
{

    transform: translate3d(-50%, 0, 0);

    transition-delay: 360ms;

}

html.jsEnabled [data-animate].isAnimated
{

    opacity: 1;

    transform: none;

    clip-path: inset(0 0 0 0);

}

html.jsEnabled .whyContent .sectionKicker[data-animate="fadeUp"].isAnimated,
html.jsEnabled .whyContent .sectionHeading[data-animate="fadeUp"].isAnimated,
html.jsEnabled .facebookPosts .postCard[data-animate="fadeUp"].isAnimated,
html.jsEnabled .servicesGrid .serviceCard:nth-child(3n + 1)[data-animate="fadeUp"].isAnimated,
html.jsEnabled .servicesGrid .serviceCard:nth-child(3n)[data-animate="fadeUp"].isAnimated,
html.jsEnabled .transformationStories .storyCard:nth-child(3n + 1)[data-animate="fadeUp"].isAnimated,
html.jsEnabled .transformationStories .storyCard:nth-child(3n)[data-animate="fadeUp"].isAnimated
{

    transform: none;

}

html.jsEnabled [data-animate].isAnimationComplete
{

    will-change: auto;

}

html.jsEnabled [data-heroanimate]
{

    opacity: 0;

    transition:
        opacity var(--durationHeroReveal) var(--easePremium),
        transform var(--durationHeroReveal) var(--easePremium);

    transition-delay: var(--heroAnimateDelay, 0ms);

    will-change: opacity, transform;

}

html.jsEnabled [data-heroanimate="header"]
{

    transform: translate3d(0, -22px, 0);

}

html.jsEnabled [data-heroanimate="fromLeft"]
{

    transform: translate3d(-28px, 0, 0);

}

html.jsEnabled [data-heroanimate="fromRight"]
{

    transform: translate3d(28px, 0, 0);

}

html.jsEnabled [data-heroanimate="fadeUp"]
{

    transform: translate3d(0, 24px, 0);

}

html.jsEnabled.heroSequenceReady [data-heroanimate]
{

    opacity: 1;

    transform: none;

}

html.jsEnabled.heroSequenceComplete [data-heroanimate]
{

    will-change: auto;

}

html.animationFallback [data-animate],
html.animationFallback [data-heroanimate]
{

    opacity: 1 !important;

    transform: none !important;

    clip-path: none !important;

    transition: none !important;

    will-change: auto !important;

}

html.animationFallback .comparisonSlider[data-animate] .comparisonTag,
html.animationFallback .comparisonSlider[data-animate] .comparisonHandle
{

    opacity: 1;

    transform: none;

    transition: none;

}

html.animationFallback .comparisonSlider[data-animate] .comparisonHandle
{

    transform: translate3d(-50%, 0, 0);

}

/* ============================================================
   NAVIGATION
============================================================ */

.siteHeader
{

    position: fixed;

    top: env(safe-area-inset-top, 0px);

    left: 0;

    right: 0;

    z-index: 300;

    background-color: transparent;

    transition:
        background-color 0.35s var(--easePremium),
        box-shadow 0.35s var(--easePremium),
        transform 0.35s var(--easePremium);

}

.siteHeader.isScrolled
{

    background-color: rgba(16, 18, 20, 0.94);

    box-shadow: 0 10px 30px rgba(16, 18, 20, 0.35);

    backdrop-filter: blur(10px);

}

.headerInner
{

    display: flex;

    align-items: center;

    gap: var(--headerGap);

    max-width: 1360px;

    height: var(--headerHeight);

    margin: 0 auto;

    padding: 0 var(--headerPadX);

    transition:
        gap var(--headerTransition),
        height var(--headerTransition),
        padding var(--headerTransition);

}

/* ── Brand lockup ── */

.brandLockup
{

    display: flex;

    align-items: center;

    gap: var(--headerBrandGap);

    margin-right: auto;

    transition: gap var(--headerTransition);

}

.brandBadge
{

    width: var(--headerBadgeSize);

    height: var(--headerBadgeSize);

    border-radius: 50%;

    filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.35));

    transition:
        width var(--headerTransition),
        height var(--headerTransition);

}

.brandName
{

    display: flex;

    flex-direction: column;

    white-space: nowrap;

    font-family: var(--fontDisplay);

    font-size: var(--headerBrandNameSize);

    font-weight: 700;

    line-height: 1;

    letter-spacing: 0.04em;

    text-transform: uppercase;

    color: var(--colorWhite);

    transition: font-size var(--headerTransition);

}

.brandNameSub
{

    white-space: nowrap;

    margin-top: 0.28rem;

    font-family: var(--fontBody);

    font-size: 0.62rem;

    font-weight: 600;

    letter-spacing: 0.34em;

    color: var(--colorSky);

}

/* ── Primary nav ──
   The nav and the actions never compress; the brand lockup is the
   flexible one, which is why it carries margin-right: auto. Nothing
   in the header is allowed to wrap to a second line — the header is
   a fixed-height bar, so a wrap is always a defect rather than a
   graceful fallback. When the bar can no longer hold everything the
   mobile nav takes over (see the 1150px query). */

.primaryNav
{

    flex-shrink: 0;

    /* The mega panels resolve against the nav, not against the item
       that opened them. All three are the same width and land on the
       same rectangle, so moving between Services, Service Areas and
       FAQ swaps the contents of one panel rather than sliding a
       different panel into place each time. */

    position: relative;

}

.navList
{

    display: flex;

    flex-wrap: nowrap;

    align-items: center;

    gap: var(--headerNavGap);

    margin: 0;

    padding: 0;

    list-style: none;

    transition: gap var(--headerTransition);

}

/* Deliberately not a positioning context — see .primaryNav. It stays
   the hover/open target and the panel's DOM parent, which is all the
   behaviour in indexJS.js needs. */

.navItem
{

    position: static;

}

.navLink
{

    display: inline-flex;

    align-items: center;

    gap: var(--headerNavChevronGap);

    padding: 0.6rem var(--headerNavLinkPadX);

    white-space: nowrap;

    background: none;

    border: none;

    font-family: var(--fontBody);

    font-size: 0.95rem;

    font-weight: 600;

    color: rgba(247, 249, 251, 0.88);

    border-radius: 8px;

    /* Hover colour keeps its own quicker timing; only the layout
       properties ride the shared header curve. */

    transition:
        color 0.25s var(--easePremium),
        background-color 0.25s var(--easePremium),
        gap var(--headerTransition),
        padding var(--headerTransition);

}

.navLink:hover,
.navLink:focus-visible
{

    color: var(--colorWhite);

    background-color: rgba(247, 249, 251, 0.08);

}

.navChevron
{

    width: 11px;

    height: 8px;

    transition: transform 0.3s var(--easePremium);

}

.megaToggle[aria-expanded="true"] .navChevron
{

    transform: rotate(180deg);

}

/* ── Mega menu panels (reusable) ── */

.megaPanel
{

    position: absolute;

    top: calc(100% + 14px);

    left: 50%;

    z-index: 320;

    /* One shell for all three panels: same width, same padding, same
       radius, same surface, same edge. Anything a panel needs beyond
       this belongs to its contents, not to its container. */

    min-width: 0;

    width: min(760px, calc(100vw - 3rem));

    padding: var(--megaPanelPad);

    background-color: var(--megaPanelSurface);

    border: 1px solid var(--megaRule);

    border-radius: var(--radiusCard);

    box-shadow: var(--megaPanelShadow), var(--megaTopEdge);

    opacity: 0;

    visibility: hidden;

    transform: translateX(-50%) translateY(14px);

    transition:
        opacity 0.3s var(--easePremium),
        visibility 0.3s var(--easePremium),
        transform 0.3s var(--easePremium);

}

.navItem.isOpen .megaPanel
{

    opacity: 1;

    visibility: visible;

    transform: translateX(-50%) translateY(0);

}

/* ── Services mega panel ──
   The one panel with a hierarchy rather than a list: a full-width
   featured band for the flagship service, a hairline, then the
   remaining six in three equal, labelled groups.

   Width is 760px, matching the FAQ panel so the two large panels
   read as the same object at the same size. The panel stays centred
   on its toggle like every other one — the nav is right-aligned in
   the bar, so the Services item sits far enough in that a 760px
   panel clears both screen edges at 1151px, the narrowest viewport
   the desktop nav survives to. */

/* The 14px gap between the toggle and the panel is not over the nav
   item, so crossing it used to fire mouseleave and close the menu the
   instant the pointer left the link. This bridges it: a transparent
   band that belongs to the panel, and therefore to the item. It is
   hidden with the panel, since visibility inherits. */

.megaPanel::before
{

    content: "";

    position: absolute;

    right: 0;

    bottom: 100%;

    left: 0;

    height: 14px;

}

/* ── The featured entry point ──
   Icon, then the name and the promise, then the cue, on one baseline.
   The sky wash is the only filled surface in any panel, which is what
   makes the eye land here first — and it is the one element every
   panel opens with, so the three read as the same component before a
   visitor has processed a single word. */

.megaFeature
{

    display: grid;

    grid-template-columns: auto minmax(0, 1fr) auto;

    align-items: center;

    gap: 1.1rem;

    padding: 1.15rem;

    border: 1px solid rgba(91, 155, 213, 0.24);

    border-radius: 12px;

    background-color: rgba(91, 155, 213, 0.05);

    background-image: linear-gradient(
        152deg,
        rgba(91, 155, 213, 0.16) 0%,
        rgba(91, 155, 213, 0.04) 58%,
        rgba(91, 155, 213, 0) 100%
    );

    transition:
        border-color 0.25s var(--easePremium),
        background-color 0.25s var(--easePremium);

}

.megaFeature:hover,
.megaFeature:focus-visible
{

    border-color: rgba(91, 155, 213, 0.45);

    background-color: rgba(91, 155, 213, 0.1);

}

.megaFeatureIcon
{

    display: flex;

    align-items: center;

    justify-content: center;

    width: 52px;

    height: 52px;

    border-radius: 13px;

    background-color: rgba(91, 155, 213, 0.16);

}

.megaFeatureIcon svg
{

    width: 26px;

    height: 26px;

    fill: var(--colorSkyLight);

}

.megaFeatureBody
{

    display: flex;

    flex-direction: column;

    gap: 0.3rem;

}

.megaFeatureEyebrow
{

    font-family: var(--fontBody);

    font-size: 0.64rem;

    font-weight: 700;

    letter-spacing: 0.2em;

    text-transform: uppercase;

    color: var(--colorSky);

}

.megaFeatureTitle
{

    font-family: var(--fontDisplay);

    font-size: 1.3rem;

    font-weight: 700;

    line-height: 1.1;

    letter-spacing: 0.01em;

    color: var(--colorWhite);

}

.megaFeatureCopy
{

    font-size: 0.8rem;

    line-height: 1.5;

    color: var(--megaCopyColor);

}

.megaFeatureCue
{

    display: inline-flex;

    align-items: center;

    gap: 0.4rem;

    white-space: nowrap;

    font-size: 0.8rem;

    font-weight: 700;

    color: var(--colorSky);

    transition: color 0.25s var(--easePremium);

}

.megaFeature:hover .megaFeatureCue,
.megaFeature:focus-visible .megaFeatureCue
{

    color: var(--colorSkyLight);

}

.megaFeatureArrow
{

    width: 16px;

    height: 10px;

    transition: transform 0.25s var(--easePremium);

}

.megaFeature:hover .megaFeatureArrow,
.megaFeature:focus-visible .megaFeatureArrow
{

    transform: translateX(4px);

}

/* ── The region under the feature ──
   Shared by all three panels: one rule, one rhythm. What sits inside
   it is each panel's own business — services group in thirds, areas in
   halves by region, FAQ in halves by question. */

.megaBody
{

    margin-top: 1.4rem;

    padding-top: 1.4rem;

    border-top: 1px solid var(--megaRule);

}

/* A labelled group inside a panel body — services groups by kind,
   areas by region. min-width: 0 keeps a long label from blowing out
   its grid column. */

.megaGroup
{

    min-width: 0;

}

.megaServicesGroups
{

    display: grid;

    grid-template-columns: repeat(3, minmax(0, 1fr));

    gap: 1.5rem;

}

.megaGroupHeading
{

    display: flex;

    align-items: center;

    gap: 0.4rem;

    margin: 0 0 0.55rem;

    padding: 0 0.7rem 0.5rem;

    border-bottom: 1px solid var(--megaRule);

    font-family: var(--fontBody);

    font-size: 0.64rem;

    font-weight: 700;

    letter-spacing: 0.18em;

    text-transform: uppercase;

    color: var(--megaLabelColor);

}

/* Optional mark on a group label — used by Service Areas to carry the
   geography without putting a pin on all thirteen towns. */

.megaGroupIcon
{

    flex-shrink: 0;

    width: 11px;

    height: 11px;

    fill: var(--colorSky);

    opacity: 0.85;

}

/* ── The row primitive ──
   Every clickable line in every panel: a service, a town, a question.
   Padding, radius, hover tint and the sky rule that grows down the
   leading edge all live here once. Panels add only what their own
   content needs on top. */

.megaRow
{

    position: relative;

    display: block;

    padding: 0.6rem 0.7rem;

    border-radius: var(--megaRowRadius);

    transition: background-color 0.25s var(--easePremium);

}

.megaRow::before
{

    content: "";

    position: absolute;

    top: 0.5rem;

    bottom: 0.5rem;

    left: 0;

    width: 2px;

    border-radius: 2px;

    background-color: var(--colorSky);

    opacity: 0;

    transform: scaleY(0.35);

    transition:
        opacity 0.25s var(--easePremium),
        transform 0.25s var(--easePremium);

}

.megaRow:hover,
.megaRow:focus-visible
{

    background-color: var(--megaRowTint);

}

.megaRow:hover::before,
.megaRow:focus-visible::before
{

    opacity: 1;

    transform: scaleY(1);

}

/* ── FAQ mega panel ──
   Six of the highest-intent questions in two columns. The full library
   stays on the FAQ page; the menu is a sample, not an index, which is
   what keeps this panel the same height as the other two. Desktop only
   — the mobile drawer links straight to the FAQ page instead. */

.megaFaqList
{

    display: grid;

    grid-template-columns: 1fr 1fr;

    gap: 0.1rem 0.8rem;

    margin: 0;

    padding: 0;

    list-style: none;

}

.megaFaqLink
{

    height: 100%;

    padding: 0.7rem 0.85rem;

}

.megaFaqQuestion
{

    display: block;

    margin-bottom: 0.25rem;

    font-size: 0.94rem;

    font-weight: 700;

    line-height: 1.3;

    color: var(--colorWhite);

}

.megaFaqAnswer
{

    display: block;

    font-size: 0.8rem;

    line-height: 1.5;

    color: var(--megaCopyColor);

}

.megaServicesList,
.megaCompanyList
{

    display: flex;

    flex-direction: column;

    gap: 0.1rem;

    margin: 0;

    padding: 0;

    list-style: none;

}

/* Everything a row does — padding, radius, hover tint, leading rule —
   comes from .megaRow. A service row adds only its icon column, and the
   Our Company rows are the same shape — so they join these selector
   groups rather than restating them. One declaration, two names: the
   two panels cannot drift apart, and nothing renders differently. */

.megaServiceLink,
.megaCompanyLink
{

    display: flex;

    align-items: flex-start;

    gap: 0.65rem;

}

.megaServiceIcon,
.megaCompanyIcon
{

    flex-shrink: 0;

    width: 18px;

    height: 18px;

    margin-top: 0.12rem;

    fill: var(--colorSky);

    opacity: 0.75;

    transition: opacity 0.25s var(--easePremium);

}

.megaServiceLink:hover .megaServiceIcon,
.megaServiceLink:focus-visible .megaServiceIcon,
.megaCompanyLink:hover .megaCompanyIcon,
.megaCompanyLink:focus-visible .megaCompanyIcon
{

    opacity: 1;

}

.megaServiceText,
.megaCompanyText
{

    display: flex;

    flex-direction: column;

    gap: 0.15rem;

}

.megaServiceText strong,
.megaCompanyText strong
{

    font-size: 0.9rem;

    font-weight: 600;

    line-height: 1.25;

    color: var(--colorWhite);

}

.megaServiceText small,
.megaCompanyText small
{

    font-size: 0.76rem;

    line-height: 1.45;

    color: var(--megaCopyColor);

}

/* ── Service Areas mega panel ──
   Two regions side by side, each town list flowing down its own pair
   of columns. Multi-column rather than grid on purpose: the regions
   hold seven and six towns, and columns balance an odd count by
   themselves while still reading top-to-bottom, which a row-flowed
   grid does not. */

.megaAreasGroups,
.megaCompanyGroups
{

    display: grid;

    grid-template-columns: repeat(2, minmax(0, 1fr));

    gap: 1.5rem;

}

.megaAreaList
{

    margin: 0;

    padding: 0;

    list-style: none;

    columns: 2;

    column-gap: 0.6rem;

}

.megaAreaList li
{

    break-inside: avoid;

}

.megaAreaLink
{

    font-size: 0.9rem;

    line-height: 1.3;

    color: rgba(247, 249, 251, 0.82);

    transition:
        background-color 0.25s var(--easePremium),
        color 0.25s var(--easePremium);

}

.megaAreaLink:hover,
.megaAreaLink:focus-visible
{

    color: var(--colorWhite);

}

/* ── Header actions ── */

.headerActions
{

    display: flex;

    flex-shrink: 0;

    align-items: center;

    gap: var(--headerActionsGap);

    transition: gap var(--headerTransition);

}

.phoneChip
{

    display: inline-flex;

    align-items: center;

    gap: 0.5rem;

    padding: 0.55rem var(--headerPhonePadX);

    white-space: nowrap;

    font-size: 0.92rem;

    font-weight: 600;

    color: var(--colorWhite);

    border: 1px solid var(--colorLineDark);

    border-radius: var(--radiusPill);

    transition:
        border-color 0.25s var(--easePremium),
        background-color 0.25s var(--easePremium),
        padding var(--headerTransition);

}

.phoneChip:hover
{

    border-color: var(--colorSky);

    background-color: rgba(91, 155, 213, 0.12);

}

.phoneChipIcon
{

    width: 16px;

    height: 16px;

    fill: var(--colorSky);

}

/* The primary CTA keeps its padding at every width. Everything else
   in the header gives ground first — shrinking this is what makes a
   header look cramped rather than tidy. */

.headerCta
{

    padding: 0.62rem var(--headerCtaPadX);

    white-space: nowrap;

    font-size: 0.94rem;

}

/* ── Mobile menu toggle ── */

.mobileMenuToggle
{

    display: none;

    flex-direction: column;

    justify-content: center;

    gap: 5px;

    width: 44px;

    height: 44px;

    padding: 10px;

    background: none;

    border: none;

}

.mobileMenuToggle[aria-expanded="true"] .hamburgerLine:nth-child(1)
{

    transform: translateY(7.4px) rotate(45deg);

}

.mobileMenuToggle[aria-expanded="true"] .hamburgerLine:nth-child(2)
{

    opacity: 0;

}

.mobileMenuToggle[aria-expanded="true"] .hamburgerLine:nth-child(3)
{

    transform: translateY(-7.4px) rotate(-45deg);

}

.hamburgerLine
{

    display: block;

    width: 100%;

    height: 2.4px;

    background-color: var(--colorWhite);

    border-radius: 2px;

    transition: transform 0.3s var(--easePremium), opacity 0.3s var(--easePremium);

}

/* ============================================================
   MOBILE MENU
============================================================ */

.mobileMenu
{

    position: fixed;

    inset: 0;

    z-index: 350;

    display: flex;

    flex-direction: column;

    background-color: var(--colorNearBlack);

    opacity: 0;

    pointer-events: none;

    transform: translateX(100%);

    visibility: hidden;

    transition:
        transform 0.45s var(--easePremium),
        opacity 0.45s var(--easePremium),
        visibility 0.45s var(--easePremium);

    overflow-y: auto;

}

.mobileMenu.isOpen
{

    opacity: 1;

    pointer-events: auto;

    transform: translateX(0);

    visibility: visible;

}

.mobileMenuHeader
{

    display: flex;

    align-items: center;

    justify-content: space-between;

    padding: 1rem 1.5rem;

    border-bottom: 1px solid var(--colorLineDark);

}

.mobileMenuBrand .brandBadge
{

    width: 46px;

    height: 46px;

}

.mobileMenuClose
{

    width: 44px;

    height: 44px;

    padding: 10px;

    background: none;

    border: none;

    color: var(--colorWhite);

}

.mobileNav
{

    padding: 1rem 1.5rem 3rem;

}

.mobileAccordionToggle
{

    display: flex;

    align-items: center;

    justify-content: space-between;

    width: 100%;

    padding: 1rem 0.25rem;

    background: none;

    border: none;

    border-bottom: 1px solid var(--colorLineDark);

    font-family: var(--fontDisplay);

    font-size: 1.35rem;

    font-weight: 600;

    letter-spacing: 0.06em;

    text-transform: uppercase;

    color: var(--colorWhite);

}

.mobileAccordionToggle[aria-expanded="true"] .navChevron
{

    transform: rotate(180deg);

}

.mobileAccordionPanel
{

    max-height: 0;

    overflow: hidden;

    transition: max-height 0.45s var(--easePremium);

}

.mobileSubHeading
{

    margin: 1.1rem 0 0.3rem;

    font-size: 0.78rem;

    font-weight: 700;

    letter-spacing: 0.22em;

    text-transform: uppercase;

    color: var(--colorSky);

}

.mobileSubList
{

    margin: 0.4rem 0;

    padding: 0;

    list-style: none;

}

.mobileSubList a
{

    display: block;

    padding: 0.55rem 0.75rem;

    font-size: 1rem;

    color: rgba(247, 249, 251, 0.85);

    border-radius: 8px;

}

.mobileSubList a:hover
{

    background-color: rgba(91, 155, 213, 0.14);

}

.mobileNavList
{

    margin: 0;

    padding: 0;

    list-style: none;

}

.mobileNavList a
{

    display: block;

    padding: 1rem 0.25rem;

    border-bottom: 1px solid var(--colorLineDark);

    font-family: var(--fontDisplay);

    font-size: 1.35rem;

    font-weight: 600;

    letter-spacing: 0.06em;

    text-transform: uppercase;

    color: var(--colorWhite);

}

.mobileMenuActions
{

    display: flex;

    flex-direction: column;

    gap: 1rem;

    margin-top: 2rem;

}

.phoneChipMobile
{

    justify-content: center;

    padding: 0.9rem 1rem;

    font-size: 1.05rem;

}

/* ============================================================
   MOBILE FLOATING ACTIONS
============================================================ */

.mobileFloatingActions,
.backToTopButton
{

    display: none;

}

/* ============================================================
   HERO  (reusable "Duet Hero" engine — auto-looping Before/After
   transformation + human-typed headline; see
   docs/heroDirection/heroSpecification.md for the full direction.
   No video, no slider, no manual controls.)
============================================================ */

.heroSection
{

    position: relative;

    display: flex;

    align-items: center;

    min-height: 100svh;

    padding: calc(var(--headerHeight) + 3rem) 0 4.5rem;

    background-color: var(--colorNearBlack);

    overflow: hidden;

}

.heroMedia
{

    position: absolute;

    inset: 0;

    z-index: 0;

    animation: heroMediaDrift 22s ease-in-out infinite alternate;

}

@keyframes heroMediaDrift
{

    from
    {

        transform: scale(1);

    }

    to
    {

        transform: scale(1.015);

    }

}

/* ── The two stacked plates. BEFORE is the static base layer;
     AFTER is masked out by default and revealed by a soft,
     directional wipe (never a hard seam, never slider-like). ── */

@property --heroSweepPos
{

    syntax: '<percentage>';

    inherits: false;

    initial-value: -18%;

}

.heroPlate
{

    position: absolute;

    inset: 0;

    width: 100%;

    height: 100%;

    object-fit: cover;

    object-position: center center;

}

.heroPlateAfter
{

    --heroSweepPos: -18%;

    opacity: 1;

    -webkit-mask-image: linear-gradient(to right, black var(--heroSweepPos), transparent calc(var(--heroSweepPos) + 18%));

    mask-image: linear-gradient(to right, black var(--heroSweepPos), transparent calc(var(--heroSweepPos) + 18%));

    transition: --heroSweepPos 1400ms var(--easePremium);

}

.heroPlateAfter.isRevealed
{

    --heroSweepPos: 100%;

}

/* Reverse is a plain dissolve, never a reversed sweep — memory
   fading, not work undone. */

.heroPlateAfter.isDissolving
{

    transition: opacity 1800ms ease;

    opacity: 0;

}

.heroPlateAfter.isResetting
{

    transition: none !important;

}

.heroOverlay
{

    position: absolute;

    inset: 0;

    background:
        linear-gradient(
            100deg,
            rgba(10, 11, 12, 0.68) 0%,
            rgba(10, 11, 12, 0.44) 20%,
            rgba(16, 18, 20, 0.18) 40%,
            rgba(16, 18, 20, 0) 58%
        ),
        linear-gradient(
            180deg,
            rgba(16, 18, 20, 0.35) 0%,
            rgba(16, 18, 20, 0) 30%,
            rgba(16, 18, 20, 0) 70%,
            rgba(16, 18, 20, 0.45) 100%
        );

}

.heroTopoAccent
{

    position: absolute;

    right: -140px;

    bottom: -180px;

    width: 560px;

    height: 560px;

    stroke: rgba(91, 155, 213, 0.20);

    stroke-width: 1.4;

}

/* ── Reduced-motion "Before" inset — hidden by default, shown
     only via the reduced-motion media query below. ── */

.heroReducedInset
{

    display: none;

}

/* ── Hero layout ── */

.heroInner
{

    position: relative;

    z-index: 1;

    display: grid;

    grid-template-columns: 1.15fr 0.85fr;

    align-items: center;

    gap: 3.5rem;

    width: 100%;

    max-width: 1280px;

    margin: 0 auto;

    padding: 0 1.5rem;

}

.heroContent
{

    position: relative;

    background: transparent;

}

.heroKicker
{

    margin: 0 0 1.1rem;

    font-family: var(--fontDisplay);

    font-size: 1.02rem;

    font-weight: 600;

    letter-spacing: 0.26em;

    text-transform: uppercase;

    color: var(--colorSkyLight);

    text-shadow: 0 1px 14px rgba(0, 0, 0, 0.6);

}

.heroHeadline
{

    display: block;

    margin: 0 0 1.4rem;

}

/* The coordinated hero sequence animates the headline as one unit,
   keeping the permanent hook, typed line, and cursor synchronized. */

.heroHeadlineFixed
{

    display: block;

    font-family: var(--fontDisplay);

    font-size: clamp(3.2rem, 6.8vw, 5.6rem);

    font-weight: 700;

    line-height: 0.96;

    letter-spacing: 0.01em;

    text-transform: uppercase;

    color: var(--colorWhite);

    text-shadow: 0 3px 30px rgba(0, 0, 0, 0.65), 0 1px 3px rgba(0, 0, 0, 0.5);

}

.heroAccent
{

    color: var(--colorSky);

}

/* ── Typed line — reserved to the longest phrase via an
     invisible ghost, so no phrase ever shifts the layout. ── */

.heroTypedWrap
{

    display: inline-grid;

    vertical-align: top;

}

.heroTypedGhost,
.heroTypedLine
{

    grid-area: 1 / 1;

}

.heroTypedGhost,
.heroTypedText
{

    font-family: var(--fontDisplay);

    font-size: clamp(2.6rem, 5.6vw, 4.6rem);

    font-weight: 500;

    line-height: 0.96;

    letter-spacing: 0.01em;

    color: var(--colorSky);

    text-shadow: 0 3px 24px rgba(0, 0, 0, 0.55);

}

.heroTypedGhost
{

    visibility: hidden;

    white-space: nowrap;

}

/* The typed line holds its own compositing layer for the life of the
   loop, and this is the single largest saving in the hero.

   Without it the layer belongs to .heroHeadline, borrowed from the
   [data-heroanimate] entrance — and indexJS.js strips that attribute
   at t=2200ms, roughly the sixteenth character of the first phrase.
   From that moment the typed line paints into the same layer as the
   hero photograph and the overlay gradient, so every keystroke
   re-rasters ten 256px tiles of photograph: 655k pixels a character,
   8.0 megapixels a second at the measured cadence, for a change that
   only ever touches the glyphs. Promoting the line confines the
   raster to the text and its shadow and leaves the photograph to the
   compositor, and it also removes the layer teardown that currently
   lands mid-phrase.

   Held here rather than on .heroHeadline so the layer is the typed
   line's ~926x125 box and not the whole headline. */

.heroTypedLine
{

    display: flex;

    align-items: baseline;

    white-space: nowrap;

    will-change: transform;

}

.heroCursor
{

    width: 3px;

    height: 0.86em;

    margin-left: 3px;

    background-color: var(--colorSky);

    box-shadow: 0 0 8px rgba(91, 155, 213, 0.6);

    opacity: 0;

    transition: opacity 200ms ease;

    animation: heroCursorBlink 1s ease-in-out infinite;

}

.heroCursor.isVisible
{

    opacity: 1;

}

.heroCursor.isSolid
{

    animation: none;

    opacity: 1;

}

.heroCursor.isPaused
{

    animation: none;

    opacity: 1;

}

@keyframes heroCursorBlink
{

    0%
    {

        opacity: 1;

    }

    40%
    {

        opacity: 1;

    }

    55%
    {

        opacity: 0;

    }

    85%
    {

        opacity: 0;

    }

    100%
    {

        opacity: 1;

    }

}

.heroCopy
{

    max-width: 520px;

    margin: 0 0 2rem;

    font-size: 1.12rem;

    line-height: 1.7;

    color: rgba(247, 249, 251, 0.92);

    text-shadow: 0 1px 16px rgba(0, 0, 0, 0.7);

}

.heroActions
{

    display: flex;

    flex-wrap: wrap;

    gap: 1rem;

    margin-bottom: 2.6rem;

}

.heroStats
{

    display: flex;

    gap: 2.6rem;

    margin: 0;

}

.heroStat dt
{

    order: 2;

    font-size: 0.78rem;

    font-weight: 600;

    letter-spacing: 0.14em;

    text-transform: uppercase;

    color: rgba(247, 249, 251, 0.68);

    text-shadow: 0 1px 10px rgba(0, 0, 0, 0.6);

}

.heroStat dd
{

    order: 1;

    margin: 0 0 0.3rem;

}

.heroStat
{

    display: flex;

    flex-direction: column;

}

.statNumber
{

    font-family: var(--fontDisplay);

    font-size: 2.3rem;

    font-weight: 700;

    color: var(--colorWhite);

}

/* ============================================================
   ESTIMATE FORM CARD  (hero mini-form)
============================================================ */

.estimateFormCard
{

    position: relative;

    align-self: end;

    max-width: 424px;

    padding: 1.4rem 1.3rem;

    background-color: rgba(21, 24, 27, 0.92);

    border: 1px solid rgba(247, 249, 251, 0.14);

    border-top: 1px solid rgba(247, 249, 251, 0.24);

    border-radius: 16px;

    box-shadow: 0 22px 56px rgba(0, 0, 0, 0.4);

    backdrop-filter: blur(10px);

    -webkit-backdrop-filter: blur(10px);

}

.estimateFormHeading
{

    margin: 0 0 0.3rem;

    font-family: var(--fontDisplay);

    font-size: 1.9rem;

    font-weight: 700;

    line-height: 1.08;

    letter-spacing: 0.02em;

    text-transform: none;

    color: var(--colorWhite);

}

.estimateHeadingLine
{

    display: block;

    white-space: nowrap;

}

.estimateFormSubline
{

    margin: 0 0 0.85rem;

    font-size: 0.92rem;

    color: rgba(247, 249, 251, 0.65);

}

.miniFormTrustLine
{

    margin: 0.55rem 0 0;

    font-size: 0.8rem;

    text-align: center;

    letter-spacing: 0.04em;

    color: rgba(247, 249, 251, 0.55);

}

/* Hero card only — the shared .formField/.formLabel/.formInput/
   .formSubmitButton rules also serve the estimate modal, which
   stays untouched. */

.estimateFormCard .formField
{

    margin-bottom: 0.7rem;

}

.estimateFormCard .formLabel
{

    margin-bottom: 0.3rem;

}

.estimateFormCard .formInput
{

    padding: 0.56rem 0.75rem;

}

.estimateFormCard .formSubmitButton
{

    padding-top: 0.6rem;

    padding-bottom: 0.6rem;

}

.continueArrow
{

    width: 17px;

    height: 17px;

}

/* ============================================================
   FORM SYSTEM  (reusable fields — shared by card + modal)
============================================================ */

.formField
{

    margin-bottom: 0.95rem;

    border: none;

    padding: 0;

}

.formLabel
{

    display: block;

    margin-bottom: 0.35rem;

    font-size: 0.82rem;

    font-weight: 600;

    letter-spacing: 0.09em;

    text-transform: uppercase;

    color: rgba(247, 249, 251, 0.75);

}

.formOptionalTag
{

    font-weight: 400;

    letter-spacing: 0.02em;

    text-transform: none;

    color: rgba(247, 249, 251, 0.45);

}

.formInput
{

    width: 100%;

    padding: 0.78rem 0.95rem;

    background-color: rgba(16, 18, 20, 0.65);

    border: 1px solid rgba(247, 249, 251, 0.18);

    border-radius: 9px;

    font-family: var(--fontBody);

    font-size: 1rem;

    color: var(--colorWhite);

    transition: border-color 0.25s var(--easePremium), box-shadow 0.25s var(--easePremium);

}

.formInput::placeholder
{

    color: rgba(247, 249, 251, 0.35);

}

.formInput:focus
{

    outline: none;

    border-color: var(--colorSky);

    box-shadow: 0 0 0 3px rgba(91, 155, 213, 0.25);

}

.formInput.hasError
{

    border-color: var(--colorDanger);

}

.formSelect
{

    appearance: none;

    background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 L6 6.5 L11 1.5' fill='none' stroke='%237C8894' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");

    background-repeat: no-repeat;

    background-position: right 0.9rem center;

    background-size: 12px;

    padding-right: 2.4rem;

}

.formTextarea
{

    resize: vertical;

    min-height: 110px;

}

.fieldError
{

    margin: 0.35rem 0 0;

    font-size: 0.8rem;

    color: var(--colorDanger);

}

.formError
{

    margin: 0.9rem 0 0;

    font-size: 0.88rem;

    text-align: center;

    color: var(--colorDanger);

}

/* ── Segmented pills ── */

.segmentedControl
{

    display: flex;

    gap: 0.5rem;

}

.segmentedPill
{

    flex: 1;

}

.segmentedPill input
{

    position: absolute;

    opacity: 0;

    pointer-events: none;

}

.segmentedPill span
{

    display: block;

    padding: 0.6rem 0.4rem;

    text-align: center;

    font-size: 0.88rem;

    font-weight: 600;

    color: rgba(247, 249, 251, 0.7);

    background-color: rgba(16, 18, 20, 0.65);

    border: 1px solid rgba(247, 249, 251, 0.18);

    border-radius: 9px;

    cursor: pointer;

    transition:
        background-color 0.25s var(--easePremium),
        border-color 0.25s var(--easePremium),
        color 0.25s var(--easePremium);

}

.segmentedPill input:checked + span
{

    background-color: rgba(91, 155, 213, 0.22);

    border-color: var(--colorSky);

    color: var(--colorWhite);

}

.segmentedPill input:focus-visible + span
{

    outline: 3px solid var(--colorSky);

    outline-offset: 2px;

}

/* ── Submit button + spinner ── */

.formSubmitButton
{

    width: 100%;

    position: relative;

}

.submitSpinner
{

    display: none;

    width: 18px;

    height: 18px;

    border: 2.5px solid rgba(16, 18, 20, 0.3);

    border-top-color: var(--colorNearBlack);

    border-radius: 50%;

    animation: spinnerTurn 0.8s linear infinite;

}

.formSubmitButton.isLoading .submitSpinner
{

    display: inline-block;

}

.formSubmitButton.isLoading
{

    pointer-events: none;

    opacity: 0.85;

}

@keyframes spinnerTurn
{

    to
    {

        transform: rotate(360deg);

    }

}

/* ============================================================
   ESTIMATE MODAL  (reusable multi-step conversational modal)
============================================================ */

.estimateModal
{

    position: fixed;

    inset: 0;

    z-index: 500;

    display: flex;

    align-items: center;

    justify-content: center;

    padding: 1.25rem;

}

.estimateModal[hidden]
{

    display: none;

}

.estimateModalBackdrop
{

    position: absolute;

    inset: 0;

    background-color: rgba(10, 11, 12, 0.82);

    backdrop-filter: blur(6px);

}

.estimateModalShell
{

    position: relative;

    z-index: 1;

    width: 100%;

    max-width: 620px;

    max-height: calc(100vh - 2.5rem);

    display: flex;

    flex-direction: column;

    background-color: var(--colorCharcoal);

    border: 1px solid rgba(247, 249, 251, 0.12);

    border-radius: 18px;

    box-shadow: 0 50px 120px rgba(0, 0, 0, 0.6);

    overflow: hidden;

    animation: modalRise 0.45s var(--easePremium);

}

@keyframes modalRise
{

    from
    {

        opacity: 0;

        transform: translateY(34px) scale(0.97);

    }

    to
    {

        opacity: 1;

        transform: translateY(0) scale(1);

    }

}

.estimateModalHeader
{

    position: relative;

    padding: 1.5rem 1.75rem 1.1rem;

    border-bottom: 1px solid rgba(247, 249, 251, 0.1);

}

.estimateModalHeading
{

    margin: 0;

    font-family: var(--fontDisplay);

    font-size: 1.7rem;

    font-weight: 700;

    letter-spacing: 0.02em;

    text-transform: uppercase;

    color: var(--colorWhite);

}

.estimateModalStepLabel
{

    margin: 0.2rem 0 0;

    font-size: 0.82rem;

    letter-spacing: 0.1em;

    text-transform: uppercase;

    color: var(--colorSky);

}

.estimateModalClose
{

    position: absolute;

    top: 1.1rem;

    right: 1.1rem;

    width: 42px;

    height: 42px;

    padding: 10px;

    background: none;

    border: none;

    color: rgba(247, 249, 251, 0.7);

    border-radius: 10px;

    transition: color 0.25s var(--easePremium), background-color 0.25s var(--easePremium);

}

.estimateModalClose:hover
{

    color: var(--colorWhite);

    background-color: rgba(247, 249, 251, 0.08);

}

.estimateModalProgress
{

    height: 4px;

    margin-top: 1.1rem;

    background-color: rgba(247, 249, 251, 0.1);

    border-radius: 999px;

    overflow: hidden;

}

.estimateModalProgressFill
{

    width: 20%;

    height: 100%;

    background-color: var(--colorSky);

    border-radius: 999px;

    transition: width 0.5s var(--easePremium);

}

.estimateModalForm
{

    display: flex;

    flex-direction: column;

    flex: 1;

    min-height: 0;

}

.modalStep
{

    flex: 1;

    padding: 1.6rem 1.75rem;

    overflow-y: auto;

    animation: stepFade 0.4s var(--easePremium);

}

@keyframes stepFade
{

    from
    {

        opacity: 0;

        transform: translateX(22px);

    }

    to
    {

        opacity: 1;

        transform: translateX(0);

    }

}

.modalStepHeading
{

    margin: 0 0 1.2rem;

    font-family: var(--fontDisplay);

    font-size: 1.45rem;

    font-weight: 600;

    letter-spacing: 0.02em;

    color: var(--colorWhite);

}

.estimateModalFooter
{

    display: flex;

    flex-wrap: wrap;

    align-items: center;

    gap: 0.8rem;

    padding: 1.1rem 1.75rem 1.4rem;

    border-top: 1px solid rgba(247, 249, 251, 0.1);

}

.modalBackButton
{

    padding: 0.75rem 1.3rem;

}

.modalNextButton,
.estimateModalFooter .formSubmitButton
{

    flex: 1;

    width: auto;

}

/* ── Review summary ── */

.reviewSummaryList
{

    margin: 0;

}

.reviewSummaryItem
{

    display: flex;

    align-items: baseline;

    justify-content: space-between;

    gap: 1rem;

    padding: 0.7rem 0;

    border-bottom: 1px solid rgba(247, 249, 251, 0.08);

}

.reviewSummaryItem dt
{

    flex-shrink: 0;

    font-size: 0.78rem;

    font-weight: 600;

    letter-spacing: 0.1em;

    text-transform: uppercase;

    color: rgba(247, 249, 251, 0.55);

}

.reviewSummaryItem dd
{

    margin: 0;

    text-align: right;

    font-size: 0.95rem;

    color: var(--colorWhite);

    overflow-wrap: anywhere;

}

.reviewEditButton
{

    margin-left: 0.6rem;

    padding: 0.1rem 0.5rem;

    background: none;

    border: none;

    font-size: 0.8rem;

    font-weight: 600;

    color: var(--colorSky);

    text-decoration: underline;

}

/* ── Success panel ── */

.formSuccessPanel
{

    padding: 3rem 1.75rem;

    text-align: center;

    color: var(--colorSky);

    animation: stepFade 0.5s var(--easePremium);

}

.successIcon
{

    width: 64px;

    height: 64px;

    margin: 0 auto 1.1rem;

}

.successHeading
{

    margin: 0 0 0.5rem;

    font-family: var(--fontDisplay);

    font-size: 1.9rem;

    font-weight: 700;

    text-transform: uppercase;

    color: var(--colorWhite);

}

.successCopy
{

    margin: 0 auto 1.6rem;

    max-width: 360px;

    color: rgba(247, 249, 251, 0.72);

}

.successActions
{

    display: flex;

    flex-wrap: wrap;

    align-items: center;

    justify-content: center;

    gap: 0.9rem;

}

/* ============================================================
   PHOTO UPLOADER  (reusable drag-and-drop system)
============================================================ */

.photoDropzone
{

    display: flex;

    flex-direction: column;

    align-items: center;

    gap: 0.5rem;

    padding: 1.9rem 1rem;

    background-color: rgba(16, 18, 20, 0.45);

    border: 2px dashed rgba(247, 249, 251, 0.28);

    border-radius: 12px;

    text-align: center;

    transition: border-color 0.25s var(--easePremium), background-color 0.25s var(--easePremium);

}

.photoDropzone.isDragOver
{

    border-color: var(--colorSky);

    background-color: rgba(91, 155, 213, 0.12);

}

.dropzoneIcon
{

    width: 30px;

    height: 30px;

    color: var(--colorSky);

}

.dropzoneCopy
{

    margin: 0;

    font-size: 0.94rem;

    color: rgba(247, 249, 251, 0.75);

}

.dropzoneBrowseButton
{

    padding: 0;

    background: none;

    border: none;

    font-size: 0.94rem;

    font-weight: 700;

    color: var(--colorSky);

    text-decoration: underline;

}

.photoHelperCopy
{

    margin: 0.7rem 0 0;

    font-size: 0.82rem;

    color: rgba(247, 249, 251, 0.55);

}

/* Why a photo was not added — file too large, wrong type, too many.
   Sits above the thumbnails so it is the first thing read after a
   selection, and stays a single quiet line rather than an alert. */

.photoUploadNotice
{

    margin: 0.8rem 0 0;

    padding: 0.6rem 0.8rem;

    font-size: 0.82rem;

    line-height: 1.5;

    color: var(--colorWhite);

    background-color: rgba(217, 106, 91, 0.14);

    border-left: 3px solid var(--colorDanger);

    border-radius: 6px;

}

.photoPreviewGrid
{

    display: grid;

    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));

    gap: 0.8rem;

    margin: 1rem 0 0;

    padding: 0;

    list-style: none;

}

.photoPreviewItem
{

    position: relative;

    border-radius: 10px;

    overflow: hidden;

    background-color: rgba(16, 18, 20, 0.6);

    border: 1px solid rgba(247, 249, 251, 0.12);

}

.photoPreviewItem img
{

    width: 100%;

    aspect-ratio: 4 / 3;

    object-fit: cover;

}

.photoPreviewMeta
{

    display: block;

    padding: 0.4rem 0.5rem 0.5rem;

    font-size: 0.7rem;

    line-height: 1.35;

    color: rgba(247, 249, 251, 0.7);

    overflow-wrap: anywhere;

}

.photoProgressBar
{

    height: 4px;

    background-color: rgba(247, 249, 251, 0.12);

}

.photoProgressFill
{

    width: 0%;

    height: 100%;

    background-color: var(--colorSky);

    transition: width 0.2s linear;

}

.photoRemoveButton
{

    position: absolute;

    top: 6px;

    right: 6px;

    width: 26px;

    height: 26px;

    display: flex;

    align-items: center;

    justify-content: center;

    background-color: rgba(16, 18, 20, 0.8);

    border: none;

    border-radius: 50%;

    color: var(--colorWhite);

    font-size: 0.9rem;

    line-height: 1;

}

.photoRemoveButton:hover
{

    background-color: var(--colorDanger);

}

/* ============================================================
   TRUST BAR
============================================================ */

.trustBar
{

    background-color: var(--colorOffWhite);

    border-bottom: 1px solid var(--colorLineLight);

}

.trustList
{

    display: flex;

    flex-wrap: wrap;

    justify-content: center;

    gap: 1rem 3rem;

    max-width: var(--maxWidth);

    margin: 0 auto;

    padding: 1.6rem 1.5rem;

    list-style: none;

}

.trustItem
{

    display: flex;

    align-items: center;

    gap: 0.6rem;

    font-size: 0.9rem;

    font-weight: 600;

    letter-spacing: 0.04em;

    color: var(--colorInk);

}

.trustIcon
{

    width: 20px;

    height: 20px;

    color: var(--colorSkyDeep);

}

/* ============================================================
   SECTION DIVIDERS  (custom — never plain lines)
============================================================ */

/* Dividers ARE the transition: each one is a gradient band that blends
   the two neighboring section colors, with artwork faded almost to
   texture. Nothing reads as a line sitting on top of the page. */

.sectionDivider
{

    position: relative;

    height: 130px;

    line-height: 0;

    overflow: hidden;

}

.sectionDivider svg
{

    position: absolute;

    inset: 0;

    width: 100%;

    height: 100%;

}

/* ── Contour fade: light → dark (into a dark section) ── */

.dividerTopo
{

    background: linear-gradient(180deg, var(--colorOffWhite) 0%, #4A5259 55%, var(--colorCharcoal) 100%);

}

.dividerTopo path
{

    stroke: rgba(91, 155, 213, 0.12);

    stroke-width: 1;

}

/* ── Contour fade: dark → light (leaving a dark section) ── */

.dividerFadeUp
{

    background: linear-gradient(180deg, var(--colorCharcoal) 0%, #9AA4AD 60%, var(--colorOffWhite) 100%);

}

.dividerFadeUp path
{

    stroke: rgba(91, 155, 213, 0.10);

}

.dividerTopoOnDark
{

    background: linear-gradient(180deg, var(--colorOffWhite) 0%, #4A5259 55%, var(--colorCharcoal) 100%);

}

.dividerTopoOnDark path
{

    stroke: rgba(91, 155, 213, 0.10);

    stroke-width: 1;

}

/* ── Tread fade: light → dark, dashes barely surfacing ── */

.dividerTread
{

    background: linear-gradient(180deg, var(--colorOffWhite) 0%, #4A5259 55%, var(--colorCharcoal) 100%);

}

.treadLineHeavy
{

    stroke: rgba(124, 136, 148, 0.14);

    stroke-width: 8;

    stroke-dasharray: 22 16;

}

.treadLineLight
{

    stroke: transparent;

}

/* ── Tree rings: whisper texture between two light sections ── */

.dividerRings
{

    height: 100px;

    background: linear-gradient(180deg, var(--colorOffWhite) 0%, var(--colorWhite) 100%);

}

.dividerRings circle
{

    stroke: rgba(124, 136, 148, 0.09);

    stroke-width: 1.2;

}

/* ============================================================
   SERVICES SECTION
============================================================ */

.servicesSection
{

    background-color: var(--colorOffWhite);

}

.servicesGrid
{

    display: grid;

    grid-template-columns: repeat(3, 1fr);

    gap: 1.6rem;

}

.serviceCard
{

    display: flex;

    flex-direction: column;

    background-color: var(--colorWhite);

    border: 1px solid var(--colorLineLight);

    border-radius: var(--radiusCard);

    overflow: hidden;

    box-shadow: 0 8px 24px rgba(16, 18, 20, 0.07);

    transition: transform 0.35s var(--easePremium), box-shadow 0.35s var(--easePremium);

}

.serviceCard:hover
{

    transform: translateY(-6px);

    box-shadow: var(--shadowCardHover);

}

.serviceCardMedia
{

    aspect-ratio: 3 / 2;

    overflow: hidden;

}

.serviceCardMedia img
{

    width: 100%;

    height: 100%;

    object-fit: cover;

    transition: transform 1.4s var(--easePremium);

}

.servicesGrid .serviceCard:last-child .serviceCardMedia img
{

    object-position: center 42%;

}

.serviceCard:hover .serviceCardMedia img
{

    transform: scale(1.07);

}

/* ── Seventh card becomes a full-width feature row ── */

.servicesGrid .serviceCard:last-child
{

    grid-column: 1 / -1;

    flex-direction: row;

}

.servicesGrid .serviceCard:last-child .serviceCardMedia
{

    width: 42%;

    flex-shrink: 0;

    aspect-ratio: auto;

}

.servicesGrid .serviceCard:last-child .serviceCardBody
{

    justify-content: center;

}

.serviceCardBody
{

    display: flex;

    flex-direction: column;

    flex: 1;

    gap: 0.6rem;

    padding: 1.4rem 1.5rem 1.6rem;

}

.serviceCardTitle
{

    margin: 0;

    font-family: var(--fontDisplay);

    font-size: 1.5rem;

    font-weight: 700;

    letter-spacing: 0.02em;

    text-transform: uppercase;

    color: var(--colorCharcoal);

}

.serviceCardCopy
{

    margin: 0;

    flex: 1;

    font-size: 0.95rem;

    color: var(--colorSteel);

}

.serviceCardLink
{

    display: inline-flex;

    align-items: center;

    gap: 0.4rem;

    font-size: 0.9rem;

    font-weight: 700;

    letter-spacing: 0.05em;

    text-transform: uppercase;

    color: var(--colorSkyDeep);

    transition: gap 0.3s var(--easePremium), color 0.3s var(--easePremium);

}

.serviceCardLink:hover
{

    gap: 0.75rem;

    color: var(--colorSky);

}

/* ============================================================
   BEFORE / AFTER — TRANSFORMATION STORIES
============================================================ */

.comparisonSlider
{

    position: relative;

    aspect-ratio: 16 / 9;

    max-height: 640px;

    border-radius: var(--radiusCard);

    overflow: hidden;

    box-shadow: 0 30px 70px rgba(0, 0, 0, 0.4);

    touch-action: none;

    --sliderPos: 50%;

}

.comparisonPane
{

    position: absolute;

    inset: 0;

}

.comparisonPane img
{

    width: 100%;

    height: 100%;

    object-fit: cover;

}

.comparisonAfter
{

    clip-path: inset(0 0 0 var(--sliderPos));

}

.comparisonTag
{

    position: absolute;

    top: 1.1rem;

    padding: 0.35rem 0.9rem;

    font-size: 0.78rem;

    font-weight: 700;

    letter-spacing: 0.14em;

    text-transform: uppercase;

    border-radius: var(--radiusPill);

}

.comparisonTagBefore
{

    left: 1.1rem;

    background-color: rgba(16, 18, 20, 0.78);

    color: var(--colorWhite);

}

.comparisonTagAfter
{

    right: 1.1rem;

    background-color: var(--colorSky);

    color: var(--colorNearBlack);

}

.comparisonHandle
{

    position: absolute;

    top: 0;

    bottom: 0;

    left: var(--sliderPos);

    z-index: 2;

    width: 0;

    cursor: ew-resize;

}

.comparisonHandleLine
{

    position: absolute;

    top: 0;

    bottom: 0;

    left: -1.5px;

    width: 3px;

    background-color: var(--colorWhite);

    box-shadow: 0 0 18px rgba(0, 0, 0, 0.45);

}

.comparisonHandleGrip
{

    position: absolute;

    top: 50%;

    left: 0;

    display: flex;

    align-items: center;

    justify-content: center;

    width: 52px;

    height: 52px;

    background-color: var(--colorWhite);

    border-radius: 50%;

    color: var(--colorCharcoal);

    box-shadow: 0 8px 26px rgba(0, 0, 0, 0.45);

    transform: translate(-50%, -50%);

}

.comparisonHandleGrip svg
{

    width: 22px;

    height: 22px;

}

/* ── Story cards ── */

.transformationStories
{

    display: grid;

    grid-template-columns: repeat(3, 1fr);

    gap: 1.6rem;

    margin-top: 2.4rem;

}

.storyCard
{

    display: flex;

    flex-direction: column;

    background-color: rgba(247, 249, 251, 0.04);

    border: 1px solid var(--colorLineDark);

    border-radius: var(--radiusCard);

    overflow: hidden;

    transition: transform 0.35s var(--easePremium), border-color 0.35s var(--easePremium);

}

.storyCard:hover
{

    transform: translateY(-5px);

    border-color: rgba(91, 155, 213, 0.5);

}

.storyMedia
{

    position: relative;

    display: flex;

    gap: 3px;

}

.storyFrame
{

    position: relative;

    flex: 1;

    margin: 0;

    aspect-ratio: 4 / 3;

    overflow: hidden;

}

.storyFrameWide
{

    aspect-ratio: 8 / 3;

}

.storyFrame img
{

    width: 100%;

    height: 100%;

    object-fit: cover;

}

.storyFrame .comparisonTag
{

    top: 0.7rem;

    font-size: 0.66rem;

    padding: 0.25rem 0.65rem;

}

.storyFrame .comparisonTagBefore
{

    left: 0.7rem;

}

.storyFrame .comparisonTagAfter
{

    right: 0.7rem;

}

.storyArrow
{

    position: absolute;

    top: 50%;

    left: 50%;

    z-index: 2;

    display: flex;

    align-items: center;

    justify-content: center;

    width: 38px;

    height: 38px;

    background-color: var(--colorSky);

    border-radius: 50%;

    color: var(--colorNearBlack);

    transform: translate(-50%, -50%);

    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);

}

.storyArrow svg
{

    width: 16px;

    height: 16px;

}

.storyBody
{

    padding: 1.2rem 1.3rem 1.4rem;

}

.storyGoal
{

    margin: 0 0 0.5rem;

    font-size: 0.86rem;

    font-weight: 700;

    letter-spacing: 0.05em;

    text-transform: uppercase;

    color: var(--colorSky);

}

.storyCopy
{

    margin: 0;

    font-size: 0.93rem;

    color: rgba(247, 249, 251, 0.72);

}

/* ============================================================
   WHY CHOOSE US SECTION
============================================================ */

.whySection
{

    background-color: var(--colorOffWhite);

}

.whySplit
{

    display: grid;

    grid-template-columns: 0.95fr 1.05fr;

    gap: 3.5rem;

    align-items: center;

}

.whyMedia
{

    position: relative;

    border-radius: var(--radiusCard);

    overflow: hidden;

    box-shadow: var(--shadowCard);

}

.whyMedia img
{

    width: 100%;

    height: 100%;

    object-fit: cover;

}

.whyMediaBadge
{

    position: absolute;

    left: 1.2rem;

    bottom: 1.2rem;

    display: flex;

    flex-direction: column;

    padding: 0.75rem 1.1rem;

    background-color: rgba(16, 18, 20, 0.85);

    border-left: 3px solid var(--colorSky);

    border-radius: 8px;

    backdrop-filter: blur(6px);

}

.whyMediaBadgeTitle
{

    font-family: var(--fontDisplay);

    font-size: 1.1rem;

    font-weight: 700;

    letter-spacing: 0.05em;

    text-transform: uppercase;

    color: var(--colorWhite);

}

.whyMediaBadgeSub
{

    font-size: 0.78rem;

    letter-spacing: 0.08em;

    color: var(--colorSky);

}

.whyList
{

    margin: 1.6rem 0 0;

    padding: 0;

    list-style: none;

}

.whyItem
{

    padding: 1.1rem 0;

    border-bottom: 1px solid var(--colorLineLight);

}

.whyItem:last-child
{

    border-bottom: none;

}

.whyItemTitle
{

    margin: 0 0 0.35rem;

    font-family: var(--fontDisplay);

    font-size: 1.35rem;

    font-weight: 700;

    letter-spacing: 0.02em;

    color: var(--colorCharcoal);

}

.whyItemCopy
{

    margin: 0;

    font-size: 0.96rem;

    color: var(--colorSteel);

}

.whyStats
{

    display: flex;

    gap: 2.6rem;

    margin: 2rem 0 0;

}

.whyStat
{

    display: flex;

    flex-direction: column;

}

.whyStat .statNumber
{

    color: var(--colorCharcoal);

}

.whyStat dt
{

    font-size: 0.76rem;

    font-weight: 600;

    letter-spacing: 0.13em;

    text-transform: uppercase;

    color: var(--colorSteel);

}

.whyStat dd
{

    margin: 0;

}

/* ============================================================
   PROCESS SECTION
============================================================ */

.processSection
{

    background-color: var(--colorWhite);

}

/* ── The board ──
   A dark rectangle floating on the white section, holding the whole
   progression. Centred and capped so it reads as one object rather
   than a full-bleed band; the heading stays outside it on the white,
   and the CTA sits below it. */

.processBoard
{

    max-width: 1120px;

    margin: 0 auto;

    padding: 2.6rem 2.2rem;

    background-image: linear-gradient(158deg, var(--colorCharcoal) 0%, var(--colorNearBlack) 100%);

    border: 1px solid var(--colorLineDark);

    border-radius: var(--radiusCard);

    box-shadow: 0 28px 70px rgba(16, 18, 20, 0.3);

}

/* Flex rather than a fixed grid template on purpose: the homepage runs
   five steps and the service pages four, and arrows are interleaved
   between them, so the column count is not knowable from CSS. Steps
   share the row evenly; arrows take only what they need. */

.processSteps
{

    display: flex;

    align-items: flex-start;

    gap: 0.9rem;

    margin: 0;

    padding: 0;

    list-style: none;

}

.processStep
{

    flex: 1 1 0;

    min-width: 0;

    text-align: center;

    padding: 0 0.3rem;

}

.processStepNumber
{

    display: flex;

    align-items: center;

    justify-content: center;

    width: 48px;

    height: 48px;

    margin: 0 auto 1rem;

    background-color: rgba(91, 155, 213, 0.1);

    border: 2px solid var(--colorSky);

    border-radius: 50%;

    font-family: var(--fontDisplay);

    font-size: 1.3rem;

    font-weight: 700;

    color: var(--colorSky);

}

.processStepIcon
{

    width: 26px;

    height: 26px;

    margin: 0 auto 0.6rem;

    color: var(--colorSky);

}

.processStepTitle
{

    /* The step column is narrow by design and the face is uppercase
       display, so a long word is the one thing that could reach past
       the column. .processStep is min-width: 0, meaning it would spill
       rather than widen the board — this breaks it instead. */

    overflow-wrap: break-word;

    margin: 0 0 0.4rem;

    font-family: var(--fontDisplay);

    font-size: 1.2rem;

    font-weight: 700;

    letter-spacing: 0.03em;

    text-transform: uppercase;

    color: var(--colorWhite);

}

.processStepCopy
{

    margin: 0;

    font-size: 0.88rem;

    color: rgba(247, 249, 251, 0.62);

}

/* ── Arrowheads ──
   Chevrons only, no connecting rule. Nudged down so they sit on the
   centre line of the numbered discs, which is what makes them read as
   movement between the nodes rather than decoration floating above
   the copy. */

.processArrow
{

    /* The arrow's direction is a token, not a repeated declaration.
       Every state below composes rotate(var(--processArrowTurn)) with
       its own scale, so the vertical layout sets this once and nothing
       else — including the reduced-motion reset — can accidentally
       straighten an arrow that should be pointing down. */

    --processArrowTurn: 0deg;

    flex: 0 0 auto;

    display: flex;

    align-items: center;

    justify-content: center;

    margin-top: 1.05rem;

    color: var(--colorSky);

    /* Resting is also the no-JS and reduced-motion state, so the
       progression is legible even if the sequencer never runs. */

    opacity: 0.26;

    transform: rotate(var(--processArrowTurn));

    transition:
        opacity 260ms var(--easePremium),
        transform 260ms var(--easePremium),
        filter 260ms var(--easePremium);

}

.processArrowIcon
{

    width: 16px;

    height: 16px;

}

.processCta
{

    margin-top: 2.2rem;

    text-align: center;

}

/* ============================================================
   PROCESS SEQUENCE  (reusable Nulo Studio system)

   The step-by-step reveal. Everything here is opacity, transform and
   filter — nothing in this block can trigger layout, and every element
   holds its space from the first paint, so the board never resizes and
   no column collapses as the story plays.

   Gated on html.jsEnabled: with no JavaScript the steps are simply
   visible and the arrows sit at their resting opacity, which is the
   whole progression, just without the telling.
============================================================ */

html.jsEnabled .processStep
{

    opacity: 0;

    transform: translate3d(0, 12px, 0) scale(0.985);

    transition:
        opacity 480ms var(--easePremium),
        transform 480ms var(--easePremium);

}

html.jsEnabled .processStep.isRevealed
{

    opacity: 1;

    transform: none;

}

html.jsEnabled .processArrow
{

    opacity: 0;

    transform: rotate(var(--processArrowTurn)) scale(0.86);

}

/* Active: the flash. Brighter than resting, a restrained glow, and a
   small scale — no bounce, no travel.

   isActive and isResting carry equal specificity, so an arrow holding
   both would render as whichever is declared later — isResting. They
   are mutually exclusive, and exactly two functions in indexJS.js
   guarantee it — flashArrow() for Phase A and lightArrow() for Phase B
   — both removing one class before adding the other.

   Phase B lights arrows that are already resting and leaves them lit,
   accumulating until all four are active, so a missing removal there
   would show up as a row that never brightens at all. */

html.jsEnabled .processArrow.isActive
{

    opacity: 1;

    transform: rotate(var(--processArrowTurn)) scale(1.12);

    filter: drop-shadow(0 0 7px rgba(91, 155, 213, 0.7));

    transition-duration: 380ms;

}

html.jsEnabled .processArrow.isResting
{

    opacity: 0.26;

    transform: rotate(var(--processArrowTurn));

    filter: none;

}

/* ============================================================
   OWNER INTRODUCTION SECTION  (video-ready)
============================================================ */

.introSection
{

    overflow: hidden;

}

.introLayout
{

    display: grid;

    grid-template-columns: 1.15fr 1fr;

    gap: 2.8rem;

    align-items: start;

}

/* ── Video frame ── */

.introMediaFrame
{

    position: relative;

    border: 1px solid var(--colorLineDark);

    border-radius: var(--radiusCard);

    background-color: var(--colorNearBlack);

    box-shadow: var(--shadowCard);

    overflow: hidden;

}

/* The slot owns the 16:9 ratio, so an <iframe> or <video> injected
   later needs no styling of its own. */

.introMediaSlot
{

    position: relative;

    width: 100%;

    aspect-ratio: 16 / 9;

}

.introMediaSlot iframe,
.introMediaSlot video
{

    position: absolute;

    inset: 0;

    display: block;

    width: 100%;

    height: 100%;

    border: 0;

}

/* ── Placeholder (shown until the video is supplied) ── */

.introVideoPlaceholder
{

    position: absolute;

    inset: 0;

    margin: 0;

}

.introVideoPoster
{

    width: 100%;

    height: 100%;

    object-fit: cover;

    filter: saturate(0.72) brightness(0.52);

}

.introVideoOverlay
{

    position: absolute;

    inset: 0;

    display: flex;

    flex-direction: column;

    align-items: center;

    justify-content: center;

    gap: 1.1rem;

    padding: 1.5rem;

    text-align: center;

    background: radial-gradient(ellipse at center, rgba(16, 18, 20, 0.12) 0%, rgba(16, 18, 20, 0.58) 100%);

}

.introVideoPlayMark
{

    display: flex;

    align-items: center;

    justify-content: center;

    width: 74px;

    height: 74px;

    border: 2px solid rgba(247, 249, 251, 0.75);

    border-radius: 50%;

    background-color: rgba(91, 155, 213, 0.22);

}

.introVideoPlayMark svg
{

    width: 34px;

    height: 34px;

    margin-left: 4px;

    fill: var(--colorWhite);

}

.introVideoCaption
{

    font-family: var(--fontDisplay);

    font-size: 0.95rem;

    font-weight: 600;

    letter-spacing: 0.2em;

    text-transform: uppercase;

    color: rgba(247, 249, 251, 0.86);

}

/* ── Aside ── */

.introAside
{

    padding-top: 0.4rem;

}

.introQuote
{

    margin: 0 0 1.5rem;

    padding-left: 1.2rem;

    border-left: 3px solid var(--colorSky);

}

.introQuote p
{

    margin: 0;

    font-family: var(--fontDisplay);

    font-size: clamp(1.35rem, 2.4vw, 1.7rem);

    font-weight: 600;

    line-height: 1.25;

    color: var(--colorWhite);

}

.introCopy
{

    margin: 0 0 1.8rem;

    color: rgba(247, 249, 251, 0.78);

}

.introPointList
{

    display: grid;

    gap: 1rem;

    margin: 0 0 2rem;

    padding: 0;

    list-style: none;

}

.introPoint
{

    display: flex;

    align-items: flex-start;

    gap: 0.85rem;

    font-size: 0.98rem;

    line-height: 1.55;

    color: rgba(247, 249, 251, 0.78);

}

.introPoint strong
{

    color: var(--colorWhite);

}

.introPointIcon
{

    flex-shrink: 0;

    width: 24px;

    height: 24px;

    margin-top: 0.15rem;

    color: var(--colorSky);

}

/* ============================================================
   REVIEWS SECTION  (honest placeholder — never fabricated reviews)
============================================================ */

.reviewsInner
{

    max-width: 900px;

    text-align: center;

}

.reviewsInner .sectionLede
{

    max-width: 640px;

    margin-right: auto;

    margin-left: auto;

}

.reviewsPending
{

    display: flex;

    flex-direction: column;

    align-items: center;

    gap: 1.5rem;

    padding: 3rem 2rem;

    background-color: var(--colorWhite);

    border: 1px dashed rgba(124, 136, 148, 0.40);

    border-radius: var(--radiusCard);

}

.reviewsPendingMark
{

    display: flex;

    align-items: center;

    justify-content: center;

    width: 66px;

    height: 66px;

    color: var(--colorSkyDeep);

    background-color: rgba(91, 155, 213, 0.12);

    border-radius: 50%;

}

.reviewsPendingMark svg
{

    width: 32px;

    height: 32px;

}

.reviewsPendingBody
{

    display: flex;

    flex-direction: column;

    align-items: center;

    gap: 1.6rem;

}

.reviewsPendingCopy
{

    max-width: 520px;

    margin: 0;

    font-size: 1.05rem;

    color: var(--colorSteel);

}

.reviewsPendingActions
{

    display: flex;

    flex-wrap: wrap;

    align-items: center;

    justify-content: center;

    gap: 1rem;

}

/* ============================================================
   SERVICE AREA MAP SECTION
============================================================ */

.serviceAreaSection
{

    background-color: var(--colorOffWhite);

}

.serviceAreaLayout
{

    display: grid;

    grid-template-columns: 1.5fr 1fr;

    gap: 2.4rem;

    align-items: stretch;

}

/* ── Town pages ── */

.serviceAreaTowns
{

    margin-top: 2.6rem;

}

.serviceAreaTownsLabel
{

    margin: 0 0 1rem;

    font-size: 0.82rem;

    font-weight: 600;

    letter-spacing: 0.14em;

    text-transform: uppercase;

    color: var(--colorSteel);

}

.serviceAreaTownList
{

    display: flex;

    flex-wrap: wrap;

    gap: 0.7rem;

    margin: 0;

    padding: 0;

    list-style: none;

}

.serviceAreaTownList a
{

    display: inline-block;

    padding: 0.55rem 1.15rem;

    background-color: var(--colorWhite);

    border: 1px solid var(--colorLineLight);

    border-radius: var(--radiusPill);

    font-size: 0.92rem;

    font-weight: 600;

    color: var(--colorInk);

    transition:
        border-color 0.25s var(--easePremium),
        color 0.25s var(--easePremium);

}

.serviceAreaTownList a:hover
{

    border-color: var(--colorSky);

    color: var(--colorSkyDeep);

}

.mapFrame
{

    position: relative;

    min-height: clamp(360px, 45vw, 540px);

    overflow: hidden;

    background-color: var(--colorCharcoal);

    border: 1px solid rgba(247, 249, 251, 0.08);

    border-radius: var(--radiusCard);

    box-shadow: var(--shadowCard);

    padding: 0;

}

.serviceAreaMap
{

    display: block;

    width: 100%;

    height: 100%;

    min-height: clamp(360px, 45vw, 540px);

    border: 0;

    border-radius: inherit;

}

.serviceAreaGoogleMap
{

    background-color: var(--colorCharcoal);

}

.mapInfoPanel
{

    display: flex;

    flex-direction: column;

    padding: 2rem 1.9rem;

    background-color: var(--colorCharcoal);

    border-radius: var(--radiusCard);

    color: var(--colorOffWhite);

    box-shadow: var(--shadowCard);

}

.mapInfoState
{

    margin: 0 0 0.4rem;

    font-size: 0.78rem;

    font-weight: 700;

    letter-spacing: 0.18em;

    text-transform: uppercase;

    color: var(--colorSky);

}

.mapInfoRegion
{

    margin: 0 0 0.8rem;

    font-family: var(--fontDisplay);

    font-size: 2rem;

    font-weight: 700;

    letter-spacing: 0.02em;

    text-transform: uppercase;

    color: var(--colorWhite);

}

.mapInfoCopy
{

    margin: 0 0 1.2rem;

    font-size: 0.95rem;

    color: rgba(247, 249, 251, 0.7);

}

.mapInfoTowns
{

    display: flex;

    flex-wrap: wrap;

    gap: 0.5rem;

    margin: 0 0 auto;

    padding: 0;

    list-style: none;

}

.mapInfoTowns li
{

    padding: 0.35rem 0.85rem;

    font-size: 0.85rem;

    font-weight: 600;

    background-color: rgba(91, 155, 213, 0.16);

    border: 1px solid rgba(91, 155, 213, 0.4);

    border-radius: var(--radiusPill);

}

.mapInfoCta
{

    margin-top: 1.6rem;

}

/* ============================================================
   FACEBOOK SECTION
============================================================ */

.facebookLayout
{

    display: grid;

    grid-template-columns: 400px 1fr;

    gap: 2.4rem;

    align-items: start;

}

.facebookFrame
{

    background-color: rgba(247, 249, 251, 0.05);

    border: 1px solid var(--colorLineDark);

    border-radius: var(--radiusCard);

    overflow: hidden;

}

.facebookFrameHeader
{

    display: flex;

    align-items: center;

    gap: 0.45rem;

    padding: 0.8rem 1rem;

    border-bottom: 1px solid var(--colorLineDark);

}

.facebookFrameDot
{

    width: 10px;

    height: 10px;

    background-color: rgba(247, 249, 251, 0.25);

    border-radius: 50%;

}

.facebookFrameTitle
{

    margin-left: 0.5rem;

    font-size: 0.78rem;

    letter-spacing: 0.03em;

    color: rgba(247, 249, 251, 0.6);

}

.facebookEmbed
{

    display: block;

    width: 100%;

    background-color: rgba(16, 18, 20, 0.4);

}

.facebookEmbedSlot
{

    display: flex;

    align-items: center;

    justify-content: center;

    min-height: 430px;

}

.facebookFallback
{

    display: flex;

    flex-direction: column;

    align-items: center;

    gap: 0.5rem;

    padding: 2.6rem 1.8rem;

    text-align: center;

}

.facebookFallbackBadge
{

    width: 76px;

    height: 76px;

    margin-bottom: 0.6rem;

}

.facebookFallbackTitle
{

    margin: 0;

    font-family: var(--fontDisplay);

    font-size: 1.5rem;

    font-weight: 700;

    letter-spacing: 0.03em;

    text-transform: uppercase;

    color: var(--colorWhite);

}

.facebookFallbackCopy
{

    max-width: 280px;

    margin: 0 0 1.1rem;

    font-size: 0.9rem;

    color: rgba(247, 249, 251, 0.65);

}

.postTag
{

    margin-left: auto;

    padding: 0.22rem 0.62rem;

    font-size: 0.62rem;

    font-weight: 700;

    letter-spacing: 0.14em;

    text-transform: uppercase;

    white-space: nowrap;

    color: var(--colorSky);

    border: 1px solid rgba(91, 155, 213, 0.4);

    border-radius: var(--radiusPill);

}

/* Three cards share whatever the 400px embed frame leaves of the
   1172px content width, so a fixed repeat(3, 1fr) kept squeezing them
   below the width their own header needs. A minimum track width lets
   the row drop to two cards instead of crushing three; the ≤1080px
   and ≤640px queries below still take over from there. */

.facebookPosts
{

    display: grid;

    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));

    gap: 1.4rem;

}

.postCard
{

    background-color: rgba(247, 249, 251, 0.05);

    border: 1px solid var(--colorLineDark);

    border-radius: var(--radiusCard);

    overflow: hidden;

    transition: transform 0.35s var(--easePremium), border-color 0.35s var(--easePremium);

}

.postCard:hover
{

    transform: translateY(-5px);

    border-color: rgba(91, 155, 213, 0.5);

}

.postCardHeader
{

    display: flex;

    flex-wrap: wrap;

    align-items: center;

    gap: 0.55rem 0.7rem;

    padding: 0.9rem 1rem 0.6rem;

}

.postAvatar
{

    width: 38px;

    height: 38px;

    border-radius: 50%;

}

/* flex: 1 meant flex-basis: 0, so the meta block volunteered to shrink
   to nothing and the nowrap tag never wrapped — the author line
   ellipsed away and the date broke mid-string, stacking "July" over
   "8". A real basis makes the tag wrap to its own row instead, which
   is the row that should give way. */

.postMeta
{

    display: flex;

    flex-direction: column;

    flex: 1 1 7.5rem;

    min-width: 0;

}

.postAuthor
{

    font-size: 0.86rem;

    font-weight: 700;

    color: var(--colorWhite);

    white-space: nowrap;

    overflow: hidden;

    text-overflow: ellipsis;

}

.postDate
{

    font-size: 0.74rem;

    white-space: nowrap;

    color: rgba(247, 249, 251, 0.5);

}

.postCaption
{

    margin: 0;

    padding: 0 1rem 0.8rem;

    font-size: 0.88rem;

    line-height: 1.55;

    color: rgba(247, 249, 251, 0.78);

}

.postImage
{

    width: 100%;

    aspect-ratio: 4 / 3;

    object-fit: cover;

}

/* ============================================================
   FAQ SECTION
============================================================ */

.faqSection
{

    background-color: var(--colorWhite);

}

.faqInner
{

    max-width: 860px;

}

.faqList
{

    border-top: 1px solid var(--colorLineLight);

}

.faqItem
{

    border-bottom: 1px solid var(--colorLineLight);

}

.faqQuestion
{

    margin: 0;

}

.faqToggle
{

    display: flex;

    align-items: center;

    justify-content: space-between;

    gap: 1.2rem;

    width: 100%;

    padding: 1.25rem 0.4rem;

    background: none;

    border: none;

    text-align: left;

    font-family: var(--fontBody);

    font-size: 1.05rem;

    font-weight: 600;

    color: var(--colorCharcoal);

    transition: color 0.25s var(--easePremium);

}

.faqToggle:hover
{

    color: var(--colorSkyDeep);

}

.faqChevron
{

    flex-shrink: 0;

    width: 13px;

    height: 9px;

    transition: transform 0.35s var(--easePremium);

}

.faqToggle[aria-expanded="true"] .faqChevron
{

    transform: rotate(180deg);

}

.faqPanel
{

    max-height: 0;

    overflow: hidden;

    transition: max-height 0.45s var(--easePremium);

}

.faqPanel p
{

    margin: 0;

    padding: 0 2.4rem 1.4rem 0.4rem;

    font-size: 0.98rem;

    color: var(--colorSteel);

}

/* ============================================================
   EQUIPMENT SHOWCASE / FINAL CTA SECTION
   (cinematic parallax closer — full-width machine photo
   driven by the reusable parallax sections system)
============================================================ */

.contactSection
{

    position: relative;

    display: flex;

    align-items: center;

    min-height: 76vh;

    background-color: var(--colorNearBlack);

    overflow: hidden;

}

/* ── Parallax media layer ── */

.contactMedia
{

    position: absolute;

    inset: 0;

    z-index: 0;

    overflow: hidden;

}

.contactParallaxImage
{

    position: absolute;

    top: -15%;

    left: 0;

    width: 100%;

    height: 130%;

    max-width: none;

    object-fit: cover;

    will-change: transform;

    transform: translate3d(0, 0, 0);

    backface-visibility: hidden;

}

.contactOverlay
{

    position: absolute;

    inset: 0;

    background:
        linear-gradient(
            180deg,
            rgba(16, 18, 20, 0.88) 0%,
            rgba(28, 31, 34, 0.46) 26%,
            rgba(28, 31, 34, 0.30) 50%,
            rgba(28, 31, 34, 0.46) 74%,
            rgba(16, 18, 20, 0.92) 100%
        ),
        linear-gradient(
            90deg,
            rgba(16, 18, 20, 0.55) 0%,
            rgba(16, 18, 20, 0) 32%,
            rgba(16, 18, 20, 0) 68%,
            rgba(16, 18, 20, 0.55) 100%
        );

}

/* ── Content ── */

.contactInner
{

    position: relative;

    z-index: 1;

    width: 100%;

    text-align: center;

    padding-top: 7.5rem;

    padding-bottom: 7.5rem;

}

.contactHeading
{

    margin: 0 0 1.2rem;

    font-family: var(--fontDisplay);

    font-size: clamp(2.6rem, 6vw, 4.4rem);

    font-weight: 700;

    line-height: 1;

    letter-spacing: 0.01em;

    text-transform: uppercase;

    color: var(--colorWhite);

    text-shadow: 0 2px 30px rgba(16, 18, 20, 0.65);

}

/* Floating caption — a subtle glass chip, not a card. Sized to
   its own content and centered above the CTAs. */

.contactCaption
{

    display: inline-block;

    margin: 0 auto 2.4rem;

    padding: 1rem 2rem;

    background-color: rgba(16, 18, 20, 0.42);

    border: 1px solid rgba(247, 249, 251, 0.16);

    border-radius: 16px;

    backdrop-filter: blur(10px);

    -webkit-backdrop-filter: blur(10px);

}

.contactCopy
{

    max-width: 560px;

    margin: 0;

    font-family: var(--fontBody);

    font-size: 1.12rem;

    color: rgba(247, 249, 251, 0.9);

    text-shadow: 0 1px 18px rgba(16, 18, 20, 0.7);

}

.contactActions
{

    display: flex;

    flex-wrap: wrap;

    align-items: center;

    justify-content: center;

    gap: 1.1rem;

}

/* Outlined secondary actions, scoped to this section only — the hero
   and the modal keep the frosted treatment. The old translucent white
   fill read as weak next to the solid primary sitting beside it, so
   these now carry the brand blue on their edge and fill with it on
   hover and focus. Both states use existing tokens; no new colour. */

.contactActions .buttonGhost,
.contactActions .contactPhone
{

    background-color: transparent;

    color: var(--colorSky);

    border: 2px solid var(--colorSky);

    transition:
        border-color 0.25s var(--easePremium),
        background-color 0.25s var(--easePremium),
        color 0.25s var(--easePremium),
        transform 0.25s var(--easePremium);

}

.contactActions .buttonGhost:hover,
.contactActions .buttonGhost:focus-visible,
.contactActions .contactPhone:hover,
.contactActions .contactPhone:focus-visible
{

    background-color: var(--colorSky);

    color: var(--colorNearBlack);

    border-color: var(--colorSky);

}

/* The section-wide focus ring is the same blue these buttons fill
   with, so it would vanish against their focused state. Inside this
   section the ring goes white and keeps its offset. */

.contactActions .buttonGhost:focus-visible,
.contactActions .contactPhone:focus-visible
{

    outline: 3px solid var(--colorWhite);

    outline-offset: 2px;

}

/* Shape and type only. Colour, fill and border live in the
   .contactActions block above, which is the one place the outlined
   states are declared. */

.contactPhone
{

    display: inline-flex;

    align-items: center;

    gap: 0.7rem;

    padding: 1.05rem 1.8rem;

    font-family: var(--fontDisplay);

    font-size: 1.5rem;

    font-weight: 700;

    letter-spacing: 0.04em;

    border-radius: 10px;

    transition:
        border-color 0.25s var(--easePremium),
        background-color 0.25s var(--easePremium),
        color 0.25s var(--easePremium);

}

/* currentColor, so the glyph follows the button from blue-on-dark to
   dark-on-blue instead of disappearing into the filled hover state. */

.contactPhoneIcon
{

    width: 22px;

    height: 22px;

    fill: currentColor;

}

/* ============================================================
   FOOTER
============================================================ */

.siteFooter
{

    background-color: var(--colorNearBlack);

    color: rgba(247, 249, 251, 0.75);

}

.footerInner
{

    display: grid;

    grid-template-columns: 1.4fr 1fr 1fr 1fr;

    gap: 2.8rem;

    max-width: var(--maxWidth);

    margin: 0 auto;

    padding: 4.5rem 1.5rem 3rem;

}

.footerBadge
{

    width: 120px;

    height: 120px;

    margin-bottom: 1.1rem;

}

.footerOneLiner
{

    margin: 0 0 1.4rem;

    max-width: 320px;

    font-size: 0.94rem;

    line-height: 1.65;

}

.footerContactList
{

    display: flex;

    flex-direction: column;

    gap: 0.55rem;

    margin: 0;

    padding: 0;

    list-style: none;

}

.footerContactList a
{

    color: rgba(247, 249, 251, 0.85);

    font-size: 0.95rem;

    transition: color 0.25s var(--easePremium);

}

.footerContactList a:hover
{

    color: var(--colorSky);

}

.footerSocialItem
{

    display: flex;

    align-items: center;

    gap: 0.9rem;

}

.footerFacebookLink,
.footerGoogleLink
{

    display: inline-flex;

    align-items: center;

}

.footerFacebookIcon,
.footerGoogleIcon
{

    width: 17px;

    height: 17px;

    fill: currentColor;

}

.footerColumnHeading
{

    margin: 0 0 1rem;

    font-family: var(--fontDisplay);

    font-size: 1.05rem;

    font-weight: 700;

    letter-spacing: 0.14em;

    text-transform: uppercase;

    color: var(--colorWhite);

}

.footerLinkList
{

    display: flex;

    flex-direction: column;

    gap: 0.5rem;

    margin: 0;

    padding: 0;

    list-style: none;

    font-size: 0.92rem;

}

.footerLinkList a
{

    color: rgba(247, 249, 251, 0.72);

    transition: color 0.25s var(--easePremium);

}

.footerLinkList a:hover
{

    color: var(--colorSky);

}

.footerAreasList
{

    color: rgba(247, 249, 251, 0.55);

}

.footerBottomBar
{

    border-top: 1px solid var(--colorLineDark);

}

.footerBottomInner
{

    display: flex;

    flex-wrap: wrap;

    align-items: center;

    justify-content: space-between;

    gap: 0.8rem 1.5rem;

    max-width: var(--maxWidth);

    margin: 0 auto;

    padding: 1.2rem 1.5rem;

}

.footerBottomBar p
{

    margin: 0;

    font-size: 0.84rem;

    color: rgba(247, 249, 251, 0.45);

}

.devCredit
{

    display: inline-flex;

    align-items: center;

    gap: 0.65rem;

}

.devCreditLabel
{

    font-size: 0.76rem;

    letter-spacing: 0.06em;

    color: rgba(247, 249, 251, 0.4);

}

.devCreditLogo
{

    width: 78px;

    height: auto;

    opacity: 0.4;

    transition: opacity 0.25s var(--easePremium);

}

.devCredit:hover .devCreditLogo
{

    opacity: 1;

}

/* ============================================================
   MEDIA QUERIES
============================================================ */

/* ============================================================
   HEADER — COMPACT DESKTOP BAND

   Measured against the real Inter/Rokkitt metrics. This band tightens
   spacing only — no font sizes, no CTA padding — and buys 105px,
   because .headerInner is a flex row whose items would otherwise
   shrink before anything else gives.

   It starts at 1360px, which is .headerInner's own max-width, and
   that is the whole argument for the number. Above 1360px the inner
   is capped, so the available width never changes and full spacing
   always clears by 124px. Below it every pixel of viewport is a pixel
   of header, which is exactly where the compact tokens should begin.

   The band moved up from 1280px when "Our Company" made the nav five
   items. Full spacing then needed 1236px, leaving only 45px at 1281px
   — the tightest point on the whole sweep sitting in the *widest*
   band, which is the wrong shape for a responsive header. Anchoring
   the band to the inner width fixes that by construction.

   Crossing 1360px downward still makes the bar roomier, not tighter:
   +124px above, +229px below.
============================================================ */

@media (max-width: 1360px)
{

    /* Tokens only — every header rule already reads these, so the
       compact state is expressed as data rather than as a second copy
       of the layout. --headerCtaPadX is pointedly absent: the primary
       CTA keeps its padding at every width. */

    :root
    {

        --headerPadX: 1.25rem;

        --headerGap: 1.1rem;

        /* The logo area is the one part allowed to give ground, which
           is what its margin-right: auto already implies. */

        --headerBrandGap: 0.75rem;

        --headerBadgeSize: 60px;

        --headerNavGap: 0.25rem;

        --headerNavLinkPadX: 0.7rem;

        --headerNavChevronGap: 0.3rem;

        --headerActionsGap: 0.7rem;

        --headerPhonePadX: 0.75rem;

    }

}

/* ============================================================
   HEADER — MOBILE NAV SWITCH

   Fully tightened, the five-item bar needs 1131px of viewport. The
   switch sits at 1200px rather than at that number because the
   breakpoint has always been tuned to hold ~45px of slack, which is
   what absorbs the wider 'Segoe UI' fallback if Inter has not loaded
   yet — a cold-cache visitor must never see the header wrap during a
   font swap.

   At 1201px, the last desktop width, the bar clears by 70px on Inter
   and by 28px on the fallback face. 1176px would have been the
   arithmetic minimum and leaves 4px on the fallback; 1200px is the
   round number that keeps a real margin.

   It moved up from 1150px when "Our Company" joined the nav: that
   item costs 144px including its gap, and at 1151px it would have
   left 20px on Inter and wrapped outright on the fallback.

   This is header-only on purpose. The 1080px query below also drives
   the hero, the services grid, and other section layouts; moving all
   of that would be a redesign of things nobody asked about.
============================================================ */

@media (max-width: 1200px)
{

    :root
    {

        --headerHeight: 70px;

        --headerBadgeSize: 56px;

        --headerBrandNameSize: 1.45rem;

    }

    .siteHeader.isHiddenMobile
    {

        transform: translate3d(0, calc(-100% - env(safe-area-inset-top, 0px)), 0);

    }

    /* The only part of the morph that cannot be animated: display is
       not an interpolable property, and there is no honest tween from
       a five-item nav to a hamburger. The bar's height, logo, and
       padding still ease across, so the switch reads as the header
       resolving into its compact form rather than as a jump cut. */

    .primaryNav
    {

        display: none;

    }

    .phoneChip
    {

        display: none;

    }

    .headerCta
    {

        display: none;

    }

    .mobileMenuToggle
    {

        display: flex;

    }

}

/* ============================================================
   PROCESS BOARD — HORIZONTAL ROW GIVES WAY

   1167px is derived, not chosen: the board is max-width 1120px and
   sits inside .sectionInner's 1.5rem padding, so 1120 + 48 = 1168px
   is the narrowest viewport at which it can still render at the width
   it was designed for. Below that the five-across row is running
   compressed — at 1081px each step column is 147px against a design
   value of 164px — and a compressed row is what the browser QA
   reported as steps running past the edge of the board.

   So the horizontal presentation is kept for exactly as long as it
   genuinely fits, and hands over the moment it does not. Above
   1168px every column is at its full design width on every board;
   below it the vertical layout takes the whole story.

   It moved up from 1080px, and out of that shared query, because
   1080px also drives the hero, the services grid and several section
   layouts — none of which had any reason to move with it.

   The vertical layout itself is unchanged. The old two-up grid broke
   the story: the arrow at the end of a row pointed right, into the
   edge of the board, rather than at the step that actually follows.
   Stacked, the arrows rotate to point down and the progression stays
   true at any step count.
============================================================ */

@media (max-width: 1167px)
{

    .processBoard
    {

        padding: 2rem 1.4rem;

    }

    .processSteps
    {

        flex-direction: column;

        align-items: stretch;

        gap: 1.1rem;

    }

    .processStep
    {

        flex: 0 0 auto;

        max-width: 30rem;

        margin: 0 auto;

    }

    .processArrow
    {

        --processArrowTurn: 90deg;

        margin-top: 0;

    }

}

@media (max-width: 1080px)
{

    /* ── Hero background decoupled from the estimate card ──
       .heroInner collapses to one column at this breakpoint, so the
       estimate card stacks underneath the hero copy. .heroMedia was
       pinned to inset: 0, which meant the photograph grew with the
       card and ran hundreds of pixels past the fold.

       The correction is to stop letting section height drive the
       picture at all: .heroMedia is pinned to the top with an explicit
       height, the hero copy is sized to fill that same band, and the
       estimate card sits on its own background below the seam.
       Changing the form can no longer change the photograph. */

    .heroSection
    {

        /* One number drives the media band, the copy block, and the
           estimate band. lvh keeps the picture covering the viewport
           in every browser-chrome state; vh is the older fallback. */
        --heroMediaHeight: 100vh;
        --heroMediaHeight: 100lvh;

        min-height: var(--heroMediaHeight);

        padding-top: calc(var(--headerHeight) + 2rem);

        padding-bottom: 3rem;

    }

    /* The estimate band. Its own background, opening in the same
       near-black the photograph fades into, so the seam reads as one
       continuous surface rather than two stacked sections. */

    .heroSection::after
    {

        content: "";

        position: absolute;

        top: var(--heroMediaHeight);

        right: 0;

        bottom: 0;

        left: 0;

        z-index: 0;

        background: linear-gradient(180deg, var(--colorNearBlack) 0%, var(--colorCharcoal) 100%);

    }

    .heroMedia
    {

        inset: 0 0 auto;

        height: var(--heroMediaHeight);

    }

    /* Lands the photograph on solid --colorNearBlack exactly at the
       bottom of the media band. Done on the overlay rather than on
       .heroPlate because the AFTER plate's mask-image *is* the sweep
       animation and must not be overwritten. */

    .heroOverlay
    {

        background:
            linear-gradient(
                100deg,
                rgba(10, 11, 12, 0.72) 0%,
                rgba(10, 11, 12, 0.48) 24%,
                rgba(16, 18, 20, 0.20) 48%,
                rgba(16, 18, 20, 0) 70%
            ),
            linear-gradient(
                180deg,
                rgba(16, 18, 20, 0.38) 0%,
                rgba(16, 18, 20, 0) 26%,
                rgba(16, 18, 20, 0.34) 64%,
                rgba(16, 18, 20, 0.88) 88%,
                var(--colorNearBlack) 100%
            );

    }

    .heroPlate
    {

        object-position: center 68%;

    }

    .heroInner
    {

        grid-template-columns: 1fr;

        gap: 3rem;

        padding-top: 1rem;

    }

    /* Holds the copy to the first screen so the estimate card always
       arrives at the seam, whatever the copy happens to measure.
       This is the min-height that used to live on .heroSection — it
       belongs on the block it actually describes. */

    .heroContent
    {

        min-height: calc(var(--heroMediaHeight) - var(--headerHeight) - 3rem);

    }

    .heroActions
    {

        margin-bottom: 1rem;

    }

    /* Rides up over the seam for the layered edge. */

    .estimateFormCard
    {

        max-width: 560px;

        margin-top: -4.5rem;

    }

    .servicesGrid
    {

        grid-template-columns: repeat(2, 1fr);

    }

    .servicesGrid .serviceCard:last-child
    {

        grid-column: auto;

        flex-direction: column;

    }

    .servicesGrid .serviceCard:last-child .serviceCardMedia
    {

        width: 100%;

        aspect-ratio: 3 / 2;

    }

    .servicesGrid .serviceCard:last-child .serviceCardBody
    {

        justify-content: flex-start;

    }

    .transformationStories
    {

        grid-template-columns: 1fr;

    }

    .whySplit
    {

        grid-template-columns: 1fr;

        gap: 2.6rem;

    }

    .introLayout
    {

        grid-template-columns: 1fr;

        gap: 2.2rem;

    }

    .serviceAreaLayout
    {

        grid-template-columns: 1fr;

    }

    .facebookLayout
    {

        grid-template-columns: 1fr;

    }

    .facebookPosts
    {

        grid-template-columns: repeat(2, 1fr);

    }

}

@media (max-width: 640px)
{

    :root
    {

        --headerHeight: 64px;

        --headerBadgeSize: 50px;

        --headerBrandNameSize: 1.35rem;

    }

    html.jsEnabled [data-animate="slideLeft"],
    html.jsEnabled [data-animate="slideRight"]
    {

        transform: translate3d(0, 20px, 0);

    }

    html.jsEnabled .servicesGrid .serviceCard:nth-child(3n + 1)[data-animate="fadeUp"],
    html.jsEnabled .servicesGrid .serviceCard:nth-child(3n)[data-animate="fadeUp"],
    html.jsEnabled .transformationStories .storyCard:nth-child(3n + 1)[data-animate="fadeUp"],
    html.jsEnabled .transformationStories .storyCard:nth-child(3n)[data-animate="fadeUp"]
    {

        transform: translate3d(0, 22px, 0);

    }

    html.jsEnabled .facebookPosts .postCard[data-animate="fadeUp"]
    {

        transform: translate3d(0, 22px, 0);

    }

    html.jsEnabled .faqItem[data-animate]
    {

        transition-delay: 0ms;

    }

    html.jsEnabled .facebookPosts .postCard[data-animate="fadeUp"].isAnimated,
    html.jsEnabled .servicesGrid .serviceCard:nth-child(3n + 1)[data-animate="fadeUp"].isAnimated,
    html.jsEnabled .servicesGrid .serviceCard:nth-child(3n)[data-animate="fadeUp"].isAnimated,
    html.jsEnabled .transformationStories .storyCard:nth-child(3n + 1)[data-animate="fadeUp"].isAnimated,
    html.jsEnabled .transformationStories .storyCard:nth-child(3n)[data-animate="fadeUp"].isAnimated
    {

        transform: none;

    }

    .sectionInner
    {

        padding: 4.5rem 1.25rem;

    }

    .heroHeadlineFixed
    {

        font-size: clamp(2.6rem, 12vw, 3.4rem);

    }

    .heroTypedGhost,
    .heroTypedText
    {

        font-size: clamp(2.1rem, 9.8vw, 2.8rem);

        white-space: normal;

    }

    .heroTypedLine
    {

        white-space: normal;

        flex-wrap: wrap;

    }

    .heroTypedWrap
    {

        width: 100%;

        min-height: 5rem;

    }

    .heroStats
    {

        gap: 1.6rem;

    }

    .statNumber
    {

        font-size: 1.9rem;

    }

    .heroActions .buttonLarge
    {

        width: 100%;

    }

    .heroSection
    {

        padding-top: calc(var(--headerHeight) + 1.2rem);

        padding-bottom: 2.2rem;

    }

    /* Tracks the tighter top padding above so the copy block still
       ends exactly on the media seam. */

    .heroContent
    {

        min-height: calc(var(--heroMediaHeight) - var(--headerHeight) - 2.2rem);

    }

    .heroPlate
    {

        object-position: center 78%;

    }

    .estimateFormCard
    {

        padding: 1.6rem 1.3rem;

    }

    .sectionDivider
    {

        height: 90px;

    }

    .servicesGrid
    {

        grid-template-columns: 1fr;

    }

    .servicesGrid .serviceCard:last-child .serviceCardMedia img
    {

        object-position: center 38%;

    }

    /* Already vertical from 1080px down; this width only tightens it. */

    .processBoard
    {

        padding: 1.6rem 1.1rem;

    }

    .facebookPosts
    {

        grid-template-columns: 1fr;

    }

    .facebookLayout
    {

        grid-template-columns: 1fr;

    }

    .facebookFrame
    {

        max-width: 100%;

    }

    .whyStats
    {

        flex-wrap: wrap;

        gap: 1.4rem 2rem;

    }

    .footerInner
    {

        grid-template-columns: 1fr;

        gap: 2.2rem;

    }

    .estimateModal
    {

        padding: 0;

    }

    .estimateModalShell
    {

        max-height: 100vh;

        height: 100%;

        border-radius: 0;

    }

    .segmentedControl
    {

        flex-direction: column;

    }

    .contactSection
    {

        min-height: 68vh;

    }

    .contactParallaxImage
    {

        top: 0;

        height: 100%;

        transform: none;

        will-change: auto;

    }

    .contactInner
    {

        padding-top: 5.5rem;

        padding-bottom: 5.5rem;

    }

    .contactPhone
    {

        width: 100%;

        justify-content: center;

    }

    .contactActions .buttonLarge
    {

        width: 100%;

    }

    .mobileFloatingActions
    {

        position: fixed;

        right: max(1rem, env(safe-area-inset-right, 0px));

        bottom: calc(0.85rem + env(safe-area-inset-bottom, 0px));

        left: max(1rem, env(safe-area-inset-left, 0px));

        z-index: 260;

        display: grid;

        grid-template-columns: 0.92fr 1.08fr;

        align-items: center;

        gap: 0.45rem;

        /* No fixed height on purpose. box-sizing is border-box, so a
           height here is the OUTER box and the buttons have to fit
           inside it minus this padding and the border below. It used to
           say 60px, which left a 44.56px content box for 46px buttons,
           so they overflowed 0.72px past the top and bottom and painted
           over the border — pills on a 24px radius, crossing the corner
           on a different curve. Sizing to content means the bar is
           always exactly its buttons plus its own padding and border. */

        padding: 0.42rem;

        background-color: rgba(16, 18, 20, 0.84);

        border: 1px solid rgba(247, 249, 251, 0.16);

        border-radius: 24px;

        box-shadow: 0 18px 45px rgba(16, 18, 20, 0.36);

        backdrop-filter: blur(14px);

        -webkit-backdrop-filter: blur(14px);

        opacity: 0;

        pointer-events: none;

        transform: translate3d(0, calc(100% + 1.4rem + env(safe-area-inset-bottom, 0px)), 0);

        visibility: hidden;

        transition:
            transform 0.26s var(--easePremium),
            opacity 0.24s var(--easePremium),
            visibility 0.26s var(--easePremium);

    }

    .mobileFloatingActions.isVisible
    {

        opacity: 1;

        pointer-events: auto;

        transform: translate3d(0, 0, 0);

        visibility: visible;

    }

    .mobileFloatingCall,
    .mobileFloatingEstimate
    {

        display: inline-flex;

        align-items: center;

        justify-content: center;

        height: 46px;

        border-radius: var(--radiusPill);

        white-space: nowrap;

    }

    .mobileFloatingCall
    {

        gap: 0.45rem;

        color: var(--colorWhite);

        font-size: 0.82rem;

        font-weight: 700;

        letter-spacing: 0.08em;

        text-transform: uppercase;

        background-color: rgba(247, 249, 251, 0.09);

        border: 1px solid rgba(247, 249, 251, 0.18);

        transition:
            transform 0.24s var(--easePremium),
            background-color 0.24s var(--easePremium),
            border-color 0.24s var(--easePremium);

    }

    .mobileFloatingCall:hover,
    .mobileFloatingCall:focus-visible
    {

        color: var(--colorWhite);

        background-color: rgba(247, 249, 251, 0.14);

        border-color: rgba(247, 249, 251, 0.3);

        transform: translateY(-1px);

    }

    .mobileFloatingCall svg
    {

        width: 17px;

        height: 17px;

        fill: currentColor;

    }

    .mobileFloatingEstimate
    {

        width: 100%;

        padding: 0 0.95rem;

        font-size: 0.82rem;

        box-shadow: none;

    }

    .backToTopButton
    {

        position: fixed;

        right: max(1rem, env(safe-area-inset-right, 0px));

        bottom: calc(0.95rem + env(safe-area-inset-bottom, 0px));

        z-index: 270;

        display: flex;

        align-items: center;

        justify-content: center;

        width: 52px;

        height: 52px;

        padding: 0;

        color: var(--colorWhite);

        font-size: 1.35rem;

        line-height: 1;

        background-color: var(--colorSky);

        border: 0;

        border-radius: 50%;

        box-shadow: 0 16px 38px rgba(16, 18, 20, 0.34);

        cursor: pointer;

        opacity: 0;

        pointer-events: none;

        transform: translate3d(0, 12px, 0);

        visibility: hidden;

        transition:
            bottom 0.24s var(--easePremium),
            transform 0.24s var(--easePremium),
            opacity 0.22s var(--easePremium),
            visibility 0.24s var(--easePremium),
            background-color 0.24s var(--easePremium);

    }

    .backToTopButton.isVisible
    {

        opacity: 1;

        pointer-events: auto;

        transform: translate3d(0, 0, 0);

        visibility: visible;

    }

    .backToTopButton.isLifted
    {

        bottom: calc(5.65rem + env(safe-area-inset-bottom, 0px));

    }

    .backToTopButton:hover,
    .backToTopButton:focus-visible
    {

        background-color: var(--colorSkyLight);

        transform: translate3d(0, -1px, 0);

    }

}

@media (max-width: 360px)
{

    .mobileFloatingActions
    {

        right: max(0.85rem, env(safe-area-inset-right, 0px));

        left: max(0.85rem, env(safe-area-inset-left, 0px));

        gap: 0.35rem;

        /* Height stays derived here too — see the note at the 1150px
           rule. This block only retunes the inset, the gap and the
           radius. */

        border-radius: 22px;

    }

    .mobileFloatingCall,
    .mobileFloatingEstimate
    {

        height: 44px;

        font-size: 0.76rem;

        letter-spacing: 0.06em;

    }

    .backToTopButton
    {

        width: 50px;

        height: 50px;

    }

}

/* ============================================================
   REDUCED MOTION
============================================================ */

@media (prefers-reduced-motion: reduce)
{

    html
    {

        scroll-behavior: auto;

    }

    /* The header morph is motion like any other — snap between the
       three states instead of easing. One override kills all of it
       because every rule shares --headerTransition. */

    :root
    {

        --headerTransition: 0s linear;

    }

    html.jsEnabled [data-animate]
    {

        opacity: 1;

        transform: none;

        clip-path: none;

        transition: none;

    }

    /* Nothing types under reduced motion — the phrase is written once
       and left alone — so the compositing layer would be memory held
       for an animation that never runs. */

    .heroTypedLine
    {

        will-change: auto;

    }

    /* The mega menus still open and close — that is function, not
       decoration — but they do it without the rise, the arrow slide,
       or the leading rule growing. Opacity alone carries the change.
       One block covers all three panels because all three are built
       from the same parts. */

    .megaPanel,
    .megaFeature,
    .megaFeatureCue,
    .megaFeatureArrow,
    .megaRow,
    .megaRow::before,
    .megaServiceIcon,
    .megaCompanyIcon,
    .megaAreaLink,
    .navChevron
    {

        transition: none;

    }

    .navItem.isOpen .megaPanel
    {

        transform: none;

    }

    .megaPanel
    {

        transform: translateX(-50%);

    }

    .megaFeature:hover .megaFeatureArrow,
    .megaFeature:focus-visible .megaFeatureArrow
    {

        transform: none;

    }

    /* The process sequence does not run at all under reduced motion —
       initializeProcessSequences() returns before it observes anything.
       These two rules are what the visitor gets instead: the finished
       state, immediately, with every step and every arrow present. No
       information is withheld, only the telling of it. */

    html.jsEnabled .processStep
    {

        opacity: 1;

        transform: none;

        transition: none;

    }

    html.jsEnabled .processArrow,
    html.jsEnabled .processArrow.isActive,
    html.jsEnabled .processArrow.isResting
    {

        opacity: 0.26;

        transform: rotate(var(--processArrowTurn));

        filter: none;

        transition: none;

    }

    .contactParallaxImage
    {

        transform: none;

    }

    .mobileFloatingActions,
    .mobileFloatingCall,
    .backToTopButton
    {

        transition: none;

    }

    html.jsEnabled [data-heroanimate]
    {

        opacity: 1;

        transform: none;

        transition: none;

    }

    html.jsEnabled .comparisonSlider[data-animate] .comparisonTag,
    html.jsEnabled .comparisonSlider[data-animate] .comparisonHandle
    {

        opacity: 1;

        transform: none;

        transition: none;

    }

    html.jsEnabled .comparisonSlider[data-animate] .comparisonHandle
    {

        transform: translate3d(-50%, 0, 0);

    }

    /* Duet Hero composed-still fallback: AFTER is the base (sell
       the outcome), a bordered BEFORE inset explains the starting
       point, everything is visible at once — no choreography. */

    .heroHeadlineFixed
    {

        opacity: 1;

        transform: none;

        transition: none;

    }

    .heroMedia
    {

        animation: none;

    }

    .heroPlateAfter
    {

        --heroSweepPos: 100% !important;

        transition: none !important;

    }

    .heroCursor
    {

        animation: none;

        opacity: 1;

    }

    .heroTypedGhost,
    .heroTypedText
    {

        white-space: normal;

    }

    .heroReducedInset
    {

        display: block;

        position: absolute;

        left: 1.5rem;

        bottom: 1.5rem;

        z-index: 2;

        width: 180px;

        border: 2px solid rgba(247, 249, 251, 0.4);

        border-radius: 8px;

        overflow: hidden;

        box-shadow: 0 10px 24px rgba(0, 0, 0, 0.4);

    }

    .heroReducedInset img
    {

        display: block;

        width: 100%;

        height: auto;

    }

    .heroReducedInset figcaption
    {

        padding: 0.3rem 0.6rem;

        background-color: rgba(16, 18, 20, 0.85);

        color: var(--colorWhite);

        font-size: 0.72rem;

        font-weight: 600;

        letter-spacing: 0.08em;

        text-transform: uppercase;

        text-align: center;

    }

    .estimateModalShell,
    .modalStep,
    .formSuccessPanel
    {

        animation: none;

    }

    .serviceCardMedia img,
    .serviceCard,
    .postCard,
    .storyCard
    {

        transition: none;

    }

}

