@charset "utf-8";
/* ==========================================================================
   Header, mega menu, footer, search overlay.
   Loaded after site.css and using only its tokens.
   ========================================================================== */

/* --- Header ------------------------------------------------------------- */
.site-header {
  position: sticky; top: 0; z-index: 200;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line);
}
@supports not (backdrop-filter: blur(1px)) { .site-header { background: var(--bg); } }
.header-inner { display: flex; align-items: center; gap: var(--s-5); min-height: var(--header-h); }
.brand { display: flex; align-items: center; flex: 0 0 auto; }
.brand img { width: 112px; height: auto; }
/* The wordmark is dark ink on transparent, so it disappears on a dark ground. */
[data-theme="dark"] .brand img { filter: brightness(0) invert(1); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .brand img { filter: brightness(0) invert(1); } }

.site-nav { display: flex; align-items: center; gap: var(--s-1); margin-left: auto; }
.nav-link {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px;
  padding: 0 var(--s-3); border: 0; background: none; cursor: pointer;
  font: 600 var(--t-15)/1 var(--sans); color: var(--ink-soft);
  text-decoration: none; border-radius: var(--r-sm);
  transition: color var(--ease), background-color var(--ease);
}
.nav-link:hover { color: var(--navy); background: var(--bg-soft); }
.nav-item.has-mega > .nav-link::after {
  content: ""; width: 7px; height: 7px; margin-left: 2px;
  border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg) translateY(-2px); transition: transform var(--ease);
}
.nav-item.has-mega > .nav-link[aria-expanded="true"] { color: var(--navy); background: var(--bg-soft); }
.nav-item.has-mega > .nav-link[aria-expanded="true"]::after { transform: rotate(225deg) translateY(-2px); }
.nav-cta { margin-left: var(--s-3); }

.icon-btn {
  display: inline-flex; align-items: center; gap: 6px; justify-content: center;
  min-width: 44px; min-height: 44px; padding: 0 var(--s-2);
  background: none; border: 0; cursor: pointer; color: var(--ink-soft);
  border-radius: var(--r-sm); transition: color var(--ease), background-color var(--ease);
}
.icon-btn:hover { color: var(--navy); background: var(--bg-soft); }
/* In the header these buttons are a magnifier and a sun, and the shortcut hint
   is enough. In the mobile panel they sit in a list of words, where a bare
   glyph is a guess. The label is the same string as the aria-label, so the
   accessible name still contains the visible text. */
.icon-label { display: none; }
/* flex: none, because these are flex items and an svg is happy to be crushed.
   The search icon carries the "/" hint beside it, the two together were wider
   than the 44px button, and the icon lost: it rendered 3px square next to an
   18px sun and looked like a speck. An icon has one correct size. */
.icon-btn svg { flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
.kbd {
  font: 600 var(--t-11)/1 var(--mono); color: var(--ink-faint);
  border: 1px solid var(--line); border-radius: 3px; padding: 3px 5px;
}

/* --- Mega menu ---------------------------------------------------------- */
.nav-item { position: static; }
.mega {
  position: absolute; left: 0; right: 0; top: 100%;
  background: var(--bg); border-bottom: 1px solid var(--line);
  box-shadow: 0 18px 40px -28px rgba(10,26,52,.35);
}
.mega[hidden] { display: none; }
.mega-inner { display: grid; grid-template-columns: repeat(4, 1fr); padding: var(--s-6) var(--s-5); }
.mega-col { padding: 0 var(--s-5); border-left: 1px solid var(--line); }
.mega-col:first-child { border-left: 0; padding-left: 0; }
.mega-h { font-size: var(--t-15); color: var(--navy); margin-bottom: var(--s-1); }
.mega-sub { font-size: var(--t-13); line-height: 1.5; color: var(--ink-faint); margin-bottom: var(--s-4); min-height: 3em; }
.mega-col ul { list-style: none; }
.mega-col li + li { margin-top: 2px; }
.mega-col a {
  display: flex; gap: var(--s-3); align-items: flex-start; padding: var(--s-2);
  margin: 0 calc(var(--s-2) * -1); border-radius: var(--r-sm); text-decoration: none;
  transition: background-color var(--ease);
}
.mega-col a:hover { background: var(--bg-soft); }
.mega-col img { width: 24px; height: 24px; flex: 0 0 24px; margin-top: 2px; }
.mega-col b { display: block; font-size: var(--t-15); color: var(--navy); font-weight: 700; }
.mega-col em { display: block; font-style: normal; font: 400 var(--t-12)/1.45 var(--mono); color: var(--ink-faint); margin-top: 2px; }
.mega-services a { padding-left: calc(24px + var(--s-3) + var(--s-2)); }
.mega-foot { border-top: 1px solid var(--line); background: var(--bg-soft); }
.mega-foot .wrap { display: flex; justify-content: space-between; align-items: center; gap: var(--s-5); padding-block: var(--s-3); flex-wrap: wrap; }
.mega-foot span { font-size: var(--t-14); color: var(--ink-faint); }
.mega-foot .more { margin-top: 0; }

/* --- Mobile ------------------------------------------------------------- */
.nav-burger {
  display: none; width: 44px; height: 44px; margin-left: auto;
  background: none; border: 0; cursor: pointer; padding: 10px;
}
.nav-burger span { display: block; height: 2px; background: var(--ink); border-radius: 2px; }
.nav-burger span + span { margin-top: 5px; }
.nav-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
@media (prefers-reduced-motion: no-preference) { .nav-burger span { transition: transform var(--ease), opacity var(--ease); } }

@media (max-width: 1050px) {
  .nav-burger { display: block; }
  /* The blur comes off the header at this width, and it has to. A
     backdrop-filter makes the header the containing block for any fixed
     descendant, so the menu panel below sized itself against a 64px header
     instead of the viewport: it laid out 32px tall, the items below that line
     fell outside the panel's box, and every tap landed on the hero behind it.
     Eight of eight items were dead on a phone. z-index does not touch this,
     because the fault is the containing block and not the stacking order.
     The blur was decoration; an opaque header reads the same on a phone. */
  .site-header { backdrop-filter: none; background: var(--bg); }
  /* Closed, the panel leaves layout entirely. A fixed element translated off
     the right edge still counts toward document width, which is how a phone
     ends up scrolling sideways on a page that looks fine. */
  .site-nav { display: none; }
  .site-nav.open {
    display: flex; position: fixed; inset: var(--header-h) 0 0 auto;
    width: min(380px, 100%); background: var(--bg); border-left: 1px solid var(--line);
    flex-direction: column; align-items: stretch; gap: 0;
    padding: var(--s-4); overflow-y: auto;
  }
  @media (prefers-reduced-motion: no-preference) {
    .site-nav.open { animation: nav-in 160ms cubic-bezier(.2,.6,.3,1); }
    @keyframes nav-in { from { transform: translateX(100%); } to { transform: none; } }
  }
  .nav-link { justify-content: space-between; width: 100%; padding: var(--s-3) 0; border-bottom: 1px solid var(--line-soft); border-radius: 0; }
  .nav-cta { margin: var(--s-4) 0 0; width: 100%; }
  .mega { position: static; box-shadow: none; border: 0; }
  .mega-inner { grid-template-columns: 1fr; padding: var(--s-3) 0; }
  .mega-col { border-left: 0; padding: var(--s-3) 0 0; border-top: 1px solid var(--line-soft); }
  .mega-col:first-child { border-top: 0; padding-top: 0; }
  .mega-sub { min-height: 0; }
  .mega-foot { display: none; }
  .icon-btn { justify-content: flex-start; gap: var(--s-3); padding: var(--s-3) 0; width: 100%; border-bottom: 1px solid var(--line-soft); border-radius: 0; }
  .icon-label { display: inline; font: 600 var(--t-15)/1 var(--sans); color: var(--ink-soft); }
  .kbd { display: none; }
}

/* --- Footer ------------------------------------------------------------- */
.site-footer { background: var(--act-bg); color: var(--on-dark-soft); padding: var(--s-8) 0 var(--s-5); margin-top: var(--s-8); }
/* The margin is breathing room after a plain section. After a section that
   paints its own ground it was a white stripe: on the home page a dark call to
   action sat above the dark footer with 62px of white between them, which
   reads as a rendering fault rather than as spacing. Where the last section has
   a background, the two meet. */
/* :last-of-type, not :last-child. On /roi a <script> is the last child of
   main, so the last section is not the last child and the rule missed it. */
main:has(> section.act:last-of-type) + .site-footer,
main:has(> section.band:last-of-type) + .site-footer,
main:has(> section.band-soft:last-of-type) + .site-footer,
main:has(> section.band-paper:last-of-type) + .site-footer { margin-top: 0; }
.footer-top { display: grid; grid-template-columns: 1.5fr repeat(5, 1fr); gap: var(--s-6); }
.footer-brand img { width: 128px; margin-bottom: var(--s-4); filter: brightness(0) invert(1); }
.footer-brand p { font-size: var(--t-14); line-height: 1.6; color: var(--on-dark-faint); max-inline-size: 34ch; }
.footer-tag { font-family: var(--mono); font-size: var(--t-12); letter-spacing: .1em; text-transform: uppercase; color: var(--accent-on-dark); margin-top: var(--s-3); }
.footer-contact { font-style: normal; font-size: var(--t-14); line-height: 1.8; margin-top: var(--s-4); color: var(--on-dark-faint); }
.footer-contact a { color: var(--on-dark-soft); text-decoration: none; border-bottom: 1px solid var(--on-dark-line); }
.footer-contact a:hover { color: #fff; border-bottom-color: currentColor; }
.footer-col h2 { font: 600 var(--t-11)/1.4 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--on-dark-faint); margin-bottom: var(--s-3); }
.footer-col ul { list-style: none; }
.footer-col li + li { margin-top: var(--s-2); }
.footer-col a { font-size: var(--t-14); color: var(--on-dark-soft); text-decoration: none; }
.footer-col a:hover { color: #fff; text-decoration: underline; }
.footer-bar {
  display: flex; justify-content: space-between; gap: var(--s-5); flex-wrap: wrap;
  margin-top: var(--s-7); padding-top: var(--s-4); border-top: 1px solid var(--on-dark-line);
  font-size: var(--t-13); color: var(--on-dark-faint);
}
.footer-bar ul {
  list-style: none; display: flex; gap: var(--s-3) var(--s-5); flex-wrap: wrap;
  /* Five links do not fit on one line at 320px, and without wrapping the whole
     page scrolled sideways on every page of the site. */
  padding: 0; margin: 0; min-width: 0;
}
.footer-bar a { color: var(--on-dark-faint); text-decoration: none; }
.footer-bar a:hover { color: #fff; text-decoration: underline; }
@media (max-width: 1050px) { .footer-top { grid-template-columns: 1fr 1fr 1fr; } }
@media (max-width: 720px)  { .footer-top { grid-template-columns: 1fr 1fr; } .footer-brand { grid-column: 1 / -1; } }
@media (max-width: 560px)  { .footer-top { grid-template-columns: 1fr; } }

/* --- Search overlay ----------------------------------------------------- */
.search-overlay {
  position: fixed; inset: 0; z-index: 400; background: rgba(10,26,52,.45);
  padding: 10vh var(--s-4) var(--s-4); overflow-y: auto;
}
.search-overlay[hidden] { display: none; }
.search-panel {
  max-width: 720px; margin: 0 auto; background: var(--bg);
  border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden;
}
.search-form { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-4) var(--s-5); border-bottom: 1px solid var(--line); }
.search-form svg { fill: none; stroke: var(--ink-faint); stroke-width: 1.7; stroke-linecap: round; flex: 0 0 auto; }
.search-input { flex: 1; border: 0; background: none; font: 400 var(--t-19)/1.4 var(--sans); color: var(--ink); min-height: 32px; }
.search-input:focus { outline: none; }
.search-input:focus-visible {
  /* The tint ring alone measured 1.11:1 against the panel, where WCAG 2.2
     asks for 3:1 on a focus indicator. The accent outline carries the contrast
     and the tint stays as the soft halo behind it. */
  outline: 2px solid var(--accent-deep);
  outline-offset: 2px;
}
.search-close { background: none; border: 1px solid var(--line); border-radius: var(--r-sm); color: var(--ink-faint); font: 600 var(--t-12)/1 var(--mono); padding: 7px 9px; cursor: pointer; min-height: 30px; }
.search-hint { font-size: var(--t-13); color: var(--ink-faint); padding: var(--s-3) var(--s-5); border-bottom: 1px solid var(--line-soft); }
.search-hint kbd { font: 600 var(--t-11)/1 var(--mono); border: 1px solid var(--line); border-radius: 3px; padding: 2px 5px; }
.search-results { max-height: 56vh; overflow-y: auto; }
.search-results:empty { display: none; }
.sr-item { display: block; padding: var(--s-3) var(--s-5); text-decoration: none; border-bottom: 1px solid var(--line-soft); }
.sr-item:last-child { border-bottom: 0; }
.sr-item[aria-selected="true"], .sr-item:hover { background: var(--bg-soft); }
.sr-item b { display: block; font-size: var(--t-15); color: var(--navy); }
.sr-item span { display: block; font-size: var(--t-13); line-height: 1.5; color: var(--ink-faint); margin-top: 2px; }
.sr-item mark { background: var(--accent-tint); color: inherit; border-radius: 2px; padding: 0 1px; }
.sr-kind { float: right; font: 600 var(--t-11)/1 var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--accent-deep); }
.sr-empty { padding: var(--s-5); font-size: var(--t-14); color: var(--ink-faint); }
.sr-ask { display: flex; gap: var(--s-3); align-items: center; padding: var(--s-4) var(--s-5); background: var(--bg-soft); border-top: 1px solid var(--line); }
.sr-ask b { font-size: var(--t-14); color: var(--navy); }

/* --- The handoff, which chains one product page to the next ------------- */
.handoff {
  margin-top: var(--s-6); padding: var(--s-5); border: 1px solid var(--line);
  border-left: 3px solid var(--accent); border-radius: 0 var(--r-md) var(--r-md) 0;
  background: var(--bg-soft);
}
.handoff .k { display: block; font: 600 var(--t-11)/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--accent-deep); margin-bottom: var(--s-2); }
.handoff p { font-size: var(--t-16); line-height: 1.6; color: var(--ink-soft); max-inline-size: 62ch; }
.handoff b { color: var(--navy); }

/* ---- consent -----------------------------------------------------------
   Anchored to the bottom of the viewport, because a choice has to be seen to
   be made, but never covering the page: the body carries matching padding for
   as long as the banner is up. Accept and decline are the same size and sit
   next to each other. */
.consent {
  position: fixed; inset: auto 0 0 0; z-index: 90;
  background: var(--bg); border-top: 2px solid var(--accent);
  box-shadow: 0 -8px 28px rgb(0 0 0 / 0.10);
}
.consent-in {
  max-width: var(--wrap, 1180px); margin: 0 auto;
  padding: var(--s-4) var(--s-5);
  display: flex; flex-wrap: wrap; gap: var(--s-4);
  align-items: center; justify-content: space-between;
}
.consent-t { flex: 1 1 420px; min-width: 0; }
.consent h2 { font-size: var(--t-16); margin: 0 0 var(--s-1); }
.consent p { margin: 0; font-size: var(--t-14); color: var(--ink-soft); max-width: 78ch; }
.consent-a { display: flex; gap: var(--s-3); flex-wrap: wrap; }
.consent-a .btn { white-space: nowrap; }
body { padding-bottom: var(--consent-h, 0); }

@media (max-width: 640px) {
  .consent-in { padding: var(--s-3) var(--s-4) var(--s-4); gap: var(--s-3); }
  .consent p { font-size: var(--t-13); }
  /* Side by side, not stacked. Stacked, the banner took a third of a phone
     screen, which stops being a banner and starts being a wall. */
  .consent-a { width: 100%; display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-2); }
  .consent-a .btn { text-align: center; padding-inline: var(--s-2); font-size: var(--t-14); }
}

/* Back to the top. Part of the footer, so it never covers the page. */
.to-top {
  display: inline-block; margin-top: var(--s-5);
  color: var(--on-dark-soft); font-size: var(--t-13); text-decoration: none;
}
.to-top::before { content: '\2191'; margin-right: 6px; }
.to-top:hover { color: #fff; text-decoration: underline; }

/* --- Local time, and weather on request -------------------------------- */
/* Sits in the right-hand cluster of the header, left of the icon buttons. It
   is the least important thing up there, so it is quiet: the same size as the
   nav links, in the muted ink, and it never moves the layout when the weather
   arrives because the row reserves its own height. */
.wx {
  display: flex; align-items: center; gap: var(--s-2);
  margin-inline-start: var(--s-3);
  padding-inline-start: var(--s-3);
  border-inline-start: 1px solid var(--line-soft);
  font-size: var(--t-13); line-height: 1;
  color: var(--ink-soft);
  white-space: nowrap;
}
.wx-time { font-variant-numeric: tabular-nums; font-weight: 500; color: var(--ink); }
.wx-place { color: var(--ink-faint); }
.wx-place:empty { display: none; }
.wx-weather { display: inline-flex; align-items: center; gap: 4px; }
.wx-weather svg { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
.wx-temp { font-variant-numeric: tabular-nums; }
.wx-ask { width: 26px; height: 26px; }
.wx-ask svg { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
.wx-ask[disabled] { opacity: 0.5; }

/* A nav label must never wrap. The header has a fixed height and a row of
   items that has to fit inside it, so when something is added the right answer
   is for that something to give way, not for "How it works" to become two
   lines. */
.site-nav .nav-link,
.site-nav .nav-cta { white-space: nowrap; }

/* The clock gives way in two steps: the place name first, then the whole
   widget, well before the burger menu takes over. */
@media (max-width: 1400px) { .wx-place { display: none; } }
@media (max-width: 1180px) { .wx { display: none; } }
