/* Global overrides — bypasses Astro's <style> scoping by being served as a
   static file from /public. Loaded as the LAST stylesheet in <head> so it
   wins specificity over the WP-injected styles. */

/* ─── The Cookiebot dialog is NOT hidden here — on purpose ─────────────────
   A rule here used to hide it, left over from the JS-less static rebuild where it
   could never be dismissed. On the SSR site it meant no visitor ever saw the banner,
   so consent stayed denied for everyone: GA4 cookieless only, no Ads remarketing.
   scripts/check-tracking.ts fails the gate if such a rule comes back. The pixel
   gate removes the dialog on its own (scripts/lib/pin-page.mjs).              */

/* ─── Top-nav mega-menu + mobile off-canvas ─────────────────────────────────
   Driven by /public/init-nav.js (vanilla replacement for the WP theme's
   Foundation/jQuery menu JS). It toggles `.dropdown-pane.is-open` +
   `.top-bar.dropdown-opened` (white-header state) on desktop, and the
   `.off-canvas.is-open` panel + accordion submenus on mobile. The theme
   stylesheet already styles all of those hooks — no CSS-only hover hack
   needed (it could open the pane but never set the white-header state).
   Lock background scroll while the mobile off-canvas is open: */
html.is-off-canvas-open,
html.is-off-canvas-open body {
  overflow: hidden;
}

/* ─── Solutions cluster "See more / See less" expand ────────────────────────
   The bundled CSS sets .cluster__items { display: none } and the original
   site's JS set display:block inline when expanding. Our init-clusters.js
   only toggles .cluster--open on the parent; this rule does the rest. */
.cluster.cluster--open .cluster__items {
  display: block !important;
}

/* ─── /references archive: client-side tag filter (init-references-filter.js) ──
   Keep every chip full-colour (matching the live site); indicate the active
   filter with a ring instead of dimming the others, which made the whole bar
   look greyed/"already clicked". Scoped to the filter bar. */
.categories-list[data-references-filter] a {
  transition: box-shadow .15s ease;
}
.categories-list[data-references-filter] a.is-active {
  box-shadow: 0 0 0 2px #021b41;
}

/* ─── /references archive cards: the .card--reference .headline navy colour rule
   isn't in the stylesheet subset loaded on the index page, so the case-study
   titles inherited grey. Restore the live navy. */
.card--reference .headline {
  color: #021b41;
}

/* ─── /resources index: client-side category filter (init-resources-filter.js).
   Same treatment as the /references bar — full-colour chips, active chip ringed
   rather than dimming the rest. Scoped to the resources filter bar. */
.categories-list[data-resources-filter] a {
  transition: box-shadow .15s ease;
}
.categories-list[data-resources-filter] a.is-active {
  box-shadow: 0 0 0 2px #021b41;
}

/* ─── Solution-page redesign (2026-07): theme-CSS deltas the stale May bundle is
   missing. Ported verbatim from the current live theme CSS. */

/* Hero logo was rendering at its full medium-size 300×60; the redesign constrains
   the hero__content logo to 3rem tall (→240×48). */
.hero--cluster-style .hero__content img {
  display: block;
  max-height: 3rem;
  width: auto;
  margin-bottom: 2rem;
}

/* cs-divider must stack ABOVE the section--benefits gradient overlay, else the
   overlay paints over the divider's navy hump and fades it. */
.cs-divider {
  z-index: 2;
}

/* The redesign disabled the benefits/performance decorative gradient + bg-image
   overlays (they covered left:25%→right and were smearing the divider). */
.section--benefits::before,
.section--performance::before,
.section--benefits .bg-image,
.section--performance .bg-image {
  display: none !important;
}

/* The redesign added a `.small-headline` cluster variant. Our stale bundle sizes
   `.section--cluster h2` up to 3.875rem (62px) without the `:not(.small-headline)`
   guard the live theme uses, so these headings render too large. On live the variant
   simply falls back to the BASE h2 sizing, which this restates.

   Two things this override got wrong before, both found by measuring live rather
   than reading the rule:

   1. `line-height`. The guarded live rule is
      `.section--cluster:not(.small-headline) h2{line-height:1.12}`, so a
      small-headline h2 keeps the base 1.2222 on live. Our unguarded copy applied
      1.12, which is why these measured 39.2px against live's 42.777px.

   2. The size is RESPONSIVE, and this pinned the largest step at every width — so
      the headings rendered 35px on a phone where live renders 25px. Measured off
      live at 390/640/768/1024/1200/1440: 25px → 30px → 35px, switching at
      Foundation's medium (40em) and large (64em). margin-bottom is 0.75em at every
      step, so it follows from the font-size and needs no rule here. */
.section--cluster.small-headline .section__headline .headline,
.section--cluster.small-headline .section__headline h2,
.section--cluster.small-headline h2 {
  font-size: 1.5625rem;
  line-height: 1.2222;
}

@media screen and (min-width: 40em) {
  .section--cluster.small-headline .section__headline .headline,
  .section--cluster.small-headline .section__headline h2,
  .section--cluster.small-headline h2 {
    font-size: 1.875rem;
  }
}

@media screen and (min-width: 64em) {
  .section--cluster.small-headline .section__headline .headline,
  .section--cluster.small-headline .section__headline h2,
  .section--cluster.small-headline h2 {
    font-size: 2.1875rem;
  }
}

/* `.hero--cluster-style` typography — the rest of the same stale-bundle gap.
   The live theme ships 24 rules for this hero variant; our May bundle ships none,
   so every `.headline` inside it fell back to the generic 1.3333 heading
   line-height and the lead paragraph to the dimmed 70%-white body colour.
   Measured against live on all 7 pages that use this hero (border-control,
   smart-corridors-egates, identity-verification-technology, the three
   innovatrics-abis pages, and trusted-identity-verification-…): h1 60px→48.6px,
   the feature labels 16px→12.96px, the lead paragraph 27px→22.2px.

   Ported verbatim from the live bundle:
     .hero--cluster-style .headline{line-height:1.08}
     .hero--cluster-style .hero__content p{color:#fff;line-height:1.48}
   The accent colours for this hero (`.style--mint …` et al.) already resolve
   correctly and are deliberately NOT repeated here. */
.hero--cluster-style .headline {
  line-height: 1.08;
}

.hero--cluster-style .hero__content p {
  color: #fff;
  line-height: 1.48;
}

/* ─── Two rules our bundle has but in the WRONG ORDER ───────────────────────
   Both of these exist verbatim in our bundle AND in live's, with identical
   selectors and identical specificity — they simply appear in the opposite
   source order, because our bundle is an older LiteSpeed concatenation than the
   one live serves today. Specificity ties are broken by source order, so the
   loser differs between the two sites. Confirmed by CDP `getMatchedStylesForNode`
   on both, and reproduced on border-control, smart-corridors-egates and
   biometrics-for-oem as well as this page.

   Restated here (overrides.css loads last) so the rule live actually applies is
   the one that wins for us too. */

/* WordPress core's media-text padding. Ours resolves to `.section--cluster
   .wp-block-media-text__content{padding:0}`, which drops the 8% side padding and
   widens the text column from 440px to 524px — enough that headings which wrap to
   two lines on live fit on one, so the section came out 50px short. 7 pages. */
.wp-block-media-text > .wp-block-media-text__content {
  padding: 0 8%;
}

/* NOT FIXED HERE, deliberately — `.button.primary` label colour.
   Live paints this label near-black (#131313) on the solution pages (this one,
   border-control, smart-corridors-egates, enterprise-identity-verification) and
   white on home and about-us — same markup, same classes, and the SAME two
   competing rules at the same offsets in the stylesheet the browser actually
   loads (captured off the wire, not curl'd). By cascade `.button.primary{color:#fff}`
   comes last and should win everywhere, which is what we render; live disagrees
   with itself per page for a reason not visible in its served CSS.
   An override here is global, so matching the solution pages means breaking the
   4 teal buttons on the homepage — measured, not assumed. Left alone until the
   cause is known; our render matches live on home/about-us today. */

/* A rule live has and our bundle simply does not carry (the only `:last-child`
   rule in that position missing from ours). Without it the cases carousel keeps
   its 4.5rem bottom margin even when it is the last thing in the section, so the
   section ran 72px tall against live. 4 pages carry a `swiper--cases`. */
.swiper--cases:last-child {
  margin-bottom: 0;
}

/* --- Lead-form submit feedback (Zoho) -------------------------------------
   Contact Form 7 painted its status message into `.wpcf7-response-output`, but
   the theme only styles/hides that element under a `.wpcf7` ANCESTOR — which
   most of our contact blocks do not have (see LESSONS.md lesson 42, where the
   permanently-empty node was removed for exactly this reason). Our own AJAX
   submit needs a message target that behaves identically on every form variant,
   so `.lead-form-response` is styled here in overrides.css, which loads last and
   wins everywhere (lesson 53).

   Collapses when empty, so it takes no space until there is something to say.

   Deliberately BORDERLESS: the surrounding form is built from bare underlined
   inputs on a flat colour field, so a bordered/rounded status box read as a
   stray card pasted onto the section. A leading glyph carries the
   success/error state instead, which sits far better with the form's styling.

   The TEXT inherits the section's own colour, never a fixed one. Forms sit on
   four backgrounds — dark blue (contact blocks, webinar box-form), ocean
   (newsletter), light blue (ContactLight) and white (event dialog) — and a fixed
   #021b41 was 1.0:1 on dark blue: 176 pages showed a bare ✓ and no message
   (LESSONS.md lesson 143). Inherited, it measures 8:1 to 17:1 on all four.
   No single glyph colour clears 3:1 on all four either, so each glyph sits in a
   filled badge that carries its own contrast (white on green / red). */
.lead-form-response {
  margin: 1.25rem 0 1rem;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: inherit;
}

.lead-form-response:empty {
  display: none;
}

.lead-form-response.is-sent::before,
.lead-form-response.is-error::before {
  display: inline-block;
  width: 1.4em;
  height: 1.4em;
  margin-right: 0.5em;
  border-radius: 50%;
  font-size: 0.875em;
  font-weight: 700;
  line-height: 1.4em;
  text-align: center;
  vertical-align: 0.1em;
  color: #fff;
}

.lead-form-response.is-sent::before {
  content: "✓";
  background: #1a7f45;
}

.lead-form-response.is-error {
  font-weight: 600; /* the state must not rest on the badge colour alone */
}

.lead-form-response.is-error::before {
  content: "!";
  background: #c92a2a;
}

/* Submit button feedback while the request is in flight. */
form[data-lead-form].submitting button[type="submit"],
form[data-lead-form] button[disabled] {
  opacity: 0.6;
  cursor: not-allowed;
}

/* --- Cloudflare Turnstile widget ------------------------------------------
   Turnstile renders a fixed-size (~300x65) iframe we cannot restyle from here,
   so only its surroundings are ours to control. Without this it sits flush
   against the submit button. `max-width` keeps it inside narrow form columns
   (the mc4wp material-download boxes) rather than overflowing them. */
.cf-turnstile {
  max-width: 100%;
  overflow: hidden;
  /* No margin by default. In INVISIBLE mode the widget renders zero-height (it
     contains only the hidden token input), so any margin here would leave ~40px
     of dead space between the consent checkbox and the submit button. */
  margin: 0;
}

/* Spacing only when the widget is actually VISIBLE. Turnstile injects an
   <iframe> for the interactive/managed widget and none at all in invisible mode
   (verified against Cloudflare's test keys), so `:has(iframe)` distinguishes
   them without JavaScript. Browsers without :has() simply get no margin, which
   is the harmless case. */
.cf-turnstile:has(iframe) {
  margin: 1.5rem 0 1rem;
}

/* --- Solutions menu: expandable sublink (live, 2026-10) ---------------------
   "Enterprise Identity Verification Platform" became a <button> that expands
   two nested links (SiteTopBar, desktop #mm-solutions + off-canvas). Our CSS
   bundle predates it, so these are the live bundle's `sublinks__*` rules
   verbatim (lesson 57); the toggle itself is in init-nav.js. */
.sublinks__toggle{gap:.5rem;margin:0;border:0;border-radius:0;background:0 0;font-family:inherit;font-size:.875rem;font-weight:500;color:#021b41;text-align:left;cursor:pointer}
.sublinks__toggle::after{content:'';-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;width:.625rem;height:.625rem;background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath d='M1.455 10.036l3.2-2.909 11.345 12.509 11.345-12.509 3.2 2.909-13.091 14.255c-0.291 0.582-0.873 0.582-1.745 0.582-0.582 0-1.164-0.291-1.745-0.873l-12.509-13.964z' fill='%23021B41'/%3E%3C/svg%3E") center/contain no-repeat;-webkit-transition:background-color .25s ease,-webkit-transform .3s cubic-bezier(.22,1,.36,1);transition:background-color .25s ease,-webkit-transform .3s cubic-bezier(.22,1,.36,1);transition:transform .3s cubic-bezier(.22,1,.36,1),background-color .25s ease;transition:transform .3s cubic-bezier(.22,1,.36,1),background-color .25s ease,-webkit-transform .3s cubic-bezier(.22,1,.36,1)}
.sublinks__toggle[aria-expanded=true]::after{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}
@supports ((-webkit-mask:url("")) or (mask:url(""))) or (-webkit-mask:url("")){.sublinks__toggle::after{background:#021b41;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath d='M1.455 10.036l3.2-2.909 11.345 12.509 11.345-12.509 3.2 2.909-13.091 14.255c-0.291 0.582-0.873 0.582-1.745 0.582-0.582 0-1.164-0.291-1.745-0.873l-12.509-13.964z' fill='%23021B41'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath d='M1.455 10.036l3.2-2.909 11.345 12.509 11.345-12.509 3.2 2.909-13.091 14.255c-0.291 0.582-0.873 0.582-1.745 0.582-0.582 0-1.164-0.291-1.745-0.873l-12.509-13.964z' fill='%23021B41'/%3E%3C/svg%3E") center/contain no-repeat}@media (hover:hover){.sublinks__toggle:hover::after{background-color:#00bfb2}}}
.sublinks__toggle:focus-visible{outline:2px solid #00bfb2;outline-offset:2px}
.sublinks__children{display:grid;grid-template-rows:0fr;opacity:0;visibility:hidden;-webkit-transition:grid-template-rows .3s cubic-bezier(.22,1,.36,1),opacity .2s ease,visibility 0s linear .3s;transition:grid-template-rows .3s cubic-bezier(.22,1,.36,1),opacity .2s ease,visibility 0s linear .3s;transition:grid-template-rows .3s cubic-bezier(.22,1,.36,1),opacity .2s ease,visibility 0s linear .3s,-ms-grid-rows .3s cubic-bezier(.22,1,.36,1)}
.sublinks__children>ul{min-height:0;overflow:hidden}
.sublinks__children li{-webkit-transform:translateY(-4px);-ms-transform:translateY(-4px);transform:translateY(-4px);-webkit-transition:-webkit-transform .3s cubic-bezier(.22,1,.36,1);transition:-webkit-transform .3s cubic-bezier(.22,1,.36,1);transition:transform .3s cubic-bezier(.22,1,.36,1);transition:transform .3s cubic-bezier(.22,1,.36,1),-webkit-transform .3s cubic-bezier(.22,1,.36,1)}
.sublinks__toggle[aria-expanded=true]+.sublinks__children{grid-template-rows:1fr;opacity:1;visibility:visible;-webkit-transition:grid-template-rows .3s cubic-bezier(.22,1,.36,1),opacity .3s ease 50ms,visibility 0s;transition:grid-template-rows .3s cubic-bezier(.22,1,.36,1),opacity .3s ease 50ms,visibility 0s;transition:grid-template-rows .3s cubic-bezier(.22,1,.36,1),opacity .3s ease 50ms,visibility 0s,-ms-grid-rows .3s cubic-bezier(.22,1,.36,1)}
.sublinks__toggle[aria-expanded=true]+.sublinks__children li{-webkit-transform:none;-ms-transform:none;transform:none}
.sublinks__toggle[aria-expanded=true]+.sublinks__children li:nth-child(2){-webkit-transition-delay:40ms;transition-delay:40ms}
.sublinks__toggle[aria-expanded=true]+.sublinks__children li:nth-child(3){-webkit-transition-delay:80ms;transition-delay:80ms}
#mm-solutions .sublinks .sublinks__toggle{display:block;padding:.25rem 0;line-height:1.5}
#mm-solutions .sublinks .sublinks__toggle::after{display:inline-block;width:.5625rem;height:.5625rem;margin-left:.375rem;vertical-align:1px}
#mm-solutions .sublinks .sublinks__children ul{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:.625rem;list-style:none;margin:0;padding:0 0 0 1.1875rem}
#mm-solutions .sublinks .sublinks__children li:first-child{margin-top:.25rem}
#mm-solutions .sublinks .sublinks__children a{padding:0 1.1875rem 0 0;color:#7c878e}
#mm-solutions .sublinks .sublinks__children a:hover{padding:0 0 0 1.1875rem;color:#021b41}
.off-canvas .menu.solutions .sublinks .sublinks__toggle{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:.625rem 0;line-height:1}
.off-canvas .menu.solutions .sublinks .sublinks__toggle::after{width:.6875rem;height:.6875rem}
.off-canvas .menu.solutions .sublinks .sublinks__children{margin-left:1.1875rem}
.off-canvas .menu.solutions .sublinks .sublinks__children ul{list-style:none;margin:0;padding:0}
.off-canvas .menu.solutions .sublinks .sublinks__children a{padding-right:0;color:#7c878e;-webkit-transition:color .25s ease;transition:color .25s ease}
.off-canvas .menu.solutions .sublinks .sublinks__children a::after{content:none}
@media (hover:hover){.off-canvas .menu.solutions .sublinks .sublinks__children a:hover{color:#021b41}}