/*
Theme Name: Andy's Roofing
Theme URI: https://andysroofingct.com
Author: E11 Group
Author URI: https://e11group.com
Description: Child theme of Launchpad for Andy's Roofing — a family-owned Connecticut roofing company since 1931. Overrides brand colors, fonts, and patterns while inheriting Launchpad's block library and design system.
Template: launchpad
Tags: block-theme, full-site-editing, child-theme
Tested up to: 7.0
Requires PHP: 8.0
Version: 0.20.28
License: GNU General Public License v3 or later
License URI: https://www.gnu.org/licenses/gpl-3.0.html
Text Domain: andysroofing
Repository: E11-Group/andysroofing
*/

/* ============================================================
   Section tag (eyebrow with triangle) — used across patterns
   ============================================================ */
.ar-tag {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--wp--preset--color--accent);
}
.ar-tag::before {
    content: '▲';
    font-size: 0.625rem;
}
.ar-tag-navy {
    color: var(--wp--preset--color--primary);
}
p.ar-tag.has-text-align-center {
    display: flex;
    width: fit-content;
    margin-inline: auto;
}

/* ============================================================
   Section background textures
   ============================================================
   Applied via className on full-width groups. Image URLs are
   injected as CSS variables from functions.php (relative url()
   paths are unreliable in child themes).                       */
.ar-pattern-dark {
    background-color: var(--wp--preset--color--primary-dark);
    background-image: radial-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px);
    background-size: 20px 20px;
}
.ar-pattern-light {
    background-color: var(--wp--preset--color--surface);
    background-image: repeating-linear-gradient(45deg, rgba(32, 33, 81, 0.035) 0 2px, transparent 2px 16px);
}
.ar-texture-shingle {
    background-image:
        linear-gradient(rgba(21, 22, 58, 0.92), rgba(21, 22, 58, 0.9)),
        var(--ar-img-shingle);
    background-size: cover;
    background-position: center;
}
.ar-texture-shingle-gray {
    background-image:
        linear-gradient(rgba(15, 16, 32, 0.72), rgba(15, 16, 32, 0.78)),
        var(--ar-img-shingle-gray);
    background-size: cover;
    background-position: center;
}

/* ============================================================
   Header
   ============================================================ */
/* Utility bar phone */
.ar-utility-call {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 1.125rem;
    font-weight: 600;
    letter-spacing: 0.02em;
}
.ar-utility-call svg {
    color: var(--wp--preset--color--accent);
    flex: none;
}

/* Logo sizing (wordmark PNG) */
.header-logo-default img,
.ar-header-logo img {
    height: 46px;
    width: auto;
}

/* Nav: uppercase Oswald links with gold hover underline */
.ar-main-nav a {
    text-decoration: none;
}
.ar-main-nav .wp-block-navigation-item__content {
    position: relative;
}
@media (min-width: 782px) {
    .ar-main-nav .wp-block-navigation-item__content::before {
        content: '';
        position: absolute;
        left: 0;
        right: 0;
        bottom: -0.25rem;
        height: 2px;
        background: var(--wp--preset--color--accent);
        transform: scaleX(0);
        transform-origin: left;
        transition: transform 0.25s ease;
    }
    .ar-main-nav .wp-block-navigation-item__content:hover::before {
        transform: scaleX(1);
    }
}
/* Current page item in gold */
.ar-main-nav .current-menu-item > .wp-block-navigation-item__content {
    color: var(--wp--preset--color--accent);
}

/* Dropdown: the parent's nav-dropdown.css forces a white panel, but the
   header sets every nav link to white — so submenu items rendered white on
   white until hovered. Give them navy text on the panel (gold fails
   contrast on white, so the current page gets the hover tint instead). */
@media (min-width: 782px) {
    .ar-main-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
        color: var(--wp--preset--color--primary);
    }
    .ar-main-nav .wp-block-navigation__submenu-container .current-menu-item > .wp-block-navigation-item__content {
        color: var(--wp--preset--color--primary-dark);
        background-color: var(--wp--preset--color--primary-light);
    }
    .ar-main-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content::before {
        content: none;
    }
    /* The parent's margin-top floats the panel 0.75rem below the trigger,
       and the pointer leaves the hover target crossing that gap, closing the
       menu before it can be reached. An invisible strip, part of the panel,
       spans the gap (and the 1px border) so hover never breaks. */
    .ar-main-nav .wp-block-navigation__submenu-container::before {
        content: "";
        position: absolute;
        top: calc(-0.75rem - 1px);
        left: 0;
        right: 0;
        height: calc(0.75rem + 1px);
    }
}

/* ============================================================
   Buttons: subtle lift on hover (motion system)
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
    .wp-block-button__link {
        transition: background-color 0.15s ease, color 0.15s ease,
            transform 0.2s ease, box-shadow 0.2s ease;
    }
    .wp-block-button__link:hover {
        transform: translateY(-2px);
        box-shadow: 0 8px 20px rgba(21, 22, 58, 0.2);
    }
    .wp-block-button__link:active {
        transform: translateY(0) scale(0.98);
        box-shadow: none;
    }
}

/* ============================================================
   Gold-check list — used in service patterns
   ============================================================ */
ul.ar-checks {
    list-style: none;
    padding-inline-start: 0;
}
ul.ar-checks li {
    display: flex;
    gap: 0.625rem;
    align-items: baseline;
    font-size: 0.9375rem;
    margin-bottom: 0.625rem;
}
ul.ar-checks li::before {
    /* Bare check glyph — no circle. The tick carries the accent colour
       itself now, so it needs to be larger than it was inside the disc. */
    content: '✓';
    flex: none;
    font-weight: 700;
    color: var(--wp--preset--color--accent);
    font-size: 1.0625rem;
    line-height: 1;
    transform: translateY(2px);
}

/* ============================================================
   Outlined numerals (01/02/03 accents)
   ============================================================ */
.ar-why-item p.ar-num,
.ar-sign-card p.ar-num,
p.ar-num,
.ar-num {
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 700;
    font-size: 2.5rem;
    line-height: 1;
    color: transparent;
    -webkit-text-stroke: 1.5px var(--wp--preset--color--accent);
}

/* ============================================================
   Footer
   ============================================================ */
.ar-footer-logo img {
    height: 42px;
    width: auto;
}
/* theme.json's global link color (primary navy) is invisible on the
   dark footer — double selector beats the global elements rule */
.site-footer a:not(.wp-block-button__link),
footer.site-footer a:not(.wp-block-button__link) {
    color: rgba(255, 255, 255, 0.75);
}
.site-footer a:not(.wp-block-button__link):hover {
    color: #ffffff;
}
.site-footer ul {
    list-style: none;
    padding-inline-start: 0;
}
.site-footer li {
    margin-bottom: 0.375rem;
}
.site-footer-bottom,
.ar-footer-bottom {
    font-size: 0.8125rem;
}
/* Keep dark button text on the gold footer quote button despite
   footer link color rules (double class beats parent specificity) */
.ar-footer-quote.ar-footer-quote .wp-block-button__link {
    color: var(--wp--preset--color--primary-dark);
}

/* ============================================================
   Scroll reveal (elements are tagged by assets/js/andys.js)
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
    .ar-reveal {
        opacity: 0;
        transform: translateY(14px);
        transition: opacity 0.55s ease, transform 0.55s ease;
    }
    .ar-reveal.ar-in {
        opacity: 1;
        transform: none;
    }
}
/* Never hide content inside the block editor */
.editor-styles-wrapper .ar-reveal {
    opacity: 1;
    transform: none;
}

/* The editor gives every block `position: relative` through a two-class
   selector (.block-editor-block-list__layout .block-editor-block-list__block),
   which outranks the single-class `position: absolute` these blocks rely on.
   In the editor the hero photos dropped out of the band and stacked above
   the copy, and the tip-card topic chips and the split-section float chip
   fell into the flow below their photos. Restore the front-end positioning;
   the offsets and the 900px breakpoints still come from the rules below. */
.editor-styles-wrapper .block-editor-block-list__layout .ar-resource-topic,
.editor-styles-wrapper .block-editor-block-list__layout .ar-float-chip {
    position: absolute;
}
/* The "Nested blockGap" reset further down (.ar-photo-trio > * etc.) ties on
   specificity with core's `:root :where(.is-layout-flow) > *` rule. On the
   front end this stylesheet loads last and wins; in the editor core's rule
   loads last, so every grid item after the first got a 24px top margin and
   sat lower than its first sibling. Same containers as every `.x > *` margin
   reset in this file, with an editor-only boost. */
.editor-styles-wrapper .ar-why-item > *,
.editor-styles-wrapper .ar-services-grid > *,
.editor-styles-wrapper .ar-service-tabs > *,
.editor-styles-wrapper .ar-section-head > *,
.editor-styles-wrapper .ar-sign-grid > *,
.editor-styles-wrapper .ar-projects-grid > *,
.editor-styles-wrapper .ar-gallery-grid > *,
.editor-styles-wrapper .ar-photo-trio > *,
.editor-styles-wrapper .ar-pitch-row > *,
.editor-styles-wrapper .ar-split > *,
.editor-styles-wrapper .ar-svc-hero-actions > *,
.editor-styles-wrapper .ar-hero-chips > *,
.editor-styles-wrapper .ar-hero-heading > *,
.editor-styles-wrapper .ar-quote-slider > *,
.editor-styles-wrapper .ar-quote-grid > *,
.editor-styles-wrapper .ar-quote-head > *,
.editor-styles-wrapper .ar-svc-intro > *,
.editor-styles-wrapper .ar-svc-tiles > *,
.editor-styles-wrapper .ar-svc-tile > * {
    margin-block-start: 0;
}

@media (min-width: 900px) {
    .editor-styles-wrapper .block-editor-block-list__layout .ar-hero-media,
    .editor-styles-wrapper .block-editor-block-list__layout .ar-svc-hero-media {
        position: absolute;
    }
}

/* ============================================================
   Utility bar: desktop only (mobile shows just logo + nav)
   ============================================================ */
.ar-utility-bar {
    display: none;
}
@media (min-width: 782px) {
    .ar-utility-bar {
        display: block;
    }
}

/* ============================================================
   HOME — Hero
   ============================================================ */
.ar-hero {
    position: relative;
    overflow: hidden;
    color: var(--wp--preset--color--base);
}
.ar-hero-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    display: block;
}
.ar-hero-inner {
    max-width: calc(var(--wp--style--global--wide-size) + 2 * var(--wp--preset--spacing--medium));
    margin: 0 auto;
    position: relative;
}
.ar-hero-content {
    padding: var(--wp--preset--spacing--large) var(--wp--preset--spacing--medium) var(--wp--preset--spacing--x-large);
    position: relative;
    z-index: 2;
}
.ar-hero h1 {
    color: var(--wp--preset--color--base);
    font-size: clamp(2.75rem, 1.75rem + 4.5vw, 5rem);
    text-transform: uppercase;
    letter-spacing: 0.01em;
    line-height: 1.05;
    margin: 0 0 1.25rem;
}
.ar-hero .ar-gold {
    color: var(--wp--preset--color--accent);
}
.ar-h1-line {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.5rem;
}
.ar-review-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.875rem;
    background: rgba(0, 0, 0, 0.4);
    border-radius: 999px;
    padding: 0.5rem 1.375rem 0.5rem 0.5rem;
    text-decoration: none;
    font-family: var(--wp--preset--font-family--primary);
    font-size: 1rem;
    font-weight: 400;
    letter-spacing: normal;
    text-transform: none;
    line-height: 1.35;
}
.ar-review-pill:hover {
    background: rgba(0, 0, 0, 0.55);
}
.ar-avatar-stack {
    display: flex;
    flex: none;
}
.ar-avatar-stack img {
    width: 46px;
    height: 46px;
    border-radius: 50%;
    border: 3px solid #fff;
    object-fit: cover;
    display: block;
}
.ar-avatar-stack img + img {
    margin-inline-start: -14px;
}
.ar-review-pill-text strong {
    display: block;
    color: #fff;
    font-size: 1.0625rem;
    font-weight: 600;
}
.ar-review-pill-text .ar-rating {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    color: rgba(255, 255, 255, 0.85);
    font-size: 0.9375rem;
}
.ar-review-pill-text .ar-rating .ar-star,
.ar-review-pill-text .ar-rating .ar-stars {
    color: var(--wp--preset--color--accent);
}

.ar-review-pill-text .ar-rating .ar-stars {
    letter-spacing: 0.08em;
    font-size: 1rem;
    line-height: 1;
}
.ar-hero-lede {
    max-width: 60ch;
    color: rgba(255, 255, 255, 0.82);
    font-size: 0.9375rem;
}
.ar-hero-actions {
    margin-top: 1.75rem;
}
/* Mobile-first: hero stacks, media below the copy. Reset at 900px below. */
.ar-hero {
    display: flex;
    flex-direction: column;
}
.ar-hero-inner {
    order: 1;
}
.ar-hero-media {
    order: 2;
    height: 280px;
}
.ar-hero-media img {
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 45%);
    mask-image: linear-gradient(to bottom, transparent 0%, #000 45%);
}
@media (min-width: 900px) {
    .ar-hero {
        display: block;
    }
    .ar-hero-content {
        max-width: 60%;
    }
    .ar-hero-media {
        height: auto;
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        width: 50%;
        z-index: 1;
    }
    .ar-hero-media img {
        -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 60%);
        mask-image: linear-gradient(to right, transparent 0%, #000 60%);
    }
}

/* ============================================================
   HOME — Ticker
   ============================================================ */
.ar-ticker {
    background: var(--wp--preset--color--base);
    border-top: 1px solid var(--wp--preset--color--outline);
    border-bottom: 1px solid var(--wp--preset--color--outline);
    overflow: hidden;
}
.ar-ticker-track {
    display: flex;
    /* No gap on the track: translateX(-50%) moves by half the TRACK width, and
       10 items with 9 gaps don't split evenly — the loop drifted by half a gap
       and showed a blank. Spacing lives on each item so all 10 are identical. */
    gap: 0;
    align-items: center;
    padding: 1rem 0;
    white-space: nowrap;
    animation: ar-ticker-scroll 28s linear infinite;
    width: max-content;
}
.ar-ticker:hover .ar-ticker-track {
    animation-play-state: paused;
}
.ar-ticker-item {
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
    font-size: 1.125rem;
    text-transform: uppercase;
    color: var(--wp--preset--color--primary);
    display: flex;
    align-items: center;
    gap: 3rem;
    margin-inline-end: 3rem;
}
.ar-ticker-item::after {
    content: '•';
    color: var(--wp--preset--color--outline);
    font-size: 0.875rem;
}
@keyframes ar-ticker-scroll {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
    .ar-ticker-track {
        animation: none;
    }
}

/* ============================================================
   HOME — Why choose us (light, faded roof photo backdrop)
   ============================================================ */
.ar-why {
    position: relative;
}
.ar-why::before {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--ar-img-roof-detail) center / cover no-repeat;
    filter: grayscale(1);
    opacity: 0.09;
    pointer-events: none;
}
.ar-why > * {
    position: relative;
    z-index: 1;
}
.ar-why-item {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 1.25rem;
    margin-top: 1.75rem;
}
.ar-why-item .ar-num {
    font-size: 2.25rem;
}
.ar-why-item h4 {
    margin-top: 0;
    margin-bottom: 0.25rem;
}
.ar-why-item p {
    color: var(--wp--preset--color--muted);
    font-size: 0.9375rem;
    margin: 0;
    max-width: 44ch;
}
.ar-why .wp-block-buttons {
    margin-top: 2rem;
}
.wp-block-column.ar-why-collage {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
}
.ar-why-collage .wp-block-image {
    margin: 0;
}
.ar-why-collage img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    min-height: 300px;
}
.ar-cut-a img {
    clip-path: polygon(24% 0, 100% 0, 76% 100%, 0 100%);
}
.wp-block-image.ar-cut-b {
    margin-top: 3.5rem;
    margin-inline-start: -14%;
}
.ar-cut-b img {
    clip-path: polygon(24% 0, 100% 0, 76% 100%, 0 100%);
}

/* ============================================================
   HOME — Services tabs (dark, giant logomark backdrop)
   ============================================================ */
.ar-services {
    position: relative;
    overflow: hidden;
}
.ar-services::before {
    content: '';
    position: absolute;
    top: 50%;
    right: -220px;
    width: 1050px;
    height: 660px;
    transform: translateY(-50%);
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 150'%3E%3Crect x='152' y='30' width='17' height='42' fill='%23ffffff'/%3E%3Cpath d='M12 138 L118 28 L204 108' stroke='%23ffffff' stroke-width='17' fill='none'/%3E%3Cpath d='M52 132 L119 62 L180 118' stroke='%23f68b1f' stroke-width='13' fill='none'/%3E%3C/svg%3E") center / contain no-repeat;
    opacity: 0.05;
    pointer-events: none;
}
.ar-services > * {
    position: relative;
    z-index: 1;
}
.ar-services-head h2 {
    margin: 0;
    /* No measure cap — this heading is meant to sit on one line. */
    max-width: none;
    text-wrap: balance;
}
.ar-services-grid {
    display: grid;
    gap: var(--wp--preset--spacing--medium);
}
@media (min-width: 900px) {
    .ar-services-grid {
        grid-template-columns: 4fr 7fr;
        align-items: start;
    }
}
.ar-service-tabs {
    display: grid;
    gap: 0.625rem;
    align-content: start;
}
.ar-service-tab {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    background: var(--wp--preset--color--base);
    border: 1px solid var(--wp--preset--color--outline);
    border-left: 4px solid transparent;
    border-radius: 0.5rem;
    padding: 1rem 1.125rem;
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
    font-size: 1.0625rem;
    color: var(--wp--preset--color--contrast);
    cursor: pointer;
    text-align: left;
    width: 100%;
    transition: border-color 0.15s ease, color 0.15s ease, opacity 0.15s ease;
}
/* Once a tab is selected, dim the others so the active one reads clearly.
   aria-selected is only present once the JS has paired tabs with panels, so
   without JS every tab stays at full strength. */
.ar-service-tab[aria-selected="false"] {
    opacity: 0.62;
}
.ar-service-tab[aria-selected="false"]:hover,
.ar-service-tab[aria-selected="false"]:focus-visible {
    opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
    .ar-service-tab {
        transition: none;
    }
}
.ar-service-tab .ar-glyph {
    width: 38px;
    height: 38px;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--wp--preset--color--primary-light);
    border-radius: 0.375rem;
    color: var(--wp--preset--color--primary);
}
.ar-service-tab[aria-selected="true"] {
    border-left-color: var(--wp--preset--color--accent);
    color: var(--wp--preset--color--primary);
}
.ar-service-tab[aria-selected="true"] .ar-glyph {
    background: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--base);
}
.ar-service-panel {
    background: var(--wp--preset--color--base);
    border: 1px solid var(--wp--preset--color--outline);
    border-radius: 0.5rem;
    overflow: hidden;
    display: grid;
    grid-template-columns: 1fr;
    color: var(--wp--preset--color--contrast);
}
@media (min-width: 700px) {
    .ar-service-panel {
        grid-template-columns: 1fr 1fr;
    }
}
/* JS adds .ar-tabs-on to the grid; without JS all panels stack visibly */
.ar-tabs-on .ar-service-panel {
    display: none;
}
.ar-tabs-on .ar-service-panel.ar-active {
    display: grid;
}
/* Until the JS turns tabs on — always in the block editor, and for visitors
   without JS — every panel is visible. Left to auto-placement, the tab list
   and the panels alternate between the narrow and wide columns, squeezing
   every other panel into the tab column. Keep the tabs in the left column and
   stack the panels in the right one, as they appear once tabs are on. */
@media (min-width: 900px) {
    .ar-services-grid:not(.ar-tabs-on) > .ar-service-tabs {
        grid-column: 1;
        grid-row: 1;
    }
    .ar-services-grid:not(.ar-tabs-on) > .ar-service-panel {
        grid-column: 2;
    }
}
.ar-panel-media {
    position: relative;
    min-height: 260px;
    margin: 0;
}
.ar-panel-media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* The editor's image block writes an inline `height: auto` on the <img>, so
   the photo covered only the top of the panel. Only !important beats an
   inline style; scoped to the editor so the front end is untouched. */
.editor-styles-wrapper .ar-panel-media img {
    height: 100% !important;
}
.ar-panel-body {
    padding: 1.75rem;
}
.ar-panel-body h3 {
    margin-top: 0;
    margin-bottom: 0.5rem;
}
.ar-panel-body p {
    color: var(--wp--preset--color--muted);
    font-size: 0.9375rem;
}

/* ============================================================
   HOME — Testimonials slider
   ============================================================ */
.ar-quote-intro .ar-stars {
    color: var(--wp--preset--color--accent);
    font-size: 1.25rem;
    letter-spacing: 0.15em;
    margin-bottom: 0.5rem;
}
.ar-quote-intro p:not(.ar-stars):not(.ar-tag) {
    color: var(--wp--preset--color--muted);
    max-width: 36ch;
}
.ar-quote-slider {
    position: relative;
}
.ar-quote-card {
    background: var(--wp--preset--color--base);
    border: 1px solid var(--wp--preset--color--outline);
    border-bottom: 4px solid var(--wp--preset--color--accent);
    border-radius: 0.5rem;
    box-shadow: 0 16px 40px rgba(21, 22, 58, 0.08);
    position: relative;
    margin-bottom: 1rem;
}
/* Beats the block-layout padding without !important. */
.wp-block-group.ar-quote-card {
    padding: 2.25rem 2.25rem 2rem;
}
.ar-slider-on .ar-quote-card {
    display: none;
    margin-bottom: 0;
}
.ar-slider-on .ar-quote-card.ar-active {
    display: block;
    animation: ar-quote-in 0.45s ease;
}
@keyframes ar-quote-in {
    from { opacity: 0; transform: translateX(24px); }
    to { opacity: 1; transform: none; }
}
.ar-quote-card .ar-stars {
    color: var(--wp--preset--color--accent);
    letter-spacing: 0.12em;
    margin-bottom: 0.75rem;
}
.ar-quote-text {
    font-size: 1.125rem;
    line-height: 1.6;
    font-weight: 600;
    color: var(--wp--preset--color--primary);
    margin-bottom: 1.5rem;
}
.ar-quote-attrib {
    display: flex;
    align-items: center;
    gap: 0.875rem;
}
.ar-quote-attrib .ar-quote-name {
    line-height: 1.3;
    margin: 0;
}
.ar-quote-attrib .ar-quote-name span {
    display: block;
    font-size: 0.875rem;
    color: var(--wp--preset--color--muted);
}
.ar-quote-controls {
    display: none;
    align-items: center;
    justify-content: space-between;
    margin-top: 1.25rem;
}
.ar-slider-on .ar-quote-controls {
    display: flex;
    /* Specificity matters: the nested-blockGap reset zeroes
       `.ar-quote-slider > *` margins, which swallowed the margin-top above and
       left the arrows sitting flush against the card. */
    margin-top: 2rem;
}
.ar-quote-dots {
    display: flex;
    gap: 0.5rem;
}
.ar-quote-dots button {
    width: 26px;
    height: 4px;
    border-radius: 2px;
    border: none;
    cursor: pointer;
    background: var(--wp--preset--color--outline);
    padding: 0;
}
.ar-quote-dots button.ar-active {
    background: var(--wp--preset--color--accent);
}
.ar-quote-arrows {
    display: flex;
    gap: 0.5rem;
}
.ar-quote-arrows button {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 1px solid var(--wp--preset--color--outline);
    background: var(--wp--preset--color--base);
    color: var(--wp--preset--color--primary);
    font-size: 1rem;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}
.ar-quote-arrows button:hover {
    background: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--base);
}

/* ============================================================
   HOME — Service area (aerial photo bg + faded map overlay)
   ============================================================ */
.ar-towns {
    position: relative;
    overflow: hidden;
    border-radius: 0.5rem;
    background-image:
        linear-gradient(rgba(21, 22, 58, 0.86), rgba(21, 22, 58, 0.86)),
        var(--ar-img-aerial);
    background-size: cover;
    background-position: center;
}
.ar-towns > * {
    position: relative;
    z-index: 1;
}
.ar-towns p {
    color: rgba(255, 255, 255, 0.75);
}

/* The map column is gone, so the copy runs the full width of the band. */
.ar-towns-lede {
    max-width: 62ch;
    font-size: clamp(1.0625rem, 1.6vw, 1.375rem);
    line-height: 1.55;
    text-wrap: balance;
}

.ar-town {
    color: var(--wp--preset--color--accent);
    font-weight: 600;
}

/* One line: the heading previously sat in a 45% column and wrapped there. */
.ar-towns h2 {
    max-width: none;
    text-wrap: nowrap;
}

@media (max-width: 899px) {
    /* Below this the band is too narrow to hold it on one line. */
    .ar-towns h2 { text-wrap: balance; }
}
.ar-map-wrap svg {
    width: 100%;
    height: auto;
    display: block;
}

/* ============================================================
   HOME — Contact split (pitch + form)
   ============================================================ */
/* Per the design: the badge sits top-right of the pitch column, tilted —
   not stacked above the copy. The heading is capped so it wraps clear of the
   badge instead of running underneath it; without this the two collide. */
.ar-contact-pitch {
    position: relative;
}
.ar-contact-pitch h2 {
    max-width: 20ch;
    margin-bottom: 1.125rem;
}
.ar-contact-pitch > p:not(.ar-tag) {
    max-width: 52ch;
    /* Design spec — without it the copy sits flush on the crew photo below. */
    margin-block-end: 2rem;
}

.ar-medal {
    width: 100px;
    height: auto;
    display: block;
    position: absolute;
    top: -1rem;
    right: 0.5rem;
    transform: rotate(8deg);
    filter: drop-shadow(0 10px 24px rgba(21, 22, 58, 0.25));
    z-index: 1;
}
@media (min-width: 900px) {
    .ar-medal {
        width: 150px;
        top: -0.5rem;
        right: 0;
    }
}
.wp-block-andysroofing-medal {
    display: contents;
}
.ar-pitch-row {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem;
    align-items: center;
    margin-top: 0.5rem;
}
@media (min-width: 640px) {
    .ar-pitch-row {
        grid-template-columns: 5fr 6fr;
    }
}
.ar-pitch-photo {
    margin: 0;
}
.ar-pitch-photo img {
    width: 100%;
    height: 100%;
    max-height: 360px;
    object-fit: cover;
    border-radius: 0.5rem;
}
.ar-call-cell span {
    display: block;
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
    margin-bottom: 0.25rem;
}
.ar-call-cell a {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 1.75rem;
    font-weight: 600;
    color: var(--wp--preset--color--primary);
    text-decoration: none;
}
.ar-call-cell a:hover {
    color: var(--wp--preset--color--primary-dark);
}
.ar-call-cell svg {
    color: var(--wp--preset--color--accent);
    flex: none;
}
.ar-promise {
    font-size: 1.1875rem;
    font-weight: 600;
    font-style: italic;
    color: var(--wp--preset--color--secondary);
    border-left: 3px solid var(--wp--preset--color--accent);
    padding-inline-start: 1rem;
}
.ar-form-card {
    background: var(--wp--preset--color--surface);
    border: 1px solid var(--wp--preset--color--outline);
    border-radius: 0.5rem;
    padding: 2rem;
}
.ar-form-card h3 {
    margin-top: 0.25rem;
    margin-bottom: 1.25rem;
}
.ar-form-card label {
    display: block;
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 0.8125rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 0.375rem;
    color: var(--wp--preset--color--contrast);
}
.ar-form-card input,
.ar-form-card textarea {
    width: 100%;
    border: 1px solid var(--wp--preset--color--outline);
    border-radius: 0.375rem;
    background: var(--wp--preset--color--base);
    padding: 0.75rem 0.875rem;
    font-family: var(--wp--preset--font-family--primary);
    font-size: 0.9375rem;
    margin-bottom: 1rem;
    box-sizing: border-box;
}
.ar-form-card input:focus,
.ar-form-card textarea:focus {
    outline: 2px solid var(--wp--preset--color--primary);
    outline-offset: 1px;
}
.ar-form-note {
    font-size: 0.8125rem;
    color: var(--wp--preset--color--muted);
    margin-top: 0.75rem;
    margin-bottom: 0;
}

/* ============================================================
   SERVICE PAGES — hero (photo right, faded into navy)
   ============================================================ */
.ar-svc-hero {
    position: relative;
    overflow: hidden;
    color: var(--wp--preset--color--base);
}
.ar-svc-hero-media {
    position: relative;
    height: 240px;
}
.ar-svc-hero-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.ar-svc-hero-inner {
    max-width: calc(var(--wp--style--global--wide-size) + 2 * var(--wp--preset--spacing--medium));
    margin: 0 auto;
    position: relative;
}
.ar-svc-hero-content {
    padding: var(--wp--preset--spacing--large) var(--wp--preset--spacing--medium) var(--wp--preset--spacing--x-large);
    position: relative;
    z-index: 2;
}
.ar-breadcrumb {
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 0.8125rem;
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.55);
    margin-bottom: 1rem;
}
.ar-breadcrumb a {
    color: rgba(255, 255, 255, 0.75);
    text-decoration: none;
}
.ar-breadcrumb a:hover {
    color: var(--wp--preset--color--accent);
}
.ar-breadcrumb span {
    margin: 0 0.375rem;
}
.ar-svc-hero h1 {
    color: var(--wp--preset--color--base);
    font-size: clamp(2.5rem, 1.5rem + 4vw, 4.5rem);
    text-transform: uppercase;
    margin: 0 0 0.75rem;
}
.ar-svc-hero h1 .ar-gold,
.ar-svc-hero .ar-gold {
    color: var(--wp--preset--color--accent);
}
.ar-hero-lede-svc {
    color: rgba(255, 255, 255, 0.82);
    max-width: 46ch;
    margin-bottom: 1.75rem;
}
.ar-svc-hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.875rem 1.5rem;
    align-items: center;
    margin-bottom: 1.5rem;
}
.ar-hero-phones {
    font-size: 0.9375rem;
    color: rgba(255, 255, 255, 0.7);
    margin: 0;
    /* Small label, big number — same treatment as the .ar-call-cell at the
       foot of the page, so the phone reads at the same weight in both. */
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.ar-hero-phones a {
    color: var(--wp--preset--color--base);
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 1.75rem;
    font-weight: 600;
    text-decoration: none;
}
.ar-hero-phones a:hover {
    color: var(--wp--preset--color--accent);
}
.ar-hero-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.ar-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 999px;
    padding: 0.375rem 0.875rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.85);
}
.ar-chip::before {
    content: '';
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--wp--preset--color--accent);
}
/* Mobile-first: service hero stacks, media below the copy. Reset at 900px. */
.ar-svc-hero {
    display: flex;
    flex-direction: column;
}
.ar-svc-hero-inner {
    order: 1;
}
.ar-svc-hero-media {
    order: 2;
}
.ar-svc-hero-media img {
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 45%);
    mask-image: linear-gradient(to bottom, transparent 0%, #000 45%);
}
@media (min-width: 900px) {
    .ar-svc-hero {
        display: block;
    }
    .ar-svc-hero-media {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        width: 52%;
        height: auto;
        z-index: 1;
    }
    .ar-svc-hero-media img {
        -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 55%);
        mask-image: linear-gradient(to right, transparent 0%, #000 55%);
    }
    .ar-svc-hero-content {
        max-width: 56%;
    }
}

/* ============================================================
   SERVICE PAGES — section head + sign cards
   ============================================================ */
.ar-section-head {
    /* Single column: the supporting sentence sits under the heading rather
       than beside it. */
    display: grid;
    grid-template-columns: 1fr;
    align-items: end;
    gap: 0.75rem 2rem;
    margin-bottom: var(--wp--preset--spacing--medium);
}

.ar-section-head h2 {
    margin: 0;
}
.ar-section-head > p {
    color: var(--wp--preset--color--muted);
    margin: 0;
    font-size: 0.9375rem;
    /* No cap: these supporting lines are short enough to sit on one line
       across the section, and 60ch was breaking them at ~447px. */
    max-width: none;
}
.ar-sign-grid {
    display: grid;
    gap: 1.25rem;
    grid-template-columns: 1fr;
}
@media (min-width: 640px) {
    .ar-sign-grid {
        grid-template-columns: 1fr 1fr;
    }
}
@media (min-width: 1000px) {
    .ar-sign-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}
@media (min-width: 1000px) {
    .ar-sign-grid.ar-sign-grid-flow {
        grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    }
}
/* The 2-up variant used to sit in a 900px well, which left it visibly inset
   against the 3-up grids on the other service pages. No max-width here at all
   now, so the block's own .alignwide governs and it lines up with them —
   `max-width: none` was wrong, because it also cancelled alignwide and let the
   grid run wider than its own section heading. */
.ar-sign-grid.ar-sign-grid-2 {
    margin-inline: auto;
}
@media (min-width: 1000px) {
    .ar-sign-grid.ar-sign-grid-2 {
        grid-template-columns: 1fr 1fr;
    }
}
.ar-sign-card {
    position: relative;
    background: var(--wp--preset--color--base);
    border: 1px solid var(--wp--preset--color--outline);
    border-radius: 0.5rem;
    overflow: hidden;
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.wp-block-group.ar-sign-card {
    padding: 1.75rem 1.5rem 1.5rem;
}
.ar-sign-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: var(--wp--preset--color--accent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.3s ease;
}
.ar-sign-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 16px 36px rgba(21, 22, 58, 0.12);
}
.ar-sign-card:hover::before {
    transform: scaleX(1);
}
.ar-sign-card .ar-num {
    display: block;
    margin-bottom: 0.875rem;
}
.ar-sign-card h4 {
    margin-top: 0;
    margin-bottom: 0.375rem;
}
.ar-sign-card p {
    font-size: 0.9375rem;
    color: var(--wp--preset--color--muted);
    margin: 0;
}
/* Navy variant ("Not sure?" card) */
.ar-sign-card-navy {
    background: var(--wp--preset--color--primary);
    border-color: var(--wp--preset--color--primary);
}
.ar-sign-card-navy h4 {
    color: var(--wp--preset--color--base);
}
.ar-sign-card-navy p {
    color: rgba(255, 255, 255, 0.75);
}

/* ============================================================
   SERVICE PAGES — split with floating chip
   ============================================================ */
.ar-split {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--wp--preset--spacing--large);
    align-items: center;
}
@media (min-width: 900px) {
    .ar-split {
        grid-template-columns: 1fr 1fr;
    }
}
.ar-split-photo {
    position: relative;
    overflow: hidden;
    border-radius: 0.5rem;
    margin: 0;
}
.ar-split-photo > img,
.ar-split-photo .wp-block-image img {
    width: 100%;
    border-radius: 0.5rem;
    object-fit: cover;
    max-height: 560px;
    display: block;
}
.ar-split-photo .wp-block-image {
    margin: 0;
}
.ar-float-chip {
    position: absolute;
    left: 1.25rem;
    bottom: 1.25rem;
    display: flex;
    align-items: center;
    gap: 0.875rem;
    background: var(--wp--preset--color--base);
    border-radius: 0.5rem;
    box-shadow: 0 14px 34px rgba(21, 22, 58, 0.22);
    padding: 0.875rem 1.25rem 0.875rem 0.875rem;
    max-width: 320px;
}
.ar-float-chip .ar-dot {
    flex: none;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: var(--wp--preset--color--accent);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--wp--preset--color--primary-dark);
}
.ar-float-chip strong {
    display: block;
    font-size: 0.9375rem;
    line-height: 1.3;
    color: var(--wp--preset--color--primary);
}
.ar-float-chip span span {
    font-size: 0.8125rem;
    color: var(--wp--preset--color--muted);
}
.ar-split-content h2 {
    max-width: 22ch;
}
.ar-split-content > p {
    color: var(--wp--preset--color--muted);
}
ul.ar-checks.ar-checks-2col {
    margin: 1.25rem 0 1.5rem;
}
@media (min-width: 560px) {
    ul.ar-checks.ar-checks-2col {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 0.625rem 1.5rem;
    }
    ul.ar-checks.ar-checks-2col li {
        margin-bottom: 0;
    }
}

/* ============================================================
   SERVICE PAGES — recent projects band (dark, textured)
   ============================================================ */
.ar-projects-band {
    color: var(--wp--preset--color--base);
    background-image:
        linear-gradient(rgba(21, 22, 58, 0.92), rgba(21, 22, 58, 0.9)),
        var(--ar-img-shingle);
    background-size: cover;
    background-position: center;
}
.ar-projects-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem 2rem;
    margin-bottom: var(--wp--preset--spacing--medium);
}
.ar-projects-head h2 {
    color: var(--wp--preset--color--base);
    margin: 0;
    position: relative;
    padding-bottom: 0.75rem;
}
.ar-projects-head h2::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 64px;
    height: 3px;
    background: var(--wp--preset--color--accent);
}
.ar-projects-grid {
    display: grid;
    gap: var(--wp--preset--spacing--medium) 1.5rem;
    grid-template-columns: 1fr;
}
@media (min-width: 640px) {
    .ar-projects-grid {
        grid-template-columns: 1fr 1fr;
    }
}
@media (min-width: 1000px) {
    .ar-projects-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}
.ar-project-card {
    display: block;
    text-decoration: none;
}
.ar-project-card img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: 0.5rem;
    display: block;
    margin-bottom: 1rem;
    transition: transform 0.3s ease, filter 0.3s ease;
}
.ar-project-card:hover img {
    filter: brightness(1.08);
}
.ar-project-cat {
    display: inline-block;
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--wp--preset--color--accent);
    border-left: 3px solid var(--wp--preset--color--accent);
    padding-inline-start: 0.625rem;
    margin-bottom: 0.375rem;
}
.ar-project-card h3 {
    color: var(--wp--preset--color--base);
    font-size: 1.375rem;
    margin: 0;
}
.ar-project-card:hover h3 {
    color: var(--wp--preset--color--accent);
}
/* Outline-light button (used on dark bands) */
.ar-btn-outline-light .wp-block-button__link {
    background: transparent;
    border: 2px solid rgba(255, 255, 255, 0.4);
    color: var(--wp--preset--color--base);
}
.ar-btn-outline-light .wp-block-button__link:hover {
    border-color: var(--wp--preset--color--base);
}

/* ============================================================
   SERVICE PAGES — closing CTA band (pitch + form)
   ============================================================ */
.ar-call-cell {
    /* Gold rule removed per design direction — the gold phone icon already
       carries the accent here. The .ar-promise quote below keeps its bar. */
}
.ar-promise-lg {
    color: var(--wp--preset--color--secondary);
    font-size: 1.375rem;
    font-weight: 400;
    line-height: 1.5;
    max-width: 40ch;
}

/* ============================================================
   INNER PAGES — simple navy page hero
   ============================================================ */
.ar-page-hero {
    color: var(--wp--preset--color--base);
}
.ar-page-hero-inner {
    max-width: calc(var(--wp--style--global--wide-size) + 2 * var(--wp--preset--spacing--medium));
    margin: 0 auto;
    padding: var(--wp--preset--spacing--large) var(--wp--preset--spacing--medium);
}
.ar-page-hero h1 {
    color: var(--wp--preset--color--base);
    font-size: clamp(2.25rem, 1.5rem + 3vw, 3.75rem);
    text-transform: uppercase;
    margin: 0 0 0.625rem;
}
.ar-page-hero-lede {
    color: rgba(255, 255, 255, 0.82);
    max-width: 62ch;
    margin-bottom: 1.25rem;
}

/* ============================================================
   CONTACT — office map with floating panel
   ============================================================ */
.ar-office-map {
    position: relative;
    border-radius: 0.5rem;
    overflow: hidden;
    border: 1px solid var(--wp--preset--color--outline);
}

/* With a map image the panel floats over it; without one the card is just the
   panel, so it sits in normal flow and fills the width. */
.ar-office-map:has(> img) { min-height: 340px; }
.ar-office-map > img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s ease;
}
.ar-office-map:hover > img {
    transform: scale(1.035);
}
.ar-office-panel {
    position: static;
    max-width: none;
    background: var(--wp--preset--color--base);
    border-radius: 0.5rem;
    padding: 1.375rem 1.375rem 1.25rem;
}

.ar-office-map:has(> img) .ar-office-panel {
    position: absolute;
    top: 1.25rem;
    left: 1.25rem;
    max-width: 300px;
    box-shadow: 0 14px 34px rgba(21, 22, 58, 0.22);
}
.ar-office-panel h3 {
    font-size: 1.25rem;
    margin: 0 0 0.25rem;
}
.ar-office-panel a.ar-phone {
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
    font-size: 1.375rem;
    color: var(--wp--preset--color--primary);
    text-decoration: none;
    display: inline-block;
    margin-bottom: 0.5rem;
}
.ar-office-panel a.ar-phone:hover {
    color: var(--wp--preset--color--primary-dark);
}
.ar-office-panel p {
    font-size: 0.875rem;
    color: var(--wp--preset--color--muted);
    margin: 0;
}
.ar-office-panel .ar-directions {
    display: inline-block;
    margin-top: 0.625rem;
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
    font-size: 0.8125rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--wp--preset--color--primary);
    text-decoration: underline;
    text-decoration-color: var(--wp--preset--color--accent);
    text-decoration-thickness: 2px;
    text-underline-offset: 5px;
}
.ar-office-panel .ar-directions:hover {
    color: var(--wp--preset--color--accent);
}
.ar-form-card select {
    width: 100%;
    border: 1px solid var(--wp--preset--color--outline);
    border-radius: 0.375rem;
    background: var(--wp--preset--color--base);
    padding: 0.75rem 0.875rem;
    font-family: var(--wp--preset--font-family--primary);
    font-size: 0.9375rem;
    margin-bottom: 1rem;
    box-sizing: border-box;
}

/* ============================================================
   GALLERY — grid + lightbox (lightbox DOM built by andys.js)
   ============================================================ */
.ar-gallery-grid {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr 1fr;
}
@media (min-width: 900px) {
    .ar-gallery-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}
.ar-gallery-item {
    border-radius: 0.5rem;
    overflow: hidden;
    background: var(--wp--preset--color--base);
    border: 1px solid var(--wp--preset--color--outline);
    margin: 0;
    cursor: zoom-in;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.ar-gallery-item:hover {
    transform: translateY(-3px);
    box-shadow: 0 12px 28px rgba(21, 22, 58, 0.14);
}
.ar-gallery-item img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    display: block;
}
.ar-gallery-item figcaption {
    font-size: 0.875rem;
    padding: 0.625rem 0.875rem;
    color: var(--wp--preset--color--muted);
}
.ar-gallery-item figcaption strong {
    color: var(--wp--preset--color--contrast);
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
}
.ar-gallery-note {
    font-size: 0.9375rem;
    color: var(--wp--preset--color--muted);
    margin-top: var(--wp--preset--spacing--small);
}
.ar-lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    background: rgba(14, 15, 44, 0.94);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3.5rem 1rem;
}
.ar-lightbox[hidden] {
    display: none;
}
.ar-lb-figure {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    margin: 0;
    max-width: 100%;
}
.ar-lightbox img {
    max-width: min(1100px, 100%);
    max-height: 76vh;
    object-fit: contain;
    border-radius: 0.5rem;
    animation: ar-lb-in 0.25s ease;
}
@keyframes ar-lb-in {
    from { opacity: 0; transform: scale(0.97); }
    to { opacity: 1; transform: none; }
}
.ar-lightbox figcaption {
    color: rgba(255, 255, 255, 0.85);
    margin-top: 1rem;
    font-size: 0.9375rem;
}
.ar-lightbox figcaption strong {
    color: #fff;
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
}
.ar-lb-btn {
    position: absolute;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.25);
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    font-size: 1.125rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s ease;
}
.ar-lb-btn:hover {
    background: var(--wp--preset--color--accent);
    color: var(--wp--preset--color--primary-dark);
    border-color: var(--wp--preset--color--accent);
}
.ar-lb-close { top: 1.25rem; right: 1.25rem; }
.ar-lb-prev { left: 0.5rem; top: 50%; transform: translateY(-50%); }
.ar-lb-next { right: 0.5rem; top: 50%; transform: translateY(-50%); }
.ar-lb-count {
    position: absolute;
    top: 1.85rem;
    left: 1.5rem;
    color: rgba(255, 255, 255, 0.6);
    font-size: 0.875rem;
    font-family: var(--wp--preset--font-family--secondary);
}
@media (min-width: 641px) {
    .ar-lightbox { padding: 3.5rem 4.5rem; }
    .ar-lb-prev { left: 1.25rem; }
    .ar-lb-next { right: 1.25rem; }
}

/* ============================================================
   ABOUT — hero, intro, cards band, trio, dark band
   ============================================================ */
.ar-abt-hero {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: clamp(420px, 62vh, 640px);
    background-image:
        linear-gradient(rgba(21, 22, 58, 0.5), rgba(21, 22, 58, 0.72)),
        var(--ar-img-abt-hero);
    background-size: cover;
    background-position: center 12%;
    text-align: center;
    padding: var(--wp--preset--spacing--x-large) var(--wp--preset--spacing--medium);
}
.ar-abt-hero h1 {
    margin: 0;
}
.ar-abt-hero .ar-l1 {
    display: block;
    color: var(--wp--preset--color--base);
    font-size: clamp(2.25rem, 1.5rem + 3.5vw, 4.25rem);
    text-transform: uppercase;
    line-height: 1.1;
}
.ar-abt-hero .ar-l2 {
    display: block;
    color: var(--wp--preset--color--accent);
    font-size: clamp(1.5rem, 1.125rem + 1.75vw, 2.5rem);
    text-transform: uppercase;
    line-height: 1.1;
    margin-top: 0.625rem;
}
.ar-abt-prose {
    font-size: 1.125rem;
    line-height: 1.85;
    max-width: 58ch;
}
.ar-abt-prose p:first-of-type::first-letter {
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 700;
    font-size: 4rem;
    line-height: 0.85;
    float: left;
    padding: 0.4rem 0.875rem 0 0;
    color: var(--wp--preset--color--primary);
}
.ar-est-lockup {
    text-align: center;
    position: relative;
    padding: var(--wp--preset--spacing--medium) 0;
    /* Fill the column and centre the claim in it, rather than the block
       shrinking to its text and sitting wherever that lands. */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
}

/* The column is vertically centred by default, so it shrinks to its content
   and never fills the row for the rule above to centre within. */
.wp-block-column:has(> .ar-est-lockup) {
    align-self: stretch;
}
.ar-est-lockup .ar-claim {
    position: relative;
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
    font-size: clamp(1.875rem, 1.375rem + 2.25vw, 3rem);
    line-height: 1.3;
    color: var(--wp--preset--color--primary);
    max-width: 15ch;
    margin: 0 auto;
}
.ar-est-lockup .ar-claim::after {
    content: '';
    display: block;
    width: 72px;
    height: 3px;
    background: var(--wp--preset--color--accent);
    margin: 1.25rem auto 0;
}
.ar-abt-cards-band {
    border-radius: 0.5rem;
    overflow: hidden;
}
.ar-abt-card .ar-icon {
    width: 64px;
    height: 64px;
    border-radius: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--wp--preset--color--accent);
    color: var(--wp--preset--color--primary-dark);
    margin-bottom: 1.125rem;
    transition: transform 0.25s ease;
}
.ar-abt-card:hover .ar-icon {
    transform: translateY(-4px) rotate(-4deg);
}
.ar-abt-card h3 {
    font-family: var(--wp--preset--font-family--primary);
    font-size: 1.0625rem;
    font-weight: 700;
    color: var(--wp--preset--color--base);
    margin: 0 0 1.125rem;
}
.ar-abt-card p {
    margin: 0;
    font-size: 1.3125rem;
    font-weight: 400;
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.85);
}
.ar-photo-trio {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr;
}
@media (min-width: 700px) {
    .ar-photo-trio {
        grid-template-columns: repeat(3, 1fr);
    }
}
.ar-trio-item {
    position: relative;
    border-radius: 0.5rem;
    overflow: hidden;
    margin: 0;
}
.ar-trio-item img {
    width: 100%;
    height: 500px;
    object-fit: cover;
    display: block;
    transition: transform 0.5s ease;
}
.ar-trio-item:hover img {
    transform: scale(1.035);
}
.ar-trio-overlay {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 3rem 1.5rem 1.5rem;
    background: linear-gradient(to top, rgba(14, 15, 44, 0.95), rgba(14, 15, 44, 0.6) 70%, transparent);
}
.ar-trio-overlay h3 {
    color: var(--wp--preset--color--base);
    font-size: 1.75rem;
    margin: 0 0 0.5rem;
}
.ar-trio-overlay p {
    color: rgba(255, 255, 255, 0.92);
    font-size: 1.125rem;
    line-height: 1.55;
    margin: 0;
}
.ar-abt-dark h2 {
    color: var(--wp--preset--color--base);
    /* The map column that used to sit beside this is gone, so the band is the
       measure now — capping at 20ch left ~730px of dead space to its right. */
    max-width: none;
    text-wrap: balance;
}
.ar-abt-dark p {
    color: rgba(255, 255, 255, 0.9);
    max-width: 54ch;
    font-size: 1.25rem;
    line-height: 1.6;
    text-wrap: pretty;
}
.ar-loc-card {
    display: block;
    background: var(--wp--preset--color--base);
    border-radius: 0.5rem;
    overflow: hidden;
    text-decoration: none;
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.ar-loc-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.35);
}
.ar-loc-card img {
    width: 100%;
    aspect-ratio: 16 / 11;
    object-fit: cover;
    display: block;
}
.ar-loc-body {
    display: block;
    padding: 1.125rem 1.25rem 1.25rem;
}
.ar-loc-body em {
    font-style: normal;
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
    font-size: 1.125rem;
    color: var(--wp--preset--color--primary);
}
.ar-loc-card:hover .ar-loc-body em {
    color: var(--wp--preset--color--accent);
}

/* ============================================================
   HOME — Resources / blog cards
   ============================================================ */
.ar-resource-card {
    transition: transform 0.2s ease, box-shadow 0.2s ease;
    background: var(--wp--preset--color--base);
    border: 1px solid var(--wp--preset--color--outline);
    border-radius: 0.5rem;
    overflow: hidden;
    position: relative;
    height: 100%;
    text-align: left;
}
.ar-resource-card .wp-block-image {
    margin: 0;
}
.ar-resource-card .wp-block-image img {
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
}
.ar-resource-topic {
    position: absolute;
    top: 0.875rem;
    left: 0.875rem;
    background: var(--wp--preset--color--accent);
    color: var(--wp--preset--color--primary-dark);
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.25rem 0.625rem;
    border-radius: 0.25rem;
    margin: 0;
    z-index: 1;
}
.ar-resource-body {
    padding: 1.25rem 1.375rem 1.5rem;
}
.ar-resource-body h4 {
    margin-top: 0;
    margin-bottom: 0.375rem;
}
.ar-resource-body p {
    font-size: 0.9375rem;
    color: var(--wp--preset--color--muted);
    margin-bottom: 1rem;
}
.ar-read-more a {
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
    font-size: 0.875rem;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--wp--preset--color--primary);
}
.ar-read-more a:hover {
    text-decoration: underline;
}

/* ── Block wrappers ───────────────────────────────────────────
   Classes used by the child theme's own blocks (blocks/*). The block
   wrapper adds its own wp-block-* class, so these target the semantic
   class the design CSS above already styles.
   ============================================================ */

/* Call cell: optional breathing room when it sits between text blocks. */
.ar-call-cell--spaced {
    margin: 1.5rem 0 2rem;
}

/* Hero heading: the H1 and the review pill are now sibling blocks, so the
   inline-flex that used to live on .ar-h1-line moves to their container. */
.ar-hero-heading {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem 1.5rem;
}
.ar-hero-heading h1,
.ar-hero-heading .wp-block-heading {
    margin: 0;
}

/* The editor renders dynamic blocks through the same classes as the front
   end; these keep block wrappers from adding layout the design didn't have. */
.editor-styles-wrapper .ar-quote-card,
.editor-styles-wrapper .ar-project-card,
.editor-styles-wrapper .ar-gallery-item {
    max-width: none;
}

/* Gallery figures are keyboard-activatable (they open the lightbox), so they
   need a visible focus ring like any other control. */
.ar-gallery-item:focus-visible {
    outline: 3px solid var(--wp--preset--color--accent);
    outline-offset: 3px;
}

/* ── Button styles ────────────────────────────────────────────
   Registered via register_block_style() so they appear in the editor's
   Styles panel. Patterns reference them by class instead of repeating
   colour/typography block attributes at each call site.
   ============================================================ */
.wp-block-button.is-style-ar-accent .wp-block-button__link {
    background-color: var(--wp--preset--color--accent);
    color: var(--wp--preset--color--primary-dark);
}
.wp-block-button.is-style-ar-primary .wp-block-button__link,
.wp-block-button.is-style-ar-primary-sm .wp-block-button__link {
    background-color: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--base);
}
.wp-block-button.is-style-ar-primary-sm .wp-block-button__link,
.wp-block-button.is-style-ar-outline-light .wp-block-button__link {
    font-size: 0.875rem;
}
.wp-block-button.is-style-ar-outline-light .wp-block-button__link {
    background-color: transparent;
    border: 2px solid rgba(255, 255, 255, 0.4);
    color: var(--wp--preset--color--base);
}
.wp-block-button.is-style-ar-outline-light .wp-block-button__link:hover {
    border-color: var(--wp--preset--color--base);
}

/* ── Motion pause control (WCAG 2.2.2) ────────────────────────
   Injected by andys.js next to each auto-advancing component.
   ============================================================ */
.ar-motion-toggle {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 1px solid var(--wp--preset--color--outline);
    background: var(--wp--preset--color--base);
    color: var(--wp--preset--color--primary);
    font-size: 0.75rem;
    line-height: 1;
    cursor: pointer;
    flex: none;
}
.ar-motion-toggle:hover {
    border-color: var(--wp--preset--color--primary);
}
.ar-motion-toggle:focus-visible {
    outline: 3px solid var(--wp--preset--color--accent);
    outline-offset: 2px;
}
/* Panels are hidden via [hidden] as well as the display rules above, so the
   attribute must win over .ar-service-panel's own display value. */
.ar-tabs-on .ar-service-panel[hidden] {
    display: none;
}

/* ── Quote form states ────────────────────────────────────────
   The card renders a phone CTA until a real form handler is wired up —
   never a static form that silently drops submissions.
   ============================================================ */
.ar-form-fallback {
    font-size: 0.9375rem;
    color: var(--wp--preset--color--muted);
    margin-bottom: 1rem;
}
.ar-form-fallback-cta {
    display: inline-block;
    background-color: var(--wp--preset--color--accent);
    color: var(--wp--preset--color--primary-dark);
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 1.25rem;
    text-decoration: none;
}
.ar-form-admin-notice {
    margin-top: 1rem;
    padding: 0.75rem 1rem;
    border-left: 3px solid var(--wp--preset--color--highlight);
    background: var(--wp--preset--color--surface);
    font-size: 0.8125rem;
    color: var(--wp--preset--color--contrast);
}

/* ── Front-end layout corrections ─────────────────────────────
   Found in a full-page visual QA pass; these are not covered by
   text/class parity checks.
   ============================================================ */

/* WP injects --wp--style--block-gap (24px) between top-level blocks as
   margin-block-start, which put a white band between every section. The
   design is flush — each section carries its own padding. Physical
   margin-top does NOT override this; it must be the logical property.

   Scoped to .alignfull: every built section is a full-width group, while
   ordinary prose pages (privacy, terms, accessibility) are plain headings
   and paragraphs that still need their normal rhythm. */
.entry-content > .alignfull,
.wp-site-blocks > .alignfull,
main.site-content > .alignfull {
    margin-block-start: 0;
    margin-block-end: 0;
}

/* The header, main and footer are the other .wp-site-blocks children, and the
   footer is a <footer> template part rather than an .alignfull group, so the
   rule above never reached it — leaving a 24px strip of page background
   between the last section and the footer on every page. */
.wp-site-blocks > header.site-header,
.wp-site-blocks > main,
.wp-site-blocks > footer.site-footer {
    margin-block-start: 0;
    margin-block-end: 0;
}

/* Pseudo-elements don't inherit the border-box reset, so the quote mark's
   padding-top was added on top of its 48px height and rendered it as an
   oval instead of a circle. */
.ar-sign-card::before,
.ar-float-chip .ar-dot {
    box-sizing: border-box;
}

/* ── Gravity Forms → match the design's form card ─────────────
   GF ships its own theme CSS; without these the fields and submit
   button fall back to GF's grey/navy defaults.
   ============================================================ */
.ar-form-card .gform_wrapper .gfield_label {
    font-family: var(--wp--preset--font-family--primary);
    font-size: 0.8125rem;
    font-weight: 600;
    text-transform: none;
    color: var(--wp--preset--color--contrast);
}
.ar-form-card .gform_wrapper input[type="text"],
.ar-form-card .gform_wrapper input[type="tel"],
.ar-form-card .gform_wrapper input[type="email"],
.ar-form-card .gform_wrapper select,
.ar-form-card .gform_wrapper textarea {
    border: 1px solid var(--wp--preset--color--outline);
    border-radius: 0.5rem;
    padding: 0.75rem 0.875rem;
    font-size: 0.9375rem;
    background: var(--wp--preset--color--base);
    color: var(--wp--preset--color--contrast);
    width: 100%;
}
.ar-form-card .gform_wrapper select {
    height: auto;
    min-height: 46px;
    appearance: auto;
}
.ar-form-card .gform_wrapper input:focus,
.ar-form-card .gform_wrapper select:focus,
.ar-form-card .gform_wrapper textarea:focus {
    outline: 2px solid var(--wp--preset--color--accent);
    outline-offset: 1px;
    border-color: var(--wp--preset--color--accent);
}
/* The submit is the page's primary CTA — gold, full width, dark text
   (white-on-gold fails contrast, per the brand rule). */
/* GF's own button rule outranks a plain class chain (its input rules don't,
   which is why the fields above style cleanly). !important here is overriding
   a third-party plugin's theme CSS — not WP block layout. */
.ar-form-card .gform_wrapper .gform-footer button.gform_button,
.ar-form-card .gform_wrapper .gform_footer button.gform_button,
.ar-form-card .gform_wrapper .gform-footer input[type="submit"],
.ar-form-card .gform_wrapper form .gform_button,
.ar-quote-modal .gform_wrapper .gform-footer button.gform_button,
.ar-quote-modal .gform_wrapper .gform_footer button.gform_button,
.ar-quote-modal .gform_wrapper form .gform_button {
    background-color: var(--wp--preset--color--accent) !important;
    color: var(--wp--preset--color--primary-dark) !important;
    border: none !important;
    border-radius: 0.5rem !important;
    font-family: var(--wp--preset--font-family--secondary) !important;
    font-size: 1rem !important;
    font-weight: 600 !important;
    letter-spacing: 0.01em;
    padding: 0.875rem 1.75rem !important;
    width: 100% !important;
    cursor: pointer;
}
.ar-form-card .gform_wrapper .gform_button:hover,
.ar-quote-modal .gform_wrapper .gform_button:hover {
    filter: brightness(0.95);
}
.ar-form-card .gform_wrapper .gform_required_legend {
    display: none;
}

/* ── Blog cards: whole box clickable ──────────────────────────
   The read-more link is stretched over the card, so there is still
   exactly one link with real link text — the whole box is just its
   hit area.
   ============================================================ */
.ar-read-more a::after {
    content: '';
    position: absolute;
    inset: 0;
}
.ar-resource-card:hover,
.ar-resource-card:focus-within {
    transform: translateY(-4px);
    box-shadow: 0 14px 30px rgba(21, 22, 58, 0.13);
}
@media (prefers-reduced-motion: reduce) {
    .ar-resource-card {
        transition: none;
    }
    .ar-resource-card:hover,
    .ar-resource-card:focus-within {
        transform: none;
    }
}

/* ── Card interaction, site-wide ──────────────────────────────
   One hover treatment for every card surface so they behave alike.
   :focus-within gives keyboard users the same affordance, and the
   whole motion is dropped under prefers-reduced-motion.
   ============================================================ */
.ar-resource-card,
.ar-project-card,
.ar-gallery-item,
.ar-loc-card,
.ar-sign-card,
.ar-abt-card,
.ar-trio-item {
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.ar-resource-card:hover,
.ar-resource-card:focus-within,
.ar-project-card:hover,
.ar-project-card:focus-within,
.ar-gallery-item:hover,
.ar-gallery-item:focus-within,
.ar-sign-card:hover,
.ar-abt-card:hover,
.ar-trio-item:hover {
    transform: translateY(-4px);
    box-shadow: 0 14px 30px rgba(21, 22, 58, 0.13);
}
/* The location card sits on a dark map, so it needs a deeper shadow. */
.ar-loc-card:hover,
.ar-loc-card:focus-within {
    transform: translateY(-4px);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.35);
}
@media (prefers-reduced-motion: reduce) {
    .ar-resource-card,
    .ar-project-card,
    .ar-gallery-item,
    .ar-loc-card,
    .ar-sign-card,
    .ar-abt-card,
    .ar-trio-item {
        transition: none;
    }
    .ar-resource-card:hover,
    .ar-resource-card:focus-within,
    .ar-project-card:hover,
    .ar-project-card:focus-within,
    .ar-gallery-item:hover,
    .ar-gallery-item:focus-within,
    .ar-loc-card:hover,
    .ar-loc-card:focus-within,
    .ar-sign-card:hover,
    .ar-abt-card:hover,
    .ar-trio-item:hover {
        transform: none;
    }
}

/* ── Nested blockGap ──────────────────────────────────────────
   WP applies margin-block-start:24px to children of every flow
   container. Our grid/flex wrappers already space themselves with
   `gap`, so that margin just pushes their children out of line —
   it was offsetting the service panel from its tab list and the
   numbered headings from their numerals by exactly 24px.
   ============================================================ */
.ar-why-item > *,
.ar-services-grid > *,
.ar-service-tabs > *,
.ar-section-head > *,
.ar-sign-grid > *,
.ar-projects-grid > *,
.ar-gallery-grid > *,
.ar-photo-trio > *,
.ar-pitch-row > *,
.ar-split > *,
.ar-svc-hero-actions > *,
.ar-hero-chips > *,
.ar-hero-heading > *,
.ar-quote-slider > * {
    margin-block-start: 0;
    margin-block-end: 0;
}

/* ── Link underlines ──────────────────────────────────────────
   Removed at rest per design direction. Kept on hover so a link
   still announces itself as one on interaction, and focus-visible
   keeps keyboard users oriented.
   ============================================================ */
.entry-content a:not(.wp-block-button__link):not(.ar-service-tab):not(.gform_button),
.wp-site-blocks a:not(.wp-block-button__link):not(.ar-service-tab):not(.gform_button) {
    text-decoration: none;
}
.entry-content a:not(.wp-block-button__link):hover,
.wp-site-blocks a:not(.wp-block-button__link):hover {
    text-decoration: underline;
}
.screen-reader-text:focus {
    text-decoration: underline;
}

/* ── Sticky header: keep the wordmark, shrink it ──────────────
   The parent collapses .header-logo-default on scroll (max-height:0,
   position:absolute) so a .header-logo-compact can take its place.
   This theme has no compact logo, so the wordmark simply left the
   flex row and the nav slid left to fill the gap. Keep it in flow
   and scale it down instead. Selectors carry one extra class so they
   outrank the parent's without !important.
   ============================================================ */
header.site-header.is-scrolled .ar-header-logo.header-logo-default {
    opacity: 1;
    max-height: 200px;
    position: static;
    pointer-events: auto;
}
.ar-header-logo img {
    transition: height 0.3s ease;
}
header.site-header.is-scrolled .ar-header-logo img {
    height: 34px;
}

/* ── Eyebrow → heading rhythm ─────────────────────────────────
   Gaps measured 27 / 3 / 27 / 44 / 7 / 24px across the site because
   WP's 24px blockGap landed on the heading rather than the eyebrow.
   Own the spacing explicitly: 10px everywhere.
   ============================================================ */
.ar-tag {
    margin-block-end: 0.625rem;
}
/* p.ar-tag rather than .ar-tag so this outranks component rules like
   `.ar-form-card h3`, which otherwise add their own top margin on top of
   the eyebrow's 20px. */
p.ar-tag + * {
    margin-block-start: 0;
}

/* ── Quote form density ───────────────────────────────────────
   GF's default rhythm (30px between fields, a 10-row textarea) made
   the card far taller than the copy beside it. Tighten both.
   ============================================================ */
.ar-form-card .gform_wrapper {
    --gf-form-gap-y: 1.125rem;
}
.ar-form-card .gform_wrapper .gform_fields {
    row-gap: 1.125rem;
}
.ar-form-card .gform_wrapper .gfield {
    margin-block-start: 0;
    margin-block-end: 0;
}
.ar-form-card .gform_wrapper .gfield_label {
    margin-bottom: 0.25rem;
}
.ar-form-card .gform_wrapper textarea {
    min-height: 104px;
    height: 104px;
}
.ar-form-card .gform_wrapper .gform-footer {
    margin-block-start: 1.25rem;
    padding-top: 0;
}

/* Footer intro: cap the measure so it doesn't run up to the next column.
   Matches the design's .footer-brand p. */
.ar-footer-logo ~ p {
    max-width: 34ch;
}

/* Photo closing the estimate band's first column. On mobile it is a plain
   4:3 crop. Side by side, it instead grows into whatever space the form
   leaves, so both columns end level: flex-basis 0 keeps the photo out of
   the column's natural height, so the row is sized by the form and the
   photo fills the remainder. */
.ar-estimate-photo {
    margin-block-start: 1.75rem;
}
.ar-estimate-photo img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: 0.5rem;
    display: block;
}
@media (min-width: 782px) {
    #estimate .wp-block-column:first-child {
        display: flex;
        flex-direction: column;
    }
    .ar-estimate-photo {
        flex: 1 1 0;
        min-height: 170px;
    }
    .ar-estimate-photo img {
        height: 100%;
        aspect-ratio: auto;
    }
}

/* Far-footer legal links, sitting opposite the copyright line. */
.ar-footer-legal {
    gap: 0.375rem 1.25rem;
    align-items: center;
}
.ar-footer-legal p {
    margin: 0;
}

/* Marks unresolved legal/business decisions on the policy pages. Remove the
   markers (and this rule) once the copy has been reviewed and signed off. */
.ar-review-note {
    border-left: 3px solid var(--wp--preset--color--highlight);
    background: var(--wp--preset--color--accent-light);
    padding: 0.875rem 1rem;
    font-size: 0.9375rem;
    color: var(--wp--preset--color--contrast);
    border-radius: 0.25rem;
}

/* --- Quote popup ---------------------------------------------------------
   Opened with show(), not showModal() (see initQuoteModal in andys.js), so
   the backdrop and the centering are ours rather than ::backdrop's. */
.ar-modal-backdrop {
	position: fixed;
	inset: 0;
	z-index: 1000;
	background: rgba(21, 22, 58, 0.62);
}

.ar-modal-backdrop[hidden] { display: none; }

body.ar-modal-open { overflow: hidden; }

dialog.ar-quote-modal {
	position: fixed;
	inset: 0;
	z-index: 1001;
	width: min(560px, calc(100vw - 2rem));
	max-height: min(88vh, 780px);
	margin: auto;
	padding: 0;
	/* The dialog clips and .__inner scrolls, so the absolutely-positioned
	   close button stays put instead of scrolling away with the fields. */
	display: flex;
	overflow: hidden;
	border: 0;
	border-radius: 0.75rem;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	box-shadow: 0 24px 60px rgba(21, 22, 58, 0.35);
}

dialog.ar-quote-modal:not([open]) { display: none; }

.ar-quote-modal__inner {
	flex: 1 1 auto;
	overflow-y: auto;
	padding: 0;
}

.ar-quote-modal__intro {
	padding: 1.75rem 1.5rem 1.375rem;
	background: var(--wp--preset--color--primary-light);
}

.ar-quote-modal__form { padding: 1.5rem; }

.ar-quote-modal__close {
	position: absolute;
	top: 0.75rem;
	right: 0.75rem;
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: var(--wp--preset--color--primary);
	cursor: pointer;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.ar-quote-modal__close:hover,
.ar-quote-modal__close:focus-visible {
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
}

dialog.ar-quote-modal h2 {
	margin: 0 0 0.5rem;
	padding-right: 2rem;
	font-size: 1.5rem;
	line-height: 1.15;
}

.ar-quote-modal__sub {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.5;
	color: var(--wp--preset--color--muted);
}

.ar-quote-modal__sub a {
	color: var(--wp--preset--color--primary);
	font-weight: 600;
}

/* The popup is deliberately compact: label beside field, no gaps, and the
   controls collapse into one connected stack. Message keeps its label above,
   since a textarea beside a centred label reads badly.

   Note the selectors: Gravity Forms renders this form with its *orbital*
   theme (.gform-theme--orbital), not the older .gravity-theme, so anything
   scoped to .gravity-theme here is dead CSS. Orbital lays the fields out on a
   12-column grid whose row-gap comes from --gf-form-gap-y, and that property
   is set by an inline <style> scoped to #gform_wrapper_N[data-form-index] —
   an id selector no class-based override can outrank. So the gap is closed by
   setting row-gap on .gform_fields directly rather than by redefining the
   custom property. */
.ar-quote-modal .gform_wrapper .gform_fields {
	row-gap: 0;
}

/* :not(...) matters — a bare .gfield display rule outranks the theme's
   display:none and would reveal the hidden Source page field as a blank row. */
.ar-quote-modal .gform_wrapper .gfield:not(.gform_hidden):not(.gfield--type-hidden):not(.gfield--type-textarea):not(.gfield--type-turnstile) {
	display: grid;
	grid-template-columns: 8.5rem 1fr;
	align-items: center;
	column-gap: 0.875rem;
}

.ar-quote-modal .gform_wrapper .gfield_label {
	margin: 0;
	font-size: 0.875rem;
	line-height: 1.25;
}

/* Explicit placement, because Gravity Forms renders the validation message
   BETWEEN the label and the input (the form is set to validation_above). With
   auto-placement that message takes the input's cell and shoves every control
   onto its own row, so the whole form comes apart the moment it errors. */
.ar-quote-modal .gform_wrapper .gfield > .gfield_label {
	grid-column: 1;
	grid-row: 1;
}

.ar-quote-modal .gform_wrapper .gfield > .ginput_container {
	grid-column: 2;
	grid-row: 1;
}

.ar-quote-modal .gform_wrapper .gfield > .gfield_validation_message,
.ar-quote-modal .gform_wrapper .gfield > .gfield_description {
	grid-column: 2;
	grid-row: 2;
	margin: 0.25rem 0 0;
	padding: 0;
	background: none;
	border: 0;
	font-size: 0.8125rem;
}

/* The textarea keeps its stacked layout, so its message flows normally. */
.ar-quote-modal .gform_wrapper .gfield--type-textarea > .gfield_label,
.ar-quote-modal .gform_wrapper .gfield--type-textarea > .ginput_container,
.ar-quote-modal .gform_wrapper .gfield--type-textarea > .gfield_validation_message,
.ar-quote-modal .gform_wrapper .gfield--type-textarea > .gfield_description {
	grid-column: auto;
	grid-row: auto;
}



/* Compact the error summary so it doesn't dominate a small popup. */
.ar-quote-modal .gform_wrapper .gform_submission_error,
.ar-quote-modal .gform_wrapper .gform_validation_errors {
	margin-bottom: 1rem;
	padding: 0.75rem 0.875rem;
	border-radius: 0.5rem;
	font-size: 0.875rem;
}

.ar-quote-modal .gform_wrapper .gform_submission_error h2,
.ar-quote-modal .gform_wrapper .gform_validation_errors h2 {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.35;
}

.ar-quote-modal .gform_wrapper .gfield--type-textarea {
	margin-top: 0.875rem;
}

/* The CAPTCHA has no label, so it stays out of the label/input grid and sits
   flush left under the message box like the fields above it. */
.ar-quote-modal .gform_wrapper .gfield--type-turnstile {
	margin-top: 1.125rem;
}

.ar-quote-modal .gform_wrapper .gfield--type-textarea .gfield_label {
	margin-bottom: 0.25rem;
}

/* Square the shared edges and pull them together, so adjacent 1px borders
   read as one hairline instead of a 2px seam. */
.ar-quote-modal .gform_wrapper .gfield input,
.ar-quote-modal .gform_wrapper .gfield select,
.ar-quote-modal .gform_wrapper .gfield textarea {
	border-radius: 0;
	border-color: var(--wp--preset--color--outline);
}

.ar-quote-modal .gform_wrapper .gfield ~ .gfield input,
.ar-quote-modal .gform_wrapper .gfield ~ .gfield select {
	margin-top: -1px;
}

/* Must come after the border-color rule above, and carry an extra class, or
   the neutral outline colour wins the cascade and errored fields look fine. */
.ar-quote-modal .gform_wrapper .gfield.gfield_error input,
.ar-quote-modal .gform_wrapper .gfield.gfield_error select,
.ar-quote-modal .gform_wrapper .gfield.gfield_error textarea {
	border-color: #b02a30;
	position: relative;
	z-index: 1;
}

.ar-quote-modal .gform_wrapper .gfield:first-child input {
	border-top-left-radius: 0.5rem;
	border-top-right-radius: 0.5rem;
}

.ar-quote-modal .gform_wrapper .gfield--type-select select {
	border-bottom-left-radius: 0.5rem;
	border-bottom-right-radius: 0.5rem;
}

.ar-quote-modal .gform_wrapper .gfield--type-textarea textarea {
	height: 5rem;
	border-radius: 0.5rem;
}

/* Otherwise the focus ring is clipped by the control stacked over it. */
.ar-quote-modal .gform_wrapper .gfield input:focus,
.ar-quote-modal .gform_wrapper .gfield select:focus {
	position: relative;
	z-index: 1;
}

.ar-quote-modal .gform_wrapper .gform-footer,
.ar-quote-modal .gform_wrapper .gform_footer {
	margin-top: 1.125rem;
	padding-top: 0;
}

@media (max-width: 560px) {
	.ar-quote-modal .gform_wrapper .gfield:not(.gform_hidden):not(.gfield--type-hidden):not(.gfield--type-textarea):not(.gfield--type-turnstile) {
		grid-template-columns: 6rem 1fr;
		column-gap: 0.75rem;
	}
}

@media (prefers-reduced-motion: no-preference) {
	dialog.ar-quote-modal[open] { animation: ar-quote-in 0.22s ease-out; }
	@keyframes ar-quote-in {
		from { opacity: 0; transform: translateY(0.75rem); }
		to   { opacity: 1; transform: translateY(0); }
	}
}

/* --- Mobile call bar -----------------------------------------------------
   Only below 782px, where the header's utility bar (and with it the phone)
   is hidden. See inc/mobile-call-bar.php for why this exists. */
.ar-call-bar { display: none; --ar-call-bar-h: 3.25rem; }

@media (max-width: 781px) {
	.ar-call-bar {
		position: fixed;
		inset-inline: 0;
		bottom: 0;
		z-index: 900;
		display: block;
		background: var(--wp--preset--color--accent);
		box-shadow: 0 -2px 12px rgba(21, 22, 58, 0.28);
		/* Clears the iOS home indicator. */
		padding-bottom: env(safe-area-inset-bottom, 0px);
	}

	.ar-call-bar__link {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 0.5rem;
		/* 52px tall: comfortably over the 24x24 minimum target size. Vertical
		   padding stays at 0 so the bar's height is exactly --ar-call-bar-h and
		   the body padding below can't drift out of sync with it. */
		min-height: var(--ar-call-bar-h);
		padding: 0 1rem;
		color: var(--wp--preset--color--primary-dark);
		font-family: var(--wp--preset--font-family--secondary);
		font-size: 1.0625rem;
		font-weight: 600;
		letter-spacing: 0.01em;
		text-decoration: none;
	}

	.ar-call-bar__link:hover,
	.ar-call-bar__link:focus-visible { color: var(--wp--preset--color--primary-dark); }

	/* Keep the bar from covering the end of the page. */
	/* Bar height plus a little breathing room, so the last footer line is not
	   jammed flush against the bar. */
	body { padding-bottom: calc(3.25rem + 0.75rem + env(safe-area-inset-bottom, 0px)); }
	.ar-call-bar { --ar-call-bar-h: 3.25rem; }

	/* The quote popup owns the screen while it is open. */
	body.ar-modal-open .ar-call-bar { display: none; --ar-call-bar-h: 3.25rem; }
}

/* --- Blog: index, archive, single ---------------------------------------
   Card visuals are shared with the homepage tip cards (.ar-resource-card),
   so only the query-loop scaffolding and the post page need styles here. */
/* One shared column for every hero child, left-aligned. A constrained layout
   centres each child on its own max-width instead, which puts the capped h1 in
   the middle while the inline-block eyebrow stays at the container edge. */
.ar-blog-hero-inner,
.ar-post-hero-inner {
	max-width: var(--wp--style--global--wide-size, 1200px);
	margin-inline: auto;
}

.ar-blog-hero .ar-tag,
.ar-post-hero .ar-tag { margin-block-end: 0.625rem; }

.ar-blog-hero h1 {
	margin: 0;
	/* No measure cap: this heading is short and reads as one line. */
	max-width: none;
	text-wrap: balance;
}


.ar-blog-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--wp--preset--spacing--large, 2rem);
}

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

@media (min-width: 900px) {
	.ar-blog-grid { grid-template-columns: repeat(3, 1fr); }
}

/* The post-template <li> is a grid item; the card inside it does the work. */
.ar-blog-grid > li { list-style: none; margin: 0; }
.ar-blog-grid > li > .ar-resource-card { height: 100%; }

/* Featured image and title come from core blocks here rather than raw markup,
   so they need the same treatment .ar-resource-card gives its own children. */
.ar-resource-card .wp-block-post-featured-image { margin: 0; }

.ar-resource-card .wp-block-post-featured-image img {
	display: block;
	width: 100%;
	aspect-ratio: 3 / 2;
	object-fit: cover;
}

.ar-resource-card .wp-block-post-title {
	margin: 0 0 0.5rem;
	font-family: var(--wp--preset--font-family--secondary);
	font-size: 1.25rem;
	line-height: 1.2;
}

.ar-resource-card .wp-block-post-title a {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

.ar-resource-card .wp-block-post-title a:hover { color: var(--wp--preset--color--primary); }

.ar-resource-card .wp-block-post-excerpt { margin: 0; }

.ar-resource-card .wp-block-post-excerpt__excerpt {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.6;
	color: var(--wp--preset--color--muted);
}

/* post-terms renders links; the topic chip should read as a chip, not a link. */
.ar-resource-topic a {
	color: inherit;
	text-decoration: none;
}

.ar-blog-pagination {
	margin-top: var(--wp--preset--spacing--x-large, 3rem);
	gap: 0.75rem;
}

.ar-blog-pagination a,
.ar-blog-pagination .current {
	font-family: var(--wp--preset--font-family--secondary);
	font-weight: 600;
	color: var(--wp--preset--color--primary);
	text-decoration: none;
}

.ar-blog-pagination .current { color: var(--wp--preset--color--muted); }

/* --- Single post --- */
.ar-post-hero h1 {
	margin: 0;
}

.ar-post-hero .ar-tag a { color: inherit; text-decoration: none; }

.ar-post-date {
	margin: 0.875rem 0 0;
	font-size: 0.9375rem;
	color: var(--wp--preset--color--muted);
}

.ar-post-image { margin-block-end: var(--wp--preset--spacing--large, 2rem); }

.ar-post-image img {
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	border-radius: 0.5rem;
}

/* Comfortable measure for long-form reading. In rem, not ch: ch is
   font-relative, so the larger headings got a wider measure than the body copy
   and sat further left — which read as the paragraphs being indented. One
   fixed measure keeps every child on the same left edge, still centred. */
.ar-post-body .wp-block-post-content > * { max-width: 42rem; margin-inline: auto; }

.ar-post-body .wp-block-post-content h2 {
	margin-block-start: 2.25rem;
	font-size: 1.625rem;
}

.ar-post-body .wp-block-post-content h3 {
	margin-block-start: 1.75rem;
	font-size: 1.25rem;
}

.ar-post-body .wp-block-post-content p,
.ar-post-body .wp-block-post-content li { line-height: 1.7; }

.ar-post-body .wp-block-post-content ul { padding-inline-start: 1.25rem; }
.ar-post-body .wp-block-post-content li { margin-block-end: 0.5rem; }

.ar-post-cta-lede {
	margin: 0.75rem auto 1.5rem;
	max-width: 52ch;
	opacity: 0.85;
}

.ar-post-cta-phone {
	margin: 1rem 0 0;
	font-size: 0.9375rem;
	opacity: 0.85;
}

.ar-post-cta-phone a {
	color: var(--wp--preset--color--accent);
	font-weight: 600;
}

/* --- QA fixes ------------------------------------------------------------ */

/* #62: in-page anchors landed under the sticky header, so "Book a Repair
   Visit" appeared to go nowhere. Clear the header (plus the mobile call bar's
   worth of breathing room) whenever an anchor target is scrolled to. */
:target,
[id="estimate"],
[id="contact"],
[id="contact-form"],
[id="services"] {
	scroll-margin-top: 6.5rem;
}

/* #61: on mobile the 90+ medal sat on top of the heading it is meant to sit
   beside. Below the two-column breakpoint it moves out of the text's way. */
@media (max-width: 899px) {
	.ar-contact-pitch { padding-top: 4.5rem; }

	.ar-medal {
		top: 0;
		right: 0;
		width: 84px;
	}

	.ar-contact-pitch h2 { max-width: none; }
}

/* #63: the lightbox sat at z-index 200 while the sticky header is 999, so the
   close button rendered underneath it. Above the header, the call bar (900)
   and the quote popup (1001). */
.ar-lightbox { z-index: 1100; }

/* #63: over a wide photo the arrows were nearly invisible against the image.
   A solid dark disc keeps them readable whatever is behind them. */
.ar-lb-btn {
	background: rgba(14, 15, 44, 0.72);
	border-color: rgba(255, 255, 255, 0.55);
	backdrop-filter: blur(2px);
}

@media (max-width: 599px) {
	.ar-lb-btn { width: 40px; height: 40px; }
	.ar-lb-close { top: 0.75rem; right: 0.75rem; }
	/* Keep the arrows off the photo's edges on small screens. */
	.ar-lb-prev { left: 0.5rem; }
	.ar-lb-next { right: 0.5rem; }
}

/* Cliff's #6/#13/#16/#18/#19/#23/#24 are all the same defect: a heading or
   lead paragraph wrapping so the last line holds one or two words. Balancing
   the lines fixes the whole class of them rather than hand-tuning each string,
   and keeps working when the copy changes. */
h1, h2, h3, h4,
.ar-tag,
.ar-project-card h3,
.ar-resource-body h4 {
	text-wrap: balance;
}

/* The short supporting sentence under a section heading is only ever a line or
   two, so balance it like a heading — `pretty` only kills a one-word orphan and
   these were left with two-word stubs. */
.ar-section-head > p,
.ar-services-head p,
.ar-post-cta-lede {
	text-wrap: balance;
}

/* pretty, not balance, for longer running text: it prevents the orphan on the
   last line without evening out every line of a long paragraph. */
.ar-hero-lede,
.ar-svc-hero p,
.ar-svc-intro p,
.ar-blog-hero p,
.ar-quote-text,
.ar-resource-body p {
	text-wrap: pretty;
}

.ar-svc-hero-inner {
    max-width: calc(var(--wp--style--global--wide-size) + 2 * var(--wp--preset--spacing--medium));
    margin: 0 auto;
    position: relative;
}
.ar-svc-hero-content {
    padding: var(--wp--preset--spacing--large) var(--wp--preset--spacing--medium) var(--wp--preset--spacing--x-large);
    position: relative;
    z-index: 2;
}
.ar-breadcrumb {
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 0.8125rem;
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.55);
    margin-bottom: 1rem;
}
.ar-breadcrumb a {
    color: rgba(255, 255, 255, 0.75);
    text-decoration: none;
}
.ar-breadcrumb a:hover {
    color: var(--wp--preset--color--accent);
}
.ar-breadcrumb span {
    margin: 0 0.375rem;
}
.ar-svc-hero h1 {
    color: var(--wp--preset--color--base);
    font-size: clamp(2.5rem, 1.5rem + 4vw, 4.5rem);
    text-transform: uppercase;
    margin: 0 0 0.75rem;
}
.ar-svc-hero h1 .ar-gold,
.ar-svc-hero .ar-gold {
    color: var(--wp--preset--color--accent);
}
.ar-hero-lede-svc {
    color: rgba(255, 255, 255, 0.82);
    max-width: 46ch;
    margin-bottom: 1.75rem;
}
.ar-svc-hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.875rem 1.5rem;
    align-items: center;
    margin-bottom: 1.5rem;
}
.ar-hero-phones {
    font-size: 0.9375rem;
    color: rgba(255, 255, 255, 0.7);
    margin: 0;
    /* Small label, big number — same treatment as the .ar-call-cell at the
       foot of the page, so the phone reads at the same weight in both. */
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.ar-hero-phones a {
    color: var(--wp--preset--color--base);
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 1.75rem;
    font-weight: 600;
    text-decoration: none;
}
.ar-hero-phones a:hover {
    color: var(--wp--preset--color--accent);
}
.ar-hero-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.ar-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 999px;
    padding: 0.375rem 0.875rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.85);
}
.ar-chip::before {
    content: '';
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--wp--preset--color--accent);
}
/* Mobile-first: service hero stacks, media below the copy. Reset at 900px. */
.ar-svc-hero {
    display: flex;
    flex-direction: column;
}
.ar-svc-hero-inner {
    order: 1;
}
.ar-svc-hero-media {
    order: 2;
}
.ar-svc-hero-media img {
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 45%);
    mask-image: linear-gradient(to bottom, transparent 0%, #000 45%);
}
@media (min-width: 900px) {
    .ar-svc-hero {
        display: block;
    }
    .ar-svc-hero-media {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        width: 52%;
        height: auto;
        z-index: 1;
    }
    .ar-svc-hero-media img {
        -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 55%);
        mask-image: linear-gradient(to right, transparent 0%, #000 55%);
    }
    .ar-svc-hero-content {
        max-width: 56%;
    }
}

/* ============================================================
   SERVICE PAGES — section head + sign cards
   ============================================================ */
.ar-section-head {
    /* Single column: the supporting sentence sits under the heading rather
       than beside it. */
    display: grid;
    grid-template-columns: 1fr;
    align-items: end;
    gap: 0.75rem 2rem;
    margin-bottom: var(--wp--preset--spacing--medium);
}

.ar-section-head h2 {
    margin: 0;
}
.ar-section-head > p {
    color: var(--wp--preset--color--muted);
    margin: 0;
    font-size: 0.9375rem;
    /* No cap: these supporting lines are short enough to sit on one line
       across the section, and 60ch was breaking them at ~447px. */
    max-width: none;
}
.ar-sign-grid {
    display: grid;
    gap: 1.25rem;
    grid-template-columns: 1fr;
}
@media (min-width: 640px) {
    .ar-sign-grid {
        grid-template-columns: 1fr 1fr;
    }
}
@media (min-width: 1000px) {
    .ar-sign-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}
@media (min-width: 1000px) {
    .ar-sign-grid.ar-sign-grid-flow {
        grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    }
}
/* The 2-up variant used to sit in a 900px well, which left it visibly inset
   against the 3-up grids on the other service pages. No max-width here at all
   now, so the block's own .alignwide governs and it lines up with them —
   `max-width: none` was wrong, because it also cancelled alignwide and let the
   grid run wider than its own section heading. */
.ar-sign-grid.ar-sign-grid-2 {
    margin-inline: auto;
}
@media (min-width: 1000px) {
    .ar-sign-grid.ar-sign-grid-2 {
        grid-template-columns: 1fr 1fr;
    }
}
.ar-sign-card {
    position: relative;
    background: var(--wp--preset--color--base);
    border: 1px solid var(--wp--preset--color--outline);
    border-radius: 0.5rem;
    overflow: hidden;
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.wp-block-group.ar-sign-card {
    padding: 1.75rem 1.5rem 1.5rem;
}
.ar-sign-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: var(--wp--preset--color--accent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.3s ease;
}
.ar-sign-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 16px 36px rgba(21, 22, 58, 0.12);
}
.ar-sign-card:hover::before {
    transform: scaleX(1);
}
.ar-sign-card .ar-num {
    display: block;
    margin-bottom: 0.875rem;
}
.ar-sign-card h4 {
    margin-top: 0;
    margin-bottom: 0.375rem;
}
.ar-sign-card p {
    font-size: 0.9375rem;
    color: var(--wp--preset--color--muted);
    margin: 0;
}
/* Navy variant ("Not sure?" card) */
.ar-sign-card-navy {
    background: var(--wp--preset--color--primary);
    border-color: var(--wp--preset--color--primary);
}
.ar-sign-card-navy h4 {
    color: var(--wp--preset--color--base);
}
.ar-sign-card-navy p {
    color: rgba(255, 255, 255, 0.75);
}

/* ============================================================
   SERVICE PAGES — split with floating chip
   ============================================================ */
.ar-split {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--wp--preset--spacing--large);
    align-items: center;
}
@media (min-width: 900px) {
    .ar-split {
        grid-template-columns: 1fr 1fr;
    }
}
.ar-split-photo {
    position: relative;
    overflow: hidden;
    border-radius: 0.5rem;
    margin: 0;
}
.ar-split-photo > img,
.ar-split-photo .wp-block-image img {
    width: 100%;
    border-radius: 0.5rem;
    object-fit: cover;
    max-height: 560px;
    display: block;
}
.ar-split-photo .wp-block-image {
    margin: 0;
}
.ar-float-chip {
    position: absolute;
    left: 1.25rem;
    bottom: 1.25rem;
    display: flex;
    align-items: center;
    gap: 0.875rem;
    background: var(--wp--preset--color--base);
    border-radius: 0.5rem;
    box-shadow: 0 14px 34px rgba(21, 22, 58, 0.22);
    padding: 0.875rem 1.25rem 0.875rem 0.875rem;
    max-width: 320px;
}
.ar-float-chip .ar-dot {
    flex: none;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: var(--wp--preset--color--accent);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--wp--preset--color--primary-dark);
}
.ar-float-chip strong {
    display: block;
    font-size: 0.9375rem;
    line-height: 1.3;
    color: var(--wp--preset--color--primary);
}
.ar-float-chip span span {
    font-size: 0.8125rem;
    color: var(--wp--preset--color--muted);
}
.ar-split-content h2 {
    max-width: 22ch;
}
.ar-split-content > p {
    color: var(--wp--preset--color--muted);
}
ul.ar-checks.ar-checks-2col {
    margin: 1.25rem 0 1.5rem;
}
@media (min-width: 560px) {
    ul.ar-checks.ar-checks-2col {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 0.625rem 1.5rem;
    }
    ul.ar-checks.ar-checks-2col li {
        margin-bottom: 0;
    }
}

/* ============================================================
   SERVICE PAGES — recent projects band (dark, textured)
   ============================================================ */
.ar-projects-band {
    color: var(--wp--preset--color--base);
    background-image:
        linear-gradient(rgba(21, 22, 58, 0.92), rgba(21, 22, 58, 0.9)),
        var(--ar-img-shingle);
    background-size: cover;
    background-position: center;
}
.ar-projects-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem 2rem;
    margin-bottom: var(--wp--preset--spacing--medium);
}
.ar-projects-head h2 {
    color: var(--wp--preset--color--base);
    margin: 0;
    position: relative;
    padding-bottom: 0.75rem;
}
.ar-projects-head h2::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 64px;
    height: 3px;
    background: var(--wp--preset--color--accent);
}
.ar-projects-grid {
    display: grid;
    gap: var(--wp--preset--spacing--medium) 1.5rem;
    grid-template-columns: 1fr;
}
@media (min-width: 640px) {
    .ar-projects-grid {
        grid-template-columns: 1fr 1fr;
    }
}
@media (min-width: 1000px) {
    .ar-projects-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}
.ar-project-card {
    display: block;
    text-decoration: none;
}
.ar-project-card img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: 0.5rem;
    display: block;
    margin-bottom: 1rem;
    transition: transform 0.3s ease, filter 0.3s ease;
}
.ar-project-card:hover img {
    filter: brightness(1.08);
}
.ar-project-cat {
    display: inline-block;
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--wp--preset--color--accent);
    border-left: 3px solid var(--wp--preset--color--accent);
    padding-inline-start: 0.625rem;
    margin-bottom: 0.375rem;
}
.ar-project-card h3 {
    color: var(--wp--preset--color--base);
    font-size: 1.375rem;
    margin: 0;
}
.ar-project-card:hover h3 {
    color: var(--wp--preset--color--accent);
}
/* Outline-light button (used on dark bands) */
.ar-btn-outline-light .wp-block-button__link {
    background: transparent;
    border: 2px solid rgba(255, 255, 255, 0.4);
    color: var(--wp--preset--color--base);
}
.ar-btn-outline-light .wp-block-button__link:hover {
    border-color: var(--wp--preset--color--base);
}

/* ============================================================
   SERVICE PAGES — closing CTA band (pitch + form)
   ============================================================ */
.ar-call-cell {
    /* Gold rule removed per design direction — the gold phone icon already
       carries the accent here. The .ar-promise quote below keeps its bar. */
}
.ar-promise-lg {
    color: var(--wp--preset--color--secondary);
    font-size: 1.375rem;
    font-weight: 400;
    line-height: 1.5;
    max-width: 40ch;
}

/* ============================================================
   INNER PAGES — simple navy page hero
   ============================================================ */
.ar-page-hero {
    color: var(--wp--preset--color--base);
}
.ar-page-hero-inner {
    max-width: calc(var(--wp--style--global--wide-size) + 2 * var(--wp--preset--spacing--medium));
    margin: 0 auto;
    padding: var(--wp--preset--spacing--large) var(--wp--preset--spacing--medium);
}
.ar-page-hero h1 {
    color: var(--wp--preset--color--base);
    font-size: clamp(2.25rem, 1.5rem + 3vw, 3.75rem);
    text-transform: uppercase;
    margin: 0 0 0.625rem;
}
.ar-page-hero-lede {
    color: rgba(255, 255, 255, 0.82);
    max-width: 62ch;
    margin-bottom: 1.25rem;
}

/* ============================================================
   GALLERY — grid + lightbox (lightbox DOM built by andys.js)
   ============================================================ */
.ar-gallery-grid {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr 1fr;
}
@media (min-width: 900px) {
    .ar-gallery-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}
.ar-gallery-item {
    border-radius: 0.5rem;
    overflow: hidden;
    background: var(--wp--preset--color--base);
    border: 1px solid var(--wp--preset--color--outline);
    margin: 0;
    cursor: zoom-in;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.ar-gallery-item:hover {
    transform: translateY(-3px);
    box-shadow: 0 12px 28px rgba(21, 22, 58, 0.14);
}
.ar-gallery-item img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    display: block;
}
.ar-gallery-item figcaption {
    font-size: 0.875rem;
    padding: 0.625rem 0.875rem;
    color: var(--wp--preset--color--muted);
}
.ar-gallery-item figcaption strong {
    color: var(--wp--preset--color--contrast);
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
}
.ar-gallery-note {
    font-size: 0.9375rem;
    color: var(--wp--preset--color--muted);
    margin-top: var(--wp--preset--spacing--small);
}
.ar-lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    background: rgba(14, 15, 44, 0.94);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3.5rem 1rem;
}
.ar-lightbox[hidden] {
    display: none;
}
.ar-lb-figure {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    margin: 0;
    max-width: 100%;
}
.ar-lightbox img {
    max-width: min(1100px, 100%);
    max-height: 76vh;
    object-fit: contain;
    border-radius: 0.5rem;
    animation: ar-lb-in 0.25s ease;
}
@keyframes ar-lb-in {
    from { opacity: 0; transform: scale(0.97); }
    to { opacity: 1; transform: none; }
}
.ar-lightbox figcaption {
    color: rgba(255, 255, 255, 0.85);
    margin-top: 1rem;
    font-size: 0.9375rem;
}
.ar-lightbox figcaption strong {
    color: #fff;
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
}
.ar-lb-btn {
    position: absolute;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.25);
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    font-size: 1.125rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s ease;
}
.ar-lb-btn:hover {
    background: var(--wp--preset--color--accent);
    color: var(--wp--preset--color--primary-dark);
    border-color: var(--wp--preset--color--accent);
}
.ar-lb-close { top: 1.25rem; right: 1.25rem; }
.ar-lb-prev { left: 0.5rem; top: 50%; transform: translateY(-50%); }
.ar-lb-next { right: 0.5rem; top: 50%; transform: translateY(-50%); }
.ar-lb-count {
    position: absolute;
    top: 1.85rem;
    left: 1.5rem;
    color: rgba(255, 255, 255, 0.6);
    font-size: 0.875rem;
    font-family: var(--wp--preset--font-family--secondary);
}
@media (min-width: 641px) {
    .ar-lightbox { padding: 3.5rem 4.5rem; }
    .ar-lb-prev { left: 1.25rem; }
    .ar-lb-next { right: 1.25rem; }
}

/* ============================================================
   ABOUT — hero, intro, cards band, trio, dark band
   ============================================================ */
.ar-abt-hero {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: clamp(420px, 62vh, 640px);
    background-image:
        linear-gradient(rgba(21, 22, 58, 0.5), rgba(21, 22, 58, 0.72)),
        var(--ar-img-abt-hero);
    background-size: cover;
    background-position: center 12%;
    text-align: center;
    padding: var(--wp--preset--spacing--x-large) var(--wp--preset--spacing--medium);
}
.ar-abt-hero h1 {
    margin: 0;
}
.ar-abt-hero .ar-l1 {
    display: block;
    color: var(--wp--preset--color--base);
    font-size: clamp(2.25rem, 1.5rem + 3.5vw, 4.25rem);
    text-transform: uppercase;
    line-height: 1.1;
}
.ar-abt-hero .ar-l2 {
    display: block;
    color: var(--wp--preset--color--accent);
    font-size: clamp(1.5rem, 1.125rem + 1.75vw, 2.5rem);
    text-transform: uppercase;
    line-height: 1.1;
    margin-top: 0.625rem;
}
.ar-abt-prose {
    font-size: 1.125rem;
    line-height: 1.85;
    max-width: 58ch;
}
.ar-abt-prose p:first-of-type::first-letter {
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 700;
    font-size: 4rem;
    line-height: 0.85;
    float: left;
    padding: 0.4rem 0.875rem 0 0;
    color: var(--wp--preset--color--primary);
}
.ar-est-lockup {
    text-align: center;
    position: relative;
    padding: var(--wp--preset--spacing--medium) 0;
    /* Fill the column and centre the claim in it, rather than the block
       shrinking to its text and sitting wherever that lands. */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
}

/* The column is vertically centred by default, so it shrinks to its content
   and never fills the row for the rule above to centre within. */
.wp-block-column:has(> .ar-est-lockup) {
    align-self: stretch;
}
.ar-est-lockup .ar-claim {
    position: relative;
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
    font-size: clamp(1.875rem, 1.375rem + 2.25vw, 3rem);
    line-height: 1.3;
    color: var(--wp--preset--color--primary);
    max-width: 15ch;
    margin: 0 auto;
}
.ar-est-lockup .ar-claim::after {
    content: '';
    display: block;
    width: 72px;
    height: 3px;
    background: var(--wp--preset--color--accent);
    margin: 1.25rem auto 0;
}
.ar-abt-cards-band {
    border-radius: 0.5rem;
    overflow: hidden;
}
.ar-abt-card .ar-icon {
    width: 64px;
    height: 64px;
    border-radius: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--wp--preset--color--accent);
    color: var(--wp--preset--color--primary-dark);
    margin-bottom: 1.125rem;
    transition: transform 0.25s ease;
}
.ar-abt-card:hover .ar-icon {
    transform: translateY(-4px) rotate(-4deg);
}
.ar-abt-card h3 {
    font-family: var(--wp--preset--font-family--primary);
    font-size: 1.0625rem;
    font-weight: 700;
    color: var(--wp--preset--color--base);
    margin: 0 0 1.125rem;
}
.ar-abt-card p {
    margin: 0;
    font-size: 1.3125rem;
    font-weight: 400;
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.85);
}
.ar-photo-trio {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr;
}
@media (min-width: 700px) {
    .ar-photo-trio {
        grid-template-columns: repeat(3, 1fr);
    }
}
.ar-trio-item {
    position: relative;
    border-radius: 0.5rem;
    overflow: hidden;
    margin: 0;
}
.ar-trio-item img {
    width: 100%;
    height: 500px;
    object-fit: cover;
    display: block;
    transition: transform 0.5s ease;
}
.ar-trio-item:hover img {
    transform: scale(1.035);
}
.ar-trio-overlay {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 3rem 1.5rem 1.5rem;
    background: linear-gradient(to top, rgba(14, 15, 44, 0.95), rgba(14, 15, 44, 0.6) 70%, transparent);
}
.ar-trio-overlay h3 {
    color: var(--wp--preset--color--base);
    font-size: 1.75rem;
    margin: 0 0 0.5rem;
}
.ar-trio-overlay p {
    color: rgba(255, 255, 255, 0.92);
    font-size: 1.125rem;
    line-height: 1.55;
    margin: 0;
}
.ar-abt-dark h2 {
    color: var(--wp--preset--color--base);
    /* The map column that used to sit beside this is gone, so the band is the
       measure now — capping at 20ch left ~730px of dead space to its right. */
    max-width: none;
    text-wrap: balance;
}
.ar-abt-dark p {
    color: rgba(255, 255, 255, 0.9);
    max-width: 54ch;
    font-size: 1.25rem;
    line-height: 1.6;
    text-wrap: pretty;
}
.ar-loc-card {
    display: block;
    background: var(--wp--preset--color--base);
    border-radius: 0.5rem;
    overflow: hidden;
    text-decoration: none;
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.ar-loc-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.35);
}
.ar-loc-card img {
    width: 100%;
    aspect-ratio: 16 / 11;
    object-fit: cover;
    display: block;
}
.ar-loc-body {
    display: block;
    padding: 1.125rem 1.25rem 1.25rem;
}
.ar-loc-body em {
    font-style: normal;
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
    font-size: 1.125rem;
    color: var(--wp--preset--color--primary);
}
.ar-loc-card:hover .ar-loc-body em {
    color: var(--wp--preset--color--accent);
}

/* ============================================================
   HOME — Resources / blog cards
   ============================================================ */
.ar-resource-card {
    transition: transform 0.2s ease, box-shadow 0.2s ease;
    background: var(--wp--preset--color--base);
    border: 1px solid var(--wp--preset--color--outline);
    border-radius: 0.5rem;
    overflow: hidden;
    position: relative;
    height: 100%;
    text-align: left;
}
.ar-resource-card .wp-block-image {
    margin: 0;
}
.ar-resource-card .wp-block-image img {
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
}
.ar-resource-topic {
    position: absolute;
    top: 0.875rem;
    left: 0.875rem;
    background: var(--wp--preset--color--accent);
    color: var(--wp--preset--color--primary-dark);
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.25rem 0.625rem;
    border-radius: 0.25rem;
    margin: 0;
    z-index: 1;
}
.ar-resource-body {
    padding: 1.25rem 1.375rem 1.5rem;
}
.ar-resource-body h4 {
    margin-top: 0;
    margin-bottom: 0.375rem;
}
.ar-resource-body p {
    font-size: 0.9375rem;
    color: var(--wp--preset--color--muted);
    margin-bottom: 1rem;
}
.ar-read-more a {
    font-family: var(--wp--preset--font-family--secondary);
    font-weight: 600;
    font-size: 0.875rem;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--wp--preset--color--primary);
}
.ar-read-more a:hover {
    text-decoration: underline;
}

/* ── Block wrappers ───────────────────────────────────────────
   Classes used by the child theme's own blocks (blocks/*). The block
   wrapper adds its own wp-block-* class, so these target the semantic
   class the design CSS above already styles.
   ============================================================ */

/* Call cell: optional breathing room when it sits between text blocks. */
.ar-call-cell--spaced {
    margin: 1.5rem 0 2rem;
}

/* Hero heading: the H1 and the review pill are now sibling blocks, so the
   inline-flex that used to live on .ar-h1-line moves to their container. */
.ar-hero-heading {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem 1.5rem;
}
.ar-hero-heading h1,
.ar-hero-heading .wp-block-heading {
    margin: 0;
}

/* The editor renders dynamic blocks through the same classes as the front
   end; these keep block wrappers from adding layout the design didn't have. */
.editor-styles-wrapper .ar-quote-card,
.editor-styles-wrapper .ar-project-card,
.editor-styles-wrapper .ar-gallery-item {
    max-width: none;
}

/* Gallery figures are keyboard-activatable (they open the lightbox), so they
   need a visible focus ring like any other control. */
.ar-gallery-item:focus-visible {
    outline: 3px solid var(--wp--preset--color--accent);
    outline-offset: 3px;
}

/* ── Button styles ────────────────────────────────────────────
   Registered via register_block_style() so they appear in the editor's
   Styles panel. Patterns reference them by class instead of repeating
   colour/typography block attributes at each call site.
   ============================================================ */
.wp-block-button.is-style-ar-accent .wp-block-button__link {
    background-color: var(--wp--preset--color--accent);
    color: var(--wp--preset--color--primary-dark);
}
.wp-block-button.is-style-ar-primary .wp-block-button__link,
.wp-block-button.is-style-ar-primary-sm .wp-block-button__link {
    background-color: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--base);
}
.wp-block-button.is-style-ar-primary-sm .wp-block-button__link,
.wp-block-button.is-style-ar-outline-light .wp-block-button__link {
    font-size: 0.875rem;
}
.wp-block-button.is-style-ar-outline-light .wp-block-button__link {
    background-color: transparent;
    border: 2px solid rgba(255, 255, 255, 0.4);
    color: var(--wp--preset--color--base);
}
.wp-block-button.is-style-ar-outline-light .wp-block-button__link:hover {
    border-color: var(--wp--preset--color--base);
}

/* ── Motion pause control (WCAG 2.2.2) ────────────────────────
   Injected by andys.js next to each auto-advancing component.
   ============================================================ */
.ar-motion-toggle {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 1px solid var(--wp--preset--color--outline);
    background: var(--wp--preset--color--base);
    color: var(--wp--preset--color--primary);
    font-size: 0.75rem;
    line-height: 1;
    cursor: pointer;
    flex: none;
}
.ar-motion-toggle:hover {
    border-color: var(--wp--preset--color--primary);
}
.ar-motion-toggle:focus-visible {
    outline: 3px solid var(--wp--preset--color--accent);
    outline-offset: 2px;
}
/* Panels are hidden via [hidden] as well as the display rules above, so the
   attribute must win over .ar-service-panel's own display value. */
.ar-tabs-on .ar-service-panel[hidden] {
    display: none;
}

/* ── Quote form states ────────────────────────────────────────
   The card renders a phone CTA until a real form handler is wired up —
   never a static form that silently drops submissions.
   ============================================================ */
.ar-form-fallback {
    font-size: 0.9375rem;
    color: var(--wp--preset--color--muted);
    margin-bottom: 1rem;
}
.ar-form-fallback-cta {
    display: inline-block;
    background-color: var(--wp--preset--color--accent);
    color: var(--wp--preset--color--primary-dark);
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 1.25rem;
    text-decoration: none;
}
.ar-form-admin-notice {
    margin-top: 1rem;
    padding: 0.75rem 1rem;
    border-left: 3px solid var(--wp--preset--color--highlight);
    background: var(--wp--preset--color--surface);
    font-size: 0.8125rem;
    color: var(--wp--preset--color--contrast);
}

/* ── Front-end layout corrections ─────────────────────────────
   Found in a full-page visual QA pass; these are not covered by
   text/class parity checks.
   ============================================================ */

/* WP injects --wp--style--block-gap (24px) between top-level blocks as
   margin-block-start, which put a white band between every section. The
   design is flush — each section carries its own padding. Physical
   margin-top does NOT override this; it must be the logical property.

   Scoped to .alignfull: every built section is a full-width group, while
   ordinary prose pages (privacy, terms, accessibility) are plain headings
   and paragraphs that still need their normal rhythm. */
.entry-content > .alignfull,
.wp-site-blocks > .alignfull,
main.site-content > .alignfull {
    margin-block-start: 0;
    margin-block-end: 0;
}

/* The header, main and footer are the other .wp-site-blocks children, and the
   footer is a <footer> template part rather than an .alignfull group, so the
   rule above never reached it — leaving a 24px strip of page background
   between the last section and the footer on every page. */
.wp-site-blocks > header.site-header,
.wp-site-blocks > main,
.wp-site-blocks > footer.site-footer {
    margin-block-start: 0;
    margin-block-end: 0;
}

/* Pseudo-elements don't inherit the border-box reset, so the quote mark's
   padding-top was added on top of its 48px height and rendered it as an
   oval instead of a circle. */
.ar-sign-card::before,
.ar-float-chip .ar-dot {
    box-sizing: border-box;
}

/* ── Gravity Forms → match the design's form card ─────────────
   GF ships its own theme CSS; without these the fields and submit
   button fall back to GF's grey/navy defaults.
   ============================================================ */
.ar-form-card .gform_wrapper .gfield_label {
    font-family: var(--wp--preset--font-family--primary);
    font-size: 0.8125rem;
    font-weight: 600;
    text-transform: none;
    color: var(--wp--preset--color--contrast);
}
.ar-form-card .gform_wrapper input[type="text"],
.ar-form-card .gform_wrapper input[type="tel"],
.ar-form-card .gform_wrapper input[type="email"],
.ar-form-card .gform_wrapper select,
.ar-form-card .gform_wrapper textarea {
    border: 1px solid var(--wp--preset--color--outline);
    border-radius: 0.5rem;
    padding: 0.75rem 0.875rem;
    font-size: 0.9375rem;
    background: var(--wp--preset--color--base);
    color: var(--wp--preset--color--contrast);
    width: 100%;
}
.ar-form-card .gform_wrapper select {
    height: auto;
    min-height: 46px;
    appearance: auto;
}
.ar-form-card .gform_wrapper input:focus,
.ar-form-card .gform_wrapper select:focus,
.ar-form-card .gform_wrapper textarea:focus {
    outline: 2px solid var(--wp--preset--color--accent);
    outline-offset: 1px;
    border-color: var(--wp--preset--color--accent);
}
/* The submit is the page's primary CTA — gold, full width, dark text
   (white-on-gold fails contrast, per the brand rule). */
/* GF's own button rule outranks a plain class chain (its input rules don't,
   which is why the fields above style cleanly). !important here is overriding
   a third-party plugin's theme CSS — not WP block layout. */
.ar-form-card .gform_wrapper .gform-footer button.gform_button,
.ar-form-card .gform_wrapper .gform_footer button.gform_button,
.ar-form-card .gform_wrapper .gform-footer input[type="submit"],
.ar-form-card .gform_wrapper form .gform_button,
.ar-quote-modal .gform_wrapper .gform-footer button.gform_button,
.ar-quote-modal .gform_wrapper .gform_footer button.gform_button,
.ar-quote-modal .gform_wrapper form .gform_button {
    background-color: var(--wp--preset--color--accent) !important;
    color: var(--wp--preset--color--primary-dark) !important;
    border: none !important;
    border-radius: 0.5rem !important;
    font-family: var(--wp--preset--font-family--secondary) !important;
    font-size: 1rem !important;
    font-weight: 600 !important;
    letter-spacing: 0.01em;
    padding: 0.875rem 1.75rem !important;
    width: 100% !important;
    cursor: pointer;
}
.ar-form-card .gform_wrapper .gform_button:hover,
.ar-quote-modal .gform_wrapper .gform_button:hover {
    filter: brightness(0.95);
}
.ar-form-card .gform_wrapper .gform_required_legend {
    display: none;
}

/* ── Blog cards: whole box clickable ──────────────────────────
   The read-more link is stretched over the card, so there is still
   exactly one link with real link text — the whole box is just its
   hit area.
   ============================================================ */
.ar-read-more a::after {
    content: '';
    position: absolute;
    inset: 0;
}
.ar-resource-card:hover,
.ar-resource-card:focus-within {
    transform: translateY(-4px);
    box-shadow: 0 14px 30px rgba(21, 22, 58, 0.13);
}
@media (prefers-reduced-motion: reduce) {
    .ar-resource-card {
        transition: none;
    }
    .ar-resource-card:hover,
    .ar-resource-card:focus-within {
        transform: none;
    }
}

/* ── Card interaction, site-wide ──────────────────────────────
   One hover treatment for every card surface so they behave alike.
   :focus-within gives keyboard users the same affordance, and the
   whole motion is dropped under prefers-reduced-motion.
   ============================================================ */
.ar-resource-card,
.ar-project-card,
.ar-gallery-item,
.ar-loc-card,
.ar-sign-card,
.ar-abt-card,
.ar-trio-item {
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.ar-resource-card:hover,
.ar-resource-card:focus-within,
.ar-project-card:hover,
.ar-project-card:focus-within,
.ar-gallery-item:hover,
.ar-gallery-item:focus-within,
.ar-sign-card:hover,
.ar-abt-card:hover,
.ar-trio-item:hover {
    transform: translateY(-4px);
    box-shadow: 0 14px 30px rgba(21, 22, 58, 0.13);
}
/* The location card sits on a dark map, so it needs a deeper shadow. */
.ar-loc-card:hover,
.ar-loc-card:focus-within {
    transform: translateY(-4px);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.35);
}
@media (prefers-reduced-motion: reduce) {
    .ar-resource-card,
    .ar-project-card,
    .ar-gallery-item,
    .ar-loc-card,
    .ar-sign-card,
    .ar-abt-card,
    .ar-trio-item {
        transition: none;
    }
    .ar-resource-card:hover,
    .ar-resource-card:focus-within,
    .ar-project-card:hover,
    .ar-project-card:focus-within,
    .ar-gallery-item:hover,
    .ar-gallery-item:focus-within,
    .ar-loc-card:hover,
    .ar-loc-card:focus-within,
    .ar-sign-card:hover,
    .ar-abt-card:hover,
    .ar-trio-item:hover {
        transform: none;
    }
}

/* ── Nested blockGap ──────────────────────────────────────────
   WP applies margin-block-start:24px to children of every flow
   container. Our grid/flex wrappers already space themselves with
   `gap`, so that margin just pushes their children out of line —
   it was offsetting the service panel from its tab list and the
   numbered headings from their numerals by exactly 24px.
   ============================================================ */
.ar-why-item > *,
.ar-services-grid > *,
.ar-service-tabs > *,
.ar-section-head > *,
.ar-sign-grid > *,
.ar-projects-grid > *,
.ar-gallery-grid > *,
.ar-photo-trio > *,
.ar-pitch-row > *,
.ar-split > *,
.ar-svc-hero-actions > *,
.ar-hero-chips > *,
.ar-hero-heading > *,
.ar-quote-slider > * {
    margin-block-start: 0;
    margin-block-end: 0;
}

/* ── Link underlines ──────────────────────────────────────────
   Removed at rest per design direction. Kept on hover so a link
   still announces itself as one on interaction, and focus-visible
   keeps keyboard users oriented.
   ============================================================ */
.entry-content a:not(.wp-block-button__link):not(.ar-service-tab):not(.gform_button),
.wp-site-blocks a:not(.wp-block-button__link):not(.ar-service-tab):not(.gform_button) {
    text-decoration: none;
}
.entry-content a:not(.wp-block-button__link):hover,
.wp-site-blocks a:not(.wp-block-button__link):hover {
    text-decoration: underline;
}
.screen-reader-text:focus {
    text-decoration: underline;
}

/* ── Sticky header: keep the wordmark, shrink it ──────────────
   The parent collapses .header-logo-default on scroll (max-height:0,
   position:absolute) so a .header-logo-compact can take its place.
   This theme has no compact logo, so the wordmark simply left the
   flex row and the nav slid left to fill the gap. Keep it in flow
   and scale it down instead. Selectors carry one extra class so they
   outrank the parent's without !important.
   ============================================================ */
header.site-header.is-scrolled .ar-header-logo.header-logo-default {
    opacity: 1;
    max-height: 200px;
    position: static;
    pointer-events: auto;
}
.ar-header-logo img {
    transition: height 0.3s ease;
}
header.site-header.is-scrolled .ar-header-logo img {
    height: 34px;
}

/* ── Eyebrow → heading rhythm ─────────────────────────────────
   Gaps measured 27 / 3 / 27 / 44 / 7 / 24px across the site because
   WP's 24px blockGap landed on the heading rather than the eyebrow.
   Own the spacing explicitly: 10px everywhere.
   ============================================================ */
.ar-tag {
    margin-block-end: 0.625rem;
}
/* p.ar-tag rather than .ar-tag so this outranks component rules like
   `.ar-form-card h3`, which otherwise add their own top margin on top of
   the eyebrow's 20px. */
p.ar-tag + * {
    margin-block-start: 0;
}

/* ── Quote form density ───────────────────────────────────────
   GF's default rhythm (30px between fields, a 10-row textarea) made
   the card far taller than the copy beside it. Tighten both.
   ============================================================ */
.ar-form-card .gform_wrapper {
    --gf-form-gap-y: 1.125rem;
}
.ar-form-card .gform_wrapper .gform_fields {
    row-gap: 1.125rem;
}
.ar-form-card .gform_wrapper .gfield {
    margin-block-start: 0;
    margin-block-end: 0;
}
.ar-form-card .gform_wrapper .gfield_label {
    margin-bottom: 0.25rem;
}
.ar-form-card .gform_wrapper textarea {
    min-height: 104px;
    height: 104px;
}
.ar-form-card .gform_wrapper .gform-footer {
    margin-block-start: 1.25rem;
    padding-top: 0;
}

/* Footer intro: cap the measure so it doesn't run up to the next column.
   Matches the design's .footer-brand p. */
.ar-footer-logo ~ p {
    max-width: 34ch;
}

/* Photo closing the estimate band's first column. On mobile it is a plain
   4:3 crop. Side by side, it instead grows into whatever space the form
   leaves, so both columns end level: flex-basis 0 keeps the photo out of
   the column's natural height, so the row is sized by the form and the
   photo fills the remainder. */
.ar-estimate-photo {
    margin-block-start: 1.75rem;
}
.ar-estimate-photo img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: 0.5rem;
    display: block;
}
@media (min-width: 782px) {
    #estimate .wp-block-column:first-child {
        display: flex;
        flex-direction: column;
    }
    .ar-estimate-photo {
        flex: 1 1 0;
        min-height: 170px;
    }
    .ar-estimate-photo img {
        height: 100%;
        aspect-ratio: auto;
    }
}

/* Far-footer legal links, sitting opposite the copyright line. */
.ar-footer-legal {
    gap: 0.375rem 1.25rem;
    align-items: center;
}
.ar-footer-legal p {
    margin: 0;
}

/* Marks unresolved legal/business decisions on the policy pages. Remove the
   markers (and this rule) once the copy has been reviewed and signed off. */
.ar-review-note {
    border-left: 3px solid var(--wp--preset--color--highlight);
    background: var(--wp--preset--color--accent-light);
    padding: 0.875rem 1rem;
    font-size: 0.9375rem;
    color: var(--wp--preset--color--contrast);
    border-radius: 0.25rem;
}

/* --- Quote popup ---------------------------------------------------------
   Opened with show(), not showModal() (see initQuoteModal in andys.js), so
   the backdrop and the centering are ours rather than ::backdrop's. */
.ar-modal-backdrop {
	position: fixed;
	inset: 0;
	z-index: 1000;
	background: rgba(21, 22, 58, 0.62);
}

.ar-modal-backdrop[hidden] { display: none; }

body.ar-modal-open { overflow: hidden; }

dialog.ar-quote-modal {
	position: fixed;
	inset: 0;
	z-index: 1001;
	width: min(560px, calc(100vw - 2rem));
	max-height: min(88vh, 780px);
	margin: auto;
	padding: 0;
	/* The dialog clips and .__inner scrolls, so the absolutely-positioned
	   close button stays put instead of scrolling away with the fields. */
	display: flex;
	overflow: hidden;
	border: 0;
	border-radius: 0.75rem;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	box-shadow: 0 24px 60px rgba(21, 22, 58, 0.35);
}

dialog.ar-quote-modal:not([open]) { display: none; }

.ar-quote-modal__inner {
	flex: 1 1 auto;
	overflow-y: auto;
	padding: 0;
}

.ar-quote-modal__intro {
	padding: 1.75rem 1.5rem 1.375rem;
	background: var(--wp--preset--color--primary-light);
}

.ar-quote-modal__form { padding: 1.5rem; }

.ar-quote-modal__close {
	position: absolute;
	top: 0.75rem;
	right: 0.75rem;
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: var(--wp--preset--color--primary);
	cursor: pointer;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.ar-quote-modal__close:hover,
.ar-quote-modal__close:focus-visible {
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
}

dialog.ar-quote-modal h2 {
	margin: 0 0 0.5rem;
	padding-right: 2rem;
	font-size: 1.5rem;
	line-height: 1.15;
}

.ar-quote-modal__sub {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.5;
	color: var(--wp--preset--color--muted);
}

.ar-quote-modal__sub a {
	color: var(--wp--preset--color--primary);
	font-weight: 600;
}

/* The popup is deliberately compact: label beside field, no gaps, and the
   controls collapse into one connected stack. Message keeps its label above,
   since a textarea beside a centred label reads badly.

   Note the selectors: Gravity Forms renders this form with its *orbital*
   theme (.gform-theme--orbital), not the older .gravity-theme, so anything
   scoped to .gravity-theme here is dead CSS. Orbital lays the fields out on a
   12-column grid whose row-gap comes from --gf-form-gap-y, and that property
   is set by an inline <style> scoped to #gform_wrapper_N[data-form-index] —
   an id selector no class-based override can outrank. So the gap is closed by
   setting row-gap on .gform_fields directly rather than by redefining the
   custom property. */
.ar-quote-modal .gform_wrapper .gform_fields {
	row-gap: 0;
}

/* :not(...) matters — a bare .gfield display rule outranks the theme's
   display:none and would reveal the hidden Source page field as a blank row. */
.ar-quote-modal .gform_wrapper .gfield:not(.gform_hidden):not(.gfield--type-hidden):not(.gfield--type-textarea):not(.gfield--type-turnstile) {
	display: grid;
	grid-template-columns: 8.5rem 1fr;
	align-items: center;
	column-gap: 0.875rem;
}

.ar-quote-modal .gform_wrapper .gfield_label {
	margin: 0;
	font-size: 0.875rem;
	line-height: 1.25;
}

/* Explicit placement, because Gravity Forms renders the validation message
   BETWEEN the label and the input (the form is set to validation_above). With
   auto-placement that message takes the input's cell and shoves every control
   onto its own row, so the whole form comes apart the moment it errors. */
.ar-quote-modal .gform_wrapper .gfield > .gfield_label {
	grid-column: 1;
	grid-row: 1;
}

.ar-quote-modal .gform_wrapper .gfield > .ginput_container {
	grid-column: 2;
	grid-row: 1;
}

.ar-quote-modal .gform_wrapper .gfield > .gfield_validation_message,
.ar-quote-modal .gform_wrapper .gfield > .gfield_description {
	grid-column: 2;
	grid-row: 2;
	margin: 0.25rem 0 0;
	padding: 0;
	background: none;
	border: 0;
	font-size: 0.8125rem;
}

/* The textarea keeps its stacked layout, so its message flows normally. */
.ar-quote-modal .gform_wrapper .gfield--type-textarea > .gfield_label,
.ar-quote-modal .gform_wrapper .gfield--type-textarea > .ginput_container,
.ar-quote-modal .gform_wrapper .gfield--type-textarea > .gfield_validation_message,
.ar-quote-modal .gform_wrapper .gfield--type-textarea > .gfield_description {
	grid-column: auto;
	grid-row: auto;
}



/* Compact the error summary so it doesn't dominate a small popup. */
.ar-quote-modal .gform_wrapper .gform_submission_error,
.ar-quote-modal .gform_wrapper .gform_validation_errors {
	margin-bottom: 1rem;
	padding: 0.75rem 0.875rem;
	border-radius: 0.5rem;
	font-size: 0.875rem;
}

.ar-quote-modal .gform_wrapper .gform_submission_error h2,
.ar-quote-modal .gform_wrapper .gform_validation_errors h2 {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.35;
}

.ar-quote-modal .gform_wrapper .gfield--type-textarea {
	margin-top: 0.875rem;
}

/* The CAPTCHA has no label, so it stays out of the label/input grid and sits
   flush left under the message box like the fields above it. */
.ar-quote-modal .gform_wrapper .gfield--type-turnstile {
	margin-top: 1.125rem;
}

.ar-quote-modal .gform_wrapper .gfield--type-textarea .gfield_label {
	margin-bottom: 0.25rem;
}

/* Square the shared edges and pull them together, so adjacent 1px borders
   read as one hairline instead of a 2px seam. */
.ar-quote-modal .gform_wrapper .gfield input,
.ar-quote-modal .gform_wrapper .gfield select,
.ar-quote-modal .gform_wrapper .gfield textarea {
	border-radius: 0;
	border-color: var(--wp--preset--color--outline);
}

.ar-quote-modal .gform_wrapper .gfield ~ .gfield input,
.ar-quote-modal .gform_wrapper .gfield ~ .gfield select {
	margin-top: -1px;
}

/* Must come after the border-color rule above, and carry an extra class, or
   the neutral outline colour wins the cascade and errored fields look fine. */
.ar-quote-modal .gform_wrapper .gfield.gfield_error input,
.ar-quote-modal .gform_wrapper .gfield.gfield_error select,
.ar-quote-modal .gform_wrapper .gfield.gfield_error textarea {
	border-color: #b02a30;
	position: relative;
	z-index: 1;
}

.ar-quote-modal .gform_wrapper .gfield:first-child input {
	border-top-left-radius: 0.5rem;
	border-top-right-radius: 0.5rem;
}

.ar-quote-modal .gform_wrapper .gfield--type-select select {
	border-bottom-left-radius: 0.5rem;
	border-bottom-right-radius: 0.5rem;
}

.ar-quote-modal .gform_wrapper .gfield--type-textarea textarea {
	height: 5rem;
	border-radius: 0.5rem;
}

/* Otherwise the focus ring is clipped by the control stacked over it. */
.ar-quote-modal .gform_wrapper .gfield input:focus,
.ar-quote-modal .gform_wrapper .gfield select:focus {
	position: relative;
	z-index: 1;
}

.ar-quote-modal .gform_wrapper .gform-footer,
.ar-quote-modal .gform_wrapper .gform_footer {
	margin-top: 1.125rem;
	padding-top: 0;
}

@media (max-width: 560px) {
	.ar-quote-modal .gform_wrapper .gfield:not(.gform_hidden):not(.gfield--type-hidden):not(.gfield--type-textarea):not(.gfield--type-turnstile) {
		grid-template-columns: 6rem 1fr;
		column-gap: 0.75rem;
	}
}

@media (prefers-reduced-motion: no-preference) {
	dialog.ar-quote-modal[open] { animation: ar-quote-in 0.22s ease-out; }
	@keyframes ar-quote-in {
		from { opacity: 0; transform: translateY(0.75rem); }
		to   { opacity: 1; transform: translateY(0); }
	}
}

/* --- Mobile call bar -----------------------------------------------------
   Only below 782px, where the header's utility bar (and with it the phone)
   is hidden. See inc/mobile-call-bar.php for why this exists. */
.ar-call-bar { display: none; --ar-call-bar-h: 3.25rem; }

@media (max-width: 781px) {
	.ar-call-bar {
		position: fixed;
		inset-inline: 0;
		bottom: 0;
		z-index: 900;
		display: block;
		background: var(--wp--preset--color--accent);
		box-shadow: 0 -2px 12px rgba(21, 22, 58, 0.28);
		/* Clears the iOS home indicator. */
		padding-bottom: env(safe-area-inset-bottom, 0px);
	}

	.ar-call-bar__link {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 0.5rem;
		/* 52px tall: comfortably over the 24x24 minimum target size. Vertical
		   padding stays at 0 so the bar's height is exactly --ar-call-bar-h and
		   the body padding below can't drift out of sync with it. */
		min-height: var(--ar-call-bar-h);
		padding: 0 1rem;
		color: var(--wp--preset--color--primary-dark);
		font-family: var(--wp--preset--font-family--secondary);
		font-size: 1.0625rem;
		font-weight: 600;
		letter-spacing: 0.01em;
		text-decoration: none;
	}

	.ar-call-bar__link:hover,
	.ar-call-bar__link:focus-visible { color: var(--wp--preset--color--primary-dark); }

	/* Keep the bar from covering the end of the page. */
	/* Bar height plus a little breathing room, so the last footer line is not
	   jammed flush against the bar. */
	body { padding-bottom: calc(3.25rem + 0.75rem + env(safe-area-inset-bottom, 0px)); }
	.ar-call-bar { --ar-call-bar-h: 3.25rem; }

	/* The quote popup owns the screen while it is open. */
	body.ar-modal-open .ar-call-bar { display: none; --ar-call-bar-h: 3.25rem; }
}

/* --- Blog: index, archive, single ---------------------------------------
   Card visuals are shared with the homepage tip cards (.ar-resource-card),
   so only the query-loop scaffolding and the post page need styles here. */
/* One shared column for every hero child, left-aligned. A constrained layout
   centres each child on its own max-width instead, which puts the capped h1 in
   the middle while the inline-block eyebrow stays at the container edge. */
.ar-blog-hero-inner,
.ar-post-hero-inner {
	max-width: var(--wp--style--global--wide-size, 1200px);
	margin-inline: auto;
}

.ar-blog-hero .ar-tag,
.ar-post-hero .ar-tag { margin-block-end: 0.625rem; }

.ar-blog-hero h1 {
	margin: 0;
	/* No measure cap: this heading is short and reads as one line. */
	max-width: none;
	text-wrap: balance;
}


.ar-blog-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--wp--preset--spacing--large, 2rem);
}

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

@media (min-width: 900px) {
	.ar-blog-grid { grid-template-columns: repeat(3, 1fr); }
}

/* The post-template <li> is a grid item; the card inside it does the work. */
.ar-blog-grid > li { list-style: none; margin: 0; }
.ar-blog-grid > li > .ar-resource-card { height: 100%; }

/* Featured image and title come from core blocks here rather than raw markup,
   so they need the same treatment .ar-resource-card gives its own children. */
.ar-resource-card .wp-block-post-featured-image { margin: 0; }

.ar-resource-card .wp-block-post-featured-image img {
	display: block;
	width: 100%;
	aspect-ratio: 3 / 2;
	object-fit: cover;
}

.ar-resource-card .wp-block-post-title {
	margin: 0 0 0.5rem;
	font-family: var(--wp--preset--font-family--secondary);
	font-size: 1.25rem;
	line-height: 1.2;
}

.ar-resource-card .wp-block-post-title a {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

.ar-resource-card .wp-block-post-title a:hover { color: var(--wp--preset--color--primary); }

.ar-resource-card .wp-block-post-excerpt { margin: 0; }

.ar-resource-card .wp-block-post-excerpt__excerpt {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.6;
	color: var(--wp--preset--color--muted);
}

/* post-terms renders links; the topic chip should read as a chip, not a link. */
.ar-resource-topic a {
	color: inherit;
	text-decoration: none;
}

.ar-blog-pagination {
	margin-top: var(--wp--preset--spacing--x-large, 3rem);
	gap: 0.75rem;
}

.ar-blog-pagination a,
.ar-blog-pagination .current {
	font-family: var(--wp--preset--font-family--secondary);
	font-weight: 600;
	color: var(--wp--preset--color--primary);
	text-decoration: none;
}

.ar-blog-pagination .current { color: var(--wp--preset--color--muted); }

/* --- Single post --- */
.ar-post-hero h1 {
	margin: 0;
}

.ar-post-hero .ar-tag a { color: inherit; text-decoration: none; }

.ar-post-date {
	margin: 0.875rem 0 0;
	font-size: 0.9375rem;
	color: var(--wp--preset--color--muted);
}

.ar-post-image { margin-block-end: var(--wp--preset--spacing--large, 2rem); }

.ar-post-image img {
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	border-radius: 0.5rem;
}

/* Comfortable measure for long-form reading. In rem, not ch: ch is
   font-relative, so the larger headings got a wider measure than the body copy
   and sat further left — which read as the paragraphs being indented. One
   fixed measure keeps every child on the same left edge, still centred. */
.ar-post-body .wp-block-post-content > * { max-width: 42rem; margin-inline: auto; }

.ar-post-body .wp-block-post-content h2 {
	margin-block-start: 2.25rem;
	font-size: 1.625rem;
}

.ar-post-body .wp-block-post-content h3 {
	margin-block-start: 1.75rem;
	font-size: 1.25rem;
}

.ar-post-body .wp-block-post-content p,
.ar-post-body .wp-block-post-content li { line-height: 1.7; }

.ar-post-body .wp-block-post-content ul { padding-inline-start: 1.25rem; }
.ar-post-body .wp-block-post-content li { margin-block-end: 0.5rem; }

.ar-post-cta-lede {
	margin: 0.75rem auto 1.5rem;
	max-width: 52ch;
	opacity: 0.85;
}

.ar-post-cta-phone {
	margin: 1rem 0 0;
	font-size: 0.9375rem;
	opacity: 0.85;
}

.ar-post-cta-phone a {
	color: var(--wp--preset--color--accent);
	font-weight: 600;
}

/* --- QA fixes ------------------------------------------------------------ */

/* #62: in-page anchors landed under the sticky header, so "Book a Repair
   Visit" appeared to go nowhere. Clear the header (plus the mobile call bar's
   worth of breathing room) whenever an anchor target is scrolled to. */
:target,
[id="estimate"],
[id="contact"],
[id="contact-form"],
[id="services"] {
	scroll-margin-top: 6.5rem;
}

/* #61: on mobile the 90+ medal sat on top of the heading it is meant to sit
   beside. Below the two-column breakpoint it moves out of the text's way. */
@media (max-width: 899px) {
	.ar-contact-pitch { padding-top: 4.5rem; }

	.ar-medal {
		top: 0;
		right: 0;
		width: 84px;
	}

	.ar-contact-pitch h2 { max-width: none; }
}

/* #63: the lightbox sat at z-index 200 while the sticky header is 999, so the
   close button rendered underneath it. Above the header, the call bar (900)
   and the quote popup (1001). */
.ar-lightbox { z-index: 1100; }

/* #63: over a wide photo the arrows were nearly invisible against the image.
   A solid dark disc keeps them readable whatever is behind them. */
.ar-lb-btn {
	background: rgba(14, 15, 44, 0.72);
	border-color: rgba(255, 255, 255, 0.55);
	backdrop-filter: blur(2px);
}

@media (max-width: 599px) {
	.ar-lb-btn { width: 40px; height: 40px; }
	.ar-lb-close { top: 0.75rem; right: 0.75rem; }
	/* Keep the arrows off the photo's edges on small screens. */
	.ar-lb-prev { left: 0.5rem; }
	.ar-lb-next { right: 0.5rem; }
}

/* Cliff's #6/#13/#16/#18/#19/#23/#24 are all the same defect: a heading or
   lead paragraph wrapping so the last line holds one or two words. Balancing
   the lines fixes the whole class of them rather than hand-tuning each string,
   and keeps working when the copy changes. */
h1, h2, h3, h4,
.ar-tag,
.ar-project-card h3,
.ar-resource-body h4 {
	text-wrap: balance;
}

/* The short supporting sentence under a section heading is only ever a line or
   two, so balance it like a heading — `pretty` only kills a one-word orphan and
   these were left with two-word stubs. */
.ar-section-head > p,
.ar-services-head p,
.ar-post-cta-lede {
	text-wrap: balance;
}

/* pretty, not balance, for longer running text: it prevents the orphan on the
   last line without evening out every line of a long paragraph. */
.ar-hero-lede,
.ar-svc-hero p,
.ar-svc-intro p,
.ar-blog-hero p,
.ar-quote-text,
.ar-resource-body p {
	text-wrap: pretty;
}

/* Services landing page (QA #12) — same card shape as the blog/tip cards. */
.ar-svc-index-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--wp--preset--spacing--large, 2rem);
	margin-top: var(--wp--preset--spacing--large, 2rem);
}

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

.ar-svc-index-grid > .ar-resource-card { height: 100%; }

.ar-svc-index-grid .ar-resource-body h3 {
	margin: 0 0 0.5rem;
	font-size: 1.375rem;
	line-height: 1.2;
}

.ar-svc-hero-inner {
	max-width: var(--wp--style--global--wide-size, 1200px);
	margin-inline: auto;
}

.ar-svc-hero-lede {
	margin: 1rem 0 1.75rem;
	max-width: 56ch;
	font-size: 1.0625rem;
	line-height: 1.6;
	opacity: 0.85;
}

/* Behaviour hook only — the lightbox binds to it; all appearance stays with
   .ar-project-card / .ar-gallery-item. */
.ar-lightbox-item { cursor: zoom-in; }

/* The call-cell defaults to navy text, which is invisible on the Services
   hero's navy background. (The block has only `cell` and `inline` variants —
   there is no `light` one — so the colour has to come from the context.) */
.ar-pattern-dark .ar-call-cell a,
.ar-svc-hero .ar-call-cell a {
	color: var(--wp--preset--color--base);
}

.ar-pattern-dark .ar-call-cell a:hover,
.ar-svc-hero .ar-call-cell a:hover {
	color: var(--wp--preset--color--accent);
}

.ar-pattern-dark .ar-call-cell span,
.ar-svc-hero .ar-call-cell span {
	color: rgba(255, 255, 255, 0.72);
}

/* Services cards: equal height with the "See ..." link pinned to the bottom,
   so cards with shorter descriptions still line up with their neighbours. */
.ar-svc-index-grid > .ar-resource-card {
	display: flex;
	flex-direction: column;
	/* blockGap gives every child after the first a 24px margin-block-start,
	   which offset the top row against itself. The grid's own gap handles
	   spacing. */
	margin-block-start: 0;
	margin-block-end: 0;
}

.ar-svc-index-grid > .ar-resource-card .ar-resource-body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
}

/* The link stays in the DOM: it is what stretches over the card (see the
   .ar-read-more a::after rule), and it supplies the card's accessible name.
   Only its visible text goes. It must stay in normal flow and unclipped —
   position or overflow on this paragraph would become the ::after's
   containing block or clip it, and the whole card would stop being
   clickable. */
.ar-svc-index-grid > .ar-resource-card .ar-read-more {
	margin: 0;
	padding: 0;
	height: 0;
}

.ar-svc-index-grid > .ar-resource-card .ar-read-more a {
	font-size: 0;
	line-height: 0;
	color: transparent;
}

/* blockGap was adding 24px above the body and again above the description,
   so the image, heading and text drifted apart. The card's own padding does
   the spacing instead. */
.ar-svc-index-grid > .ar-resource-card .ar-resource-body {
	margin-block-start: 0;
	padding: 1.25rem;
}

.ar-svc-index-grid > .ar-resource-card .ar-resource-body > * {
	margin-block-start: 0;
	margin-block-end: 0;
}

.ar-svc-index-grid > .ar-resource-card .ar-resource-body h3 {
	margin-bottom: 0.5rem;
}

/* ============================================================
   SERVICES — split intro + icon tiles
   Text column left, a 2x2 tile grid right. Hover and texture
   follow the site's own conventions: the same 4px lift and
   navy-tinted shadow the blog and gallery cards use, and the
   diagonal hatch from .ar-pattern-light — no accent outline,
   no gradient wash, no photographic texture.
   ============================================================ */
.ar-svc-index {
	position: relative;
	overflow: hidden;
}

.ar-svc-index > * { position: relative; }

.ar-svc-split {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--wp--preset--spacing--x-large, 3rem);
	align-items: center;
}

@media (min-width: 900px) {
	.ar-svc-split {
		grid-template-columns: 5fr 6fr;
		gap: var(--wp--preset--spacing--xx-large, 4rem);
	}
}

.ar-svc-intro > * { margin-block: 0; }

/* The left column is now a single large statement rather than a heading plus
   body copy. No measure cap — the grid column is the measure, and capping
   inside it left dead space that read as padding.

   Weight 300 is a real Light face — source-sans-3-300-latin.woff2 was added
   to assets/fonts and registered in theme.json. Without it the browser would
   synthesise a lighter face, which renders noticeably worse. */
.ar-svc-intro p {
	max-width: none;
	margin: 0;
	color: var(--wp--preset--color--primary);
	font-size: clamp(1.125rem, 2.02vw, 1.78rem);
	font-weight: 300;
	line-height: 1.4;
	letter-spacing: -0.01em;
	/* pretty, not balance: at 75% size this runs to 8 lines, past the point
	   where browsers still balance, and the widow came back. pretty applies at
	   any length and prevents the single-word last line. */
	text-wrap: pretty;
}

/* Below the split's breakpoint the column goes full width, so the paragraph
   is short enough for balance — which evens the lines rather than leaving the
   two-word stub `pretty` still allows. */
@media (max-width: 899px) {
	.ar-svc-intro p { text-wrap: balance; }
}

/* --- tiles --- */
.ar-svc-tiles {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 1.25rem;
}

.ar-svc-tiles > * { margin-block: 0; }

.ar-svc-tile {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0;
	min-height: 15rem;
	padding: 2.5rem 1.75rem;
	text-align: center;
	background-color: var(--wp--preset--color--primary-dark);
	/* Photo behind a navy wash, the same construction .ar-texture-shingle uses.
	   The image itself comes from a CSS variable set in functions.php, because
	   relative url() paths are unreliable from a child theme. */
	background-size: cover;
	background-position: center;
	border: 1px solid transparent;
	border-radius: 0.5rem;
	transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.ar-svc-tile > * { margin-block: 0; }

.ar-svc-tile--repairs {
	background-image: linear-gradient(rgba(21, 22, 58, 0.74), rgba(21, 22, 58, 0.8)), var(--ar-img-svc-repairs);
}

.ar-svc-tile--replacements {
	background-image: linear-gradient(rgba(21, 22, 58, 0.74), rgba(21, 22, 58, 0.8)), var(--ar-img-svc-replacements);
}

.ar-svc-tile--gutters {
	background-image: linear-gradient(rgba(21, 22, 58, 0.74), rgba(21, 22, 58, 0.8)), var(--ar-img-svc-gutters);
}

.ar-svc-tile--snow {
	background-image: linear-gradient(rgba(21, 22, 58, 0.74), rgba(21, 22, 58, 0.8)), var(--ar-img-svc-snow);
}

/* Lift and shadow match .ar-resource-card and .ar-gallery-item; the wash
   easing back is the same idea as .ar-project-card brightening its photo. */
.ar-svc-tile {
	transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}

.ar-svc-tile:hover,
.ar-svc-tile:focus-within {
	transform: translateY(-4px);
	box-shadow: 0 14px 30px rgba(21, 22, 58, 0.2);
}

.ar-svc-tile:hover::after,
.ar-svc-tile:focus-within::after { opacity: 1; }

/* A second, lighter wash faded in on hover — animating background-image
   itself does not transition. */
.ar-svc-tile::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	background: rgba(21, 22, 58, 0.16);
	opacity: 0;
	z-index: 0;
	transition: opacity 0.2s ease;
	pointer-events: none;
}

.ar-svc-tile svg {
	position: relative;
	z-index: 1;
	box-sizing: content-box;
	padding: 0.875rem;
	border-radius: 50%;
	background: var(--wp--preset--color--accent-light);
	color: var(--wp--preset--color--accent);
}

.ar-svc-tile h3 {
	position: relative;
	z-index: 1;
	margin-top: 1.375rem;
	font-size: 1.4375rem;
	line-height: 1.2;
	color: var(--wp--preset--color--base);
}

.ar-svc-tile p {
	position: relative;
	z-index: 1;
	margin-top: 0.5rem;
	font-size: 0.875rem;
	line-height: 1.55;
	color: rgba(255, 255, 255, 0.76);
	/* Two-line blurbs — balance keeps both lines even rather than leaving a
	   stub. */
	text-wrap: balance;
}

/* The link IS the overlay — absolutely positioned over the tile rather than
   relying on a pseudo-element, which was not hit-testing. Its text is hidden
   by type size, so the accessible name survives. */
.ar-svc-tile p.ar-svc-tile-go {
	/* Must out-specify `.ar-svc-tile p` (0,1,1) above, which sets
	   position:relative — that made this 0-height paragraph the link's
	   containing block and collapsed the overlay to 0x0, so the tile looked
	   right and silently was not clickable. */
	position: static;
	height: 0;
	margin: 0;
}

.ar-svc-tile p.ar-svc-tile-go a {
	position: absolute;
	inset: 0;
	z-index: 2;
	border-radius: inherit;
	font-size: 0;
	line-height: 0;
	color: transparent;
}

.ar-svc-tile p.ar-svc-tile-go a:focus-visible {
	outline: 2px solid var(--wp--preset--color--primary);
	outline-offset: 2px;
}

@media (max-width: 479px) {
	.ar-svc-tiles { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
	.ar-svc-tile { transition: none; }
	.ar-svc-tile:hover,
	.ar-svc-tile:focus-within { transform: none; }
}

/* ============================================================
   TESTIMONIALS — centred head, all three shown at once
   The slider is gone (.ar-quote-slider no longer exists here), so
   initQuotes() simply does not bind — no autoplay, dots or arrows.
   ============================================================ */
.ar-quote-head {
	margin-bottom: var(--wp--preset--spacing--x-large, 3rem);
	text-align: center;
}

.ar-quote-head > * { margin-block: 0; }

.ar-quote-head .ar-tag { margin-block-end: 0.625rem; }

.ar-quote-head h2 {
	margin: 0;
	/* One line — it sat in a 42% column before and wrapped there. */
	max-width: none;
	text-wrap: nowrap;
}

@media (max-width: 899px) {
	/* Too narrow to hold it on one line below this. */
	.ar-quote-head h2 { text-wrap: balance; }
}

.ar-quote-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--wp--preset--spacing--large, 2rem);
	align-items: stretch;
}

@media (min-width: 782px) {
	.ar-quote-grid { grid-template-columns: repeat(3, 1fr); }
}

/* blockGap would otherwise offset every card after the first inside the grid. */
.ar-quote-grid > * { margin-block: 0; }

/* Out of the slider these are static cards: always visible, full height, and
   no absolute stacking. */
.ar-quote-grid .ar-quote-card {
	display: flex;
	flex-direction: column;
	position: static;
	height: 100%;
	opacity: 1;
	visibility: visible;
	transform: none;
}

.ar-quote-grid .ar-quote-text { flex: 1 1 auto; }

/* Real reviewer photos, sized to match the initials monogram they replace. */
.ar-quote-photo {
	flex: none;
	width: 46px;
	height: 46px;
	border-radius: 50%;
	object-fit: cover;
	display: block;
}

/* ============================================================
   NO WIDOWS — site-wide default
   Appended last so it wins regardless of where the per-section
   rules above sit (style.css still carries duplicated regions).

   balance for headings and other short blocks: it evens the lines
   out, but browsers stop applying it past roughly six lines.
   pretty for running text: it works at any length and is what
   actually prevents a single word stranded on the last line.
   ============================================================ */
h1, h2, h3, h4, h5, h6,
figcaption,
blockquote,
.ar-tag,
.ar-quote-text,
.ar-project-card h3,
.ar-resource-body h4,
.wp-block-button__link,
.ar-lb-figure figcaption {
	text-wrap: balance;
}

p, li, dd, dt,
.wp-block-paragraph,
.wp-block-post-excerpt__excerpt,
.ar-form-note {
	text-wrap: pretty;
}

/* Short supporting paragraphs read better balanced than merely orphan-free —
   a two-word last line is still a stub. These are all a few lines at most. */
.ar-section-head > p,
.ar-services-head p,
.ar-post-cta-lede,
.ar-svc-tile p,
.ar-resource-body p,
.ar-loc-card .ar-loc-body,
.ar-office-panel p,
.ar-card p,
.ar-num-item p,
.ar-sign-card p,
.ar-why-item p,
.ar-trio-overlay p {
	text-wrap: balance;
}

/* nowrap headings stay as authored — balance would re-introduce wrapping. */
.ar-towns h2,
.ar-quote-head h2 {
	text-wrap: nowrap;
}

@media (max-width: 899px) {
	.ar-towns h2,
	.ar-quote-head h2 {
		text-wrap: balance;
	}
}

/* The crew cutout beside "Your Locally Trusted Roofing Company". It is a
   transparent PNG, so it sits straight on the shingle texture with no card or
   frame — a drop shadow keeps it from floating flat against the background. */
/* Selector carries three classes deliberately: WordPress' layout CSS zeroes
   this with `:root :where(.is-layout-flow) > :last-child`, which is (0,2,0) —
   a single class loses to it. */
.ar-abt-dark .wp-block-column .ar-abt-crew {
	margin: 0;
	/* Pull the cutout through the band's bottom padding so the crew stand on
	   the section edge rather than floating with 64px of dead space beneath.
	   margin-block-end, not margin-bottom: WordPress' flow layout sets
	   `margin-block-end: 0` on a last child, and a physical margin is a
	   different property that loses on declaration order rather than winning
	   on specificity. */
	margin-block-end: calc(-1 * var(--wp--preset--spacing--xx-large));
	align-self: end;
}

/* The column is vertically centred by default; the crew sit on the floor. */
.ar-abt-dark .wp-block-column.is-vertically-aligned-bottom {
	align-self: flex-end;
}

.ar-abt-crew img {
	display: block;
	width: 100%;
	height: auto;
	filter: drop-shadow(0 18px 28px rgba(0, 0, 0, 0.38));
}

/* The cutout's drop shadow extends past the band's bottom edge. On the front
   end the footer paints over it; the editor has no footer, so it showed as
   blurred patches on the white canvas. Clip it at the band edge, which is
   what the front end shows. */
.editor-styles-wrapper .ar-abt-dark {
	overflow: clip;
}

@media (max-width: 781px) {
	/* The cutout keeps its bottom pull when the columns stack — it used to be
	   zeroed here, which left the crew floating in the band's bottom padding
	   instead of standing on the section edge as they do at desktop. */
	.ar-abt-crew img {
		max-width: 22rem;
		margin-inline: auto;
	}
}

/* Section heads read as one line: heading and supporting sentence both run the
   full width of the section rather than wrapping inside a measure cap. nowrap
   would risk overflow if the copy grows, so the caps are simply removed and
   the lines are left to balance if they ever do need to wrap. */
.ar-section-head h2,
.ar-section-head > p,
.ar-services-head h2,
.ar-services-head p {
	max-width: none;
}

/* ---------------------------------------------------------------
   Contact page — phone + email side by side, then the form
   --------------------------------------------------------------- */
.ar-contact-direct .wp-block-columns {
    gap: var(--wp--preset--spacing--large);
}
.ar-contact-big {
    margin: 0;
    font-family: var(--wp--preset--font-family--secondary);
    font-size: clamp(1.125rem, 0.7rem + 1.1vw, 1.75rem);
    line-height: 1.2;
    letter-spacing: -0.01em;
    text-align: center;
    text-transform: uppercase;
    overflow-wrap: anywhere;
}
.ar-contact-big a {
    color: var(--wp--preset--color--contrast);
    text-decoration: none;
    border-bottom: 2px solid var(--wp--preset--color--accent);
    padding-bottom: 0.15em;
    transition: color 0.2s ease, border-color 0.2s ease;
}
.ar-contact-big a:hover,
.ar-contact-big a:focus-visible {
    color: var(--wp--preset--color--primary);
    border-bottom-color: var(--wp--preset--color--primary);
}
.ar-contact-form-band .wp-block-andysroofing-quote-form,
.ar-contact-form-band .ar-form-card {
    max-width: 46rem;
    margin-inline: auto;
}
@media (max-width: 781px) {
    .ar-contact-direct .wp-block-columns {
        gap: var(--wp--preset--spacing--medium);
    }
}

/* Contact details — icon + link, centred as one row */
.ar-contact-big::before {
    content: "";
    display: inline-block;
    vertical-align: -0.12em;
    width: 1em;
    height: 1em;
    margin-right: 0.45em;
    background-color: var(--wp--preset--color--accent);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: contain;
    mask-size: contain;
}
.ar-contact-big--phone::before {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z%22/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z%22/%3E%3C/svg%3E");
}
.ar-contact-big--email::before {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z%22/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z%22/%3E%3C/svg%3E");
}
.ar-contact-row {
    align-items: center;
}

/* ---------------------------------------------------------------
   Sticky footer — short pages (accessibility, 404) must not leave
   the footer floating mid-viewport on tall screens.
   --------------------------------------------------------------- */
.wp-site-blocks {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
}
.wp-site-blocks > main {
    flex: 1 0 auto;
}
.wp-site-blocks > footer.site-footer {
    margin-top: auto;
}

/* ---------------------------------------------------------------
   Submitted state — Gravity Forms swaps the form for its
   confirmation; the card drops its form chrome to match.
   --------------------------------------------------------------- */
.ar-form-card--sent,
.ar-form-card:has(.gform_confirmation_wrapper) {
    text-align: center;
}
/* AJAX submits never re-run render.php — Gravity Forms swaps the form for the
   confirmation in the DOM — so the form chrome has to be hidden from CSS.
   .gform_confirmation_wrapper only exists as an element once a confirmation
   is actually rendered. */
.ar-form-card:has(.gform_confirmation_wrapper) > .ar-tag,
.ar-form-card:has(.gform_confirmation_wrapper) > h3,
.ar-form-card:has(.gform_confirmation_wrapper) > .ar-form-note {
    display: none;
}
.ar-form-card--sent::before,
.ar-form-card:has(.gform_confirmation_wrapper)::before {
    content: "";
    display: block;
    width: 2.5rem;
    height: 2.5rem;
    margin: 0 auto 1rem;
    border-radius: 50%;
    background-color: var(--wp--preset--color--accent);
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 20 20%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.8%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M3 10.5 8 15 17 5%22/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 20 20%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.8%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M3 10.5 8 15 17 5%22/%3E%3C/svg%3E");
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: 2rem 2rem;
    mask-size: 2rem 2rem;
}
.ar-form-card .gform_confirmation_wrapper,
.ar-form-card .gform_confirmation_message {
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    font-size: 1.0625rem;
    line-height: 1.6;
    color: var(--wp--preset--color--contrast);
}

/* ---------------------------------------------------------------
   MOBILE — services tabs become a horizontal icon strip, and the
   panel + testimonial cards tighten up.
   --------------------------------------------------------------- */
@media (max-width: 699.98px) {

    /* Tabs: one row of icons. The label stays in the accessibility
       tree — display:none would strip each button's name. */
    .ar-service-tabs {
        display: flex;
        flex-direction: row;
        gap: 0.5rem;
    }
    .ar-service-tab {
        flex: 1 1 0;
        width: auto;
        min-width: 0;
        justify-content: center;
        gap: 0;
        padding: 0.5rem;
        border-left: 1px solid var(--wp--preset--color--outline);
        border-bottom: 3px solid transparent;
    }
    .ar-service-tab[aria-selected="true"] {
        border-left-color: var(--wp--preset--color--outline);
        border-bottom-color: var(--wp--preset--color--accent);
    }
    .ar-service-tab-label {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        clip-path: inset(50%);
        white-space: nowrap;
        border: 0;
    }
    .ar-service-tab .ar-glyph {
        width: 34px;
        height: 34px;
    }

    /* Panel card */
    .ar-panel-media {
        min-height: 180px;
    }
    .ar-panel-body {
        padding: 1.25rem 1.125rem 1.375rem;
    }
    .ar-panel-body h3 {
        font-size: 1.375rem;
    }

    /* Testimonial cards */
    .ar-quote-grid {
        gap: var(--wp--preset--spacing--medium, 1.25rem);
    }
    .wp-block-group.ar-quote-card {
        padding: 1.5rem 1.375rem 1.25rem;
    }
    .ar-quote-card .ar-stars {
        font-size: 0.9375rem;
        margin-bottom: 0.5rem;
    }
    .ar-quote-text {
        font-size: 1rem;
        line-height: 1.5;
        margin-bottom: 1.125rem;
    }
    .ar-quote-attrib {
        gap: 0.75rem;
    }
    .ar-quote-photo {
        width: 40px;
        height: 40px;
    }
}

/* ---------------------------------------------------------------
   MOBILE — the 90-years medal overlaps the pitch heading at phone
   widths. Hidden below the two-column breakpoint, which also frees
   the padding-top that only existed to clear it.
   --------------------------------------------------------------- */
@media (max-width: 899.98px) {
    .ar-medal,
    .wp-block-andysroofing-medal {
        display: none;
    }
    .ar-contact-pitch {
        padding-top: 0;
    }
}

/* ---------------------------------------------------------------
   MOBILE — the towns card and the pitch below it each carry an
   xx-large wrapper pad, so the seam between them ran to ~134px.
   The pads are inline on the baked wrappers, so a breakpoint
   override is the only thing that can reach them.
   --------------------------------------------------------------- */
@media (max-width: 899.98px) {
    main .alignfull:has(> .ar-towns) {
        padding-bottom: var(--wp--preset--spacing--medium) !important;
    }
    main .alignfull:has(.ar-contact-pitch) {
        padding-top: var(--wp--preset--spacing--medium) !important;
    }
}

/* ---------------------------------------------------------------
   MOBILE MENU
   Core's overlay is a centred, undifferentiated list. This gives it
   a brand row, a real hierarchy between top-level and service links,
   full-width tap targets and a footer that can act.
   --------------------------------------------------------------- */
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open {
    padding: 0;
}
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-dialog {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
    padding: 0 1.25rem 1.25rem;
}

/* Brand row — mirrors the site header so the overlay reads as the
   same surface rather than a separate screen. */
.ar-menu-brand {
    display: flex;
    align-items: center;
    min-height: 4.5rem;
    padding-right: 3.5rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}
.ar-menu-brand img {
    width: 130px;
    height: auto;
    display: block;
}
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-close {
    top: 1.375rem;
    right: 1.25rem;
    width: 2.75rem;
    height: 2.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 0.5rem;
    color: var(--wp--preset--color--base);
    background: rgba(255, 255, 255, 0.08);
}
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-close:hover,
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-close:focus-visible {
    background: rgba(255, 255, 255, 0.16);
}
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-close svg {
    width: 22px;
    height: 22px;
}

/* The list fills the space between brand row and footer. */
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-content {
    flex: 1 1 auto;
    padding: 0;
    align-items: stretch;
}
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container.is-responsive {
    display: block;
    gap: 0;
}
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container.is-responsive > .wp-block-navigation-item {
    display: block;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container.is-responsive > .wp-block-navigation-item > a {
    display: block;
    width: 100%;
    padding: 1rem 0;
    font-size: 1.125rem;
    letter-spacing: 0.02em;
    text-align: left;
}

/* Service links sit under Services, not beside it. */
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__submenu-container.wp-block-navigation-submenu {
    display: block;
    width: 100%;
    min-width: 0;
    padding: 0 0 0.5rem 0.875rem;
    border-left: 2px solid var(--wp--preset--color--accent);
    margin-left: 0.125rem;
}
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__submenu-container.wp-block-navigation-submenu > .wp-block-navigation-item {
    display: block;
    width: 100%;
}
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__submenu-container.wp-block-navigation-submenu .wp-block-navigation-item > a {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.5625rem 0;
    font-size: 0.9375rem;
    text-transform: none;
    letter-spacing: 0.01em;
    color: rgba(255, 255, 255, 0.74);
}
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__submenu-container .wp-block-navigation-item > a:hover,
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__submenu-container .wp-block-navigation-item > a:focus-visible {
    color: var(--wp--preset--color--base);
}
/* The chevron is meaningless when the submenu is always expanded here. */
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__submenu-icon.wp-block-navigation-submenu__toggle {
    display: none;
}

/* Footer — the two things someone opening this menu most wants. */
.ar-menu-foot {
    flex: none;
    padding-top: 1.25rem;
    border-top: 1px solid rgba(255, 255, 255, 0.14);
}
.ar-menu-foot .ar-menu-cta,
.ar-menu-foot .ar-menu-cta .wp-block-button__link {
    display: block;
    width: 100%;
    text-align: center;
}
.ar-menu-foot .ar-menu-cta .wp-block-button__link {
    padding: 0.9375rem 1.25rem;
    font-size: 1rem;
}
.ar-menu-call {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 0.875rem;
    padding: 0.5rem;
    font-family: var(--wp--preset--font-family--secondary);
    font-size: 1.0625rem;
    color: var(--wp--preset--color--base);
    text-decoration: none;
}
.ar-menu-call svg {
    width: 18px;
    height: 18px;
    color: var(--wp--preset--color--accent);
}
.ar-menu-call:hover,
.ar-menu-call:focus-visible {
    color: var(--wp--preset--color--accent);
}

/* Subtle entrance only, and none at all if the visitor asked for less. */
@media (prefers-reduced-motion: no-preference) {
    .wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open
    .wp-block-navigation__container.is-responsive > .wp-block-navigation-item,
    .ar-menu-foot {
        animation: ar-menu-in 0.28s ease both;
    }
    @keyframes ar-menu-in {
        from { opacity: 0; transform: translateY(6px); }
        to { opacity: 1; transform: none; }
    }
}

/* ---------------------------------------------------------------
   Hamburger — core ships a two-bar, 1.5px glyph. Three bars, a
   little thicker and wider, drawn in CSS so core's SVG markup
   stays untouched.
   --------------------------------------------------------------- */
.wp-site-blocks .wp-block-navigation__responsive-container-open svg {
    display: none;
}
.wp-site-blocks .wp-block-navigation__responsive-container-open {
    width: 30px;
    height: 22px;
    padding: 0;
    background-color: transparent;
    background-image:
        linear-gradient(currentColor, currentColor),
        linear-gradient(currentColor, currentColor),
        linear-gradient(currentColor, currentColor);
    background-size: 100% 2.5px;
    background-repeat: no-repeat;
    background-position: left top, left center, left bottom;
}

/* ---------------------------------------------------------------
   The brand row and footer injected into the nav overlay live in
   core's responsive container, which is NOT hidden at desktop —
   it holds the inline menu. Without this they render in the header.
   --------------------------------------------------------------- */
.ar-menu-brand,
.ar-menu-foot {
    display: none;
}
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open .ar-menu-brand {
    display: flex;
}
.wp-site-blocks .wp-block-navigation__responsive-container.is-menu-open .ar-menu-foot {
    display: block;
}

/* A little more air between the hamburger and the CTA beside it. */
@media (max-width: 899.98px) {
    .site-header .ar-quote-trigger {
        margin-left: 0.5rem;
    }
}

/* ---------------------------------------------------------------
   Header CTA must stay on one line. The label needs 78px; flex was
   squeezing the button below that, so nowrap holds its min-content
   width and the side padding comes in to pay for it. Mobile only —
   desktop already fits at the full 20px.
   --------------------------------------------------------------- */
@media (max-width: 899.98px) {
    .site-header .ar-quote-trigger .wp-block-button__link {
        white-space: nowrap;
        padding-left: 1rem !important;
        padding-right: 1rem !important;
    }
    .site-header .ar-quote-trigger,
    .site-header .wp-block-buttons:has(.ar-quote-trigger) {
        flex: none;
    }
}

/* ---------------------------------------------------------------
   Button arrows sit low: Oswald has no U+2192, so the glyph falls
   back to a system font whose ink centre is 0.153em below the cap
   band. andys.js wraps the trailing arrow so this can lift it.
   --------------------------------------------------------------- */
.ar-arrow {
    display: inline-block;
    transform: translateY(-0.153em);
}

/* ---------------------------------------------------------------
   HOME — "From Our Blog" query loop (patterns/resources.php)
   The homepage tip cards are the blog-grid card, but they keep the
   look they had as static columns: 16:10 photos, an h4-sized title,
   flow-layout spacing and a "Read More →" link stretched over the
   card (the same single-link card as .ar-read-more a::after).
   Scoped to .ar-home-blog so the blog index, archives and "More
   Roofing Tips" on posts keep their own treatment.
   --------------------------------------------------------------- */
/* Same breakpoint and gutters the core Columns block gave the cards:
   one column below 782px, three from there up. Two classes beat the
   generated .wp-container-* grid rule. */
.ar-home-blog .ar-blog-grid {
	grid-template-columns: 1fr;
	gap: 2em 1.25rem;
}

@media (min-width: 782px) {
	.ar-home-blog .ar-blog-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.ar-home-blog .ar-resource-card .wp-block-post-featured-image img {
	aspect-ratio: 16 / 10;
}

.ar-home-blog .ar-resource-card .wp-block-post-title {
	margin: 0 0 0.375rem;
	font-size: var(--wp--preset--font-size--xx-large);
	line-height: 1.4;
}

/* The excerpt wrapper is the body group's second child, so it takes the
   flow gap a static paragraph did; the more-text paragraph inside it is
   not a flow child, so it gets that gap by hand. */
.ar-home-blog .ar-resource-card .wp-block-post-excerpt {
	margin-block-start: var(--wp--style--block-gap, 24px);
}

.ar-home-blog .ar-resource-card .wp-block-post-excerpt__excerpt {
	margin: 0 0 1rem;
	line-height: inherit;
}

.ar-home-blog .ar-resource-card .wp-block-post-excerpt__more-text {
	margin: var(--wp--style--block-gap, 24px) 0 0;
}

.ar-home-blog .wp-block-post-excerpt__more-link {
	font-family: var(--wp--preset--font-family--secondary);
	font-weight: 600;
	font-size: 0.875rem;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--wp--preset--color--primary);
}

.ar-home-blog .wp-block-post-excerpt__more-link:hover {
	text-decoration: underline;
}

/* One link per card, with the whole box as its hit area. */
.ar-home-blog .wp-block-post-excerpt__more-link::after {
	content: '';
	position: absolute;
	inset: 0;
}

/* In the editor the overlay would sit over the title, image and excerpt and
   swallow the clicks that select them, so the link keeps its own box there. */
.editor-styles-wrapper .ar-home-blog .wp-block-post-excerpt__more-link::after {
	content: none;
}
