/**
 * Header, navigation, footer, buttons, breadcrumbs.
 * Mobile-first: base rules target small screens, desktop nav takes over
 * at the 960px breakpoint.
 */

/* ---------- Buttons ---------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-5);
    border-radius: var(--radius-md);
    font-weight: 700;
    text-decoration: none;
    border: 2px solid transparent;
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
}

.btn--accent {
    background: var(--color-accent);
    color: var(--color-accent-contrast);
}

.btn--accent:hover {
    background: var(--color-accent-dark);
    color: #fff;
}

.btn--outline {
    background: transparent;
    border-color: var(--color-ink);
    color: var(--color-ink);
}

.btn--outline:hover {
    background: var(--color-ink);
    color: #fff;
}

.btn--whatsapp {
    background: #25d366;
    color: #fff;
}

.btn--whatsapp:hover {
    background: #1ebc59;
    color: #fff;
}

/* ---------- Header ---------- */

.site-header {
    position: sticky;
    top: 0;
    z-index: var(--z-header);
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
}

.site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: var(--header-height);
    gap: var(--space-4);
}

/* ---------- Brand lockup (logo) ---------- */
/* Shared by the header and footer (see partials/brand-lockup.php) so the
   two never drift apart visually. The logo artwork carries the wordmark
   and tagline itself, so there is no brand text to style here. */

.brand-lockup {
    display: flex;
    align-items: center;
    text-decoration: none;
    min-width: 0;
    flex-shrink: 0;
}

/* Mobile first, and sized by HEIGHT rather than width: the header bar is a
   fixed --header-height, so constraining the height is what guarantees the
   logo can never blow the bar out, whatever aspect ratio the artwork has.
   Width follows from the file's own ratio via width:auto (the intrinsic
   width/height attributes in the markup give the browser that ratio up
   front, so the space is reserved before the image loads and the header
   doesn't shift). max-width is the backstop on very narrow phones: a wide
   mark shrinks to fit beside the hamburger instead of overflowing. */
.brand-lockup__logo {
    height: 44px;
    width: auto;
    max-width: 100%;
    object-fit: contain;
}

@media (min-width: 600px) {
    .brand-lockup__logo {
        height: 50px;
    }
}

@media (min-width: 960px) {
    .brand-lockup__logo {
        height: 54px;
    }
}

/* Footer variant: the artwork's primary wordmark is dark navy, which has
   almost no contrast on the footer's dark navy ground. The logo sits on a
   light plate instead of being filtered, so its two-tone palette stays
   exactly as drawn. */
.brand-lockup--dark .brand-lockup__logo {
    background: #fff;
    padding: 10px 14px;
    border-radius: var(--radius-lg);
}

/* ---------- Nav toggle (mobile hamburger) ---------- */

.nav-toggle {
    display: inline-flex;
    flex-direction: column;
    gap: 4px;
    background: none;
    border: none;
    padding: var(--space-2);
    cursor: pointer;
}

.nav-toggle__bar {
    width: 22px;
    height: 2px;
    background: var(--color-ink);
}

/* ---------- Primary nav (mobile: full-screen panel) ---------- */

.primary-nav {
    position: fixed;
    inset: var(--header-height) 0 0 0;
    width: 100%;
    max-width: 100vw;
    background: var(--color-surface);
    overflow-x: hidden;
    overflow-y: auto;
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--transition-base), transform var(--transition-base);
    z-index: var(--z-header);
}

.primary-nav.is-open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.primary-nav__list {
    list-style: none;
    margin: 0;
    padding: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.primary-nav__list > li:not(.primary-nav__cta) > a,
.mega-trigger {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
    text-align: left;
    padding: var(--space-3) var(--space-2);
    font-weight: 600;
    color: var(--color-ink);
    text-decoration: none;
    border-radius: var(--radius-sm);
    background: none;
    border: none;
}

/* Leading icon before each mobile menu item — hidden again at the
   desktop breakpoint below, so the desktop bar reads exactly as before. */
.primary-nav__icon {
    color: var(--color-accent);
    flex-shrink: 0;
}

.primary-nav__list > li:not(.primary-nav__cta) > a:hover,
.mega-trigger:hover {
    background: var(--color-surface-muted);
}

.primary-nav__cta {
    margin-top: var(--space-3);
}

.primary-nav__cta .btn {
    width: 100%;
}

/* ---------- Mega menu ---------- */

.has-mega {
    position: relative;
}

.mega-menu {
    display: none;
    padding: var(--space-2) 0 var(--space-2) var(--space-3);
}

.mega-menu.is-open {
    display: block;
}

.mega-menu__group {
    margin-bottom: var(--space-4);
}

.mega-menu__heading {
    display: block;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-muted);
    font-weight: 700;
    margin-bottom: var(--space-1);
}

.mega-menu__group ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.mega-menu__group a {
    display: block;
    padding: var(--space-1) 0;
    color: var(--color-text);
    text-decoration: none;
}

.mega-menu__group a:hover {
    color: var(--color-accent-dark);
}

/* ---------- Footer ---------- */

.site-footer {
    background: var(--color-ink);
    color: #fff;
    padding-block: var(--space-8) var(--space-6);
}

.site-footer a {
    color: #d9e2ec;
    text-decoration: none;
}

.site-footer a:hover {
    color: #fff;
}

.site-footer__inner {
    display: grid;
    gap: var(--space-6);
    grid-template-columns: 1fr;
}

.site-footer__brand .brand-lockup {
    margin-bottom: var(--space-4);
}

.site-footer__brand p {
    color: #c3cdd6;
}

.site-footer__tagline {
    margin-bottom: var(--space-4);
}

.site-footer__rating {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    color: #fff;
    font-weight: 600;
    font-size: 0.92rem;
    margin-bottom: var(--space-4);
}

.site-footer__stars {
    color: var(--color-accent);
    letter-spacing: 0.08em;
}

.site-footer__contact {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.site-footer__contact li {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    color: #c3cdd6;
}

.site-footer__contact .icon {
    color: var(--color-accent);
    flex-shrink: 0;
    margin-top: 2px;
}

.site-footer__contact strong {
    color: #fff;
}

.site-footer__links {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.site-footer__heading {
    display: block;
    font-weight: 700;
    margin-bottom: var(--space-2);
    color: #fff;
}

.site-footer__group ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.site-footer__bottom {
    border-top: 1px solid rgba(255, 255, 255, 0.15);
    margin-top: var(--space-6);
    padding-top: var(--space-4);
    font-size: 0.85rem;
    color: #b7c3cf;
}

/* ---------- Breadcrumbs ---------- */

.breadcrumbs {
    padding-block: var(--space-4);
}

.breadcrumbs ol {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    padding: 0;
    margin: 0;
    font-size: 0.88rem;
    color: var(--color-text-muted);
}

.breadcrumbs li {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.breadcrumbs li:not(:last-child)::after {
    content: "/";
    color: var(--color-border);
}

.breadcrumbs a {
    color: var(--color-text-muted);
    text-decoration: none;
}

.breadcrumbs a:hover {
    color: var(--color-accent-dark);
}

.breadcrumbs--dark ol {
    color: rgba(255, 255, 255, 0.6);
}

.breadcrumbs--dark li:not(:last-child)::after {
    color: rgba(255, 255, 255, 0.3);
}

.breadcrumbs--dark a {
    color: rgba(255, 255, 255, 0.75);
}

.breadcrumbs--dark a:hover {
    color: #fff;
}

.breadcrumbs--dark [aria-current="page"] {
    color: #fff;
}

/* ---------- Desktop breakpoint ---------- */

@media (min-width: 960px) {
    .nav-toggle {
        display: none;
    }

    .primary-nav {
        position: static;
        inset: auto;
        transform: none;
        opacity: 1;
        pointer-events: auto;
        background: transparent;
        overflow: visible;
    }

    .primary-nav__list {
        flex-direction: row;
        align-items: center;
        padding: 0;
        gap: var(--space-5);
    }

    .primary-nav__cta {
        margin-top: 0;
        margin-left: var(--space-2);
    }

    .primary-nav__cta .btn {
        width: auto;
    }

    /* Icons and the WhatsApp CTA are a mobile-menu-only enhancement —
       the desktop bar keeps its original text-only links + single CTA. */
    .primary-nav__icon {
        display: none;
    }

    .primary-nav__cta--whatsapp {
        display: none;
    }

    .mega-menu {
        position: absolute;
        top: 100%;
        left: 0;
        background: var(--color-surface);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-md);
        box-shadow: var(--shadow-md);
        padding: var(--space-5);
        grid-template-columns: repeat(5, minmax(150px, 1fr));
        gap: var(--space-5);
        z-index: var(--z-mega);
        min-width: 720px;
    }

    .has-mega:hover .mega-menu,
    .has-mega:focus-within .mega-menu,
    .mega-menu.is-open {
        display: grid;
    }
}

@media (min-width: 720px) {
    .site-footer__inner {
        grid-template-columns: 1fr 2fr;
    }

    .site-footer__links {
        flex-direction: row;
        flex-wrap: wrap;
    }

    .site-footer__group {
        flex: 1 1 160px;
    }
}

/* ---------- CTA block ---------- */
/* Dark parallax band reusing the hero's scrim/grid-pattern language.
   Fixed attachment dropped below 768px, same reasoning as .trust-band. */

.cta-block {
    position: relative;
    overflow: hidden;
    background: linear-gradient(135deg, var(--color-ink) 0%, #16324f 100%);
    background-attachment: fixed;
    padding-block: var(--space-8);
    color: #fff;
}

/* When $bgImage is supplied, the section's flat gradient becomes a photo
   (applied lazily by assets/js/lazy-bg.js) with a dark scrim on top so
   text and buttons stay legible over any photo. */
.cta-block--photo {
    background-size: cover;
    background-position: center;
}

.cta-block__scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, rgba(11, 31, 51, 0.92) 0%, rgba(22, 50, 79, 0.88) 100%);
}

.cta-block__inner {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-6);
    text-align: center;
}

.cta-block__copy {
    max-width: 640px;
    margin-inline: auto;
}

.cta-block__copy h2 {
    color: #fff;
    margin-bottom: var(--space-2);
}

.cta-block__copy p {
    color: rgba(255, 255, 255, 0.78);
}

.cta-block__actions {
    display: flex;
    justify-content: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

@media (max-width: 767px) {
    .cta-block {
        background-attachment: scroll;
    }
}

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

.service-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--space-5);
}

/* Same dark glassy gradient card treatment as .value-props__item /
   .process-steps__card, reused here so "Related Services" cards match
   the rest of the site's card language instead of a plain light box. */
.service-card {
    background: linear-gradient(135deg, rgba(11, 31, 51, 0.94) 0%, rgba(28, 51, 80, 0.88) 100%);
    backdrop-filter: blur(14px) saturate(160%);
    -webkit-backdrop-filter: blur(14px) saturate(160%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
    box-shadow: 0 8px 28px rgba(11, 31, 51, 0.18);
    transition: transform var(--transition-base), box-shadow var(--transition-base);
}

.service-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 16px 36px rgba(11, 31, 51, 0.28);
}

/* Every heading level the card can emit, not just h3. partials/service-card.php
   takes a $headingLevel so callers can keep the document outline correct —
   the city location pages pass h4 — and an h3-only rule left those titles
   inheriting --color-ink (dark navy) on the card's dark navy ground, which
   is effectively invisible rather than merely off-brand. */
.service-card h2,
.service-card h3,
.service-card h4 {
    font-size: 1.15rem;
    margin-bottom: var(--space-2);
    color: #fff;
}

.service-card h2 a,
.service-card h3 a,
.service-card h4 a {
    color: #fff;
    text-decoration: none;
}

.service-card h2 a:hover,
.service-card h3 a:hover,
.service-card h4 a:hover {
    color: var(--color-accent);
}

.service-card p {
    color: rgba(255, 255, 255, 0.72);
}

.service-card__link {
    color: var(--color-accent);
    font-weight: 700;
    text-decoration: none;
}

/* ---------- Service area ---------- */

.service-area {
    padding-block: var(--space-6);
}

/* Responsive area grid: 2 cols mobile -> 3 tablet -> 4 desktop -> 5 large
   desktop. A real grid (not flex-wrap chips) so areas align into clean,
   scannable rows at every size. */
.service-area__list {
    list-style: none;
    padding: 0;
    margin: var(--space-4) 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-3);
}

/* Same dark glassy gradient used by .value-props__item / .service-card,
   reused here so coverage-area chips match the rest of the site's card
   language instead of a plain light box. */
.service-area__list li {
    background: linear-gradient(135deg, rgba(11, 31, 51, 0.94) 0%, rgba(28, 51, 80, 0.88) 100%);
    backdrop-filter: blur(14px) saturate(160%);
    -webkit-backdrop-filter: blur(14px) saturate(160%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: var(--radius-sm);
    padding: var(--space-3) var(--space-4);
    font-size: 0.92rem;
    font-weight: 600;
    color: #fff;
    text-align: center;
}

/* Linked chips (cities, which have their own pages) stretch the anchor
   over the whole chip so the entire card is the tap target on touch,
   rather than just the few characters of the city name. */
.service-area__list li a {
    display: block;
    margin: calc(var(--space-3) * -1) calc(var(--space-4) * -1);
    padding: var(--space-3) var(--space-4);
    color: inherit;
    text-decoration: none;
    border-radius: inherit;
}

.service-area__list-item--link {
    transition: border-color var(--transition-base), transform var(--transition-base);
}

.service-area__list-item--link:hover,
.service-area__list-item--link:focus-within {
    border-color: var(--color-accent);
    transform: translateY(-2px);
}

@media (min-width: 600px) {
    .service-area__list {
        grid-template-columns: repeat(3, 1fr);
    }
}

@media (min-width: 960px) {
    .service-area__list {
        grid-template-columns: repeat(4, 1fr);
    }
}

@media (min-width: 1440px) {
    .service-area__list {
        grid-template-columns: repeat(5, 1fr);
    }
}

/* "Don't see your area?" CTA card — a highlighted conversion element, not
   an alert/warning: same surface-muted card language as the rest of the
   design system, with a single accent-colored edge rather than alert
   colors. */
.area-cta {
    margin-top: var(--space-5);
    padding: var(--space-5);
    border-radius: var(--radius-md);
    background: var(--color-surface-muted);
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-accent);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.area-cta__content h3 {
    font-size: 1.1rem;
    margin-bottom: var(--space-2);
}

.area-cta__content p {
    margin: 0;
    color: var(--color-text-muted);
}

.area-cta__btn {
    align-self: flex-start;
    white-space: nowrap;
}

@media (min-width: 720px) {
    .area-cta {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-5);
    }

    .area-cta__btn {
        align-self: center;
        flex-shrink: 0;
    }
}

/* ---------- FAQ accordion ---------- */

.faq-accordion {
    padding-block: var(--space-6);
}

.faq-accordion__item {
    border-bottom: 1px solid var(--color-border);
    padding-block: var(--space-3);
}

.faq-accordion__item summary {
    font-weight: 700;
    cursor: pointer;
    color: var(--color-ink);
}

.faq-accordion__item p {
    margin-top: var(--space-3);
    color: var(--color-text-muted);
}

/* ---------- Testimonials ---------- */

.testimonials {
    padding-block: var(--space-7);
}

.testimonials__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--space-5);
}

.testimonials__card {
    margin: 0;
    padding: var(--space-5);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
}

.testimonials__card blockquote {
    margin: 0 0 var(--space-4);
    color: var(--color-text);
    font-size: 1rem;
    line-height: 1.6;
}

.testimonials__card figcaption {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    font-size: 0.88rem;
}

.testimonials__card figcaption strong {
    color: var(--color-ink);
}

.testimonials__card figcaption span {
    color: var(--color-text-muted);
}

/* ---------- Gallery ---------- */

.gallery-filter {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-bottom: var(--space-5);
}

.gallery-filter__btn {
    padding: var(--space-2) var(--space-4);
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    cursor: pointer;
    font-weight: 600;
}

.gallery-filter__btn.is-active {
    background: var(--color-ink);
    color: #fff;
    border-color: var(--color-ink);
}

.gallery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--space-5);
}

.gallery-grid__item {
    margin: 0;
    display: flex;
    flex-direction: column;
}

.gallery-grid__item[hidden] {
    display: none;
}

.gallery-grid__zoom {
    position: relative;
    display: block;
    width: 100%;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--color-surface-muted);
    cursor: zoom-in;
}

.gallery-grid__zoom img {
    aspect-ratio: 4 / 3;
    object-fit: cover;
    width: 100%;
    display: block;
}

.gallery-grid__zoom-icon {
    position: absolute;
    right: var(--space-2);
    bottom: var(--space-2);
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: rgba(11, 31, 51, 0.75);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity var(--transition-fast);
}

.gallery-grid__zoom:hover .gallery-grid__zoom-icon,
.gallery-grid__zoom:focus-visible .gallery-grid__zoom-icon {
    opacity: 1;
}

.gallery-grid__item figcaption {
    padding-top: var(--space-2);
    font-size: 0.85rem;
}

.gallery-grid__item figcaption a {
    color: var(--color-text-muted);
    text-decoration: none;
}

.gallery-grid__item figcaption a:hover {
    color: var(--color-accent-dark);
}

/* ---------- Lightbox ---------- */

.lightbox {
    position: relative;
    border: none;
    padding: 0;
    background: transparent;
    max-width: min(90vw, 900px);
    width: 100%;
}

.lightbox::backdrop {
    background: rgba(11, 31, 51, 0.85);
}

.lightbox__figure {
    margin: 0;
    background: var(--color-ink);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.lightbox__figure img {
    display: block;
    width: 100%;
    min-height: 240px;
    max-height: 80vh;
    object-fit: contain;
    background: var(--color-surface-muted);
}

.lightbox__figure figcaption {
    padding: var(--space-3) var(--space-4);
    color: #fff;
    font-size: 0.9rem;
}

.lightbox__close,
.lightbox__nav {
    position: absolute;
    background: rgba(11, 31, 51, 0.75);
    color: #fff;
    border: none;
    border-radius: 50%;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 2;
}

.lightbox__close {
    top: var(--space-3);
    right: var(--space-3);
}

.lightbox__nav {
    top: 50%;
    transform: translateY(-50%);
}

.lightbox__nav--prev {
    left: var(--space-3);
}

.lightbox__nav--next {
    right: var(--space-3);
}

/* ---------- Enquiry form ---------- */

.form-field {
    margin-bottom: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.form-field label {
    font-weight: 600;
    font-size: 0.9rem;
}

.form-field input[type="text"],
.form-field input[type="tel"],
.form-field select,
.form-field textarea {
    padding: var(--space-3);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font: inherit;
    width: 100%;
    background: var(--color-surface);
    color: var(--color-text);
}

.enquiry-form fieldset {
    border: none;
    padding: 0;
    margin: 0 0 var(--space-4);
}

.enquiry-form fieldset legend {
    font-weight: 600;
    font-size: 0.9rem;
    margin-bottom: var(--space-2);
    padding: 0;
}

.enquiry-form fieldset label {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    margin-right: var(--space-4);
    font-weight: 400;
}

.enquiry-form__honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.enquiry-form__errors {
    background: #fdecea;
    border: 1px solid #f3b4ac;
    color: #8a2c22;
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-sm);
    margin-bottom: var(--space-4);
}

.enquiry-form__errors ul {
    margin: 0;
    padding-left: var(--space-4);
}

/* ---------- Icons ---------- */

.icon {
    width: 24px;
    height: 24px;
}

.icon--sm {
    width: 18px;
    height: 18px;
}

/* ---------- Section rhythm ---------- */

.section-heading {
    max-width: 720px;
    margin-bottom: var(--space-6);
}

.section-heading p {
    color: var(--color-text-muted);
}

.section-link {
    margin-top: var(--space-5);
}

/* Shared eyebrow + H2 + lede header, used by every section built to this
   pattern (services showcase, why choose us, process, coverage areas,
   testimonials, FAQ) so the header markup/styling exists once. */
.section-header {
    max-width: 720px;
    margin: 0 auto var(--space-7);
    text-align: center;
}

.section-header__eyebrow {
    display: inline-block;
    padding: var(--space-1) var(--space-4);
    border-radius: 999px;
    background: rgba(224, 127, 16, 0.12);
    color: var(--color-accent-dark);
    font-weight: 700;
    font-size: 0.8rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    margin-bottom: var(--space-4);
}

.section-header h2 {
    margin: 0 0 var(--space-3);
}

.section-header__lede {
    color: var(--color-text-muted);
    font-size: 1.05rem;
    margin: 0 auto;
}

/* A plain paragraph directly following a section header (rather than
   passed as $lede, needed when the copy has real inline links that
   $lede's escaping would break) gets the same centered, readable-width
   treatment for visual consistency. */
.section-header + p {
    max-width: 720px;
    margin: 0 auto;
    text-align: center;
    color: var(--color-text-muted);
}

.section-link a {
    font-weight: 700;
}

/* ---------- Location page category blocks ---------- */

.location-category {
    margin-top: var(--space-6);
    padding-top: var(--space-6);
    border-top: 1px solid var(--color-border);
}

.location-category:first-of-type {
    margin-top: var(--space-5);
    padding-top: 0;
    border-top: none;
}

.location-category h3 {
    font-size: 1.15rem;
    margin-bottom: var(--space-3);
}

.location-category > p {
    color: var(--color-text-muted);
}

/* Reuses .service-showcase__card's exact gradient+icon card styling (see
   partials/service-showcase-card.php) in a wrapped grid instead of the
   homepage's horizontal scroller — appropriate here since every service
   is already grouped and shown at once, with no need for category tabs. */
.location-category__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--space-5);
    margin-top: var(--space-4);
}

/* ---------- Scroll reveal ---------- */
/* Gated behind .js (set by an inline script in partials/head.php) so
   content stays visible by default with JavaScript disabled — only a
   confirmed-JS page hides it pending reveal.js adding .is-visible. */

.js [data-reveal] {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 500ms ease, transform 500ms ease;
}

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

/* ---------- Hero ---------- */

.hero {
    position: relative;
    display: flex;
    align-items: center;
    min-height: 640px;
    color: #fff;
    background: var(--color-ink);
    padding-block: var(--space-8) var(--space-9);
}

.hero__media {
    position: absolute;
    inset: 0;
    z-index: 0;
}

/* One per service, all stacked in the same spot; the active slide's
   photo crossfades in via opacity (see assets/js/hero-carousel.js, which
   also lazy-loads each slide's photo the first time it becomes active). */
.hero__bg-slide {
    position: absolute;
    inset: 0;
    background-color: var(--color-ink);
    background-size: cover;
    background-position: center;
    opacity: 0;
    transition: opacity 700ms ease;
}

.hero__bg-slide.is-active {
    opacity: 1;
}

/* Left-to-right scrim so text on the left stays legible while the photo
   remains visible toward the right edge. */
.hero__scrim {
    position: absolute;
    inset: 0;
    z-index: 1;
    background: linear-gradient(90deg, rgba(11, 31, 51, 0.93) 0%, rgba(11, 31, 51, 0.82) 45%, rgba(11, 31, 51, 0.5) 100%);
}

.hero__inner {
    position: relative;
    z-index: 2;
    width: 100%;
}

.hero__h1 {
    color: #fff;
    font-size: clamp(1.1rem, 0.95rem + 0.6vw, 1.4rem);
    font-weight: 700;
    max-width: 640px;
    margin: 0 0 var(--space-2);
}

.hero__subhead {
    color: rgba(255, 255, 255, 0.72);
    font-size: 0.95rem;
    max-width: 55ch;
    margin: 0 0 var(--space-7);
}

.btn--on-dark.btn--outline {
    border-color: rgba(255, 255, 255, 0.5);
    color: #fff;
}

.btn--on-dark.btn--outline:hover {
    background: #fff;
    border-color: #fff;
    color: var(--color-ink);
}

/* ---------- Hero service slides ---------- */
/* Full-bleed text directly over the video/scrim (no boxed card) — a
   bolder, gradient-and-glass-accented treatment scoped to this one
   component, distinct from the flatter cards used across the rest of
   the site. */

/* All 10 slides are stacked in the SAME grid cell, so the grid row's
   height is always the tallest slide's natural height — constant,
   regardless of which slide is currently active. This is deliberate: a
   min-height guess can't account for every slide's different text length
   at every viewport width, and being even slightly short causes the
   whole page below the hero to shift up/down as the carousel advances
   (real, measured layout shift — not just a cosmetic risk). Inactive
   slides use visibility:hidden (not display:none/[hidden]) so they still
   count toward that sizing, while still being correctly excluded from
   the accessibility tree and tab order. */
.hero-slides {
    display: grid;
}

.hero-slide {
    grid-area: 1 / 1;
    max-width: 640px;
    visibility: hidden;
    opacity: 0;
    pointer-events: none;
    transition: opacity 400ms ease;
}

.hero-slide.is-active {
    visibility: visible;
    opacity: 1;
    pointer-events: auto;
    animation: heroSlideIn 500ms ease;
}

@keyframes heroSlideIn {
    from {
        opacity: 0;
        transform: translateY(12px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

.hero-slide__badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.25);
    backdrop-filter: blur(8px) saturate(150%);
    -webkit-backdrop-filter: blur(8px) saturate(150%);
    color: #fff;
    font-weight: 700;
    font-size: 0.76rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    margin-bottom: var(--space-4);
}

.hero-slide__badge .icon {
    color: var(--color-accent);
}

.hero-slide__title {
    color: #fff;
    font-family: var(--font-heading);
    font-weight: 800;
    font-size: clamp(1.9rem, 1.5rem + 2vw, 3rem);
    line-height: 1.12;
    margin: 0 0 var(--space-2);
}

.hero-slide__subtitle {
    color: var(--color-accent);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.3rem);
    margin: 0 0 var(--space-4);
}

.hero-slide__desc {
    color: rgba(255, 255, 255, 0.85);
    max-width: 58ch;
    margin: 0 0 var(--space-5);
}

.hero-slide__keywords {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin: 0 0 var(--space-6);
}

.hero-slide__keyword {
    padding: var(--space-1) var(--space-4);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.22);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    color: rgba(255, 255, 255, 0.92);
    font-size: 0.82rem;
    font-weight: 600;
}

.hero-slide__actions {
    display: flex;
    gap: var(--space-3);
    flex-wrap: wrap;
}

/* ---------- Carousel chrome: arrows + dots ---------- */

.hero-carousel__arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.12);
    backdrop-filter: blur(10px) saturate(150%);
    -webkit-backdrop-filter: blur(10px) saturate(150%);
    border: 1px solid rgba(255, 255, 255, 0.3);
    color: #fff;
    display: none;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 3;
}

.hero-carousel__arrow:hover {
    background: var(--color-accent);
    border-color: var(--color-accent);
}

.hero-carousel__arrow--prev {
    left: var(--space-4);
}

.hero-carousel__arrow--next {
    right: var(--space-4);
}

/* Normal document flow (not absolutely positioned) — sits right below
   whichever slide is showing, so it can never overlap the CTA buttons
   above it regardless of how tall that slide's content is. */
.hero-carousel__dots {
    display: flex;
    gap: var(--space-2);
    margin-top: var(--space-6);
}

.hero-carousel__dot {
    width: 9px;
    height: 9px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.35);
    border: none;
    padding: 0;
    cursor: pointer;
    transition: width var(--transition-fast), background var(--transition-fast);
}

.hero-carousel__dot[aria-selected="true"] {
    width: 28px;
    background: var(--color-accent);
    box-shadow: 0 0 0 3px rgba(224, 127, 16, 0.25);
}

/* ---------- Bottom wave divider ---------- */

.hero__wave {
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    z-index: 2;
    line-height: 0;
    pointer-events: none;
}

.hero__wave svg {
    display: block;
    width: 100%;
    height: 60px;
}

.hero__wave-path {
    /* Matches .trust-band's own top color below, so the curve reads as a
       seamless join rather than a stray sliver of the page's white
       background between two dark sections. */
    fill: var(--color-ink);
}

@media (min-width: 720px) {
    .hero {
        min-height: 680px;
    }

    .hero__wave svg {
        height: 90px;
    }
}

@media (min-width: 960px) {
    .hero-carousel__arrow {
        display: flex;
    }
}

@media (min-width: 1440px) {
    .hero {
        min-height: 760px;
    }
}

/* ---------- Service page hero ---------- */
/* Each service's real photo (see data/service-images.php) as the
   background — set inline by templates/service.php since it's this
   page's LCP element (also preloaded via $preloadImage in head.php), so
   it loads eagerly rather than through the lazy-bg.js path used further
   down the page. The gradient below is just the fallback for the rare
   case a service has no photo mapped. */

.service-hero {
    position: relative;
    overflow: hidden;
    background: linear-gradient(135deg, var(--color-ink) 0%, #16324f 100%);
    background-size: cover;
    background-position: center;
    padding-block: var(--space-7) var(--space-8);
    color: #fff;
}

.service-hero__scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, rgba(11, 31, 51, 0.92) 0%, rgba(22, 50, 79, 0.88) 100%);
}

.service-hero__inner {
    position: relative;
    z-index: 1;
}

.service-hero__badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.25);
    backdrop-filter: blur(8px) saturate(150%);
    -webkit-backdrop-filter: blur(8px) saturate(150%);
    font-weight: 700;
    font-size: 0.76rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    margin: var(--space-5) 0 var(--space-4);
}

.service-hero__badge .icon {
    color: var(--color-accent);
}

.service-hero__badge span {
    color: #fff;
}

.service-hero__inner h1 {
    color: #fff;
    font-size: clamp(1.9rem, 1.5rem + 2vw, 2.75rem);
    line-height: 1.15;
    max-width: 720px;
    margin: 0 0 var(--space-4);
}

.service-hero__intro {
    color: rgba(255, 255, 255, 0.8);
    font-size: 1.05rem;
    max-width: 62ch;
    margin: 0 0 var(--space-6);
}

.service-hero__actions {
    display: flex;
    gap: var(--space-3);
    flex-wrap: wrap;
}

/* ---------- Applications & materials panel (service pages) ---------- */
/* Two-column dark section: a checklist of real applications on the left,
   an optional materials panel (light glass card, same treatment as the
   hero slide keyword chips) on the right. Single column when a service
   has no 'materials' text. */

.applications-panel {
    position: relative;
    overflow: hidden;
    background: linear-gradient(135deg, var(--color-ink) 0%, #16324f 100%);
    padding-block: var(--space-8);
    color: #fff;
}

.applications-panel__grid {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-7);
}

.applications-panel__col .section-header {
    text-align: left;
    margin: 0 0 var(--space-5);
    max-width: none;
}

.applications-panel__col .section-header h2 {
    color: #fff;
}

.applications-panel__col .section-header__eyebrow {
    background: rgba(224, 127, 16, 0.18);
    color: var(--color-accent);
}

.applications-panel__list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: var(--space-3);
}

.applications-panel__list li {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    color: rgba(255, 255, 255, 0.9);
}

.applications-panel__list .icon {
    color: var(--color-accent);
    flex-shrink: 0;
    margin-top: 2px;
}

.applications-panel__panel {
    padding: var(--space-6);
    background: rgba(255, 255, 255, 0.06);
    backdrop-filter: blur(14px) saturate(150%);
    -webkit-backdrop-filter: blur(14px) saturate(150%);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: var(--radius-lg);
}

.applications-panel__panel h3 {
    color: #fff;
    margin-bottom: var(--space-3);
}

.applications-panel__panel p {
    color: rgba(255, 255, 255, 0.78);
    margin: 0;
}

@media (min-width: 900px) {
    .applications-panel__grid {
        grid-template-columns: 1.1fr 0.9fr;
        align-items: start;
    }
}

/* ---------- SEO overview (service pages) ---------- */
/* Long-form location-focused copy block, narrower than the standard
   container for readability, eyebrow/heading/body all centered to match
   the "centered badge + title" treatment used across every section. */

.seo-overview {
    padding-block: var(--space-8);
}

.seo-overview__inner {
    max-width: 760px;
    margin: 0 auto;
    text-align: center;
}

.seo-overview__inner .section-header__eyebrow {
    margin-bottom: var(--space-4);
}

.seo-overview__inner h2 {
    margin-bottom: var(--space-4);
}

.seo-overview__inner h3 {
    margin-top: var(--space-6);
    margin-bottom: var(--space-3);
}

.seo-overview__inner p {
    color: var(--color-text-muted);
}

.seo-overview__inner strong {
    color: var(--color-ink);
}

/* ---------- Recent projects slider (service pages) ---------- */

.recent-projects {
    padding-block: var(--space-8);
    background: var(--color-surface-muted);
}

.recent-projects__slider {
    max-width: 900px;
    margin: var(--space-6) auto 0;
}

.recent-projects__track {
    position: relative;
    aspect-ratio: 4 / 3;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--color-ink);
    box-shadow: var(--shadow-md);
}

.recent-projects__slide {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    transition: opacity 600ms ease;
}

.recent-projects__slide.is-active {
    opacity: 1;
}

.recent-projects__slide img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.recent-projects__slide figcaption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    margin: 0;
    padding: var(--space-4) var(--space-5);
    background: linear-gradient(180deg, transparent 0%, rgba(11, 31, 51, 0.85) 100%);
    color: #fff;
    font-weight: 700;
    font-size: 0.95rem;
}

.recent-projects__dots {
    display: flex;
    justify-content: center;
    gap: var(--space-2);
    margin-top: var(--space-5);
}

.recent-projects__dot {
    width: 9px;
    height: 9px;
    border-radius: 999px;
    background: var(--color-border);
    border: none;
    padding: 0;
    cursor: pointer;
    transition: width var(--transition-fast), background var(--transition-fast);
}

.recent-projects__dot[aria-selected="true"] {
    width: 28px;
    background: var(--color-accent);
}

/* ---------- Trust band (stat highlights) ---------- */
/* Gradient background with a fixed-attachment parallax effect — the
   background stays put in the viewport while the stat content scrolls
   normally over it. Fixed attachment is dropped below 768px: some mobile
   browsers repaint it poorly (jank) and iOS Safari has a long history of
   inconsistent support, so this is a progressive enhancement, not load-
   bearing — the section still reads correctly with a normal scrolling
   background on small screens. */

.trust-band {
    position: relative;
    background: linear-gradient(180deg, var(--color-ink) 0%, #16324f 55%, var(--color-ink) 100%);
    background-attachment: fixed;
    color: #fff;
}

.trust-band__grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-7) var(--space-4);
    padding-block: var(--space-8);
    text-align: center;
}

.trust-band__item {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.trust-band__value {
    font-family: var(--font-heading);
    font-weight: 800;
    font-size: clamp(2rem, 1.6rem + 1.6vw, 2.75rem);
    color: var(--color-accent);
    line-height: 1;
}

.trust-band__label {
    color: rgba(255, 255, 255, 0.85);
    font-weight: 600;
    font-size: 0.92rem;
}

.trust-band__sub {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 1.05rem;
    color: #fff;
    margin-top: calc(var(--space-2) * -1);
}

.trust-band__stars {
    color: var(--color-accent);
    font-size: 1.15rem;
    letter-spacing: 0.12em;
    margin-top: calc(var(--space-2) * -1);
}

@media (min-width: 720px) {
    .trust-band__grid {
        /* auto-fit rather than a fixed count: the band is data-driven now
           (see templates/home.php), so adding or removing a stat never
           leaves an orphaned tile on the last row. */
        grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    }
}

@media (max-width: 767px) {
    .trust-band {
        background-attachment: scroll;
    }
}

/* ---------- Region intro (content section) ---------- */

.region-intro {
    background: var(--color-surface);
    padding-block: var(--space-8);
}

.region-intro__inner {
    max-width: 860px;
    margin-inline: auto;
    text-align: center;
}

.region-intro__inner h2 {
    margin-bottom: var(--space-5);
}

.region-intro__inner p {
    max-width: none;
    font-size: 1.05rem;
    line-height: 1.75;
    color: var(--color-text-muted);
}

.region-intro__inner strong {
    color: var(--color-ink);
    font-weight: 700;
}

.region-intro__inner .section-link {
    text-align: center;
}

/* ---------- Before/after: single widget (default homepage case) ---------- */
/* Full width within the page's normal container padding on mobile;
   contained and centered on larger screens rather than stretching edge
   to edge. */

.ba-single {
    max-width: 640px;
    margin-inline: auto;
}

.ba-single .ba-slide {
    flex: none;
    width: 100%;
}

/* ---------- Before/after: carousel (fallback for 2+ pairs) ---------- */

.ba-carousel {
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    display: flex;
    gap: var(--space-5);
    padding-bottom: var(--space-2);
}

.ba-slide {
    flex: 0 0 min(420px, 85vw);
    scroll-snap-align: start;
}

.ba {
    position: relative;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    border-radius: var(--radius-md);
    touch-action: pan-y;
    cursor: ew-resize;
    background: var(--color-surface-muted);
    user-select: none;
    border: 1px solid var(--color-border);
}

.ba__after,
.ba__before {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    pointer-events: none;
}

.ba__before {
    clip-path: inset(0 calc(100% - var(--ba-pos, 50%)) 0 0);
}

.ba__label {
    position: absolute;
    top: var(--space-3);
    padding: var(--space-1) var(--space-3);
    background: rgba(11, 31, 51, 0.75);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    border-radius: var(--radius-sm);
    pointer-events: none;
}

.ba__label--before {
    left: var(--space-3);
}

.ba__label--after {
    right: var(--space-3);
}

.ba__handle {
    position: absolute;
    top: 0;
    bottom: 0;
    left: var(--ba-pos, 50%);
    width: 0;
    pointer-events: none;
}

.ba__handle::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 2px;
    background: #fff;
    transform: translateX(-50%);
}

.ba__handle-grip {
    position: absolute;
    top: 50%;
    left: 0;
    transform: translate(-50%, -50%);
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #fff;
    box-shadow: var(--shadow-md);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-ink);
}

.ba-slide__caption {
    margin-top: var(--space-3);
    font-size: 0.9rem;
    color: var(--color-text-muted);
}

.ba-note {
    margin-top: var(--space-5);
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

/* ---------- Value props ---------- */
/* Premium "frosted glass" card treatment: a soft gradient wash behind the
   section gives the semi-transparent, blurred cards something worth
   blurring, so the effect actually reads instead of just looking like a
   plain white box. Shared by every page that uses this component (both
   homepage instances + the location pages), so the enhancement is
   consistent everywhere at once rather than needing to be duplicated. */

.value-props {
    position: relative;
    padding-block: var(--space-7);
    background: linear-gradient(180deg, var(--color-surface) 0%, var(--color-surface-muted) 100%);
}

.value-props__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--space-5);
    margin-top: var(--space-5);
}

/* Dark glassy gradient card — deliberately darker than the section's own
   light background, so it reads as an elevated, premium surface (the same
   navy the hero/CTA bands already use, just as a translucent card rather
   than a full section). */
.value-props__item {
    padding: var(--space-5);
    background: linear-gradient(135deg, rgba(11, 31, 51, 0.94) 0%, rgba(28, 51, 80, 0.88) 100%);
    backdrop-filter: blur(14px) saturate(160%);
    -webkit-backdrop-filter: blur(14px) saturate(160%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: var(--radius-lg);
    box-shadow: 0 8px 28px rgba(11, 31, 51, 0.18);
    transition: transform var(--transition-base), box-shadow var(--transition-base);
}

.value-props__item:hover {
    transform: translateY(-4px);
    box-shadow: 0 16px 36px rgba(11, 31, 51, 0.28);
}

.value-props__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
    color: #fff;
    box-shadow: 0 6px 16px rgba(224, 127, 16, 0.3);
    margin-bottom: var(--space-4);
}

/* Alternating icon treatment: odd cards keep the accent gradient above,
   even cards switch to a frosted glass badge (same language as the hero
   slide badges) — navy-on-navy would disappear against the dark card, so
   this reuses the light-glass alternative instead of a flat navy repeat. */
.value-props__item:nth-child(even) .value-props__icon {
    background: rgba(255, 255, 255, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.25);
    box-shadow: none;
    color: #fff;
}

.value-props__item h3 {
    color: #fff;
    font-size: 1.05rem;
    margin-bottom: var(--space-2);
}

.value-props__item p {
    color: rgba(255, 255, 255, 0.72);
    margin-bottom: 0;
}

/* ---------- Services showcase (homepage) ---------- */

.service-showcase {
    padding-block: var(--space-6);
}

@media (min-width: 720px) {
    .service-showcase {
        padding-block: var(--space-8);
    }
}

/* Category filter tabs */
.service-tabs {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-2);
    margin-bottom: var(--space-6);
}

.service-tabs__btn {
    padding: var(--space-2) var(--space-5);
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text);
    font-weight: 700;
    font-size: 0.88rem;
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
}

.service-tabs__btn:hover {
    border-color: var(--color-accent);
    color: var(--color-accent-dark);
}

.service-tabs__btn.is-active {
    background: var(--color-ink);
    border-color: var(--color-ink);
    color: #fff;
}

/* Horizontal scroller */
.service-scroller {
    position: relative;
}

.service-scroller__track {
    display: flex;
    gap: var(--space-5);
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scroll-padding-left: var(--space-2);
    padding-block: var(--space-2) var(--space-4);
    margin: 0 calc(var(--space-2) * -1);
    padding-inline: var(--space-2);
    scrollbar-width: thin;
}

.service-scroller__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    color: var(--color-ink);
    box-shadow: var(--shadow-md);
    display: none;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 2;
}

.service-scroller__nav:hover {
    background: var(--color-accent);
    border-color: var(--color-accent);
    color: #fff;
}

.service-scroller__nav--prev {
    left: 0;
}

.service-scroller__nav--next {
    right: 0;
}

@media (min-width: 1180px) {
    .service-scroller__nav {
        display: flex;
    }
}

.service-showcase__card {
    flex: 0 0 270px;
    scroll-snap-align: start;
    display: flex;
    flex-direction: column;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    transition: transform var(--transition-base), box-shadow var(--transition-base), border-color var(--transition-base);
}

.service-showcase__card[hidden] {
    display: none;
}

.service-showcase__card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-md);
    border-color: rgba(224, 127, 16, 0.4);
}

/* Real photo cover (see data/service-images.php) with a bottom scrim so
   the category badge stays legible over any photo, plus a subtle
   hover-zoom on the image itself. */
.service-showcase__cover {
    position: relative;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background: var(--color-surface-muted);
}

.service-showcase__cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 500ms ease;
}

.service-showcase__card:hover .service-showcase__cover img {
    transform: scale(1.08);
}

.service-showcase__cover::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(11, 31, 51, 0) 55%, rgba(11, 31, 51, 0.5) 100%);
}

.service-showcase__badge {
    position: absolute;
    top: var(--space-3);
    left: var(--space-3);
    z-index: 1;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 6px 16px rgba(224, 127, 16, 0.35);
    transition: transform var(--transition-base);
}

.service-showcase__badge .icon {
    width: 20px;
    height: 20px;
}

.service-showcase__card:hover .service-showcase__badge {
    transform: scale(1.08);
}

.service-showcase__body {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: var(--space-5);
}

.service-showcase__category {
    color: var(--color-accent-dark);
    font-weight: 700;
    font-size: 0.76rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    margin-bottom: var(--space-2);
}

.service-showcase__body h3 {
    font-size: 1.1rem;
    margin-bottom: var(--space-2);
}

.service-showcase__body > p {
    color: var(--color-text-muted);
    font-size: 0.92rem;
    margin-bottom: var(--space-4);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.service-showcase__features {
    list-style: none;
    padding: 0;
    margin: 0 0 var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.service-showcase__features li {
    position: relative;
    padding-left: var(--space-4);
    font-size: 0.82rem;
    color: var(--color-text-muted);
}

.service-showcase__features li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.5em;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--color-accent);
}

.service-showcase__link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: auto;
    color: var(--color-accent-dark);
    font-weight: 700;
    font-size: 0.92rem;
}

.service-showcase__link .icon {
    transition: transform var(--transition-fast);
}

.service-showcase__card:hover .service-showcase__link .icon {
    transform: translateX(3px);
}

/* ---------- Process steps ---------- */
/* Numbered circles connected by a line (via ::before on the list),
   each step's heading/text sitting in the same dark glass card used by
   .value-props__item — same background gradient, so the two sections
   read as one consistent "glass card" language. */

.process-steps {
    padding-block: var(--space-7);
    background: linear-gradient(180deg, var(--color-surface) 0%, var(--color-surface-muted) 100%);
}

.process-steps__list {
    list-style: none;
    padding: 0;
    margin: var(--space-6) 0 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
    position: relative;
}

.process-steps__item {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: var(--space-4);
    text-align: left;
}

.process-steps__number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
    color: #fff;
    font-weight: 800;
    font-size: 1.05rem;
    box-shadow: 0 8px 20px rgba(224, 127, 16, 0.35);
}

.process-steps__card {
    flex: 1;
    padding: var(--space-5);
    background: linear-gradient(135deg, rgba(11, 31, 51, 0.94) 0%, rgba(28, 51, 80, 0.88) 100%);
    backdrop-filter: blur(14px) saturate(160%);
    -webkit-backdrop-filter: blur(14px) saturate(160%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: var(--radius-lg);
    box-shadow: 0 8px 28px rgba(11, 31, 51, 0.16);
    transition: transform var(--transition-base), box-shadow var(--transition-base);
}

.process-steps__item:hover .process-steps__card {
    transform: translateY(-4px);
    box-shadow: 0 16px 36px rgba(11, 31, 51, 0.26);
}

.process-steps__card h3 {
    color: #fff;
    font-size: 1rem;
    margin-bottom: var(--space-2);
}

.process-steps__card p {
    color: rgba(255, 255, 255, 0.72);
    margin-bottom: 0;
    font-size: 0.92rem;
}

/* Connecting line: vertical on mobile (runs through the number circles'
   center, left-aligned), horizontal on desktop where steps sit in a row. */
.process-steps__list::before {
    content: "";
    position: absolute;
    z-index: 0;
    left: 23px;
    top: 24px;
    bottom: 24px;
    width: 2px;
    background: var(--color-border);
}

@media (min-width: 900px) {
    .process-steps__list {
        display: grid;
        grid-template-columns: repeat(var(--step-count, 6), 1fr);
        gap: var(--space-4);
    }

    .process-steps__item {
        flex-direction: column;
        align-items: center;
        text-align: center;
    }

    .process-steps__list::before {
        left: calc(100% / var(--step-count, 6) / 2);
        right: calc(100% / var(--step-count, 6) / 2);
        top: 24px;
        bottom: auto;
        width: auto;
        height: 2px;
        background: linear-gradient(90deg, var(--color-border), var(--color-accent), var(--color-border));
    }
}

/* ---------- Status banner (form feedback) ---------- */

.status-banner {
    padding: var(--space-4) var(--space-5);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-5);
    font-weight: 600;
}

.status-banner--success {
    background: #e8f5ec;
    color: #1f7a4d;
    border: 1px solid #b9e0c6;
}

.status-banner--error {
    background: #fdecea;
    color: #8a2c22;
    border: 1px solid #f3b4ac;
}

.status-banner a {
    color: inherit;
}

/* ---------- Contact layout ---------- */
/* Same dark glassy gradient card used for value-props/process-steps/
   service-card elsewhere on the site, applied to both the form and the
   "reach us directly" aside so the two read as one deliberate pair. */

.contact-layout {
    display: grid;
    gap: var(--space-6);
}

.contact-form-card,
.contact-layout__aside {
    padding: var(--space-6);
    border-radius: var(--radius-lg);
    background: linear-gradient(135deg, rgba(11, 31, 51, 0.94) 0%, rgba(28, 51, 80, 0.88) 100%);
    backdrop-filter: blur(14px) saturate(160%);
    -webkit-backdrop-filter: blur(14px) saturate(160%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 8px 28px rgba(11, 31, 51, 0.18);
    color: #fff;
}

.contact-form-card h2,
.contact-layout__aside h2 {
    color: #fff;
    font-size: 1.3rem;
    margin-bottom: var(--space-2);
}

.contact-form-card > p,
.contact-layout__aside > p {
    color: rgba(255, 255, 255, 0.72);
    margin-bottom: var(--space-5);
}

.contact-layout__aside {
    align-self: start;
    display: flex;
    flex-direction: column;
}

.contact-layout__actions {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-top: auto;
}

.contact-layout__actions .btn {
    width: 100%;
}

/* Form fields need light-on-dark treatment inside the card — the base
   .form-field rules stay light-surface (in case the form is ever reused
   somewhere without the dark card), these just override for this context. */
.contact-form-card .form-field label {
    color: rgba(255, 255, 255, 0.85);
}

.contact-form-card .form-field input[type="text"],
.contact-form-card .form-field input[type="tel"],
.contact-form-card .form-field select,
.contact-form-card .form-field textarea {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 255, 255, 0.2);
    color: #fff;
}

.contact-form-card .form-field input::placeholder,
.contact-form-card .form-field textarea::placeholder {
    color: rgba(255, 255, 255, 0.4);
}

.contact-form-card .form-field select option {
    color: var(--color-text);
    background: var(--color-surface);
}

.contact-form-card .enquiry-form fieldset legend,
.contact-form-card .enquiry-form fieldset label {
    color: rgba(255, 255, 255, 0.85);
}

@media (min-width: 860px) {
    .contact-layout {
        grid-template-columns: 2fr 1fr;
        align-items: start;
    }
}

/* ---------- Large desktop ---------- */

@media (min-width: 1440px) {
    .container {
        max-width: 1320px;
    }
}

/* ---------- Cross-links (same service in other cities) ---------- */
/* Used by templates/service-location.php under "{Service} in Other
   Cities". Deliberately chips rather than cards: these are sideways
   navigational links between sibling pages, so they shouldn't carry the
   same visual weight as the content cards above them. Mobile-first —
   one per row on a phone, widening to four across on desktop. */

.crosslinks {
    list-style: none;
    padding: 0;
    margin: var(--space-4) 0 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-3);
}

.crosslinks a {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    height: 100%;
    padding: var(--space-3) var(--space-4);
    background: var(--color-surface-muted);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    color: var(--color-text);
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    transition: border-color var(--transition-base),
                transform var(--transition-base),
                color var(--transition-base);
}

.crosslinks a:hover,
.crosslinks a:focus-visible {
    border-color: var(--color-accent);
    color: var(--color-accent-dark);
    transform: translateY(-2px);
}

.crosslinks .icon {
    color: var(--color-accent);
    flex-shrink: 0;
}

@media (min-width: 600px) {
    .crosslinks {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (min-width: 960px) {
    .crosslinks {
        grid-template-columns: repeat(4, 1fr);
    }
}

/* ---------- Nav accordions (Service Locations panel) ---------- */
/* Native <details>/<summary> (see partials/nav.php): the open/close
   behaviour, keyboard support and ARIA semantics come from the browser,
   so there is no JS to keep accessible by hand. Only the default marker
   is replaced, with a chevron that rotates on [open]. */

.nav-acc {
    border-top: 1px solid var(--color-border);
}

.nav-acc:first-of-type {
    border-top: none;
}

.nav-acc__summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-2);
    font-weight: 600;
    color: var(--color-ink);
    cursor: pointer;
    border-radius: var(--radius-sm);
    list-style: none;
}

/* Hide the default disclosure triangle in both engines. */
.nav-acc__summary::-webkit-details-marker {
    display: none;
}

.nav-acc__summary::marker {
    content: '';
}

.nav-acc__summary:hover {
    background: var(--color-surface-muted);
}

.nav-acc__chevron {
    flex-shrink: 0;
    color: var(--color-accent);
    transition: transform var(--transition-base);
}

.nav-acc[open] > .nav-acc__summary .nav-acc__chevron {
    transform: rotate(180deg);
}

.nav-acc__body {
    padding: 0 0 var(--space-2) var(--space-3);
}

/* Keeps each city hub one tap away even though the individual location
   links are no longer top-level nav items. */
.nav-acc__hub {
    display: block;
    padding: var(--space-2);
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--color-accent-dark);
    text-decoration: none;
}

.nav-acc__hub:hover {
    text-decoration: underline;
}

.nav-acc--sub > .nav-acc__summary {
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-muted);
    padding-block: var(--space-2);
}

.nav-acc__links {
    list-style: none;
    margin: 0;
    padding: 0 0 var(--space-2) var(--space-3);
}

.nav-acc__links a {
    display: block;
    padding: var(--space-2) 0;
    font-size: 0.88rem;
    color: var(--color-text);
    text-decoration: none;
}

.nav-acc__links a:hover {
    color: var(--color-accent-dark);
}

@media (min-width: 960px) {
    /* The shared .mega-menu desktop rule lays panels out as five columns,
       which suits the Services panel. The locations panel is a stack of
       disclosures that grow downwards instead, so it gets a single narrow
       column and scrolls internally rather than running off the viewport. */
    .mega-menu--locations {
        grid-template-columns: 1fr;
        min-width: 360px;
        max-height: 72vh;
        overflow-y: auto;
    }
}

/* ---------- Location index (/locations/) ---------- */

.location-index {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-5);
    margin-top: var(--space-5);
}

.location-index__card {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-5);
    background: linear-gradient(135deg, rgba(11, 31, 51, 0.94) 0%, rgba(28, 51, 80, 0.88) 100%);
    backdrop-filter: blur(14px) saturate(160%);
    -webkit-backdrop-filter: blur(14px) saturate(160%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: var(--radius-md);
    color: #fff;
    transition: border-color var(--transition-base), transform var(--transition-base);
}

.location-index__card:hover {
    border-color: var(--color-accent);
    transform: translateY(-3px);
}

.location-index__card h3 {
    margin: 0;
    color: #fff;
}

.location-index__card h3 a {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: #fff;
    text-decoration: none;
}

.location-index__card h3 a:hover {
    color: var(--color-accent);
}

.location-index__card h3 .icon {
    color: var(--color-accent);
}

.location-index__areas {
    margin: 0;
    font-size: 0.88rem;
    color: #c3cdd6;
}

.location-index__links {
    list-style: none;
    margin: var(--space-2) 0 var(--space-3);
    padding: 0;
    display: grid;
    gap: var(--space-1);
}

.location-index__links a {
    color: #d9e2ec;
    text-decoration: none;
    font-size: 0.9rem;
}

.location-index__links a:hover {
    color: var(--color-accent);
}

.location-index__card .service-card__link {
    margin-top: auto;
}

@media (min-width: 600px) {
    .location-index {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (min-width: 960px) {
    .location-index {
        grid-template-columns: repeat(3, 1fr);
    }
}

/* ==================================================================
   Later overrides — these intentionally sit at the end of the file so
   they win over the earlier base rules at equal specificity.
   ================================================================== */

/* ---------- Logo sizing + header height ---------- */
/* The header bar is sized from --header-height, so growing the logo means
   growing the bar with it or the mark gets clipped. Both scale together. */

:root {
    --header-height: 76px;
}

@media (min-width: 600px) {
    :root { --header-height: 82px; }
}

@media (min-width: 960px) {
    :root { --header-height: 90px; }
}

.brand-lockup__logo {
    height: 55px;
}

@media (min-width: 600px) {
    .brand-lockup__logo { height: 60px; }
}

@media (min-width: 960px) {
    .brand-lockup__logo { height: 64px; }
}

/* ---------- Hero: service-locations strip ---------- */
/* Replaces the old H1 + standfirst. Deliberately small and single-line on
   a phone — it should read as a credential line, not a heading, and must
   not push the slide content below the fold. */

.hero-locations {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 6px 10px;
    margin: 0 0 var(--space-5);
}

.hero-locations__label {
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.5);
}

.hero-locations__list {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 8px;
    list-style: none;
    margin: 0;
    padding: 0;
}

.hero-locations__list li {
    display: flex;
    align-items: baseline;
}

/* Accent dot between cities instead of a comma — keeps the row scannable
   when it wraps to two lines on a narrow phone. */
.hero-locations__list li + li::before {
    content: "";
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--color-accent);
    margin-right: 8px;
    transform: translateY(-3px);
}

.hero-locations__list a {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.92);
    text-decoration: none;
    transition: color var(--transition-fast);
}

.hero-locations__list a:hover,
.hero-locations__list a:focus-visible {
    color: var(--color-accent);
}

@media (min-width: 600px) {
    .hero-locations__label { font-size: 0.68rem; }
    .hero-locations__list a { font-size: 0.78rem; }
}

@media (min-width: 960px) {
    .hero-locations__list a { font-size: 0.85rem; }
}

/* ---------- Hero: shorter on phones so the photo crops less ---------- */
/* A 4:3 photo inside a tall portrait hero has to lose most of its width to
   cover the box. Trimming the hero height on small screens brings the box
   closer to the photo's own shape, so noticeably more of each image shows. */

@media (max-width: 599px) {
    .hero {
        min-height: 520px;
        padding-block: var(--space-6) var(--space-8);
    }

    .hero__bg-slide {
        background-position: center center;
    }
}

/* Slide CTAs: a size down, so the pair fits one row on a small phone. */
.hero-slide__actions .btn {
    padding: var(--space-2) var(--space-4);
    font-size: 0.8rem;
}

@media (min-width: 600px) {
    .hero-slide__actions .btn { font-size: 0.88rem; }
}

/* ---------- CTA parallax ---------- */
/* The photo stays pinned to the viewport while the band scrolls over it.
   Note: iOS Safari supports background-attachment: fixed but sizes the
   image to the viewport rather than the element, so the crop is tighter
   there than on desktop — the effect still reads correctly. */

.cta-block--parallax.cta-block--photo {
    background-attachment: fixed;
    background-position: center;
    background-size: cover;
}

/* ---------- Floating call / WhatsApp ---------- */

.floating-actions {
    position: fixed;
    right: 14px;
    bottom: 14px;
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.floating-actions__btn {
    position: relative;
    width: 50px;
    height: 50px;
    border-radius: 999px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    box-shadow: 0 6px 18px rgba(11, 31, 51, 0.3);
    transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}

.floating-actions__btn--whatsapp { background: #25d366; }
.floating-actions__btn--call { background: var(--color-accent); }

.floating-actions__btn:hover,
.floating-actions__btn:focus-visible {
    transform: translateY(-3px) scale(1.04);
    box-shadow: 0 10px 24px rgba(11, 31, 51, 0.38);
}

/* Expanding ring, staggered so the two buttons don't pulse in lockstep. */
.floating-actions__btn::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 999px;
    border: 2px solid currentColor;
    opacity: 0;
    animation: floating-pulse 2.6s ease-out infinite;
}

.floating-actions__btn--call::after { animation-delay: 1.3s; }

@keyframes floating-pulse {
    0%   { transform: scale(1);    opacity: 0.5; }
    70%  { transform: scale(1.55); opacity: 0; }
    100% { transform: scale(1.55); opacity: 0; }
}

.floating-actions__tip {
    position: absolute;
    right: calc(100% + 10px);
    white-space: nowrap;
    background: var(--color-ink);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    padding: 6px 10px;
    border-radius: var(--radius-sm);
    opacity: 0;
    pointer-events: none;
    transform: translateX(6px);
    transition: opacity var(--transition-fast), transform var(--transition-fast);
}

.floating-actions__btn:hover .floating-actions__tip,
.floating-actions__btn:focus-visible .floating-actions__tip {
    opacity: 1;
    transform: translateX(0);
}

@media (prefers-reduced-motion: reduce) {
    .floating-actions__btn,
    .floating-actions__btn::after,
    .floating-actions__tip {
        animation: none;
        transition: none;
    }
}

/* ---------- Mobile drawer (redesign) ---------- */
/* Full-height dark sheet that slides down from under the header, using the
   site's existing ink/accent palette rather than a new one. The header bar
   itself stays put above it, which keeps the logo visible and means the
   toggle never has to change colour to stay legible.
   Desktop (>=960px) is unaffected — see the media query further down. */

@media (max-width: 959px) {
    .primary-nav {
        background: var(--color-ink);
        padding: var(--space-5) var(--space-5) var(--space-6);
        display: flex;
        flex-direction: column;
        width: 100%;
        max-width: 100vw;
        overflow-x: hidden;
        transform: translateY(-100%);
        opacity: 1;
        visibility: hidden;
        transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1), visibility 0.3s;
    }

    .primary-nav.is-open {
        transform: translateY(0);
        visibility: visible;
    }

    /* Soft off-brand-ground shape in the corner, purely decorative. */
    .primary-nav__blob {
        position: absolute;
        right: -110px;
        bottom: -140px;
        width: 320px;
        height: 320px;
        max-width: 100vw;
        border-radius: 999px;
        background: rgba(255, 255, 255, 0.045);
        pointer-events: none;
    }

    .primary-nav__kicker {
        position: relative;
        display: block;
        font-size: 0.66rem;
        font-weight: 700;
        letter-spacing: 0.2em;
        text-transform: uppercase;
        color: rgba(255, 255, 255, 0.42);
        margin-bottom: var(--space-2);
    }

    .primary-nav__list {
        position: relative;
        gap: 0;
        padding: 0;
        flex: 1 1 auto;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Top-level rows: large, generously spaced, hairline separated. */
    .primary-nav__list > li:not(.primary-nav__cta) > a,
    .mega-trigger {
        font-size: 1.2rem;
        font-weight: 700;
        color: #fff;
        padding: var(--space-3) 0;
        border-bottom: 1px solid rgba(255, 255, 255, 0.12);
        border-radius: 0;
        justify-content: flex-start;
    }

    .primary-nav__list > li:first-child > a {
        border-top: 1px solid rgba(255, 255, 255, 0.12);
    }

    .primary-nav__list > li:not(.primary-nav__cta) > a:hover,
    .mega-trigger:hover {
        background: none;
        color: var(--color-accent);
    }

    .primary-nav__icon {
        color: var(--color-accent);
    }

    .mega-trigger[aria-expanded="true"] {
        color: var(--color-accent);
    }

    /* Panels inside the dark sheet need the inverse of their light-mode
       colours, or they render as near-invisible dark-on-dark text. */
    .mega-menu {
        padding: var(--space-2) 0 var(--space-3) var(--space-3);
    }

    .mega-menu__heading {
        color: rgba(255, 255, 255, 0.45);
    }

    .mega-menu__group a {
        color: rgba(255, 255, 255, 0.86);
        padding: var(--space-2) 0;
    }

    .mega-menu__group a:hover {
        color: var(--color-accent);
    }

    .nav-acc {
        border-top-color: rgba(255, 255, 255, 0.1);
    }

    .nav-acc__summary {
        color: rgba(255, 255, 255, 0.94);
    }

    .nav-acc__summary:hover {
        background: rgba(255, 255, 255, 0.05);
    }

    .nav-acc--sub > .nav-acc__summary {
        color: rgba(255, 255, 255, 0.5);
    }

    .nav-acc__hub {
        color: var(--color-accent);
    }

    .nav-acc__links a {
        color: rgba(255, 255, 255, 0.82);
    }

    .nav-acc__links a:hover {
        color: var(--color-accent);
    }

    /* Pinned action block at the foot of the sheet. */
    .primary-nav__foot {
        position: relative;
        flex: 0 0 auto;
        display: flex;
        flex-direction: column;
        gap: var(--space-2);
        padding-top: var(--space-5);
        margin-top: var(--space-4);
        border-top: 1px solid rgba(255, 255, 255, 0.12);
    }

    .primary-nav__foot .btn {
        width: 100%;
    }

    .primary-nav__tel {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: var(--space-2);
        padding-top: var(--space-2);
        font-size: 0.85rem;
        font-weight: 600;
        letter-spacing: 0.04em;
        color: rgba(255, 255, 255, 0.55);
        text-decoration: none;
    }

    .primary-nav__tel .icon {
        color: var(--color-accent);
    }
}

/* Toggle morphs into an X while the sheet is open. The first child is the
   sr-only label, so the three bars are children 2-4. */
.nav-toggle__bar {
    transition: transform 0.22s ease, opacity 0.18s ease;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) {
    transform: translateY(6px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) {
    opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(4) {
    transform: translateY(-6px) rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
    .primary-nav,
    .nav-toggle__bar {
        transition: none;
    }
}

/* Desktop: the actions block flows back onto the bar beside the links. */
@media (min-width: 960px) {
    .primary-nav {
        display: flex;
        align-items: center;
        gap: var(--space-5);
    }

    .primary-nav__kicker,
    .primary-nav__blob,
    .primary-nav__tel {
        display: none;
    }

    .primary-nav__foot {
        display: flex;
        align-items: center;
        gap: var(--space-2);
        margin: 0;
        padding: 0;
        border: none;
    }

    .primary-nav__foot .primary-nav__cta--whatsapp {
        display: none;
    }

    .primary-nav__cta {
        width: auto;
        margin: 0;
    }
}

/* ---------- Menu refinements ---------- */

/* Chevron on the two mega triggers: they are disclosures, so they should
   signal that the same way the nested location accordions do. */
.mega-trigger {
    justify-content: space-between;
}

.mega-trigger__chevron {
    margin-left: auto;
    flex-shrink: 0;
    color: var(--color-accent);
    transition: transform var(--transition-base);
}

.mega-trigger[aria-expanded="true"] .mega-trigger__chevron {
    transform: rotate(180deg);
}

@media (max-width: 959px) {
    /* The drawer itself scrolls, not the link list. Previously the list was
       its own scroll container with flex:1, which squeezed the rows into a
       short window and hid items behind an inner scrollbar even when the
       sheet had room to spare. Now every top-level item is visible at once,
       and scrolling only kicks in once an accordion is expanded past the
       bottom of the screen. */
    .primary-nav {
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }

    .primary-nav__list {
        flex: 0 0 auto;
        overflow: visible;
    }

    /* margin-top:auto keeps the actions pinned to the bottom while there is
       spare height, and lets them flow naturally once there isn't. */
    .primary-nav__foot {
        margin-top: auto;
    }

    /* The quote button is dropped from the drawer: WhatsApp, the phone
       number below it and the floating call button already cover the same
       intent, and removing it keeps every menu item on one screen.
       It still shows on the desktop bar. */
    .primary-nav__foot .primary-nav__cta:not(.primary-nav__cta--whatsapp) {
        display: none;
    }

    /* Desktop hides the chevron (the panel opens on hover there). */
    .mega-trigger__chevron {
        display: inline-flex;
    }
}

@media (min-width: 960px) {
    .mega-trigger__chevron {
        display: none;
    }
}

/* ---------- "All surrounding areas" chip ---------- */
/* Closes the neighbourhood list on location and service-location pages.
   Accent-filled so it reads as a summary of the list rather than one more
   area in it. */

.service-area__list-item--all {
    background: linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-dark) 100%);
    border-color: var(--color-accent);
    color: var(--color-accent-contrast);
    font-weight: 700;
    letter-spacing: 0.01em;
}

/* ---------- Header auto-hide on scroll ---------- */
/* Hides while scrolling down the page, returns the moment the user scrolls
   back up (and is always visible at the top). See assets/js/header-scroll.js.
   Deliberately NO will-change: transform here — the mobile drawer is a
   position:fixed child of the header, and any transform (or will-change for
   one) on an ancestor makes that drawer position itself against the header
   box instead of the viewport. The JS never hides the header while the menu
   is open, so the transform is only ever live when the drawer is closed. */

.site-header {
    transition: transform 0.28s ease;
}

.site-header--hidden {
    transform: translateY(-100%);
}

@media (prefers-reduced-motion: reduce) {
    .site-header {
        transition: none;
    }
}

/* ---------- Header positioning ---------- */
/* The header was declared position:sticky, but it never actually stuck:
   html and body both set overflow-x:hidden (base.css), which computes
   overflow-y to auto and turns them into scroll containers — and sticky
   stops working as soon as an ancestor has non-visible overflow. The
   header simply scrolled away and never came back, which is why toggling
   .site-header--hidden had no visible effect.

   Fixed positioning is used instead of deleting those overflow-x rules,
   because they are what stops full-bleed sections from producing a
   horizontal scrollbar. body then carries matching top padding so the
   first section still starts below the bar, exactly as before. */

.site-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
}

body {
    padding-top: var(--header-height);
}

/* ---------- Service card: photo cover ---------- */
/* These cards now lead with the service's real photo, matching the
   homepage showcase cards — the same service used to look quite different
   depending on which page you reached it from. Padding moves from the card
   onto .service-card__body so the image sits flush to the rounded edge. */

.service-card {
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
}

.service-card__cover {
    display: block;
    aspect-ratio: 5 / 3;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.04);
}

.service-card__cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform var(--transition-base);
}

.service-card:hover .service-card__cover img {
    transform: scale(1.04);
}

.service-card__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-5);
    flex: 1 1 auto;
}

.service-card__body p {
    margin: 0;
}

/* Pins the link to the bottom so cards in a row align regardless of how
   long each summary runs. */
.service-card__body .service-card__link {
    margin-top: auto;
    padding-top: var(--space-2);
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

/* The cover repeats the title link, so it is hidden from assistive tech
   (aria-hidden + tabindex="-1" in the markup) rather than announced twice. */
@media (prefers-reduced-motion: reduce) {
    .service-card__cover img {
        transition: none;
    }
}

/* ---------- Local context (service x location pages) ---------- */
/* Carries the city-specific copy that differentiates the 50 location pages
   from one another. Two columns on desktop, stacked on mobile. */

.local-context {
    padding-block: var(--space-6);
}

.local-context__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-4);
    margin-top: var(--space-5);
}

.local-context__col {
    padding: var(--space-5);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface-muted);
}

.local-context__col--accent {
    background: linear-gradient(135deg, rgba(11, 31, 51, 0.94) 0%, rgba(28, 51, 80, 0.88) 100%);
    border-color: rgba(255, 255, 255, 0.08);
    color: #fff;
}

.local-context__col h3 {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: 1.05rem;
    margin-bottom: var(--space-3);
}

.local-context__col--accent h3 {
    color: #fff;
}

.local-context__col h3 .icon {
    color: var(--color-accent);
    flex-shrink: 0;
}

.local-context__col p {
    margin: 0 0 var(--space-3);
}

.local-context__col p:last-child {
    margin-bottom: 0;
}

.local-context__col--accent p {
    color: rgba(255, 255, 255, 0.82);
}

.local-context__areas {
    font-size: 0.9rem;
}

.local-context__col--accent .local-context__areas strong {
    color: var(--color-accent);
}

@media (min-width: 860px) {
    .local-context__grid {
        grid-template-columns: 1.15fr 1fr;
        gap: var(--space-5);
    }
}

/* Per-city checklist under the local-context columns. */
.local-context__notes {
    margin-top: var(--space-5);
    padding: var(--space-5);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}

.local-context__notes h3 {
    font-size: 1.05rem;
    margin-bottom: var(--space-3);
}

.local-context__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-3);
}

.local-context__list li {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
}

.local-context__list .icon {
    color: var(--color-accent);
    flex-shrink: 0;
    margin-top: 3px;
}

@media (min-width: 860px) {
    .local-context__list {
        grid-template-columns: repeat(3, 1fr);
    }
}

/* ---------- Framed feature shot (service x location pages) ---------- */
/* One strong photo under the hero, replacing the repeated carousel. The
   frame is a double border: an accent hairline inside a soft outer ring,
   with an offset shadow so the image reads as a deliberate plate rather
   than a raw <img> dropped on the page. */

.feature-shot {
    padding-block: var(--space-6) var(--space-4);
}

.feature-shot__inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-4);
}

.feature-shot__frame {
    position: relative;
    margin: 0;
    width: 100%;
    max-width: 900px;
    padding: 8px;
    border-radius: var(--radius-lg);
    background: linear-gradient(135deg, var(--color-accent) 0%, rgba(11, 31, 51, 0.9) 100%);
    box-shadow: 0 14px 38px rgba(11, 31, 51, 0.22);
}

.feature-shot__frame img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: calc(var(--radius-lg) - 4px);
    border: 2px solid rgba(255, 255, 255, 0.9);
}

/* Sits over the lower edge of the photo, so the frame stays tight to the
   image instead of growing a caption bar underneath it. */
.feature-shot__caption {
    position: absolute;
    left: var(--space-5);
    bottom: var(--space-5);
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 6px 12px;
    border-radius: 999px;
    background: rgba(11, 31, 51, 0.82);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    color: #fff;
    font-size: 0.78rem;
    font-weight: 600;
}

.feature-shot__caption .icon {
    color: var(--color-accent);
}

.feature-shot__cta {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-5);
    border: 2px solid var(--color-accent);
    border-radius: 999px;
    color: var(--color-accent-dark);
    font-weight: 700;
    font-size: 0.92rem;
    text-decoration: none;
    transition: background var(--transition-fast), color var(--transition-fast),
                transform var(--transition-fast);
}

.feature-shot__cta:hover,
.feature-shot__cta:focus-visible {
    background: var(--color-accent);
    color: var(--color-accent-contrast);
    transform: translateY(-2px);
}

.feature-shot__cta .icon {
    transition: transform var(--transition-fast);
}

.feature-shot__cta:hover .icon {
    transform: translateX(3px);
}

@media (max-width: 599px) {
    .feature-shot__caption {
        left: var(--space-3);
        bottom: var(--space-3);
        font-size: 0.72rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .feature-shot__cta,
    .feature-shot__cta .icon {
        transition: none;
    }
}

/* ---------- Feature shot: taller on small screens ---------- */
/* 16/9 is only ~200px tall on a 360px phone, which is too shallow to read
   the installation detail. The crop deepens as the viewport narrows and
   relaxes back to a wide cinematic ratio on desktop, where the same ratio
   already gives plenty of height. */

.feature-shot__frame img {
    aspect-ratio: 4 / 3;
}

@media (min-width: 600px) {
    .feature-shot__frame img {
        aspect-ratio: 3 / 2;
    }
}

@media (min-width: 900px) {
    .feature-shot__frame img {
        aspect-ratio: 16 / 9;
    }
}

/* ---------- Overview -> SEO overview spacing ---------- */
/* These two sections sit directly against each other on the service and
   service x location pages, and their paddings stacked: page-section
   (32/48px) plus a flat 64px on .seo-overview gave a ~96px gap on mobile.
   The band now scales with the viewport like every other section, and the
   Overview block above it drops its bottom padding so the pair reads as one
   continuous passage rather than two separated blocks. */

.seo-overview {
    padding-block: var(--space-5);
}

@media (min-width: 720px) {
    .seo-overview {
        padding-block: var(--space-7);
    }
}

.page-section--flush-bottom {
    padding-bottom: 0;
}
