/* ──────────────────────────────────────────────────────────────────────────
   DavaLeather site-wide header — mint brand palette (rolled out 2026-05-08).

   Layered as: <header.dl-header>  position: sticky; top: 0
                 ├ <div.dl-header__topbar>     audience + utility links + geo + phone
                 └ <div.dl-header__pill>       white capsule (brand, nav, lang, search, CTAs, profile)

   The :root variables block preserves every variable that other CSS
   files in /public_html/css/** depend on (--color-*, --site-gutter-x-*,
   --header-height*, --font-main, --transition-fast, --radius, --z-*),
   and exposes the new mint-brand spectrum (--brand-*, --dl-header-*).
   The site is fully recolored to consume these — see commit history
   (style(theme): flip site-wide background to brand gradient).
   ────────────────────────────────────────────────────────────────────────── */

:root {
    /* Existing site-wide layout tokens — DO NOT remove or rename. Other
       CSS files (instant-estimate.css, service-cards.css, footer.css,
       services.css, blog views, prices.blade.php, etc.) reference these. */
    --site-gutter-x-desktop: 20px;
    --site-gutter-x-mobile: 20px;
    --site-gutter-x-mobile-left:  max(var(--site-gutter-x-mobile), env(safe-area-inset-left));
    --site-gutter-x-mobile-right: max(var(--site-gutter-x-mobile), env(safe-area-inset-right));

    /* Site-wide brand palette (root cause, 2026-05-08).
       Every CSS file that consumes these tokens (sections/footer.css,
       sections/services.css, blog views, etc.) flips with the change
       without per-file !important overrides. Hardcoded #141414 / #fff /
       #ccc inside individual files are recolored alongside this commit
       so the tokens and the per-file decisions are coherent. */
    /* Page background — solid dark grey #323232. Was the vibrant
       brand-spectrum gradient (cyan → teal → green → lime → yellow at
       110°) inspired by the Sber.ru login backdrop; flipped to a
       single neutral charcoal per user request. Every consumer of
       this token (html, body::before, the mobile header on
       <=900px) picks up the new value through the variable cascade,
       so no other rule needs to change.

       Knock-on effects to keep in mind:
         - White text on the gradient (topbar, brand wordmark on
           mobile, service titles, etc.) reads with even higher
           contrast on the charcoal — the legibility shadow we layer
           on those (`text-shadow: 0 1px 3px rgba(0,0,0,0.35)`) was
           already overkill, but it's harmless.
         - The desktop brand wordmark stays gradient-filled (cyan →
           yellow) because the gradient lives inside `.dl-header__
           brand-name` directly, NOT via --color-bg. It now reads as
           a coloured logo on charcoal instead of gradient-on-
           gradient harmony — a deliberate visual contrast.
         - The dark footer (#0F1419) is still distinguishable because
           charcoal #323232 is noticeably lighter, and the 40px
           rounded top-corners still register against the body. */
    --color-bg: #323232;
    /* --color-nav and --color-header (legacy tokens for the dark theme's
       header surfaces) are removed — no CSS file in our codebase
       consumed them after the brand recolor. The header wrapper is
       transparent and the white pill carries its own bg. */
    --color-text: #1A1A1A;           /* was #ccc — dark text on mint */
    --color-accent: #21A038;         /* was #a5121a red — now brand green */
    --color-border: #21A038;         /* was #a5121a — accents stay green-driven */
    --color-border-light: #E8EAEE;   /* was #ccc — soft cool-grey divider on light surface */
    --color-shadow: rgba(0, 0, 0, 0.10); /* was rgba(0,0,0,0.5) — much softer for light bg */

    --font-main: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

    /* Header height tokens — kept for compatibility with downstream CSS
       (e.g. instant-estimate.css, mobile drawer fixed-position offsets).
       The body NO LONGER uses padding-top because the header is now
       `position: sticky` and participates in the document flow — its
       intrinsic height carves out the space at the top of the page
       naturally, without a body padding offset. */
    --header-height: 134px;
    /* Mobile bar height. Was 76px when the header lived in a floating
       white pill (with extra room for the pill's own padding); after
       flipping to a transparent edge-to-edge bar (commit f8f6efd) we
       have no pill chrome to pad around, so the bar can be tighter.
       56px matches the touch-target height (44px button) plus 6+6
       breathing room on top/bottom — same proportion as the desktop
       pill but in a slimmer mobile profile. */
    --header-height-mobile: 56px;

    --z-header: 1001;
    --z-menu: 1100;

    --transition-fast: .3s cubic-bezier(.4, 0, .2, 1);
    --radius: 4px;

    /* ── Brand palette (mint spectrum) ───────────────────────────────── */
    --brand-green:        #21A038;
    --brand-green-hover:  #1B8E2F;
    --brand-cyan:         #1FB7DD;
    --brand-teal:         #1FB6BD;
    --brand-lime:         #7AC142;
    --brand-yellow:       #C5E022;
    /* Sberbank-style "Apricot" CTA orange. Used in:
         - the small square accent next to the DAVA LEATHER wordmark
         - the "care | restoration" brand tagline
         - all topbar text + dividers + SVG meta-icons
         - the Quality Guaranteed accent tile (already declares its
           own copy via --client-service-color-accent — same value).
       Contrast on charcoal #323232: ~4.64:1, passes WCAG AA for
       normal text. */
    --brand-orange:       #C75528;

    /* Header surfaces (--dl-header-bg removed — the wrapper is now
       always transparent, no current consumer.) */
    --dl-header-text:      #1A1A1A;
    --dl-header-text-soft: rgba(26, 26, 26, 0.72);
    --dl-header-text-muted:#8A909A;

    /* Header chrome — moved to dark+orange variant. The desktop pill
       was a floating white capsule; user asked for a charcoal fill
       (#343434) that integrates with the page bg (#323232) and lets
       the orange CTA accents stand out. The inner nav-pill is a
       subtle warm-dark gradient that lifts off the outer charcoal
       just enough to read as a separate surface, and gives orange
       text inside it 6:1+ contrast (well above WCAG AA). */
    --dl-pill-bg:           #343434;
    --dl-pill-shadow:       0 4px 24px rgba(0, 0, 0, 0.40);
    --dl-pill-shadow-scrolled: 0 6px 28px rgba(0, 0, 0, 0.50);

    /* Nav-pill is now a soft terracotta wash on the charcoal page —
       same hue family as the dropdown-option hover state in the
       Latest News & Announcements section, so the two interactive
       capsules read as one design language. Hover / active climb
       the same hue at higher alpha so the scale (resting → hover →
       current page) is visible against the pill bg. */
    --dl-nav-pill-bg:        rgba(199, 85, 40, 0.10);
    --dl-nav-pill-hover-bg:  rgba(199, 85, 40, 0.25);
    --dl-nav-pill-active-bg: rgba(199, 85, 40, 0.40);
    --dl-nav-pill-active-shadow: inset 0 0 0 1px rgba(199, 85, 40, 0.55), 0 2px 8px rgba(0, 0, 0, 0.20);

    --dl-topbar-dot: rgba(26, 26, 26, 0.40);
}

* { box-sizing: border-box; }

/* Page background strategy — root cause notes:
   The earlier approach was `background: var(--color-bg);
   background-attachment: fixed` on BOTH <html> and <body>. That works
   visually but is a known macOS Safari/Chrome perf trap: the browser
   has to repaint the entire viewport on every scroll frame to keep
   the fixed gradient anchored, which manifests as (a) jank/freezes on
   fast flicks (e.g. footer-to-top) and (b) yellow streak artifacts
   along the right edge of the header — the right-end of the gradient
   (#C5E022) leaking through during the repaint sub-frame.

   New approach: a single `body::before` pseudo with `position: fixed`
   and `z-index: -1` lives in its own compositor layer. The GPU
   composites it under page content without triggering full-viewport
   paints on scroll.

   <html> ALSO carries the gradient (not a solid colour) because the
   page declares `viewport-fit=cover` in the meta viewport, so on
   iPhones with a notch / Dynamic Island the area BEHIND the camera
   cutout shows the canvas — and that canvas is `<html>`'s bg. A
   solid green there read as a foreign band above the header. With
   the gradient on <html>, the cutout zone shows the same colour
   slice as the header below it, and the seam disappears. The
   gradient on <html> uses the default scroll attachment (no
   background-attachment: fixed), so the perf trap above is avoided
   — html only paints once at layout time, not on every scroll
   frame. The colour difference between html's stretched-over-
   document gradient and body::before's viewport-anchored one is
   imperceptible at the small y-range where both are visible
   simultaneously (just the ~40px notch zone). */
html {
    background: var(--color-bg);
}

body {
    margin: 0;
    color: var(--color-text);
    font-family: var(--font-main);
    overflow-x: hidden;
    min-height: 100vh;
    position: relative;
    /* Disable browser scroll-anchoring. When the sticky topbar
       collapses (height 27px → 0), Chrome was auto-decreasing
       scrollY by 27px to keep the visible content stable — but
       that pushed scrollY back below the expand threshold, the
       topbar re-expanded, scrollY jumped back up, and the topbar
       collapsed again. Infinite flap on a single user scroll
       across 24px. Disabling anchoring lets scrollY stay where
       the user put it; the small visual jump on collapse is
       acceptable and stops the dance. */
    overflow-anchor: none;
    /* Sticky-footer pattern. Without this, short pages (e.g. /search
       with 0 results) ended at the natural content height and left a
       strip of body-gradient visible BELOW the dark footer. flex-column
       + main { flex: 1 0 auto } pushes the footer to the bottom of
       the viewport whenever content can't fill it; on tall pages the
       footer still sits naturally after the content. The sticky
       header is unaffected — `position: sticky` works inside flex
       containers since 2018. */
    display: flex;
    flex-direction: column;
    /* No padding-top: the header is `position: sticky` and lives in the
       document flow, so its own height carves out the space at the top
       of the page. A padding-top here would ADD extra blank space
       above the header. */
}

main {
    flex: 1 0 auto;
}

.dl-footer {
    flex-shrink: 0;
}

body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    /* Charcoal surface with seamless leather-grain texture — two
       layers (down from three) stacked top-down by the browser
       (first listed paints last / on top):

         1. Leather grain — single SVG tile, 1500×1500 with
            isotropic fractalNoise at baseFrequency=0.04. That gives
            60 noise waves per axis (integer, exact, so
            stitchTiles='stitch' produces a perfectly seamless wrap),
            and 4 octaves stack finer detail on top of the base
            wave. Tile is intentionally larger than any common
            viewport (1500 > 1456 desktop, way > 430 mobile) so
            even if stitchTiles had a sub-pixel artefact at the
            wrap line, the seam never lands inside one screen at a
            time. ColorMatrix tints the noise to a warm taupe
            (R=0.88, G=0.78, B=0.62) at 8% alpha — barely shifts
            the charcoal hue but lends a leather-like warmth to the
            lighter patches.

            Earlier deploys split this into a two-layer mottle +
            fine-grain pair. The mottle layer's low-frequency blobs
            were what read as "four blocks glued together": four
            quadrants of slightly different tonality, separated by
            the natural noise edges between blob centres. Removed
            the mottle layer entirely and switched the remaining
            layer's frequency from 0.012 (very large blobs) to 0.04
            (much finer features) — there are no longer any blob-
            sized features for the eye to group into "blocks".

         2. Depth vignette — soft top-centre white highlight at 5%
            alpha, transparent through the mid-band, soft black
            edge vignette at 12% alpha. The grain layer above is
            identical everywhere; the vignette modulates how light
            "catches" the texture, so grain in the lighter zone
            reads as raised and grain in the darker zone as
            recessed. Same as before.

         3. Base --color-bg (#323232) showing through.

       Performance: a single 1500×1500 SVG tile bakes its
       feTurbulence once at decode time, then composites as a
       cached bitmap. Same compositor-layer treatment as before
       (will-change + translateZ). The earlier 180×180 fine-grain
       layer is gone too — it was a redundant micro-grain that
       only added compute without solving the visible-seam issue. */
    background-color: var(--color-bg);
    background-image:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1500' height='1500'><filter id='m'><feTurbulence type='fractalNoise' baseFrequency='0.04' numOctaves='4' seed='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.88  0 0 0 0 0.78  0 0 0 0 0.62  0 0 0 0.08 0'/></filter><rect width='1500' height='1500' filter='url(%23m)'/></svg>"),
        radial-gradient(ellipse 90% 70% at 50% 30%,
            rgba(255, 255, 255, 0.05) 0%,
            rgba(0, 0, 0, 0) 50%,
            rgba(0, 0, 0, 0.12) 100%);
    background-repeat: repeat, no-repeat;
    background-size: 1500px 1500px, 100% 100%;
    /* Promote to its own GPU compositor layer so the textured
       surface stays anchored to the viewport across scroll without
       re-rasterizing on every frame. */
    will-change: transform;
    transform: translateZ(0);
}

a, a:visited { color: inherit; text-decoration: none; }

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ──────────────────────────────────────────────────────────────────────────
   Header shell
   ────────────────────────────────────────────────────────────────────────── */

.dl-header {
    /* `sticky` (vs the previous `fixed`) keeps the header pinned to the
       top of the viewport once the user scrolls past it, AND lets it
       participate in normal document flow before that — so no body
       padding-top trick is needed and the header reliably moves with
       the user (the `fixed` variant was reported as not following on
       scroll on production, this keeps the prototype's behavior).

       NO background: the page background lives once on <body> (the
       brand-spectrum gradient via --color-bg). The header wrapper is
       transparent so the body gradient bleeds through; the only
       opaque surface in the header is the white pill capsule, which
       carries its own background + shadow. This keeps "one site bg,
       one source of truth" intact even when the topbar is visible. */
    position: sticky;
    top: 0;
    z-index: var(--z-header);
    /* Tighter top padding (was 14px) so the topbar sits closer to the
       browser top edge — less wasted space above "Blog" / "About" links. */
    padding: 6px var(--site-gutter-x-desktop, 20px) 18px;
    background: transparent;
    color: var(--dl-header-text);
    /* Asymmetric transition curves (see `.dl-header.is-collapsed` block
       below for the collapsing direction). This BASE rule fires when
       the topbar is RE-EXPANDING — user scrolled back to the very top
       and the topbar should re-appear with a soft spring/settle. The
       cubic-bezier here lifts off fast then eases into place, which
       reads as "пружинит" without literal overshoot (max-height can't
       overshoot above content height anyway). */
    transition: padding .42s cubic-bezier(0.34, 1.16, 0.42, 1);
}

/* Tighter padding when the topbar collapses on scroll — keeps the
   pill comfortably centered in the slimmer header. The transition
   here is the COLLAPSING direction (user scrolled down past 24px):
   shorter duration, conventional ease-out — let it slip away
   without drawing attention. */
.dl-header.is-collapsed {
    padding-top: 10px;
    padding-bottom: 12px;
    transition: padding .24s cubic-bezier(0.4, 0, 0.6, 1);
}

/* The header wrapper is ALWAYS transparent — at the top of the page AND
   while scrolling. The user explicitly chose this aesthetic: "one bg
   only, on the body, no separate bg on the header". Trade-off: when
   sticky and content scrolls under the wrapper, that content can be
   visible through the wrapper margins to the left and right of the
   white pill (dark hero images, dark Netflix-style service cards on
   hub pages). The pill itself stays opaque, so the immediate header
   surface is always white; only the surrounding band reveals what's
   underneath. This is by design.

   The pill's own shadow on scroll (--dl-pill-shadow-scrolled, applied
   via .dl-header.scrolled .dl-header__pill below) provides the
   "lifted" cue. */
.dl-header.scrolled {
    /* (intentionally empty — wrapper stays transparent at every scroll
       position; the lifted-pill shadow lives on the pill itself.) */
}

/* ── Topbar (audience + utility + geo + phone) ──────────────────────────── */

/* Auto-collapse on scroll: when the user scrolls past 24px, header.js adds
   `.is-collapsed` to .dl-header. The topbar then animates max-height to 0,
   opacity to 0, and zeroes its margin/padding — so only the white pill
   capsule stays visible. The header becomes a slim band as the user
   scrolls down, freeing up viewport space; scrolling back to the very
   top reverses the animation. */
/* Topbar is fully driven by header.js (setupTopbarMotion) — height,
   opacity, padding and margin are all set inline by the Web Animations
   API. CSS here only describes the steady-state expanded look (font,
   colour, layout). The previous `max-height: 60px → 0` CSS transition
   had a dead phase: max-height was looser than actual content height
   (~30px), so the first half of the animation collapsed nothing
   visible. JS measures actual content height and animates `height`
   between exact pixel values, which lands precisely and feels springy.
   No CSS fallback rule for `.is-collapsed` — Element.animate has been
   universally available since 2016, and if it's somehow unavailable
   the topbar simply stays expanded (graceful, not broken). */
.dl-header__topbar {
    max-width: 1300px;
    margin: 0 auto 6px;
    padding: 4px 0;             /* aligns topbar text edges with the white pill's outer edges */
    font-size: 13.5px;
    font-weight: 600;
    color: var(--brand-orange); /* orange text — was #FFFFFF over the brand gradient body */
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
    letter-spacing: 0.01em;
    opacity: 1;
    overflow: hidden;
}

.dl-header__topbar-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 24px;
}

.dl-header__topbar-list {
    display: flex;
    list-style: none;
    margin: 0;
    padding: 0;
    align-items: center;
}

.dl-header__topbar-list li {
    position: relative;
    padding: 0 18px;
    line-height: 1.4;
}
.dl-header__topbar-list li:first-child { padding-left: 0; }
.dl-header__topbar-list li:last-child  { padding-right: 0; }

.dl-header__topbar-list li::after {
    content: "";
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.55); /* white divider dot, matches text */
}
.dl-header__topbar-list li:last-child::after { display: none; }

.dl-header__topbar-list a {
    color: #FFFFFF;
    text-decoration: none;
    transition: opacity .15s;
}
.dl-header__topbar-list a:hover { opacity: 0.85; }
.dl-header__topbar-list a[aria-current="page"] {
    color: #FFFFFF;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.50);
}

.dl-header__topbar-meta {
    display: flex;
    align-items: center;
    gap: 0;
}

.dl-header__topbar-meta-item {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 0 16px;
    position: relative;
    color: #FFFFFF;
}
.dl-header__topbar-meta-item:first-child { padding-left: 0; }
.dl-header__topbar-meta-item:last-child  { padding-right: 0; }

.dl-header__topbar-meta-item:not(:last-child)::after {
    content: "";
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.55); /* white divider dot, matches text */
}

.dl-header__topbar-meta-item svg {
    width: 14px;
    height: 14px;
    color: #FFFFFF;
    flex-shrink: 0;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.30));
}

.dl-header__topbar-meta-item a {
    color: #FFFFFF;
    text-decoration: none;
}
.dl-header__topbar-meta-item a:hover { opacity: 0.85; }

.dl-header__topbar-meta-label {
    color: rgba(255, 255, 255, 0.85);
    font-weight: 500;
}

/* ── Pill (white floating capsule) ────────────────────────────────────── */

.dl-header__pill {
    max-width: 1300px;
    margin: 0 auto;
    background: var(--dl-pill-bg);
    border-radius: 999px;
    padding: 8px 8px 8px 28px;
    /* Three-column grid: [left cluster: auto] [capsule track: 1fr] [right cluster: auto].
       The middle 1fr column expands to fill the gap between the (auto-
       sized) brand on the left and the (auto-sized) right cluster on
       the right. With `.dl-header__center { justify-self: center }`,
       the capsule sits in the visual center of that 1fr column —
       which means EQUAL distance from the brand's right edge to the
       capsule's left edge, and from the capsule's right edge to the
       lupa (the first item of the right cluster). The capsule is no
       longer pinned to the page midline; instead it's pinned to the
       midpoint of the available gap, which reads as visually balanced. */
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 10px;
    box-shadow: var(--dl-pill-shadow);
    transition: box-shadow var(--transition-fast);
}

/* Left cluster — burger (mobile only) + brand. */
.dl-header__left {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

/* Right cluster — search + lang + CTAs + profile. The cluster is in
   the third (auto) column of the pill grid; it auto-sizes to its
   content. Internal gap is 8px; the gap between search and lang
   shrinks further to 2px via the negative margin-right on
   `.dl-header__search-host`, making the lupa+flag read as a tight
   pair. */
.dl-header__right {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.dl-header.scrolled .dl-header__pill {
    box-shadow: var(--dl-pill-shadow-scrolled);
}

/* Burger lives in the pill grid but is hidden on desktop (display:none —
   doesn't take a column under CSS Grid). It re-appears at <=980px. */
.dl-header__burger {
    display: none;
}

/* ── Brand (text logo with brand-spectrum gradient) ───────────────────── */

.dl-header__brand {
    display: flex;
    align-items: center;
    text-decoration: none;
    color: inherit;
}

.dl-header__brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1;
    gap: 4px;
}

.dl-header__brand-name {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-weight: 800;
    font-size: 19px;
    letter-spacing: 0.04em;
    /* Solid white wordmark on the charcoal pill — was a cyan→yellow
       brand-spectrum gradient when the pill carried a white surface
       and the gradient body needed visual coherence with the logo.
       The pill is now charcoal #343434, so plain white reads cleaner
       and lets the small orange accent square (declared via
       ::after below) and the orange "care | restoration" tag stand
       out as the colour accents instead. */
    color: #FFFFFF;
    background: none;
    -webkit-text-fill-color: #FFFFFF;
}

.dl-header__brand-name::after {
    content: "";
    display: inline-block;
    width: 9px;
    height: 9px;
    /* Solid Sberbank-orange — matches the original logo's orange
       accent square (and the Quality Guaranteed tile downstream). */
    background: var(--brand-orange);
    border-radius: 2px;
    -webkit-text-fill-color: initial;
}

.dl-header__brand-tag {
    font-weight: 600;
    font-size: 11px;
    color: var(--brand-orange);
    letter-spacing: 0.06em;
    text-transform: lowercase;
}

/* ── Center: nav sub-pill ────────────────────────────────────────────── */

/* Capsule centered within the middle 1fr column of the pill grid.
   The 1fr column = total pill width - brand width - right cluster
   width - 2*gap. Capsule (auto-sized) is `justify-self: center`,
   which puts equal padding on either side — so the gap from brand to
   capsule equals the gap from capsule to lupa. */
.dl-header__center {
    position: relative;
    justify-self: center;
}

.dl-header__nav {
    display: flex;
    justify-content: center;
    gap: 0;
    list-style: none;
    margin: 0;
    padding: 4px;
    background: var(--dl-nav-pill-bg);
    border-radius: 999px;
    /* 1.5px solid orange inset ring — mirrors the active search-bar
       outline (.dl-header__search-host.is-active .dl-header__search-
       host__bar). Same wash + same ring = the two capsules read as
       a matched pair. */
    box-shadow: inset 0 0 0 1.5px var(--brand-orange);
    transition: opacity .25s ease;
}

.dl-header__nav li { list-style: none; }

.dl-header__nav a {
    display: inline-flex;
    align-items: center;
    padding: 9px 14px;
    border-radius: 999px;
    font-size: 14.5px;
    font-weight: 600;
    /* White nav text on the warm-dark inner pill — high-contrast on the
       dark gradient capsule, paired with the orange CTA cluster (Get
       Estimate / Book Now) on the right. */
    color: #FFFFFF;
    text-decoration: none;
    transition: background-color .18s, color .18s, box-shadow .18s;
    white-space: nowrap;
}
.dl-header__nav a:hover {
    background: var(--dl-nav-pill-hover-bg);
    color: #FFFFFF;
}
.dl-header__nav a.is-active,
.dl-header__nav a[aria-current="page"] {
    background: var(--dl-nav-pill-active-bg);
    color: #FFFFFF;
    box-shadow: var(--dl-nav-pill-active-shadow);
}
.dl-header__nav a:focus-visible {
    outline: 2px solid var(--brand-orange);
    outline-offset: 2px;
}

/* When the search bar is active, fade out the nav so the search input
   has visual breathing room. The pointer-events:none keeps clicks from
   leaking through to nav links underneath the expanded search bar. */
.dl-header__pill:has(.dl-header__search-host.is-active) .dl-header__nav {
    opacity: 0;
    pointer-events: none;
}

/* ── Search host (lupa + overlay bar) ────────────────────────────────── */

/* The host is a fixed 44×44 cell — its width never changes, so the
   surrounding right-cluster items don't reflow when the bar opens. The
   bar itself is position:absolute anchored to right:0 inside the host,
   and grows leftward via a width transition.

   No special margin — the `.dl-header__right` flex wrapper's uniform
   8px gap applies on both sides of the lupa, so the spacing between
   lupa↔lang and lang↔Get-Estimate is identical (the user wants those
   three controls equally spaced as a row). */
.dl-header__search-host {
    position: relative;
    width: 44px;
    height: 44px;
}

.dl-header__search-host__bar {
    position: absolute;
    top: 0;
    right: 0;
    height: 44px;
    width: 44px;
    display: inline-flex;
    align-items: center;
    border-radius: 999px;
    background: rgba(199, 85, 40, 0.10);
    box-shadow: inset 0 0 0 1.5px rgba(199, 85, 40, 0.30);
    overflow: hidden;
    transition: width .4s cubic-bezier(0.4, 0, 0.2, 1),
                background .3s ease,
                box-shadow .3s ease;
    z-index: 5;
}
.dl-header__search-host.is-active .dl-header__search-host__bar {
    width: 560px;
    background: var(--dl-nav-pill-bg);
    box-shadow: inset 0 0 0 1.5px var(--brand-orange), 0 6px 20px rgba(0, 0, 0, 0.30);
}

/* The input is collapsed (zero padding, hidden text) when not active.
   The padding/opacity expand together with the bar's width so the
   input fades into the visible area smoothly. */
.dl-header__search-host__bar input {
    flex: 1;
    min-width: 0;
    border: 0;
    background: transparent;
    outline: 0;
    font-family: inherit;
    font-size: 15px;
    font-weight: 500;
    color: #FFFFFF;
    padding: 0;
    opacity: 0;
    pointer-events: none;
    transition: padding .4s cubic-bezier(0.4, 0, 0.2, 1), opacity .2s ease;
}
.dl-header__search-host__bar input::placeholder {
    color: rgba(255, 255, 255, 0.55);
    font-weight: 400;
}
.dl-header__search-host.is-active .dl-header__search-host__bar input {
    padding: 0 0 0 22px;
    opacity: 1;
    pointer-events: auto;
    transition: padding .4s cubic-bezier(0.4, 0, 0.2, 1), opacity .25s ease .2s;
}

/* The lupa button itself — always visible at the right edge of the bar.
   Stays 44×44 regardless of bar state, so the icon is a stable anchor. */
.dl-header__search-host__toggle {
    flex-shrink: 0;
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    cursor: pointer;
    color: var(--brand-orange);
    font-family: inherit;
    padding: 0;
    border-radius: 50%;
    transition: background-color .15s;
}
.dl-header__search-host__toggle:hover { background: rgba(199, 85, 40, 0.12); }
.dl-header__search-host__toggle:focus-visible {
    outline: 2px solid var(--brand-orange);
    outline-offset: 2px;
}
.dl-header__search-host__toggle svg {
    width: 22px;
    height: 22px;
    stroke-width: 2.2;
}

/* The ESC keyboard hint — hidden when bar is collapsed, slides in when
   active so the user knows ESC will close the overlay. */
.dl-header__search-host__esc {
    flex-shrink: 0;
    font-size: 10px;
    font-weight: 600;
    color: var(--brand-orange);
    background: rgba(199, 85, 40, 0.10);
    border-radius: 6px;
    opacity: 0;
    pointer-events: none;
    user-select: none;
    letter-spacing: 0.05em;
    max-width: 0;
    padding: 0;
    margin: 0;
    overflow: hidden;
    white-space: nowrap;
    transition: max-width .4s cubic-bezier(0.4, 0, 0.2, 1),
                padding .4s ease,
                margin .4s ease,
                opacity .25s ease;
}
.dl-header__search-host.is-active .dl-header__search-host__esc {
    max-width: 80px;
    padding: 4px 8px;
    margin-right: 8px;
    opacity: 1;
    transition: max-width .4s cubic-bezier(0.4, 0, 0.2, 1),
                padding .4s ease,
                margin .4s ease,
                opacity .25s ease .25s;
}

/* ── Language switcher ───────────────────────────────────────────────── */

/* Globe-icon pill that shows where the next click goes. The visible text
   is the destination locale's two-letter code ("ES" when EN is active,
   "EN" when ES is active). The 🌐 icon — not a national flag — signals
   *language* rather than *country*: important in LA where the Spanish-
   speaking audience spans many Hispanic communities, not just Mexican-
   American. The blade renders both spans (`__icon` + `__code`) and the
   full title="Cambiar a inglés" / "Switch to Spanish" lives in the
   tooltip attribute, with mirrored aria-label for assistive tech. */
.dl-header__lang-btn,
.dl-header__lang-btn:link,
.dl-header__lang-btn:visited {
    /* Explicit :link + :visited overrides — without them Chrome (and
       most browsers) paint visited links with the user-agent purple,
       so once the visitor has already opened the alternate-locale URL
       once, the "ES" / "EN" code inside the pill darkens. Listing both
       pseudo-states keeps the text white regardless of history. */
    color: #FFFFFF;
}
.dl-header__lang-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    flex-shrink: 0;
    height: 40px;
    padding: 0 14px;
    border-radius: 999px;
    border: 1.5px solid rgba(199, 85, 40, 0.30);
    background: rgba(199, 85, 40, 0.10);
    cursor: pointer;
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.4px;
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    transition: background-color .15s, border-color .15s, transform .15s;
    position: relative;
}
.dl-header__lang-btn:hover {
    background: rgba(199, 85, 40, 0.20);
    border-color: rgba(199, 85, 40, 0.55);
    transform: scale(1.05);
}
.dl-header__lang-btn:focus-visible {
    outline: 3px solid var(--brand-orange);
    outline-offset: 2px;
}
.dl-header__lang-btn__icon {
    font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
    font-size: 16px;
    line-height: 1;
}
.dl-header__lang-btn__code {
    /* Letter-spacing is on the parent so this just inherits. The span
       is here so future tweaks (e.g. swapping ES → Español on wider
       viewports) can target the text without touching the icon. */
}

/* ── CTA buttons (Get Estimate ghost / Book Now solid) ───────────────── */

/* CTA shape restored to the legacy almost-square (4px radius, 8/16
   padding, 2px borders, 14px font) per user reference to the
   pre-Sber dark-theme deploy where Get Estimate / Book Now sat in
   that compact rectangular form. The Sber-era pill shape (radius
   999px, larger padding) is retired together with the white pill
   capsule. */
.dl-header__cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Explicit height — both Get Estimate (<a>) and Book Now (<button>)
       share this control. With `padding: 8px 16px` + `border: 2px` +
       `font-size: 14px / line-height: 1.2`, the computed height
       lands at ~36.8px on the <a> but Chrome's UA stylesheet on
       <button> tacks on ~2.3px of internal vertical padding (a
       baseline-alignment quirk that survives even `appearance: none`).
       Pinning `height: 38px` forces both elements to the same box
       so the two CTAs sit perfectly aligned in the row. */
    height: 38px;
    border-radius: 4px;
    font-size: 14px;
    font-weight: 700;
    font-family: inherit;
    text-decoration: none;
    white-space: nowrap;
    line-height: 1.2;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    transition: background-color .15s, color .15s, border-color .15s, box-shadow .15s, transform .15s;
}

/* Both CTAs share padding / border / font-size from .dl-header__cta
   above — visual height is identical between Get Estimate (ghost)
   and Book Now (solid). Width differs naturally with label length. */
/* :link / :visited explicit so the global `a, a:visited { color:
   inherit }` reset earlier in this file doesn't pull the Book Now
   label to the body's dark text colour once the user has visited
   /book. Same fix as the solid CTA below — climbs specificity to
   (0,2,0), beating the (0,1,1) of `a:visited`. */
.dl-header__cta--ghost,
.dl-header__cta--ghost:link,
.dl-header__cta--ghost:visited {
    background: transparent;
    color: #FFFFFF;
    padding: 8px 16px;
    border: 2px solid var(--brand-orange);
}
.dl-header__cta--ghost:hover {
    background: var(--brand-orange);
    color: #FFFFFF;
}

/* :link / :visited explicitly so the global `a, a:visited { color:
   inherit }` reset (declared earlier in this file) doesn't drag the
   Get Estimate label to the body's dark text colour once the user
   has visited /instant-estimate. The Get Estimate CTA is an <a>, so
   the visited-state quirk that hit .dl-slide__btn applies here too —
   noticed by the user on Safari mobile where the solid pill rendered
   with black text. Specificity climbs to (0,2,1), beating the reset. */
.dl-header__cta--solid,
.dl-header__cta--solid:link,
.dl-header__cta--solid:visited {
    background: var(--brand-orange);
    color: #fff;
    padding: 8px 16px;
    border: 2px solid var(--brand-orange);
}
/* No :hover rule on the solid CTA — fully flat hover per user
   preference (no lift, no colour shift). Pointer cursor + the focus
   ring on `:focus-visible` below stay as the only interaction cues. */

.dl-header__cta:focus-visible {
    outline: 2px solid var(--brand-orange);
    outline-offset: 3px;
}

/* Short labels are hidden on desktop, swap in at <=420px breakpoint. */
.dl-header__cta .btn-label-short { display: none; }
.dl-header__cta .btn-label-full  { display: inline; }

/* ── Profile / My Appointment circle ─────────────────────────────────── */

.dl-header__profile {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 999px;
    background: rgba(199, 85, 40, 0.10);
    border: 2px solid rgba(199, 85, 40, 0.30);
    color: var(--brand-orange);
    text-decoration: none;
    cursor: pointer;
    transition: background-color .15s, border-color .15s, transform .15s;
    font-family: inherit;
    padding: 0;
}
.dl-header__profile:hover {
    background: rgba(199, 85, 40, 0.20);
    border-color: var(--brand-orange);
}
.dl-header__profile:focus-visible {
    outline: 2px solid var(--brand-orange);
    outline-offset: 2px;
}
.dl-header__profile svg {
    width: 22px;
    height: 22px;
}

/* ──────────────────────────────────────────────────────────────────────────
   Burger button (mobile only)
   ────────────────────────────────────────────────────────────────────────── */

.burger {
    /* Larger tap target than the WCAG 2.5.5 minimum (44x44) — user
       asked for a more visible burger on mobile. The taller wrapper
       stays a left-aligned flex item inside the pill, so it doesn't
       drift toward the right edge as it grows. */
    width: 48px;
    height: 48px;
    padding: 0;
    margin-left: -10px;
    background: transparent;
    border: 0;
    cursor: pointer;
    display: none; /* shown via @media(max-width:980px) below */
    align-items: center;
    justify-content: center;
    z-index: 1101;
    color: var(--brand-orange);
}
.burger:focus-visible {
    outline: 2px solid var(--brand-orange);
    outline-offset: 4px;
    border-radius: var(--radius);
}

.burger-lines {
    display: inline-block;
    position: relative;
    width: 28px;
    height: 24px;
}
.burger-lines span {
    display: block;
    position: absolute;
    left: 0;
    width: 100%;
    height: 3.5px;
    background: var(--brand-orange);
    border-radius: 2px;
    transition: top var(--transition-fast),
                transform var(--transition-fast),
                opacity var(--transition-fast);
}
.burger-lines span:nth-child(1) { top: 3px; }
.burger-lines span:nth-child(2) { top: 10.25px; }
.burger-lines span:nth-child(3) { top: 17.5px; }
.burger.open .burger-lines span:nth-child(1) { top: 10.25px; transform: rotate(45deg); }
.burger.open .burger-lines span:nth-child(2) { opacity: 0; }
.burger.open .burger-lines span:nth-child(3) { top: 10.25px; transform: rotate(-45deg); }

/* ──────────────────────────────────────────────────────────────────────────
   Mobile drawer + backdrop
   ────────────────────────────────────────────────────────────────────────── */

.mobile-menu { display: none; }

.menu-backdrop {
    display: none;
    position: fixed;
    top: var(--header-height-mobile);
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.42);
    z-index: 1100;
    opacity: 0;
    visibility: hidden;
    transition: opacity .34s ease, visibility 0s linear .34s;
    pointer-events: none;
}
.menu-backdrop.open {
    display: block;
    opacity: 1;
    visibility: visible;
    transition: opacity .34s ease;
    pointer-events: auto;
}

/* ──────────────────────────────────────────────────────────────────────────
   Responsive: narrow-desktop band (901–1099px)

   The main page sections (promotion, services, works, client-service,
   announcements, etc.) go to mobile at 900px, but the desktop header
   has historically been kept on screen for a wider band. That left
   a tablet-landscape range (~1024–1099px) where the desktop layout
   was rendered but didn't have enough room: the brand + nav-pill +
   right-cluster (search + lang + Get Estimate + Book Now + profile)
   crowded each other.

   This intermediate band makes the desktop header more compact
   without falling all the way to mobile yet:
     - Brand tagline ("care | restoration") hidden so the wordmark
       can sit closer to the nav-pill.
     - Nav-pill items get tighter padding + slightly smaller font.
     - Right cluster trims down: profile circle and ghost "Get
       Estimate" CTA hidden (Book Now stays — single one-tap CTA
       always available), language switcher hidden too. What's
       left: search lupa + Book Now. The dropped controls remain
       reachable via the burger drawer once we cross 900px down.
   ────────────────────────────────────────────────────────────────────────── */

@media (min-width: 901px) and (max-width: 1099px) {
    .dl-header__brand-tag { display: none; }

    .dl-header__nav a {
        padding: 8px 11px;
        font-size: 13.5px;
    }

    .dl-header__cta--ghost,
    .dl-header__profile,
    .dl-header__lang-btn {
        display: none;
    }
}

/* ──────────────────────────────────────────────────────────────────────────
   Responsive: tablet + mobile (≤900px)

   Breakpoint is 900px (was 980 — see commit `a669fdc` which moved
   it from 940 → 980 to align with the modal cluster). The user
   asked the header to switch to burger at the SAME viewport where
   the main page content switches — that's 900px for promotion,
   services, client-service, announcements; works.css does it at
   941 and is left to its own rule. Aligning here keeps the page
   feel coherent: the moment the hero stacks, the nav becomes a
   burger, no in-between mismatch.
   ────────────────────────────────────────────────────────────────────────── */

@media (max-width: 900px) {
    body {
        padding-top: var(--header-height-mobile);
        /* Body's flex-column rule (declared at desktop) still applies
           here; the padding-top simply offsets the first item below
           the fixed-height mobile header. */
    }

    /* Mobile header — fixed at the top of the viewport with its own
       static gradient, items hugging the screen edges at the legacy
       10px gutter.

       Position: fixed (not sticky). Sticky inside a `display: flex`
       body (which we need for the sticky-footer pattern) was unreliable
       on mobile Safari/Chrome — reports of the bar scrolling out of
       view. Fixed + body padding-top sidesteps the flex/sticky
       interaction; the padding-top is already there, set to
       var(--header-height-mobile) = 56px.

       Background: the same `var(--color-bg)` gradient the body
       carries, painted directly on the bar with
       background-attachment: fixed + background-size: 100vw 100vh
       so the slice aligns 1-for-1 with the body::before gradient
       sitting behind it. When the user scrolls, page content moves
       under the bar but the bar keeps showing a static gradient
       slice — content can't peek through. (Just `transparent`
       wasn't enough: body::before is below the content in the
       stacking order, so content scrolling up overlaid the
       gradient and was visible through a transparent header.)

       Colour adjustments below are about readability on the gradient
       (the desktop pill carries a white surface that hands the gradient
       wordmark and the green burger lines a guaranteed contrasting
       backdrop — that surface is gone here, so brand text and burger
       lines flip to white-with-shadow, matching the topbar's approach). */
    .dl-header,
    .dl-header.is-collapsed {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        padding: 0;
        background: var(--color-bg);
        background-attachment: fixed;
        background-size: 100vw 100vh;
        box-shadow: none;
    }
    /* `.is-collapsed` is a desktop-only signal — when the user
       scrolls past 24px, the desktop topbar (Blog/About/Contacts +
       LA + phone) shrinks away and the wrapper wants 10px+12px
       padding so the white pill stays comfortably centered in the
       slimmer header. On mobile the topbar is `display: none` to
       begin with, so there's nothing to collapse, and that
       wrapper-padding shift made the entire mobile bar grow from
       56px to ~78px on scroll — exactly what the user reported as
       the bar "becoming wider" (height grew, the apparent visual
       footprint with it). The first selector above re-asserts the
       mobile layout regardless of the .is-collapsed state. */

    /* Topbar is desktop-only; on mobile the audience links live in the
       drawer instead. */
    .dl-header__topbar { display: none; }

    /* The `.dl-header__pill` element keeps its three-column grid for
       layout, but loses its capsule chrome on mobile — no
       border-radius, no own background, no shadow. It's now just a
       horizontal flex track. The grid's middle `auto` column collapses
       to 0 (because .dl-header__center is hidden), leaving the natural
       [left auto][1fr][right auto] three-column layout: brand on the
       left, Book Now on the right.

       Padding values are the same screen gutter the page content uses,
       so burger and Book Now sit at the exact horizontal positions
       that all sections below align to. */
    .dl-header__pill {
        background: transparent;
        border-radius: 0;
        box-shadow: none;
        /* Mobile gutter aligned to the page-content gutter
           (--site-gutter-x-mobile-* = 20px). Was a tighter 10px
           which left Book Now noticeably closer to the right edge
           than the section content below. Burger now sits at the
           same left edge as section headings, Book Now at the same
           right edge as section content. */
        padding: 6px var(--site-gutter-x-mobile-right) 6px var(--site-gutter-x-mobile-left);
        gap: 8px;
        min-height: var(--header-height-mobile);
        /* Override the desktop `display: grid` with flex on mobile.
           The desktop grid is `auto 1fr auto` and relies on the
           center column being visible to push the right cluster to
           the right edge. With `.dl-header__center { display: none }`
           grid auto-placement collapses the right cluster into
           column 2 (the 1fr), leaving Book Now hugging the left of
           the stretched cell — which read as "Book Now squished
           against the logo".

           Flex with justify-content: space-between gives us exactly
           the layout we want with no implicit column tricks:
             [.dl-header__left] ───────────── [.dl-header__right]
           so burger+brand sit at the left edge + 10px and Book Now
           sits at the right edge - 10px regardless of how much
           space the brand text takes up. */
        display: flex;
        justify-content: space-between;
    }
    .dl-header.scrolled .dl-header__pill {
        box-shadow: none; /* no lifted-pill cue on mobile — there's no pill */
    }
    .dl-header__burger { display: inline-flex; }
    .burger { color: var(--brand-orange); }
    .burger:focus-visible { outline-color: var(--brand-orange); }

    /* Burger lines tinted to the brand orange — pairs with the
       orange Book Now CTA on the right of the mobile bar so both
       the menu trigger and the booking trigger read as the same
       brand-accent family on the charcoal page background. */
    .burger-lines span {
        background: var(--brand-orange);
        filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.30));
    }

    /* Hide center nav, search, lang, ghost CTA, profile on mobile —
       they live in the drawer. Book Now stays in the pill so the user
       always has a one-tap booking action available. */
    .dl-header__center        { display: none; }
    .dl-header__search-host   { display: none; }
    .dl-header__lang-btn      { display: none; }
    .dl-header__cta--ghost    { display: none; }
    .dl-header__profile       { display: none; }

    /* Wordmark — the desktop gradient-fill clipped against background
       (cyan/teal/green/lime/yellow) reads as static white on the
       same colours of the body gradient because the brand colours
       and the body's gradient stops are the same palette. So we
       drop the gradient on mobile and use solid white with the same
       legibility shadow used in the topbar. The little square dot
       after the wordmark stays brand-green (it's a separate element
       with its own background). */
    .dl-header__brand-name {
        font-size: 17px;
        background: none;
        -webkit-text-fill-color: #FFFFFF;
        color: #FFFFFF;
        text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
    }
    .dl-header__brand-tag  { display: none; }

    /* Book Now on mobile is the same solid terracotta CTA as on
       desktop — orange fill + white text. Was a transparent / white-
       outlined ghost pill (matched the old "white outlined controls
       on gradient" mobile family); flipped to the brand-accent solid
       per user feedback so the booking CTA reads with the same
       weight everywhere. Padding/font are tuned smaller than desktop
       (7px 16px / 13.5px) to fit the tight mobile pill. */
    .dl-header__cta--solid {
        background: var(--brand-orange);
        border: 2px solid var(--brand-orange);
        color: #FFFFFF;
        box-shadow: none;
        padding: 7px 16px;
        font-size: 13.5px;
    }
    .dl-header__cta--solid:hover {
        /* No darken on hover — same flat-hover decision as desktop. */
        background: var(--brand-orange);
        border-color: var(--brand-orange);
        color: #FFFFFF;
        box-shadow: none;
        transform: none;
    }

    .menu-backdrop { display: block; }
}

/* Mobile drawer — same DOM contract as legacy (#mobileMenu, .mobile-menu.open
   class toggle from header.js), recolored to the brand palette. Slides in from
   the left under the fixed header. Breakpoint matches the main mobile
   block above (was 980, now 900 to align with the page-content mobile
   transition). */
@media (max-width: 900px) {
    .mobile-menu {
        flex-direction: column;
        justify-content: flex-start;
        align-items: flex-start;
        position: fixed;
        top: var(--header-height-mobile);
        left: 0;
        bottom: 0;
        width: 82vw;
        max-width: 350px;
        /* Drawer surface flipped from #FFFFFF to charcoal #343434
           so the drawer reads as a continuous extension of the
           mobile header pill (which sits on the same charcoal page
           bg). All inner text colours below were inverted alongside
           the bg flip — see .menu-section a / contact-info / hr
           rules later in this block. */
        background: #343434;
        z-index: var(--z-menu);
        /* Top padding tightened from 32px to 16px so the primary nav
           (Residential / Automotive / etc.) starts higher in the
           drawer, closer to the header bar. The lower padding keeps
           safe-area handling for notched devices. */
        padding: 16px 24px calc(24px + env(safe-area-inset-bottom, 0px)) 24px;
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
        color: #FFFFFF;
        box-shadow: 14px 0 38px rgba(0, 0, 0, 0.32);
        border-top-right-radius: 18px;
        border-bottom-right-radius: 18px;
        transform: translate3d(-104%, 0, 0);
        opacity: 0;
        visibility: hidden;
        transition: transform .42s cubic-bezier(.22, 1, .36, 1),
                    opacity .26s ease,
                    visibility 0s linear .42s,
                    box-shadow var(--transition-fast);
        display: flex;
        pointer-events: none;
        will-change: transform, opacity;
    }
    .mobile-menu.open {
        transform: translate3d(0, 0, 0);
        opacity: 1;
        visibility: visible;
        transition: transform .42s cubic-bezier(.22, 1, .36, 1),
                    opacity .26s ease,
                    visibility 0s;
        pointer-events: auto;
    }

    .mobile-menu-content {
        margin-top: 0;
        width: 100%;
        flex-grow: 1;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        gap: 24px;
    }

    .menu-section {
        width: 100%;
        display: flex;
        flex-direction: column;
        gap: 22px;
        padding-top: 8px;
    }
    .menu-section a {
        color: #FFFFFF !important;
        text-decoration: none !important;
        font-size: 18px;
        font-weight: 700;
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: space-between;
    }
    .menu-section a[aria-current="page"] {
        color: var(--brand-orange) !important;
    }
    .mobile-menu .menu-section:last-of-type a {
        font-weight: 500;
        font-size: 16px;
    }
    .arrow {
        margin-left: 8px;
        display: flex;
        align-items: center;
        color: var(--brand-orange);
    }

    hr {
        border: 0;
        border-top: 1px solid rgba(255, 255, 255, 0.10);
        width: 100%;
        /* Vertical breathing room around the primary↔secondary divider.
           Without these margins the line sat directly against "Prices"
           on top and "Blog" below — visually attached, not separating.
           18/14 gives the secondary block a clearer break from the
           primary one (especially noticeable in Spanish where the last
           primary item ("Precios") is shorter than its English peer,
           leaving less natural whitespace under the row). */
        margin: 18px 0 14px;
    }

    .mobile-menu .contact-info {
        display: flex;
        flex-direction: column;
        gap: 10px;
        font-size: 14px;
        padding-bottom: 18px;
        color: rgba(255, 255, 255, 0.85);
    }
    .mobile-menu .contact-info span {
        display: inline-flex;
        align-items: center;
        gap: 8px;
    }
    .mobile-menu .contact-info svg {
        width: 16px;
        height: 16px;
        color: var(--brand-orange);
        flex-shrink: 0;
    }
    .mobile-menu .contact-info a {
        color: #FFFFFF;
    }

    /* Mobile language switcher row. Restored 2026-05-11 after the
       user asked to expose locale toggling inside the burger drawer
       (the desktop .dl-header__lang-btn is `display: none` below the
       mobile breakpoint, so without this row mobile visitors have
       no UI to switch). Lives in the lower drawer column right above
       the contact-info block, padded the same as menu links so it
       reads as a peer of the existing nav rows. */
    .mobile-menu .mobile-menu-lang,
    .mobile-menu .mobile-menu-lang:link,
    .mobile-menu .mobile-menu-lang:visited {
        /* :link + :visited explicitly so Chrome can't repaint the
           "Español" / "English" label in the visited-link color once
           the visitor has touched the alt-locale URL. Same reason as
           the desktop pill above. */
        color: #FFFFFF;
    }
    .mobile-menu .mobile-menu-lang {
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 12px 4px;
        margin: 6px 0 14px;
        font-size: 16px;
        font-weight: 600;
        text-decoration: none;
        border-top: 1px solid rgba(255, 255, 255, 0.12);
        border-bottom: 1px solid rgba(255, 255, 255, 0.12);
        min-height: 44px; /* WCAG 2.5.5 touch target */
    }
    .mobile-menu .mobile-menu-lang:hover,
    .mobile-menu .mobile-menu-lang:focus-visible {
        color: var(--brand-orange);
        outline: none;
    }
    .mobile-menu .mobile-menu-lang__icon {
        font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
        font-size: 22px;
        line-height: 1;
        flex-shrink: 0;
    }
    .mobile-menu .mobile-menu-lang__label {
        flex: 1;
    }
    .mobile-menu .mobile-menu-lang__arrow {
        font-size: 22px;
        line-height: 1;
        color: rgba(255, 255, 255, 0.6);
        flex-shrink: 0;
    }

    .mobile-menu .buttons {
        display: flex;
        flex-direction: column;
        width: 100%;
        gap: 10px;
    }
    /* Override the desktop base height: 38px so the drawer CTA can
       grow to its taller padded size (full-width, larger tap target).
       The `display: inline-flex !important` is needed because the
       generic `.dl-header__cta--ghost { display: none }` rule above
       (which hides the desktop pill's Get Estimate on mobile) would
       otherwise win — they share the same element in the drawer. */
    .mobile-menu .dl-header__cta--block {
        display: inline-flex !important;
        width: 100%;
        height: auto;
        justify-content: center;
        padding: 14px 18px;
        font-size: 15px;
    }
    /* Ghost-CTA-in-drawer override removed — the drawer footer now
       only carries the solid Book Now CTA, no ghost variant lives
       in the drawer markup. Re-add if a ghost CTA is ever placed
       inside .mobile-menu (text colour would need to flip from the
       white desktop default to read on the new charcoal drawer
       background). */
    /* `.dl-header__cta--profile` and the My Appointment drawer button
       it styled were retired together with the drawer Book Now button
       (only Get Estimate stays in the drawer footer now). The Lone
       desktop profile circle uses `.dl-header__profile`, a different
       class. */
}

/* Tighter button at very small viewports. Below 420px the solid
   CTA (Get Estimate / "Solicitar cotización") starts pushing the
   "DAVA LEATHER" wordmark onto two lines on iPhone-SE-class
   viewports — especially in Spanish where the label is 21 chars.
   Swap to the short variant of the label ("Estimate" / "Cotización")
   so the brand stays on a single line.
   The ghost CTA is `display: none` on mobile already, so this rule
   only applies to the visible Get Estimate pill. */
@media (max-width: 420px) {
    .dl-header__cta--solid {
        padding: 9px 14px;
        font-size: 13px;
    }
    .dl-header__cta--solid .btn-label-full  { display: none; }
    .dl-header__cta--solid .btn-label-short { display: inline; }
}

@media (max-width: 375px) {
    .dl-header__brand-name { font-size: 15px; }
}
