/* =====================================================================
   Qualified Controls - global chrome EXTRAS
   ---------------------------------------------------------------------
   qc-global.css (copied verbatim from the client's 01_Global_Partials
   package) is the single source of truth for the mega-menu header and the
   footer. This file holds ONLY the parts that package does not ship, and
   deliberately re-declares nothing it already defines:

     1. the skip link                       (theme a11y addition)
     2. the <header> banner landmark        (theme a11y addition)
     3. the utility bar strip above the nav (not in the client package)
     4. the "chrome lock" overrides that stop an assembled page's own
        inline <style> block from repainting the global header/footer

   The old assets/css/header-footer.css was retired on 18 Aug 2026: every
   header and footer rule in it now lives in qc-global.css.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1. SKIP LINK - keyboard users jump past the nav to main content
   --------------------------------------------------------------------- */
.qc-skip-link{position:absolute;top:-100px;left:0;background:#0F6E56;color:#fff;padding:12px 24px;z-index:100000;font-family:'Plus Jakarta Sans',sans-serif;font-size:14px;font-weight:600;border-radius:0 0 8px 0;transition:top 0.25s;text-decoration:none;}
.qc-skip-link:focus{top:0;outline:2px solid #14A07A;outline-offset:2px;}

/* ---------------------------------------------------------------------
   2. SITE HEADER (banner landmark)
   The <header> exists purely to expose the banner landmark. display:contents
   keeps it out of the layout so .primary-nav stays sticky against the viewport
   instead of against a short header box. role="banner" is also set in the
   markup so the landmark is announced even where display:contents affects
   semantics.
   --------------------------------------------------------------------- */
.qc-site-header { display: contents; }

/* ---------------------------------------------------------------------
   3. UTILITY BAR (phone / email / MySirius portal strip above the nav)
   Not part of the client's qc-global package, so the theme owns it end to
   end, responsive rules included. qc-global.css carries a few
   ".utility-bar .container" rules that never match our markup (our inner
   element is .qc-utility-inner); the equivalents live here instead.
   --------------------------------------------------------------------- */
.utility-bar{background:#0D1B2A;color:rgba(255,255,255,0.7);font-size:13px;padding:8px 0;border-bottom:1px solid rgba(255,255,255,0.06);position:relative;z-index:100;}
.qc-utility-inner{width:100%;max-width:1440px;margin:0 auto;padding:0 40px;display:flex;justify-content:space-between;align-items:center;gap:24px;min-width:0;}
.utility-bar a{color:rgba(255,255,255,0.7);text-decoration:none;transition:color 0.2s;}
.utility-bar a:hover{color:#14A07A;}
.utility-left{display:flex;gap:24px;align-items:center;}
.utility-left svg{width:14px;height:14px;margin-right:6px;vertical-align:-2px;}
.utility-right{display:flex;gap:20px;}
.qc-portal-link{color:#14A07A;font-weight:600;display:inline-flex;align-items:center;gap:5px;}
.qc-portal-link svg{width:13px;height:13px;}

@media (max-width: 1180px) { .qc-utility-inner{padding:0 24px;} }
@media (max-width: 960px)  { .qc-utility-inner{padding:0 20px;} }
@media (max-width: 720px)  {
  .utility-bar{font-size:12px;}
  .qc-utility-inner{padding:0 16px;gap:10px;}
  .utility-left{gap:14px;}
  .utility-bar a{min-height:32px;display:inline-flex;align-items:center;}
}
@media (max-width: 640px) { .utility-bar { display: none; } }

/* ---------------------------------------------------------------------
   4. GLOBAL CHROME LOCK
   Assembled page content keeps the source pages' inline <style> blocks,
   which contain orphan header/footer/nav rules (e.g. .nav-cta{background:#F95300})
   and :root token overrides that bleed into the GLOBAL header/footer. These
   high-specificity !important rules force the global chrome to stay on-brand
   (teal/navy) on every page regardless of page-level CSS. Values are kept
   identical to qc-global.css so this locks, never redesigns.
   --------------------------------------------------------------------- */
body .utility-bar { background: #0D1B2A !important; }
body .utility-bar a { color: rgba(255,255,255,.7) !important; }
body .utility-bar a:hover, body .utility-right a { color: #14A07A !important; }
body nav.primary-nav { background: rgba(13,27,42,.72) !important; border-bottom-color: rgba(255,255,255,.08) !important; }
body .primary-nav .nav-trigger, body .primary-nav .nav-direct { color: rgba(255,255,255,.82) !important; background: transparent !important; }
body .primary-nav .nav-trigger:hover, body .primary-nav .nav-direct:hover { color: #fff !important; background: rgba(255,255,255,.06) !important; }
body .primary-nav .nav-trigger[aria-expanded="true"] { color: #fff !important; background: rgba(255,255,255,.06) !important; }
body .primary-nav .nav-cta { background: #0F6E56 !important; color: #fff !important; }
body .primary-nav .nav-cta:hover { background: #14A07A !important; color: #fff !important; }
/* Client issue #4: the mega panel was see-through and page content read
   through it. Two causes stacked. (a) The delivered rgba(13,27,42,.94) leaves
   6% of the backdrop showing, and on a near-black field a few percent of white
   heading text is plainly legible. (b) .primary-nav already carries a
   backdrop-filter, so it is the backdrop root and the panel's own
   backdrop-filter blur never resolves, leaving the bleed-through sharp instead
   of blurred. An opaque panel is the only thing that reads reliably. */
body .mega-menu { background: #0D1B2A !important; }
body .mega-col-title { color: #D4A852 !important; }
body .mega-link-title, body .study-co { color: #fff !important; }
body .mega-featured .featured-cta, body .mega-featured .btn-primary { background: #0F6E56 !important; color: #fff !important; }
body .mega-highlight-title { color: #fff !important; }
body .mega-highlight-eyebrow, body .mega-highlight-arrow { color: #E8C97A !important; }
body .qc-footer { background: #0D1B2A !important; }
body .qc-footer-title { color: #D4A852 !important; }

/* Footer geometry lock (client issue #5, "different footers across the
   website"). There is only one footer, but it did not look the same on every
   page. The six footer columns are <section> elements, so a page whose own
   <style> block styles the bare element, e.g. `section { padding: 100px 40px }`
   on the REM and Solutions templates, repaints the global footer: the columns
   gain 100px of vertical padding, the link text is squeezed into ~75px and
   wraps to three lines, and the footer grows from 557px to 988px. Thirteen
   pages rendered a visibly taller, differently proportioned footer for this
   reason. These rules restore the delivered geometry from qc-global.css so
   page CSS cannot reach in. Values are copied from qc-global.css, this locks,
   it never redesigns. */
body .qc-footer { padding: 56px 0 32px !important; margin: 0 !important; }
body .qc-footer .qc-footer-inner { max-width: 1200px !important; margin: 0 auto !important; padding: 0 24px !important; }
body .qc-footer .qc-footer-grid { gap: 28px !important; }
body .qc-footer .qc-footer-col { padding: 0 !important; margin: 0 !important; border: 0 !important; background: none !important; }
body .qc-footer .qc-footer-col ul { list-style: none !important; padding: 0 !important; margin: 0 !important; }
body .qc-footer .qc-footer-col li { margin: 0 !important; padding: 0 !important; list-style: none !important; }
body .qc-footer .qc-footer-col a { display: block !important; padding: 6px 0 !important; margin: 0 !important; font-size: 14px !important; }
body .qc-footer .qc-footer-title { margin: 0 0 14px 0 !important; padding: 0 !important; font-size: 11px !important; text-align: left !important; }
body .qc-footer .qc-footer-meta { margin-top: 40px !important; padding: 20px 0 0 !important; }
body .primary-nav .nav-items { justify-content: center !important; }
body .primary-nav .nav-item.has-mega { position: static !important; }
body .primary-nav .mega-menu { left: 50% !important; right: auto !important; }

/* Sticky-header guard.
   Several assembled pages keep a page-level <style> block containing
   `body { overflow-x: hidden }`. That makes <body> its own scroll container and
   silently kills position:sticky on .primary-nav, so the global nav stops
   sticking on exactly those pages. The page block is later in the document than
   our stylesheet, so plain !important does not win; body[class] outranks body.
   `clip` suppresses horizontal scroll without creating a scroll container. */
html:root, body[class] { overflow-x: clip !important; }
html:root body[class] nav.primary-nav {
  position: sticky !important;
  top: 0 !important;
  z-index: 10000 !important;
}

/* Keep in-page filter/navigation pills below the sticky site header. */
html:root body[class] .toc-pill-bar,
html:root body[class] nav.pill-toc {
  top: 72px !important;
  z-index: 9900 !important;
}


/* ---------------------------------------------------------------------------
   Agency credit in the footer meta row.
   Not part of the client package, so it lives here rather than qc-global.css.
   The link carries an underline so it is not distinguished by colour alone.
--------------------------------------------------------------------------- */
.qc-footer-meta .qc-footer-credit a {
  color: rgba(255, 255, 255, 0.72);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.qc-footer-meta .qc-footer-credit a:hover,
.qc-footer-meta .qc-footer-credit a:focus-visible {
  color: var(--clean-white, #fff);
}


/* ---------------------------------------------------------------------------
   5. MOBILE NAVIGATION OVERLAY  (client issues #4 and #10, 19 Aug 2026)

   #10  The overlay could not be closed on a phone. qc-global.css gives the
        overlay z-index 9999 and the nav 10000, so the hamburger is meant to
        stay on top and tappable. Several assembled pages carry a page-level
        <style> block re-declaring `.primary-nav { z-index: 1000 }`; that block
        is later in the document than qc-global.css, so it wins, the nav drops
        under the overlay and the hamburger stops receiving taps. The visitor
        is trapped with no way out but reloading. Restore the delivered order
        with a rule page CSS cannot outrank, and give the overlay its own
        single close control: the existing hamburger becomes an X.

   #4   The overlay was rgba(13,27,42,.98). Two percent of a large white page
        heading still ghosts through on a dark field, which is what the tester
        photographed. Opaque.
--------------------------------------------------------------------------- */
@media (max-width: 960px) {
  /* body[class] + html:root outranks the page blocks, same trick as the
     overflow-x guard above. */
  html:root body[class] nav.primary-nav {
    position: fixed !important;
    top: 0 !important;
    right: 0 !important;
    left: 0 !important;
    width: 100% !important;
    z-index: 10000 !important;
  }
  html:root body[class] main#qc-main { padding-top: 64px !important; }
  html:root body[class] .qc-mobile-overlay { background: #0D1B2A !important; z-index: 9990 !important; }

  /* Hamburger becomes an X while the panel is open. Bars are 2px tall with a
     5px gap, so the outer bars are 7px from centre. */
  .nav-mobile-toggle[aria-expanded="true"] .nav-mobile-bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-mobile-toggle[aria-expanded="true"] .nav-mobile-bar:nth-child(2) { opacity: 0; }
  .nav-mobile-toggle[aria-expanded="true"] .nav-mobile-bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

}

/* ---------------------------------------------------------------------------
   6. HUBSPOT LIVE CHAT CONTAINMENT  (client issue #1)

   The widget is HubSpot's own iframe. We cannot style anything inside it: its
   colour, its auto-opening greeting card and its default corner are portal
   settings under Conversations > Chatflows. What we can do from here is stop
   it painting over the site chrome and stop the expanded panel running past
   the viewport. HubSpot documents #hubspot-messages-iframe-container as the
   supported hook for exactly this.
--------------------------------------------------------------------------- */
#hubspot-messages-iframe-container {
  /* Stacking only. Do NOT set height here.

     HubSpot sets the container's height inline itself: 253px collapsed, 635px
     open. Overriding it with !important applied the open height to the COLLAPSED
     launcher too, so on a short screen the 651px wrapper reached the top of the
     viewport and swallowed the tap on the hamburger. Measured on the homepage:
     360x740 and 375x667 could not open the menu at all, while 390x844 and
     440x956 were fine, which is why it looked page-specific and intermittent.

     A working navigation beats a taller chat panel. If HubSpot squeezes its own
     header on short screens at its natural size, that is a portal-side chatflow
     setting for the client, not something to fix by breaking the nav. */
  z-index: 10500 !important;
  pointer-events: none !important;
}
#hubspot-messages-iframe-container iframe { pointer-events: auto !important; }

/* While the mobile menu is open the chat must get out of the way. The panel sits
   at 10500 so HubSpot renders its own header (see above), which puts it ABOVE
   the mobile overlay (9999) and the nav (10000), and it was swallowing taps on
   the menu's close button. Hidden rather than display:none so HubSpot does not
   recompute its layout every time the menu toggles. */
body.qc-mobile-nav-open #hubspot-messages-iframe-container {
  z-index: 1 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}
@media (max-width: 960px) {
  html:root body[class] .toc-pill-bar,
  html:root body[class] nav.pill-toc { top: 64px !important; }
}

/* ---------------------------------------------------------------------------
   Cookie consent banner (#qc-cookie-banner, printed by qc_consent_banner()).

   Previously styled with a long inline style attribute, which made it
   impossible to correct at narrow widths without !important everywhere. The
   markup now carries classes only and all of the sizing lives here.

   Two defects fixed:
   1. On phones the box could compute wider than the viewport, because the
      inset-based width had no explicit border-box sizing or viewport cap.
      It is now capped at 100vw minus its own insets and every child is
      allowed to shrink.
   2. Being fixed to the bottom, it landed on top of the primary call to
      action (the "Calculate My ROI" button on /rem-roi-calculator/ at 440px).
      It is now materially shorter on phones, and while the choice is pending
      the document reserves its height at the end of the page (see the
      .qc-cookie-open rule) so nothing is permanently unreachable underneath.
   --------------------------------------------------------------------------- */
#qc-cookie-banner {
  --qc-cookie-inset: 16px;
  box-sizing: border-box;
  position: fixed;
  left: var(--qc-cookie-inset);
  right: var(--qc-cookie-inset);
  bottom: var(--qc-cookie-inset);
  z-index: 99999;
  width: auto;
  max-width: min(820px, calc(100vw - (var(--qc-cookie-inset) * 2)));
  margin: 0 auto;
  background: #0D1B2A;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 14px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);
  padding: 18px 22px;
  font-family: 'Source Sans 3', sans-serif;
  display: none;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  overflow-wrap: anywhere;
  /* Guard against a very large text size turning the bar into a full screen. */
  max-height: 45vh;
  overflow-y: auto;
}
#qc-cookie-banner.is-open { display: flex; }
#qc-cookie-banner * { box-sizing: border-box; }
#qc-cookie-banner .qc-cookie-text {
  margin: 0;
  flex: 1 1 320px;
  min-width: 0;
  font-size: 14px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.85);
}
#qc-cookie-banner .qc-cookie-text a { color: #14A07A; text-decoration: underline; }
#qc-cookie-banner .qc-cookie-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  min-width: 0;
}
#qc-cookie-banner .qc-cookie-btn {
  cursor: pointer;
  border-radius: 8px;
  font-family: 'Source Sans 3', sans-serif;
  font-size: 13px;
  min-width: 0;
}
#qc-cookie-banner .qc-cookie-btn--ghost {
  background: transparent;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.3);
  padding: 9px 18px;
  font-weight: 600;
}
#qc-cookie-banner .qc-cookie-btn--accept {
  background: #0F6E56;
  color: #fff;
  border: 0;
  padding: 10px 20px;
  font-weight: 700;
}
#qc-cookie-banner .qc-cookie-btn:focus-visible {
  outline: 2px solid #14A07A;
  outline-offset: 2px;
}

/* Do NOT reserve the banner's height at the end of the document.

   It was tried twice: as a `body::after` spacer, and as extra footer padding.
   Both render as an empty dark block at the end of every page, which reads as
   broken. Reported on /client-portal/. It is also unnecessary: the banner sits
   over the footer's own bottom padding, where there is no content to cover.
   `scroll-padding-bottom` is kept so anchor jumps still clear the banner. */
html.qc-cookie-open { scroll-padding-bottom: var(--qc-cookie-offset, 0px); }

@media (max-width: 640px) {
  #qc-cookie-banner {
    --qc-cookie-inset: 12px;
    padding: 12px 14px;
    gap: 10px;
    border-radius: 12px;
  }
  #qc-cookie-banner .qc-cookie-text {
    flex: 1 1 100%;
    font-size: 13px;
    line-height: 1.4;
  }
  #qc-cookie-banner .qc-cookie-actions {
    width: 100%;
    gap: 8px;
  }
  #qc-cookie-banner .qc-cookie-btn {
    flex: 1 1 0;
    min-height: 44px;
    padding: 10px 12px;
  }
}
@media (max-width: 380px) {
  #qc-cookie-banner { --qc-cookie-inset: 8px; }
}


/* Some assembled pages paint a full-viewport fixed background layer, e.g.
   /client-portal/ ships `.portal-bg { position: fixed; inset: 0; z-index: 0 }`
   with an opaque navy base. In the client's standalone file his own footer sat
   above it; here the theme footer comes after in normal flow with no stacking
   of its own, so the fixed layer paints straight over it and the whole footer
   reads as an empty black block. Reported on /client-portal/.
   Giving the global chrome its own stacking context fixes it for every page
   that does this, not just that one. */
footer.qc-footer { position: relative; z-index: 1; }

/* ---------------------------------------------------------------------------
   Mobile: three fixed elements were competing for the bottom of the screen.

   Client's pre-launch audit, QC-F19 and QC-F20. Measured at 375x812:

   - The cookie banner sits at y 669-804 with z-index 99999. The diagnostic bar
     sits at y 739-812 with z-index 999. The banner covered 65 of the bar's 73px
     across the full width, so the bar's CTA could not be tapped until consent
     was answered.
   - The HubSpot chat launcher is anchored bottom right at z-index 10500, and
     the theme gives its iframe pointer-events:auto, so taps in the overlap hit
     the chat rather than the bar's own button. With the greeting bubble open it
     covered the bar entirely.

   The bar already animates itself in and out with translateY, so the banner case
   reuses that rather than introducing a second mechanism. The consent script
   already toggles .qc-cookie-open on <html>, so no new hook is needed either.
   --------------------------------------------------------------------------- */

/* QC-F19: while consent is open the bar waits its turn. */
html.qc-cookie-open .qc-dw-mobile,
html.qc-cookie-open .qc-dw-mobile.qc-dw-visible {
  transform: translateY(100%) !important;
}

@media (max-width: 768px) {
  /* QC-F20: lift the chat launcher clear of the 73px bar. Same technique the
     theme already uses to get the chat out of the way of the mobile menu. */
  #hubspot-messages-iframe-container {
    bottom: 80px !important;
  }
  /* While consent is open the bar is hidden, so the chat can sit low again. */
  html.qc-cookie-open #hubspot-messages-iframe-container {
    bottom: 0 !important;
  }
}

/* QC-N07: on short laptop viewports the chat greeting bubble collided with the
   desktop diagnostic panel. Below 760px of height there is not room for both. */
@media (min-width: 769px) and (max-height: 760px) {
  .qc-dw-desktop { display: none !important; }
}
