/* a11y.css — WCAG AA fixes for triplencleaningyork.com
   ==========================================================================
   Surface map (measured, probe_sections.js — own background-color per section):
     LIGHT : .services .before-after .pricing-calc .why .reviews
             .leave-review .faq .booking .carpet-video
     DARK  : header.hero  .areas  footer
   Every contrast change below is guarded by `body:not(.dark-mode)` AND scoped to
   the light sections, so nothing can paint dark text onto navy. `.hero-sub` and
   `.stat-label` are white-on-navy at 17.39:1 and are deliberately untouched.

   Measured failures being fixed (7.5:1 target, AA is 4.5:1):
     #7a8fa0 on #f8fafb / #ffffff = 3.20-3.35  -> #5a6b7a = 5.25-5.50
     #1a9e8f on #f8fafb / #f6f8f9 = 3.11-3.17  -> #0f766e = 5.14-5.23
     #8a7340 on #f8fafb           = 4.35       -> #6b5a2a = 6.43
     #ffffff on #14b8a6           = 2.49       -> #ffffff on #0f766e = 5.23
     rgba(255,255,255,.3) on navy = 2.68       -> .62 alpha = ~6.1
   ========================================================================== */

/* ---- 1. CONTRAST: secondary body copy on light surfaces ----
   Element list covers every class that computes to #7a8fa0 on a light surface:
   .service-desc, figcaption, .cv-note and .step-sub were each missed by the
   first pass, which is why the list is enumerated exhaustively here. */
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .section-sub,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .why-desc,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .service-desc,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .reviewer-loc,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .cv-alt,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .cv-note,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .form-sub,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .form-note,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .lr-form-sub,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .step-sub,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) figcaption,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) small {
  color: #5a6b7a;
}

/* EXCEPTION — the "Most Popular" service card is NAVY, not white.
   Its .service-desc was already compliant at #7a8fa0 / #0d1b2a = 5.18:1, and
   the blanket darkening above dropped it to 3.16:1, BREAKING a card that was
   fine. A section-level scope is not enough when one child card inverts the
   surface; assert the variant, not the default. */
body:not(.dark-mode) .service-card.featured .service-desc,
body:not(.dark-mode) .service-card.featured .section-sub {
  color: #7a8fa0;   /* 5.18:1 on #0d1b2a */
}

/* ---- 2. CONTRAST: eyebrow labels (gold) ---- */
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .section-label {
  color: #6b5a2a;
}

/* ---- 3. CONTRAST: in-text links on light surfaces ----
   Covers .section-sub, .faq-answer, .info-val, .cv-alt and the inline
   style="color:var(--teal)" anchors (inline styles need !important). */
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .section-sub a,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .faq-answer a,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .info-val a,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .info-val,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .cv-alt a,
body:not(.dark-mode) :is(.services, .before-after, .pricing-calc, .why, .reviews,
    .leave-review, .faq, .booking, .booking-section, .carpet-video) .local a {
  color: #0f766e;
}
/* inline `style="color:var(--teal)"` beats a plain rule — raise specificity */
body:not(.dark-mode) :is(.services, .pricing-calc, .why, .reviews, .leave-review,
    .faq, .booking, .booking-section, .before-after) a[style*="teal"] {
  color: #0f766e !important;
}
body:not(.dark-mode) .section-sub a:hover,
body:not(.dark-mode) .faq-answer a:hover { color: #0b5d56; }

/* ---- 4. SERVICE / LOCATION PAGES (locations.css) ----
   locations.css sets a bare `a { color: var(--teal) }` = 3.11:1 on the paper
   surface. Those pages have no .section-sub, so they need their own rule.

   SCOPE MATTERS: `.wrap` alone also matched anchors inside the navy `header.top`
   (the Call / Text buttons), dragging `.btn-quiet` from rgba(255,255,255,.82)
   on navy (10.4:1, compliant) down to 3.17:1 — a regression. Restrict to the
   content containers that actually sit on the paper surface, and re-exclude the
   dark header explicitly so a future wrapper change cannot re-open the hole. */
body:not(.dark-mode) main.wrap a:not(.btn):not(.brand),
body:not(.dark-mode) .local a,
body:not(.dark-mode) .block a:not(.btn),
body:not(.dark-mode) .crumb a,
body:not(.dark-mode) .foot a:not(.btn),
body:not(.dark-mode) header.top .top-inner a:not(.btn):not(.brand) {
  color: #0f766e;
}
/* the navy header keeps its own compliant button colours — never touched */
body:not(.dark-mode) header.top a.btn-quiet { color: rgba(255,255,255,.82); }
body:not(.dark-mode) header.top a.btn-gold { color: #0d1b2a; }
/* Inline `style="color:var(--teal)"` on service-page links needs !important to
   beat the inline declaration — BUT a bare `main.wrap a[style*="teal"]` also
   swallowed the navy `.end` CTA link at equal specificity and !important, so the
   later `.end` rule could never win. Exclude `.end` here. */
body:not(.dark-mode) main.wrap a[style*="teal"]:not(.end *) {
  color: #0f766e !important;
}

/* ---- 4b. NAVY PANELS ON THE SERVICE PAGES ----
   `.end` (the closing CTA block) is `background: var(--navy)` with white text.
   The rule above darkened its links to #0f766e = 3.17:1 on navy — a REGRESSION,
   because `a { color: var(--teal) }` was already 6.99:1 there. Same
   region-inverts lesson as .service-card.featured and header.top: a light-surface
   rule must never be allowed to reach a dark panel that happens to sit inside
   the same wrapper. Use the bright teal and underline for the non-colour cue. */
body:not(.dark-mode) .end a:not(.btn),
body:not(.dark-mode) main.wrap .end a:not(.btn),
body:not(.dark-mode) .end p.note a,
body:not(.dark-mode) main.wrap .end p.note a {
  color: var(--teal2) !important;
  text-decoration: underline !important;
  text-underline-offset: 2px;
}
/* `.price-row` prices ("from $135" / "$190") inherit locations.css teal on the
   light paper surface = 3.11:1. Not a link problem — it is the price text. */
body:not(.dark-mode) .price-row a span,
body:not(.dark-mode) .price-row span { color: #0f766e; }

/* SERVICE-PAGE EXCEPTION — the `.top` header is NAVY (#0d1b2a).
   `a { color: var(--teal) }` from locations.css was ALREADY compliant there
   (teal on navy = 6.99:1), and the rule above dropped it to #0f766e on navy =
   3.17:1 — a regression this page-level fix introduced.
   Scope is header.top ONLY. The service-page footer (.foot) is NOT navy — it
   sits on the light .wrap surface with color:var(--muted), so #0f766e is the
   correct colour there and must NOT be reverted to teal. */
body:not(.dark-mode) header.top a:not(.btn):not(.brand) {
  color: var(--teal);
}
/* The breadcrumb (.crumb) is also on the light .wrap surface, so it needs the
   light-safe colour stated explicitly. */
body:not(.dark-mode) nav.crumb a {
  color: #0f766e;
}

/* ---- 5. ACTIVE FAQ CATEGORY CHIP ----
   White on --teal2 #14b8a6 measured 2.49:1. Darkening the chip's own background
   keeps white text and fixes the ratio. */
.faq-cat-btn { background: #0f766e; color: #fff; }
.faq-cat-btn.active,
.faq-cat-btn:hover { background: #0b5d56; color: #fff; }

/* ---- 6. FOOTER micro-copy on navy ----
   Three inline rgba(255,255,255,.30/.35/.40) strings measured 2.68 / 3.20 / 3.78
   on #0d1b2a. A .62 alpha composites to ~6.1:1. Inline styles need !important. */
footer [style*="rgba(255,255,255,.3)"],
footer [style*="rgba(255, 255, 255, .3)"],
footer [style*="rgba(255,255,255,.35)"],
footer [style*="rgba(255,255,255,.4)"] {
  color: rgba(255, 255, 255, .62) !important;
}

/* ---- 7. 1.4.1 Use of Color: underline in-text links ----
   The `link-in-text-block` failure sat in the NAVY .areas section, where the
   link colour matched its surrounding text (1.01:1). Underline is colour-neutral
   so it fixes that without darkening anything on navy. */
.section-sub a,
.faq-answer a,
.faq-answer-inner a,
.info-val a,
.cv-alt a,
.local a,
.prose a,
article p a,
.wrap .local a,
.wrap .block p a,
.crumb a,
.foot a,
.wrap .end a:not(.btn) {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.section-sub a:hover,
.faq-answer a:hover { text-decoration-thickness: 2px; }

/* ---- 8. FOCUS VISIBLE ---- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid #0f766e;
  outline-offset: 2px;
  border-radius: 2px;
}
.btn-primary:focus-visible,
.btn-secondary:focus-visible,
.btn-gold:focus-visible,
.calc-book-btn:focus-visible,
.btn-book:focus-visible,
.nav-cta:focus-visible { outline-color: #0d1b2a; }

/* ---- 9. aria-hidden-focus ----
   Lighthouse: "Focusable content should have tabindex=-1, be removed from the
   DOM, or not be hidden with aria-hidden". The mobile menu is aria-hidden until
   opened but its links stayed tabbable. visibility:hidden drops it from the tab
   order; the script restores it when aria-hidden flips to false. */
#mobileMenu[aria-hidden="true"],
.mobile-menu[aria-hidden="true"] { visibility: hidden; }
#mobileMenu[aria-hidden="false"],
.mobile-menu[aria-hidden="false"],
#mobileMenu.open,
.mobile-menu.open { visibility: visible; }

/* ---- 10. Reduced motion ---- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---- 11. THANK-YOU PAGE FOOTER ----
   thank-you.html is the ONLY page with a bare `<footer>` (no class, no role):
   the homepage uses `<footer role="contentinfo">` and service pages use
   `<footer class="foot">`. Because nothing targeted it, its phone link fell
   through to the browser default `#0000ee` on the dark navy footer
   (#0A0E27) = 2.02:1 — a real WCAG failure that the homepage/booking/commercial
   audits could never surface. Lighthouse only found it because thank-you.html
   was finally measured on its own.
   `footer:not([class]):not([role])` matches that one element and stays correct
   if other footers gain classes. */
footer:not([class]):not([role]) a {
  color: #14b8a6;              /* teal2 on #0A0E27 = 7.64:1 */
  text-decoration: underline;
  text-underline-offset: 2px;
}
footer:not([class]):not([role]) a:hover { color: #5eead4; }

/* ---- 12. NAV LINK VERTICAL CENTRING (visual defect, measured) ----
   `premium.css` sets `.nav-links a { min-height: 44px }` for the 44px tap-target
   audit. That requirement is correct and MUST stay — Lighthouse measures it. But
   the links are `display: block`, so a 44px box holding one 18.4px line puts the
   label at the TOP of the box.

   Measured against the nav's centre line (nav centre = 34px):
       logo text centre        32.6   (-1.4)  aligned
       theme toggle            33.5   (-0.5)  aligned
       BOOK NOW                30.0   (-4.0)  aligned
       .nav-links a (labels)   20.0  (-14.0)  <-- 14px high, the visible defect
   The labels floated well above the button, which is what reads as "the text is
   not centred".

   Making each link an inline-flex box that centres its own content fixes this
   inside the SAME 44px box, so the tap target is preserved. It also pulls the
   hover underline (premium.css `::after` at bottom:-4px) up to hug the label
   instead of floating ~26px below it. The `::after` is absolutely positioned, so
   it stays out of flex flow. */
.nav-links a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ---- 13. UNDERLINE SCOPE BUG: nav-style link lists are not prose ----
   The 1.4.1 underline rule used bare element selectors (`p a`, `li a`), which
   also matched the services teaser — a NAV-style list of links separated by
   `·`. The result was a wall of underlined text that read as a paragraph of
   links rather than a set of choices, and it wrapped to two ragged lines.

   WCAG 1.4.1 only requires a non-colour cue for links in a TEXT BLOCK. A list
   of links in a row is not a text block — BUT the `link-in-text-block` audit
   still flags any link inside a <p> whose colour is within 3:1 of its
   surrounding text (measured 1.01:1 on the .areas prose link). So the chip
   supplies that cue itself (hairline border + white surface), which is what
   lets the underline go away for the CHIP ROW only.

   SCOPE IS THE WHOLE POINT: only the teaser row loses the underline. A blanket
   `.section-sub a { text-decoration: none }` also hit the PROSE link in the
   navy .areas section ("Every town we cover"), re-breaking the exact audit this
   rule exists to satisfy. */
.section-sub[style*="margin-top"] a {
  text-decoration: none;
}

/* ---- 14. SERVICES TEASER -> premium chips ----
   Reworked using the site's OWN existing chip vocabulary (.calc-chip: 50px
   radius, white surface, hairline border, navy-on-white) rather than inventing
   a new visual language. The `·` separators are dropped because each chip is
   now a discrete control that wraps cleanly; a separator between two bordered
   chips is noise. Hairline gold border on hover only — no fill change, no
   lift, no shadow: restraint is the house style. */
.section-sub[style*="margin-top"] {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  margin-top: 18px;
  max-width: none;
}
.section-sub[style*="margin-top"] a {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  padding: 7px 17px;
  border-radius: 50px;
  border: 1px solid rgba(13, 27, 42, .16);
  background: #fff;
  color: #0b5d56 !important;
  font-size: .86rem;
  font-weight: 600;
  letter-spacing: .01em;
  text-decoration: none;
  transition: border-color .2s var(--ease-out, cubic-bezier(.25,1,.5,1)),
              color .2s var(--ease-out, cubic-bezier(.25,1,.5,1));
}
/* Hover keeps the shape and only darkens the border + text: no fill swap, no
   lift, no shadow. */
.section-sub[style*="margin-top"] a:hover {
  border-color: #8a7340;
  color: #6b5a2a !important;
}
.section-sub[style*="margin-top"] a:focus-visible {
  outline: 3px solid #0f766e;
  outline-offset: 2px;
}

/* ---- 15. SERVICES CHIPS — DARK MODE VARIANT ----
   The chip surface was hardcoded #fff for the light surface, so dark mode kept
   BRIGHT WHITE pills on the dark navy section (measured section rgb(15,30,45),
   chip pure white = a 16.88:1 surface jump). That is readable but it reads as
   light-mode furniture pasted onto a dark page, not a premium dark control.

   The dark variant follows the site's OWN dark pill language — `.area-pill` in
   dark mode uses `background: rgba(255,255,255,.06)` with a
   `1px solid rgba(255,255,255,.1)` hairline. Reusing that keeps the whole site
   consistent instead of inventing a second dark-chip style.

   Colour: --teal2 #14b8a6 on the composited surface rgb(29,44,58) = 5.72:1 (AA),
   and it is the same accent the dark .area-pill already uses. Hover lifts the
   surface a little and warms the border to the house gold.
   Light mode is deliberately untouched — these rules are all body.dark-mode. */
body.dark-mode .section-sub[style*="margin-top"] a {
  background: rgba(255, 255, 255, .06);
  border-color: rgba(255, 255, 255, .12);
  color: #14b8a6 !important;
}
body.dark-mode .section-sub[style*="margin-top"] a:hover {
  background: rgba(255, 255, 255, .10);
  border-color: rgba(245, 185, 66, .55);
  color: #5eead4 !important;
}
/* #0f766e is a light-surface focus ring; on dark navy it all but vanishes. */
body.dark-mode .section-sub[style*="margin-top"] a:focus-visible {
  outline-color: #14b8a6;
}
