/* ============================================================
   Motion vocabulary — "quiet luxury" (2026-10-05). The standard is
   CLAUDE.md > Design. Smooth, brief, then still: content rises into
   place once and stays; hover is the only lively layer, and subtle.

   One treatment per element type, the same on every page:
     on load   H1 and hero dek rise in (CSS only, never waits for JS)
     on entry  H2/H3, paragraphs and list blocks fade up 16px;
               images, figures and image cards fade in from 98%
     hover     every linked or clickable image (cards, gallery thumbnails)
               and the intro/body photos: gold corner brackets close into
               a 1px frame, a soft gold glow, a linked image to 1.03
               inside its clipped frame, the label or caption up 4px
     buttons   primary (.btn-gold, .nav-cta) get .btn-trace, a gold
               border drawn around; secondary (.btn-outline,
               .btn-outline-dark) get .btn-swap, a label swap. js/
               effects.js adds the classes and inner spans.
     links     in-text links draw a gold underline left to right
     nav       current item underlined; dropdown fades in 200ms
     utility   the bar's content scrolls in a slow loop on every page (40s,
               linear, paused on hover and focus; static under reduced motion)
     drop cap  the first paragraph of "How we work" (homepage) and of About
   Kept: custom cursor (desktop), film grain, hero Ken Burns, 4px
   radius, gold corner brackets (now the resting state of the image hover).
   The only infinite loops on the site: the hero Ken Burns, the
   utility-bar marquee and the homepage hero house. The homepage's
   signature effects (portal frame, assembling house, timeline, curtain,
   count-up, hero house) live in index.html and js/home.js, not here.

   Scope comes from <body data-motion="…">, which .build-includes.py
   writes on every page from _data/motion.json: "full" (default),
   "project" (each /projects/<slug>/ page: headings and photos reveal, no paragraph
   reveals) and "reading" (FAQ and guides: headings and paragraphs
   reveal). The image hover is not scoped: it applies wherever its
   hosts appear. Pages without the attribute (the
   design prototypes) get none of the reveals.

   Reveals are CSS scroll-driven (animation-timeline: view()) where the
   browser supports it, so they run with JavaScript off. Elsewhere
   js/effects.js adds html.fx-io and an IntersectionObserver plus the
   fallbackCheck() safety net reveals each element once; anything
   already on screen is marked .is-in before html.fx-io is set, so
   nothing above the fold waits for JS. The selector lists below are
   repeated in js/effects.js (REVEAL) — keep both in step.

   Only transform (incl. translate/scale), opacity and box-shadow
   animate. prefers-reduced-motion gives a fully static page. Hover
   and the cursor exist only for (hover:hover) and (pointer:fine).

   index.html does not link this file: .build-includes.py inlines it
   into the homepage's <style> between the include:effects-css markers.
============================================================= */

:root{
  --fx-ease:cubic-bezier(.22,.61,.36,1);   /* ease-out, never bouncy */
  --fx-dur:.5s;
  --fx-glow:0 12px 32px -14px rgba(212,175,82,.45), 0 0 18px rgba(212,175,82,.14);   /* soft, low opacity */
}

@keyframes fx-rise{from{opacity:0; translate:0 16px;} to{opacity:1; translate:0 0;}}
@keyframes fx-img{from{opacity:0; scale:.98;} to{opacity:1; scale:1;}}

/* ---------- On load: H1 and hero dek (CSS only) ---------- */
.hero-inner h1, .page-hero-inner h1, .hero-inner > p, .page-hero-inner > p{
  animation:fx-rise var(--fx-dur) var(--fx-ease) both;
}
.hero-inner > p, .page-hero-inner > p{animation-delay:.08s;}

/* ---------- Stagger: siblings in a grid or list, 70ms apart, capped at 5 ---------- */
:is(.loc-grid, .awc-grid, .services-grid, .project-grid, .faq-list, .process-list, .phase-list,
    .review-cards-grid, .stats-grid, .facts-grid, .before-after) > :nth-child(2){--fx-i:1;}
:is(.loc-grid, .awc-grid, .services-grid, .project-grid, .faq-list, .process-list, .phase-list,
    .review-cards-grid, .stats-grid, .facts-grid, .before-after) > :nth-child(3){--fx-i:2;}
:is(.loc-grid, .awc-grid, .services-grid, .project-grid, .faq-list, .process-list, .phase-list,
    .review-cards-grid, .stats-grid, .facts-grid, .before-after) > :nth-child(4){--fx-i:3;}
:is(.loc-grid, .awc-grid, .services-grid, .project-grid, .faq-list, .process-list, .phase-list,
    .review-cards-grid, .stats-grid, .facts-grid, .before-after) > :nth-child(n+5){--fx-i:4;}
.gallery-grid > :nth-child(4n+1){--fx-i:0;}
.gallery-grid > :nth-child(4n+2){--fx-i:1;}
.gallery-grid > :nth-child(4n+3){--fx-i:2;}
.gallery-grid > :nth-child(4n){--fx-i:3;}

/* ---------- Reveal targets (repeated in js/effects.js as REVEAL) ----------
   section  = main > section, except the hero
   inside   = never an element inside a card, figure, list item, FAQ item, step, table
              or form: those reveal as one unit */
@media (prefers-reduced-motion:no-preference){
  @supports (animation-timeline: view()){
    :where(body[data-motion] main > section:not(.page-hero, .hero)) :is(h2, h3):not(:is(.loc-card, .awc-card, .service-card, .project-card, .review-card, .review-google-card, .faq-item, .process-step, .phase-step, figure, li, blockquote, dl, table, .compare-table, .summary-strip, .stats-grid > div, .facts-grid > div, form, .safety-note) *),
    :where(body:is([data-motion="full"], [data-motion="reading"]) main > section:not(.page-hero, .hero)) :is(p, ul, ol, dl, blockquote, .faq-item, .process-step, .phase-step, .compare-table, .review-card, .review-google-card, .stats-grid > div, .facts-grid > div):not(:is(.loc-card, .awc-card, .service-card, .project-card, .review-card, .review-google-card, .faq-item, .process-step, .phase-step, figure, li, blockquote, dl, table, .compare-table, .summary-strip, .stats-grid > div, .facts-grid > div, form, .safety-note) *),
    :where(body[data-motion="full"] main > section:not(.page-hero, .hero)) :is(figure, .loc-card, .awc-card, .service-card, .project-card):not(:is(.loc-card, .awc-card, .service-card, .project-card, .review-card, .review-google-card, .faq-item, .process-step, .phase-step, figure, li, blockquote, dl, table, .compare-table, .summary-strip, .stats-grid > div, .facts-grid > div, form, .safety-note) *),
    :where(body[data-motion="project"] main > section:not(.page-hero, .hero)) figure:not(:is(figure, li, form) *){
      animation-name:fx-rise; animation-duration:auto; animation-timing-function:var(--fx-ease); animation-fill-mode:both;
      animation-timeline:view();
      animation-range:cover calc(var(--fx-i, 0) * 24px) cover calc(var(--fx-i, 0) * 24px + 160px);
    }
    :where(body[data-motion="full"] main > section:not(.page-hero, .hero)) :is(figure, .loc-card, .awc-card, .service-card, .project-card):not(:is(.loc-card, .awc-card, .service-card, .project-card, .review-card, .review-google-card, .faq-item, .process-step, .phase-step, figure, li, blockquote, dl, table, .compare-table, .summary-strip, .stats-grid > div, .facts-grid > div, form, .safety-note) *),
    :where(body[data-motion="project"] main > section:not(.page-hero, .hero)) figure:not(:is(figure, li, form) *){animation-name:fx-img;}
    /* once revealed, stay revealed: js/effects.js adds .is-in after the range has run */
    :where(body[data-motion] main) .is-in{animation:none !important;}
  }

  /* IntersectionObserver fallback (no scroll-driven animations): js/effects.js sets html.fx-io */
  html.fx-io .fx-r{
    transition:opacity var(--fx-dur) var(--fx-ease), translate var(--fx-dur) var(--fx-ease), scale .6s var(--fx-ease), box-shadow .4s var(--fx-ease);
    transition-delay:calc(var(--fx-i, 0) * 70ms), calc(var(--fx-i, 0) * 70ms), calc(var(--fx-i, 0) * 70ms), 0s;
  }
  html.fx-io .fx-r:not(.is-in){opacity:0; translate:0 16px;}
  html.fx-io .fx-r.fx-img:not(.is-in){translate:none; scale:.98;}
}

/* ---------- Image hover: corner brackets close into a 1px gold frame ----------
   The standard for every linked or clickable image (owner, 2026-10-05), extended from the
   project cards: at rest four thin gold brackets sit on the image; on hover they run along
   the edges until they meet (.4s, ease-out), a soft gold glow fades in, a linked image scales
   to 1.03 inside its clipped frame, and the label or caption lifts 4px. Colours stay true.
   Hosts: image cards (.loc-card, .awc-card, .service-card, .project-card), gallery thumbnails,
   and the intro and body photos on service, area and guide pages (figure.fx-photo: the frame
   animates, no zoom, the photo is not a link). js/effects.js injects the brackets and wraps
   a photo's image in span.fx-frame so the frame sits on the image, not the caption.
   Never on heroes, the logo, footer or social icons, video, or the open lightbox.
   Touch devices keep the resting brackets: every hover rule needs (hover:hover). */
.gallery-grid figure{position:relative; overflow:hidden; border-radius:4px;}
.fx-frame{display:block; position:relative; overflow:hidden; border-radius:inherit;}
figure.fx-photo figcaption{position:relative; z-index:1;}
.fx-corner{position:absolute; width:20px; height:20px; pointer-events:none; z-index:2; opacity:.9;}
.fx-corner.tl{top:12px; left:12px; border-top:1px solid var(--gold-bright); border-left:1px solid var(--gold-bright);}
.fx-corner.tr{top:12px; right:12px; border-top:1px solid var(--gold-bright); border-right:1px solid var(--gold-bright);}
.fx-corner.bl{bottom:12px; left:12px; border-bottom:1px solid var(--gold-bright); border-left:1px solid var(--gold-bright);}
.fx-corner.br{bottom:12px; right:12px; border-bottom:1px solid var(--gold-bright); border-right:1px solid var(--gold-bright);}
:is(.loc-card, .awc-card, .service-card, .project-card):focus-visible .fx-corner,
:is(.loc-card, .awc-card, .service-card, .project-card, .gallery-grid figure, figure.fx-photo):focus-within .fx-corner{width:calc(100% - 24px); height:calc(100% - 24px); opacity:1;}
@media (hover:hover) and (pointer:fine){
  :is(.loc-card, .awc-card, .service-card, .project-card, .gallery-grid figure, figure.fx-photo):hover .fx-corner{width:calc(100% - 24px); height:calc(100% - 24px); opacity:1;}
  :is(.loc-card, .awc-card, .project-card, .gallery-grid figure, figure.fx-photo:not(.frame-photo)):hover{box-shadow:var(--fx-glow);}
  .service-card:hover{box-shadow:0 0 0 1px var(--line), var(--fx-glow);}
  figure.fx-photo.frame-photo:hover{box-shadow:0 1px 2px rgba(20,17,13,0.10), 0 22px 44px -18px rgba(20,17,13,0.34), var(--fx-glow);}
}
@media (hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){
  .fx-corner{transition:width .4s var(--fx-ease), height .4s var(--fx-ease), opacity .3s ease;}
  :is(.loc-card, .awc-card, .service-card, .project-card, .gallery-grid figure, figure.fx-photo){transition:box-shadow .4s var(--fx-ease);}
  :is(.loc-card, .awc-card, .service-card, .project-card, .gallery-grid figure) img,
  :is(.loc-card > span, .awc-label, .service-body h3, .project-body h3, figure.fx-photo figcaption){transition:transform .4s var(--fx-ease);}
  :is(.loc-card, .awc-card, .service-card, .project-card, .gallery-grid figure):hover img{transform:scale(1.03);}
  .loc-card:hover > span, .awc-card:hover .awc-label, .service-card:hover .service-body h3,
  .project-card:hover .project-body h3, figure.fx-photo:hover figcaption{transform:translateY(-4px);}
}

/* ---------- Buttons: primary = border trace, secondary = label swap (classes and spans added by js/effects.js) ---------- */
.btn-trace{position:relative;}
.btn-trace .trace-edge{position:absolute; background:var(--gold-bright); pointer-events:none;}
.btn-trace .trace-edge.top{top:-1px; left:-1px; right:-1px; height:1px; transform:scaleX(0); transform-origin:0 50%;}
.btn-trace .trace-edge.right{top:-1px; right:-1px; bottom:-1px; width:1px; transform:scaleY(0); transform-origin:50% 0;}
.btn-trace .trace-edge.bottom{bottom:-1px; left:-1px; right:-1px; height:1px; transform:scaleX(0); transform-origin:100% 50%;}
.btn-trace .trace-edge.left{top:-1px; left:-1px; bottom:-1px; width:1px; transform:scaleY(0); transform-origin:50% 100%;}
.btn-trace:focus-visible .trace-edge{transform:none;}
.btn-swap{position:relative; overflow:hidden;}
.btn-swap .label-stack{display:inline-grid; vertical-align:top; overflow:hidden;}
.btn-swap .label-a, .btn-swap .label-b{grid-area:1 / 1; justify-self:center; white-space:nowrap;}
.btn-swap .label-b{transform:translateY(110%);}
.btn-swap .swap-arrow{display:inline-block; translate:-4px 0;}
:is(.btn-swap:focus-visible, .project-card:focus-visible .btn-swap) .label-a{transform:translateY(-110%);}
:is(.btn-swap:focus-visible, .project-card:focus-visible .btn-swap) .label-b{transform:translateY(0);}
:is(.btn-swap:focus-visible, .project-card:focus-visible .btn-swap) .swap-arrow{translate:0 0;}
@media (hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){
  .btn-trace .trace-edge{transition:transform .12s linear;}
  .btn-trace:is(:hover, :focus-visible) .trace-edge{transform:none;}
  .btn-trace:is(:hover, :focus-visible) .trace-edge.right{transition-delay:.12s;}
  .btn-trace:is(:hover, :focus-visible) .trace-edge.bottom{transition-delay:.24s;}
  .btn-trace:is(:hover, :focus-visible) .trace-edge.left{transition-delay:.36s;}
  .btn-swap .label-a, .btn-swap .label-b{transition:transform .4s var(--fx-ease);}
  .btn-swap .swap-arrow{transition:translate .4s var(--fx-ease) .1s;}
  :is(.btn-swap:hover, .project-card:hover .btn-swap) .label-a{transform:translateY(-110%);}
  :is(.btn-swap:hover, .project-card:hover .btn-swap) .label-b{transform:translateY(0);}
  :is(.btn-swap:hover, .project-card:hover .btn-swap) .swap-arrow{translate:0 0;}
}

/* ---------- In-text links: a gold underline draws left to right ----------
   At rest the link keeps its colour and a faint underline (WCAG: not colour alone). A link
   that wraps onto two lines keeps the faint underline; the drawn line needs one line box. */
main :is(p, li, dd) a:not([class]){position:relative; text-decoration:underline; text-decoration-color:rgba(184,145,42,.4); text-decoration-thickness:1px; text-underline-offset:3px; border-bottom:0; padding-bottom:0;}
main :is(p, li, dd) a:not([class])::after{content:''; position:absolute; left:0; right:0; bottom:-2px; height:1px; background:currentColor; transform:scaleX(0); transform-origin:0 50%; pointer-events:none;}
main :is(p, li, dd) a:not([class]):focus-visible::after{transform:none;}
@media (hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){
  main :is(p, li, dd) a:not([class])::after{transition:transform .35s var(--fx-ease);}
  main :is(p, li, dd) a:not([class]):hover::after{transform:none;}
}

/* ---------- Nav: thin gold underline (current item at rest, others on hover); dropdown fades 200ms ---------- */
.nav-links a::after{width:100%; transform:scaleX(0); transform-origin:0 50%;}
.nav-links a.active::after, .nav-links a:focus-visible::after{transform:none;}
.nav-drop-panel{transition:opacity .2s var(--fx-ease), transform .2s var(--fx-ease);}
@media (hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){
  .nav-links a::after{transition:transform .3s var(--fx-ease);}
  .nav-links a:hover::after{transform:none;}
}

/* ---------- Kept: custom cursor (element injected by js/effects.js; only hover:hover + pointer:fine, never under reduced motion) ---------- */
html.fx-cursor-on, html.fx-cursor-on a, html.fx-cursor-on button, html.fx-cursor-on [role="button"], html.fx-cursor-on label, html.fx-cursor-on summary{cursor:none;}
html.fx-cursor-on input, html.fx-cursor-on textarea, html.fx-cursor-on select, html.fx-cursor-on [contenteditable]{cursor:auto;}
/* a 34px box holding an 8px gold dot (::after) and a ring (::before); over links the dot gives way to the ring — scale and opacity only */
.fx-cursor{position:fixed; top:0; left:0; width:34px; height:34px; margin:-17px 0 0 -17px; pointer-events:none; z-index:2147483000; opacity:0; will-change:transform; transition:opacity .2s ease;}
.fx-cursor::before, .fx-cursor::after{content:''; position:absolute; inset:0; border-radius:50%; transition:transform .22s var(--fx-ease), opacity .22s ease;}
.fx-cursor::after{background:var(--gold-bright); transform:scale(.24);}
.fx-cursor::before{border:1px solid var(--gold-bright); background:rgba(212,175,82,0.10); transform:scale(.24); opacity:0;}
.fx-cursor.is-ring::after{transform:scale(0);}
.fx-cursor.is-ring::before{transform:none; opacity:1;}
.fx-cursor.is-visible{opacity:1;}
.fx-cursor.is-hidden{opacity:0;}

/* ---------- Kept: film grain over hero and card images (CSS-only, SVG noise tile at ~4.5%) ---------- */
.service-photo, .project-photo{position:relative;}
.page-hero::after, .hero::after, .loc-card::after, .awc-card::before, .service-photo::after, .project-photo::after{
  content:''; position:absolute; inset:0; pointer-events:none; z-index:1;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='100%25' height='100%25' filter='url(%23g)'/></svg>");
  background-size:220px 220px; opacity:.045; mix-blend-mode:overlay;
}
.loc-card > span{position:relative; z-index:2;}

/* ---------- Kept: Ken Burns, 1.0 → 1.06 over 20s on page hero images only (never gallery images) ---------- */
@keyframes fxKenBurns{from{transform:scale(1);} to{transform:scale(1.06);}}
.page-hero-img, .hero-img{animation:fxKenBurns 20s linear both; transform-origin:center center; will-change:transform;}
.hero-img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; z-index:0;}
.hero-overlay{position:absolute; inset:0; z-index:1; pointer-events:none;}

/* ---------- Kept: 4px radius on buttons, cards and card images. Never hero images or the logo. ---------- */
.btn-gold, .btn-outline, .btn-outline-dark, .nav-cta, .nav-links-cta, .btn-trace, .btn-swap{border-radius:4px;}
.service-card, .project-card, .review-card, .review-google-card, .awc-card, .loc-card, .area-card, .frame-photo, .photo-block, .split img, .before-after img, .before-after .ba-photo, .gallery-grid img{border-radius:4px;}
.frame-photo::after{border-radius:4px;}
.service-photo, .project-photo{border-radius:4px 4px 0 0;}
.awc-card img, .service-photo::after, .project-photo::after, .loc-card::after, .loc-card::before, .awc-card::before{border-radius:inherit;}

/* ---------- Drop cap: a large serif initial with a gold underline. Two places only: the first
   paragraph of "How we work" on the homepage and the first paragraph of About (class="dropcap"). ---------- */
p.dropcap::first-letter{float:left; font-family:'Cormorant Garamond', Georgia, serif; font-weight:600; font-size:3.5em; line-height:.8; color:var(--gold-text); margin:6px 12px 0 0; padding:0 1px 5px; border-bottom:2px solid var(--gold);}

/* ---------- Utility bar: one slow marquee on every page ----------
   Gold text on the dark bar, one continuous loop (40s, linear), paused on hover and on keyboard
   focus (the bar is a tab stop for that reason; the skip link stays first). The partial holds the
   content twice, the copy aria-hidden, and the track slides by exactly one copy for a seamless loop.
   A transform animation, no JS. The bar has a fixed height and a fallback face metric-matched to
   Jost (Arial scaled to Jost's advance widths, with Jost's ascent and descent), so nothing moves
   when the web font swaps in. Reduced motion: no motion, only the first item, centred. */
@font-face{font-family:'Jost Fallback'; src:local('Arial'), local('ArialMT'), local('Helvetica'); size-adjust:95.4%; ascent-override:112.2%; descent-override:39.8%; line-gap-override:0%;}
.utility{height:39px; padding:0; box-sizing:border-box; line-height:38px; font-family:'Jost', 'Jost Fallback', sans-serif; color:var(--gold-bright);}
.u-marquee{overflow:hidden; white-space:nowrap; -webkit-mask-image:linear-gradient(90deg, transparent, #000 48px, #000 calc(100% - 48px), transparent); mask-image:linear-gradient(90deg, transparent, #000 48px, #000 calc(100% - 48px), transparent);}
.u-marquee:focus-visible{outline:1px solid var(--gold-bright); outline-offset:-4px; box-shadow:none; -webkit-mask-image:none; mask-image:none;}
.utility-track{display:flex; width:max-content;}
.u-group{display:flex; flex:none;}
.utility .u-item{position:relative; flex:none; padding-right:64px; color:var(--gold-bright);}
.utility .u-item::after{content:''; position:absolute; right:30px; top:50%; width:4px; height:4px; margin-top:-2px; border-radius:50%; background:var(--gold); opacity:.7;}
@keyframes fx-marquee{to{transform:translateX(-50%);}}
@media (prefers-reduced-motion:no-preference){
  .utility-track{animation:fx-marquee 40s linear infinite;}
  .u-marquee:is(:hover, :focus) .utility-track{animation-play-state:paused;}
}
@media (prefers-reduced-motion:reduce){
  .utility-track{width:auto; justify-content:center;}
  .u-group[aria-hidden="true"], .u-group .u-item:not(:first-child){display:none;}
  .utility .u-item{padding-right:0;}
  .utility .u-item::after{display:none;}
}

/* ---------- Rendering: no content-visibility on the footer (removed 2026-10-06) ----------
   It saved little, and twice did harm: as a bare footer selector it held the review grid on /reviews/ 700px
   wide, and while the footer was skipped offscreen, automated contrast checks read its light text against
   the cream page behind it and failed it (launch audit). */

/* ============================================================
   Shared accessibility rules (WCAG 2.1 AA audit, 2026-10-05). They sit
   in this file because it is the one stylesheet every page gets,
   the homepage included (inlined).
============================================================= */
.skip-link{position:absolute; left:16px; top:-80px; z-index:1000; background:var(--ink); color:var(--gold-bright); padding:12px 18px; border-radius:4px;}
.skip-link:focus{top:12px;}
main:focus{outline:none;}
@media (min-width:921px){.nav-drop.js-dismissed .nav-drop-panel{opacity:0 !important; pointer-events:none !important; visibility:hidden;}}
@media (max-width:920px){.nav-links a.nav-links-cta{color:var(--gold-bright);}}
.nav-links a.active::after{background:var(--gold-text);}
.faq-a{visibility:hidden;}
.faq-item.open .faq-a{visibility:visible; max-height:none;}
.review-google-cta, .review-card-cta, .testimonial-source, .gr-fallback-note a, .review-stars, .testimonial-stars{color:var(--gold-text);}
.review-google-card:focus-visible, .review-card:focus-visible, .testimonial-source:focus-visible, .gr-btn:focus-visible, .gr-track:focus-visible{outline-color:var(--gold-text);}
.call-fab{transition:transform .3s var(--fx-ease), opacity .3s ease, visibility 0s linear .3s;}
.call-fab.show{transition-delay:0s;}
.call-fab:not(.show){visibility:hidden;}
.call-fab:focus-visible{outline:2px solid var(--gold-bright); outline-offset:3px; box-shadow:0 0 0 5px var(--ink), 0 8px 24px rgba(20,17,13,.35);}
.gallery-grid img:focus-visible{outline-offset:-3px;}
/* Netlify injects a fixed badge (iframe#nl-badge-frame, about 64px tall, bottom right) on its hosted domain; it sat over
   the call button and took its taps. Where the badge exists, the button rises above it (launch audit, 2026-10-06). */
body:has(> #nl-badge-frame) .call-fab{bottom:96px;}
/* hero text over photos: a soft full-bleed dark field on the text side, and a faint halo on the small gold lines */
.page-hero::before, .hero::before{content:''; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(90deg, rgba(20,17,13,.7) 0%, rgba(20,17,13,.58) 42%, rgba(20,17,13,0) 80%);}
@media (max-width:760px){.page-hero::before, .hero::before{background:linear-gradient(180deg, rgba(20,17,13,.64) 0%, rgba(20,17,13,.62) 50%, rgba(20,17,13,.2) 100%);}}
.page-hero .breadcrumb, .hero-eyebrow{text-shadow:0 1px 3px rgba(20,17,13,.75);}
@media (forced-colors:active){
  .fx-cursor{display:none !important;}
  html.fx-cursor-on, html.fx-cursor-on *{cursor:auto !important;}
}

/* ---------- Reduced motion: a fully static page ---------- */
@media (prefers-reduced-motion:reduce){
  .hero-inner h1, .page-hero-inner h1, .hero-inner > p, .page-hero-inner > p,
  .page-hero-img, .hero-img{animation:none !important;}
  .page-hero-img, .hero-img{transform:none !important;}
  .fx-cursor{display:none !important;}
  html.fx-cursor-on, html.fx-cursor-on *{cursor:auto !important;}
}
@media (hover:none), (pointer:coarse){
  .fx-cursor{display:none !important;}
  html.fx-cursor-on, html.fx-cursor-on *{cursor:auto !important;}
}
