/* ===========================================================================
   Shared accessibility layer  (task t_21278c42)

   Loaded on EVERY page, after site.css, pages.css and home.css. Two jobs:

     1. Carry the state the early inline script writes onto <html>
        (data-a11y-text / -contrast / -motion) into actual visible behaviour.
        It is loaded as a normal stylesheet in <head> and the attributes are set
        before first paint, so there is no flash of the wrong size or theme.

     2. Fix the shared disclosure defect the audit measured: the old FAQ
        accordion clipped closed answers with max-height:0 while leaving their
        text in the accessibility tree. The component now renders native
        <details>/<summary>, and the rules below let site.css's existing FAQ
        styling apply to that markup instead of fighting it.

   This is a shared fix. It applies to BOTH homepage variants and to every
   service, industry, town and article page that renders an FAQ, exactly as the
   brief permits. It is recorded as a shared difference in REVIEW.md.
   =========================================================================== */

/* ---------- 1. FAQ: native disclosure, reusing the existing look ---------- */

/* site.css pins these shut for the old button/max-height accordion. In a
   <details> the browser already hides children when closed, so the visual
   clipping must be released or an OPEN answer would still be 0px tall. */
.faq-panel details.faq-item > .faq-answer,
details.faq-item > .faq-answer {
  max-height: none;
  overflow: visible;
  opacity: 1;
}

/* <summary> takes the place of the old <button>, so the presentation rules
   written for .faq-question carry over untouched — only the platform marker
   and the open/closed chevron selector need handling. */
summary.faq-question { list-style: none; }
summary.faq-question::-webkit-details-marker { display: none; }
summary.faq-question::marker { content: ''; }
details.faq-item[open] > summary.faq-question .faq-chevron { transform: rotate(180deg); }
summary.faq-question:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: 6px;
}
/* The question text sits inside an <h3> so the heading outline is preserved. */
.faq-question-wrap,
summary.faq-question > h3 {
  margin: 0;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
  line-height: inherit;
}

/* ---------- 2. Text size (100 / 125 / 150 / 200%) ------------------------ */

/* Mechanism: CSS `zoom`, declared by the CSS Viewport spec as establishing a
   *zoomed viewport* — it reflows layout and scales text together, exactly as
   the browser's own page zoom does. It is deliberately NOT `transform:scale()`,
   which enlarges a fixed layout without reflowing and would clip content.
   Measured reflow results (no horizontal overflow, no lost controls) are
   recorded per viewport and per setting in REVIEW.md.

   Placed on <html> so it scales what page zoom scales. The alternative,
   `body`, behaves the same for content but leaves the root's own canvas and
   the fixed-position cookie banner outside the scaled subtree. */
html[data-a11y-text="125"] { zoom: 1.25; }
html[data-a11y-text="150"] { zoom: 1.5; }
html[data-a11y-text="200"] { zoom: 2; }

/*
 * Text size and the navigation bar.
 *
 * CSS `zoom` establishes a narrower layout viewport, but — unlike the browser's
 * own page zoom — it does NOT re-evaluate @media breakpoints. The navigation bar
 * is the one element on the site whose width is set by its content rather than
 * by a fraction of the viewport, so at an enlarged text size it does not
 * collapse when it should and its right-hand CTAs get clipped. That was
 * measured, not assumed: at 1440px the bar overflowed its own inner box by
 * 260px at 125%, 451px at 150% and 694px at 200%, with body overflow-x:clip
 * hiding the damage instead of revealing it.
 *
 * So at ANY enlarged text size the bar goes straight to its collapsed
 * (hamburger) form, at every width. Nothing is lost by doing that: the mobile
 * menu carries every navigation item and all three CTAs the expanded bar
 * carries, and it is the same control a phone already uses. This is also what
 * the browser's own zoom does at high magnification, by reducing the effective
 * viewport instead.
 *
 * Before/after numbers per setting are in REVIEW.md.
 */
html[data-a11y-text] .nav-toggle { display: flex; order: 2; }
html[data-a11y-text] .nav-inner { flex-wrap: wrap; gap: 12px; }
html[data-a11y-text] .nav-links { display: none; }
html[data-a11y-text] .nav-links.is-open { display: flex; }
html[data-a11y-text] .nav-cta-group--desktop { display: none; }
/* site.css sets white-space:nowrap on the brand, which is right for the bar but
   makes the wordmark unshrinkable: at 200% text on a 390px screen the effective
   layout width is 195px and the nowrap wordmark alone exceeded it. Allowing it
   to wrap removes the last of the overflow without changing default settings. */
html[data-a11y-text] .brand { white-space: normal; }

/* ---------- 3. Higher contrast (opt-in) ---------------------------------- */

/* NOT required for the default theme to pass — it is a stronger, flatter
   variant for anyone who wants it. What it changes:
     - the page ground becomes flat and much darker, so white body text gains
       contrast instead of sitting on a mid-tone gradient;
     - every element site.css dims with opacity is pushed back to full, which
       is where the default theme's weakest text actually lives;
     - links move from the mid ember to a lighter ember, and are underlined;
     - decorative layers (the pointer burst, the page glow) are switched off so
       nothing can sit behind text. */
html[data-a11y-contrast="high"] body {
  background: #06040f;
}
html[data-a11y-contrast="high"] body::after,
html[data-a11y-contrast="high"] body::before { display: none !important; }

html[data-a11y-contrast="high"] p,
html[data-a11y-contrast="high"] li,
html[data-a11y-contrast="high"] dd,
html[data-a11y-contrast="high"] figcaption,
html[data-a11y-contrast="high"] .content-lede,
html[data-a11y-contrast="high"] .content-note,
html[data-a11y-contrast="high"] .content-eyebrow,
html[data-a11y-contrast="high"] .prose p,
html[data-a11y-contrast="high"] .footer-tagline,
html[data-a11y-contrast="high"] .footer-hq,
html[data-a11y-contrast="high"] .footer-copyright,
html[data-a11y-contrast="high"] .footer-link-list a,
html[data-a11y-contrast="high"] .footer-legal-list a,
html[data-a11y-contrast="high"] .home-eyebrow,
html[data-a11y-contrast="high"] .home-card-text,
html[data-a11y-contrast="high"] .home-post-meta,
html[data-a11y-contrast="high"] .home-section-lede,
html[data-a11y-contrast="high"] .home-body,
html[data-a11y-contrast="high"] .home-faq-answer p,
html[data-a11y-contrast="high"] .breadcrumbs li,
html[data-a11y-contrast="high"] .post-row-excerpt,
html[data-a11y-contrast="high"] .post-row-meta,
html[data-a11y-contrast="high"] .sidebar-text,
html[data-a11y-contrast="high"] .related-text,
html[data-a11y-contrast="high"] .regulatory-text,
html[data-a11y-contrast="high"] .regulatory-note {
  opacity: 1 !important;
  color: #ffffff;
}

/* NOT A BARE `span`. A first version of this block set every <span> to #fff,
   which turned the label and the phone number inside the ember CTA button white
   on orange — measured 2.37:1, i.e. the higher-contrast theme made the primary
   call to action WORSE. Any element that paints its own ember background must
   keep the dark ink text it was designed with, so those are re-asserted
   explicitly below rather than left to inherit. */
html[data-a11y-contrast="high"] .home-cta-primary,
html[data-a11y-contrast="high"] .home-cta-primary .home-cta-label,
html[data-a11y-contrast="high"] .home-cta-primary .home-cta-phone,
html[data-a11y-contrast="high"] .nav-cta,
html[data-a11y-contrast="high"] .nav-cta--mobile,
html[data-a11y-contrast="high"] .submit-btn,
html[data-a11y-contrast="high"] .submit-btn .submit-btn-label,
html[data-a11y-contrast="high"] .form-success-call,
html[data-a11y-contrast="high"] .lead-notice-call,
html[data-a11y-contrast="high"] .cookie-btn--accept,
html[data-a11y-contrast="high"] .location-card-badge,
html[data-a11y-contrast="high"] .blog-cta-btn {
  color: var(--ember-ink) !important;
}
html[data-a11y-contrast="high"] .nav-cta--support,
html[data-a11y-contrast="high"] .nav-cta--cyber {
  color: #ffffff !important;
}
html[data-a11y-contrast="high"] a:not(.home-cta-primary):not(.nav-cta):not(.form-success-call),
html[data-a11y-contrast="high"] .home-text-link,
html[data-a11y-contrast="high"] .home-hero-secondary,
html[data-a11y-contrast="high"] .home-chip {
  color: #ffd2b8 !important;
  text-decoration: underline;
  text-underline-offset: 3px;
}
html[data-a11y-contrast="high"] .glass-panel,
html[data-a11y-contrast="high"] .home-card,
html[data-a11y-contrast="high"] .home-faq-panel,
html[data-a11y-contrast="high"] .home-contact-panel,
html[data-a11y-contrast="high"] .home-chip {
  background: #120f22;
  border-color: rgba(255,255,255,.45);
}
html[data-a11y-contrast="high"] :focus-visible {
  outline: 3px solid #ffe27a;
  outline-offset: 2px;
}
html[data-a11y-contrast="high"] .nav {
  background: #0d0a1c;
  border-color: rgba(255,255,255,.5);
}
html[data-a11y-contrast="high"] .cookie-banner { background: #06040f; }

/* ---------- 4. Reduce motion -------------------------------------------- */

html[data-a11y-motion="reduce"] { scroll-behavior: auto; }
html[data-a11y-motion="reduce"] *,
html[data-a11y-motion="reduce"] *::before,
html[data-a11y-motion="reduce"] *::after {
  animation-duration: .001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: .001ms !important;
  scroll-behavior: auto !important;
}
/* Decorative loops stop entirely rather than running at 0.001ms. */
html[data-a11y-motion="reduce"] body::before,
html[data-a11y-motion="reduce"] .vendors-track { display: none !important; }
html[data-a11y-motion="reduce"] .vendors-carousel { overflow-x: auto; }
/* Reveal animations must not hide anything: content is simply shown. */
html[data-a11y-motion="reduce"] .reveal-item,
html[data-a11y-motion="reduce"] .reveal-item--card,
html[data-a11y-motion="reduce"] .scroll-reveal {
  opacity: 1 !important;
  transform: none !important;
}

/* ---------- 5. Text-spacing robustness (WCAG 1.4.12) -------------------- */

/* The bar's content is set by its labels, so a user letter-spacing override —
   which is exactly what WCAG 1.4.12 asks to be tested with — made it overflow
   its own box (measured: 234px at 1440px before this rule, clipped by
   overflow-x:clip rather than visible). Allowing the bar to wrap means extra
   spacing puts the navigation and the CTAs on a second line instead of hiding
   them. At default settings the row still fits, so nothing moves. */
.nav-inner { flex-wrap: wrap; }

/* site.css pins control heights in px. A user text-spacing override (or a
   larger minimum font size) would then clip the label inside them, so the
   height becomes a minimum and the control grows instead. Visually identical
   at default settings: 14px text + 24px padding is under the original height
   for every one of these. */
.field input,
.locations-search input,
.footer-newsletter-row input {
  height: auto;
  min-height: 42px;
  padding-top: 10px;
  padding-bottom: 10px;
  line-height: 1.45;
}
.submit-btn,
.cookie-btn,
.footer-newsletter-btn,
.location-locate-btn {
  line-height: 1.45;
  padding-top: 8px;
  padding-bottom: 8px;
}
.submit-btn { min-height: 46px; }
.cookie-btn { min-height: 40px; }
.video-pending,
.nav-cta,
.home-chip { line-height: 1.45; }

/* ---------- 6. The absent reCAPTCHA must not be advertised ------------- */

/* No page in this build loads a reCAPTCHA script, so the widget never renders
   and site.js still sets "Please confirm you're not a robot." on submit — a
   prompt for a control that is not on the page. The brief's rule is that a
   captcha must never be described as verified when there is no backend, and the
   same honesty applies to asking for one that does not exist.

   The suppression is conditional on the widget being EMPTY, via :has(). If a
   real reCAPTCHA is ever wired up and renders a widget, :empty stops matching
   and both the field and its error come straight back with no code change. The
   text node is left in the DOM either way, because pages.js uses it to decide
   whether only the captcha was blocking before it reveals the honest
   "nothing has been sent" panel. Browsers without :has() simply ignore this
   rule and behave exactly as before. */
.field-recaptcha:has(.g-recaptcha:empty) { display: none; }

/* ---------- 7. Accessibility options panel ------------------------------ */
.a11y-strip {
  max-width: 1440px;
  margin: 0 auto 28px;
  padding: 0 20px;
}
.a11y-panel {
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 14px;
  background: rgba(255,255,255,.05);
}
.a11y-panel > summary {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 18px;
  cursor: pointer;
  list-style: none;
  color: #fff;
  font-size: 14.5px;
  font-weight: 600;
}
.a11y-panel > summary::-webkit-details-marker { display: none; }
.a11y-panel > summary::before {
  content: '';
  width: 8px; height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform .18s ease;
  flex: none;
}
.a11y-panel[open] > summary::before { transform: rotate(45deg); }
.a11y-panel > summary:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; border-radius: 8px; }

.a11y-panel-body { padding: 4px 20px 20px; max-width: 760px; }
.a11y-group { margin: 0 0 18px; }
.a11y-group-label {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--mist-100);
}
.a11y-buttons { display: flex; flex-wrap: wrap; gap: 8px; }
.a11y-btn {
  padding: 10px 16px;
  border-radius: 8px;
  border: 1px solid rgba(255,255,255,.28);
  background: rgba(255,255,255,.07);
  color: #fff;
  font-size: 14px;
  cursor: pointer;
  line-height: 1.4;
}
.a11y-btn:hover { background: rgba(255,255,255,.15); }
.a11y-btn[aria-pressed="true"] {
  background: linear-gradient(180deg, var(--ember-300), var(--ember-500));
  border-color: var(--ember-500);
  color: var(--ember-ink);
  font-weight: 700;
}
.a11y-btn--reset { border-color: rgba(255,255,255,.4); font-weight: 600; }
.a11y-note { font-size: 13px; line-height: 1.55; color: var(--mist-100); margin: 14px 0 0; }
.a11y-nojs-note { display: none; }
html:not(.js) .a11y-nojs-note { display: block; }
html:not(.js) .a11y-btn { opacity: .6; }

/* Header and footer entry points. The visible glyph is decorative; the
   accessible name comes from the visually-hidden text, so the link is always
   announced as a destination rather than as "Aa". */
.nav-a11y {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 11px;
  border-radius: 8px;
  border: 1px solid rgba(255,255,255,.28);
  background: rgba(255,255,255,.06);
  color: var(--mist-100);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.nav-a11y:hover { background: rgba(255,255,255,.14); color: #fff; }
.nav-a11y-glyph { font-family: 'Poppins', sans-serif; font-weight: 700; font-size: 12.5px; }
/*
 * The visible word is shown only where the navigation bar genuinely has room
 * for it. Measured: with the word shown, .nav-inner overflows by 62px at 1440
 * and 6px at 1500 (the 1401-1599 band, where the bar still carries all three
 * CTAs); with the glyph alone it fits at every width, which is the pre-change
 * behaviour at each one. The glyph is the conventional "Aa" text-size affordance
 * and the accessible name is unchanged, so nothing is lost by hiding the word —
 * and "Accessibility options" in full is in the footer on every page.
 */
.nav-a11y-text { display: none; }
@media (min-width: 1600px) { .nav-a11y-text { display: inline; } }
