/* ============================================================
   Central Audit — shared site chrome (header, nav, footer)
   Single source of truth for every page. Loaded AFTER each
   page's inline <style> so its declarations win ties.
   Scoped under .site-header / .site-footer so legacy per-page
   nav/footer rules (dead markup) cannot interfere.
   ============================================================ */

/* Self-hosted fonts. Replaces the Google Fonts <link> (googleapis.com CSS
   -> gstatic.com font file, two extra third-party round-trips) that was on
   every page. Declared once here since site.css loads on every page. */
@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/inter-400.woff2') format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url('fonts/inter-500.woff2') format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url('fonts/inter-600.woff2') format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url('fonts/inter-700.woff2') format('woff2')}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/space-grotesk-400.woff2') format('woff2')}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:500;font-display:swap;src:url('fonts/space-grotesk-500.woff2') format('woff2')}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:600;font-display:swap;src:url('fonts/space-grotesk-600.woff2') format('woff2')}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:700;font-display:swap;src:url('fonts/space-grotesk-700.woff2') format('woff2')}

:root{
  --navy:#0B1120;
  --navy-light:#131B2E;
  --blue:#2563EB;
  --blue-dark:#1D4ED8;
  --blue-soft:#EFF6FF;
  --cyan:#06B6D4;
  --ink:#0F172A;
  --muted:#64748B;
  --line:#E2E8F0;
  --paper:#F8FAFC;
  --white:#FFFFFF;
  --purple:#8B5CF6;
  --display:'Space Grotesk',sans-serif;
  --body:'Inter',sans-serif;
  --ease:cubic-bezier(0.4,0,0.2,1);
}

/* Uniform offset below the fixed header (normalizes per-page drift) */
body{padding-top:100px}
/* Keep in-page anchor targets clear of the fixed header */
html{scroll-padding-top:110px}

/* ---------------- Header ---------------- */
header.site-header{position:fixed;top:18px;left:0;right:0;bottom:auto;z-index:60;pointer-events:none;padding:0;margin:0;background:none;border:none;box-shadow:none}
header.site-header .wrap{pointer-events:none}
header.site-header .sh-outer{pointer-events:auto;border-radius:100px;padding:1px;background:linear-gradient(135deg,rgba(37,99,235,.3),rgba(139,92,246,.3),rgba(37,99,235,.1));position:relative}
.sh-nav{display:flex;align-items:center;justify-content:space-between;gap:24px;height:62px;padding:0 16px 0 24px;
  background:rgba(255,255,255,.7);
  backdrop-filter:blur(20px) saturate(170%);-webkit-backdrop-filter:blur(20px) saturate(170%);
  border-radius:100px;
  box-shadow:0 8px 32px -8px rgba(11,17,32,.18),inset 0 1px 0 rgba(255,255,255,.8);
  transition:background .25s var(--ease),box-shadow .25s var(--ease)}
header.site-header.is-scrolled .sh-nav{background:rgba(255,255,255,.92);box-shadow:0 8px 32px -8px rgba(11,17,32,.24),inset 0 1px 0 rgba(255,255,255,.8)}

.sh-logo{font-family:var(--display);font-weight:700;font-size:21px;letter-spacing:-.01em;color:var(--navy);display:inline-flex;align-items:center;text-decoration:none}
.sh-logo .br{background:linear-gradient(135deg,var(--blue),var(--purple));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;font-weight:600}
.sh-logo .br.l{margin-right:1px}
.sh-logo .br.r{margin-left:1px}

/* Skip link — WCAG 2.4.1. Off-screen until focused, then pinned top-left.
   Every page has a matching #main target carrying tabindex="-1" so focus
   actually lands there rather than only moving the reading position. */
.skip-link{position:absolute;left:-9999px;top:0;z-index:2000;padding:12px 22px;
  background:var(--blue);color:#fff;font-family:var(--body);font-weight:600;font-size:14.5px;
  border-radius:0 0 12px 0;text-decoration:none;box-shadow:0 6px 20px rgba(11,17,32,.22)}
.skip-link:focus{left:0}
#main:focus{outline:none}

/* Tap targets — 44px minimum per Apple HIG / WCAG 2.5.5.
   Text links were roughly 20px tall; padding does the work without
   changing the visual rhythm of the bar. */
.sh-links>a{display:inline-flex;align-items:center;min-height:44px}
.sf-col a,.foot-links a,.sf-legal a{display:inline-block;padding:6px 0;min-height:24px}

.sh-links{display:flex;gap:28px;align-items:center}
.sh-links>a{font-size:14.5px;font-weight:500;color:var(--navy);opacity:.82;text-decoration:none;transition:opacity .2s var(--ease),color .2s var(--ease);position:relative}
.sh-links>a:hover{opacity:1;color:var(--blue)}
.sh-links>a:not(.sh-cta):not(.sh-portal)::after{content:'';position:absolute;bottom:-4px;left:50%;transform:translateX(-50%) scale(0);width:4px;height:4px;border-radius:50%;background:var(--blue);transition:transform .2s var(--ease)}
.sh-links>a:not(.sh-cta):not(.sh-portal):hover::after{transform:translateX(-50%) scale(1)}
.sh-links>a.active{color:var(--blue);opacity:1}

.sh-cta{font-family:var(--body);font-weight:600;font-size:14px;color:#fff!important;background:linear-gradient(135deg,var(--blue),var(--blue-dark));border:none;cursor:pointer;border-radius:100px;padding:10px 20px;text-decoration:none;display:inline-block;opacity:1;box-shadow:0 4px 14px rgba(37,99,235,.3);transition:transform .2s var(--ease),box-shadow .2s var(--ease),background .2s var(--ease);white-space:nowrap}
.sh-cta:hover{transform:translateY(-2px);box-shadow:0 8px 24px rgba(37,99,235,.35);background:linear-gradient(135deg,var(--blue-dark),#1e3a8a)}

/* Secondary CTA — returning clients heading to client.centralaudit.net.
   Outline pill so it reads as a peer of Book a Call without competing with it:
   the primary action stays the only filled button in the header. */
.sh-portal{font-family:var(--body);font-weight:600;font-size:14px;color:var(--navy);background:transparent;border:1.5px solid var(--line);cursor:pointer;border-radius:100px;padding:8.5px 18px;text-decoration:none;display:inline-flex;align-items:center;gap:7px;opacity:1;transition:border-color .2s var(--ease),color .2s var(--ease),background .2s var(--ease),transform .2s var(--ease);white-space:nowrap}
.sh-portal:hover{color:var(--blue);border-color:var(--blue);background:var(--blue-soft);transform:translateY(-2px)}

/* ---------------- Services dropdown ---------------- */
.sh-drop{position:relative;display:flex;align-items:center}
.sh-drop-btn{display:inline-flex;align-items:center;gap:5px;cursor:pointer;background:none;border:none;padding:0;margin:0;font-family:var(--body);font-size:14.5px;font-weight:500;color:var(--navy);opacity:.82;transition:opacity .2s var(--ease),color .2s var(--ease)}
.sh-drop-btn:hover,.sh-drop.open .sh-drop-btn{opacity:1;color:var(--blue)}
.sh-drop-btn.active{color:var(--blue);opacity:1}
.sh-drop-btn svg{width:12px;height:12px;transition:transform .2s var(--ease)}
.sh-drop.open .sh-drop-btn svg{transform:rotate(180deg)}
.sh-drop-menu{position:absolute;top:calc(100% + 14px);left:50%;transform:translateX(-50%) translateY(-6px);background:var(--white);border:1.5px solid var(--line);border-radius:14px;padding:14px 4px;display:flex;align-items:flex-start;box-shadow:0 8px 32px rgba(11,17,32,.14);z-index:100;
  visibility:hidden;opacity:0;pointer-events:none;
  transition:opacity .18s var(--ease),transform .18s var(--ease),visibility 0s linear .18s}
.sh-drop.open .sh-drop-menu{visibility:visible;opacity:1;pointer-events:auto;transform:translateX(-50%) translateY(0);transition:opacity .18s var(--ease),transform .18s var(--ease)}
/* invisible hover bridge so the pointer never falls in a gap */
.sh-drop-menu::before{content:'';position:absolute;top:-14px;left:0;right:0;height:14px}
.sh-drop-col{display:flex;flex-direction:column;padding:0 16px;min-width:200px}
.sh-drop-col+.sh-drop-col{border-left:1px solid var(--line)}
.sh-drop-menu a{display:block;padding:9px 12px;border-radius:9px;font-size:13.5px;font-weight:500;color:var(--navy);text-decoration:none;white-space:nowrap;transition:background .15s,color .15s}
.sh-drop-menu a:hover,.sh-drop-menu a:focus-visible{background:var(--blue-soft);color:var(--blue)}
.sh-drop-label{display:block;padding:4px 12px 8px;font-family:var(--display);font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}

/* ---------------- Burger (hidden on desktop) ---------------- */
.sh-burger{display:none;width:44px;height:44px;border:none;background:none;cursor:pointer;border-radius:12px;padding:0;align-items:center;justify-content:center;flex-shrink:0}
.sh-burger span{display:block;width:20px;height:2px;border-radius:2px;background:var(--navy);position:relative;transition:background .2s var(--ease)}
.sh-burger span::before,.sh-burger span::after{content:'';position:absolute;left:0;width:20px;height:2px;border-radius:2px;background:var(--navy);transition:transform .25s var(--ease),top .25s var(--ease)}
.sh-burger span::before{top:-6px}
.sh-burger span::after{top:6px}
.sh-burger[aria-expanded="true"] span{background:transparent}
.sh-burger[aria-expanded="true"] span::before{top:0;transform:rotate(45deg)}
.sh-burger[aria-expanded="true"] span::after{top:0;transform:rotate(-45deg)}

/* ---------------- Mobile menu panel ---------------- */
.sh-backdrop{position:fixed;inset:0;background:rgba(11,17,32,.4);z-index:55;opacity:0;visibility:hidden;transition:opacity .22s var(--ease),visibility 0s linear .22s;pointer-events:none}
.sh-backdrop.open{opacity:1;visibility:visible;pointer-events:auto;transition:opacity .22s var(--ease)}
.sh-mobile{display:none;position:fixed;z-index:58;top:78px;left:12px;right:12px;max-height:calc(100dvh - 92px);overflow-y:auto;-webkit-overflow-scrolling:touch;
  background:var(--white);border:1px solid var(--line);border-radius:20px;box-shadow:0 24px 64px -16px rgba(11,17,32,.35);
  padding:10px 8px 14px;
  opacity:0;visibility:hidden;transform:translateY(-8px);
  transition:opacity .22s var(--ease),transform .22s var(--ease),visibility 0s linear .22s}
.sh-mobile.open{opacity:1;visibility:visible;transform:translateY(0);transition:opacity .22s var(--ease),transform .22s var(--ease)}
.sh-mobile a{display:block;padding:13px 16px;font-family:var(--body);font-size:15.5px;font-weight:500;color:var(--ink);text-decoration:none;border-radius:12px}
.sh-mobile a:hover,.sh-mobile a:focus-visible{background:var(--blue-soft);color:var(--blue)}
.sh-mobile a.active{color:var(--blue);background:var(--blue-soft)}
.sh-acc-btn{display:flex;align-items:center;justify-content:space-between;width:100%;padding:13px 16px;background:none;border:none;cursor:pointer;font-family:var(--body);font-size:15.5px;font-weight:500;color:var(--ink);border-radius:12px;text-align:left}
.sh-acc-btn:hover{background:var(--blue-soft);color:var(--blue)}
.sh-acc-btn svg{width:14px;height:14px;transition:transform .22s var(--ease);flex-shrink:0}
.sh-acc.open .sh-acc-btn svg{transform:rotate(180deg)}
.sh-acc-panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .25s var(--ease)}
.sh-acc.open .sh-acc-panel{grid-template-rows:1fr}
.sh-acc-inner{overflow:hidden;min-height:0}
.sh-acc-inner a{padding:11px 16px 11px 28px;font-size:14.5px;color:var(--muted)}
.sh-acc-inner a:hover{color:var(--blue)}
.sh-mobile-ctas{display:grid;grid-template-columns:1fr 1fr;gap:10px;padding:12px 8px 4px;border-top:1px solid var(--line);margin-top:8px}
.sh-mobile-ctas a{text-align:center;font-weight:600;font-size:14.5px;padding:13px 10px;border-radius:12px}
.sh-mobile-ctas .m-ghost{border:1.5px solid var(--line);color:var(--navy)}
.sh-mobile-ctas .m-ghost:hover{border-color:var(--blue);color:var(--blue);background:var(--blue-soft)}
.sh-mobile-ctas .m-primary{background:linear-gradient(135deg,var(--blue),var(--blue-dark));color:#fff;box-shadow:0 4px 14px rgba(37,99,235,.3)}
.sh-mobile-ctas .m-primary:hover{background:linear-gradient(135deg,var(--blue-dark),#1e3a8a);color:#fff}
/* My Portal sits on its own full-width row above the two conversion CTAs, so
   the grid stays a tidy 1 + 2 rather than three uneven halves. */
.sh-mobile-ctas .m-portal{grid-column:1/-1;border:1.5px solid var(--line);color:var(--navy);display:inline-flex;align-items:center;justify-content:center;gap:7px}
.sh-mobile-ctas .m-portal:hover{border-color:var(--blue);color:var(--blue);background:var(--blue-soft)}
body.sh-locked{overflow:hidden}

/* ---------------- Header responsive ---------------- */
@media(max-width:880px){
  body{padding-top:88px}
  html{scroll-padding-top:96px}
  header.site-header{top:12px}
  .sh-nav{height:56px;padding:0 8px 0 18px;gap:12px}
  .sh-logo{font-size:19px}
  /* desktop links collapse into the burger menu */
  .sh-links{gap:10px}
  .sh-links>a:not(.sh-cta),.sh-drop{display:none}
  .sh-burger{display:inline-flex}
  .sh-mobile{display:block}
  .sh-cta{padding:9px 16px;font-size:13.5px}
  /* solid header on mobile: glass over dark heroes hurts contrast */
  .sh-nav{background:rgba(255,255,255,.94)}
}
@media(max-width:620px){
  body{padding-top:84px}
  header.site-header{top:10px;left:0;right:0}
  header.site-header .wrap{padding:0 12px}
  .sh-mobile{top:74px;left:10px;right:10px}
}
@media(max-width:480px){
  body{padding-top:82px}
  .sh-nav{height:54px}
  .sh-cta{padding:9px 14px;font-size:13px}
  .sh-mobile{top:72px}
}
@media(min-width:881px){
  .sh-mobile,.sh-backdrop,.sh-burger{display:none!important}
}

/* ---------------- Footer ---------------- */
footer.site-footer{padding:0;position:relative;margin:0}
footer.site-footer::before{content:none}
.sf-in{background:var(--navy);padding:56px 0 0;color:#9FADC2;position:relative;overflow:hidden}
.sf-in::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent,var(--blue),var(--purple),var(--cyan),transparent)}
.sf-grid{display:grid;grid-template-columns:1.3fr 1fr 1fr 1.05fr;gap:40px;padding-bottom:44px}
.sf-brand .sh-logo{color:#fff;margin-bottom:14px}
.sf-brand .sh-logo .br{-webkit-text-fill-color:transparent;background:linear-gradient(135deg,#60a5fa,#a78bfa);-webkit-background-clip:text;background-clip:text}
.sf-brand p{font-size:13.5px;color:#CDD6E2;margin:0 0 4px;line-height:1.55}
.sf-brand .sf-addr{font-size:13px;color:#9FADC2;margin-bottom:16px}
.sf-brand a{color:#CDD6E2;text-decoration:none;transition:color .2s var(--ease)}
.sf-brand a:hover{color:#fff}
.sf-socials{display:flex;gap:12px}
.sf-socials a{width:38px;height:38px;border-radius:10px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);display:flex;align-items:center;justify-content:center;transition:background .2s var(--ease),border-color .2s var(--ease)}
.sf-socials a:hover{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.25)}
.sf-socials svg{width:16px;height:16px;stroke:#B7C2D4;fill:none;stroke-width:2}
.sf-head{font-family:var(--display);font-size:13px;font-weight:600;color:#fff;letter-spacing:.06em;text-transform:uppercase;margin:0 0 7px}
.sf-col{display:flex;flex-direction:column;gap:11px;font-size:14px}
.sf-col a{color:#9FADC2;text-decoration:none;transition:color .2s var(--ease);width:fit-content}
.sf-col a:hover{color:#fff}
.sf-sub{font-family:var(--display);font-size:12px;font-weight:600;color:#94A3B8;text-transform:uppercase;letter-spacing:.05em;margin:14px 0 -3px}
.sf-bottom{border-top:1px solid rgba(255,255,255,.08);padding:22px 0;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:14px}
.sf-bottom p{font-size:13px;color:#94A3B8;margin:0}
.sf-legal{display:flex;gap:20px;font-size:13px;flex-wrap:wrap}
.sf-legal a{color:#94A3B8;text-decoration:none;transition:color .2s var(--ease)}
.sf-legal a:hover{color:#fff}

/* Footer responsive — class-based, so it actually collapses */
@media(max-width:980px){
  .sf-grid{grid-template-columns:1fr 1fr;gap:36px 28px}
  .sf-brand{grid-column:1/-1}
}
@media(max-width:560px){
  .sf-in{padding:44px 0 0}
  .sf-grid{grid-template-columns:1fr;gap:32px;padding-bottom:36px}
  .sf-col a{padding:2px 0}
  .sf-bottom{flex-direction:column;align-items:flex-start;gap:10px}
}

/* ---------------- Accessibility / motion ---------------- */
.site-header a:focus-visible,.site-header button:focus-visible,.site-footer a:focus-visible{outline:2px solid var(--blue);outline-offset:3px;border-radius:6px}
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  .site-header *,.sh-mobile,.sh-backdrop,.site-footer *{transition-duration:.01ms!important;animation-duration:.01ms!important}
}

/* ---------------- Cookie consent ---------------- */
.ca-consent{position:fixed;left:16px;right:16px;bottom:16px;z-index:200;max-width:520px;margin:0 auto;background:var(--navy);color:#E2E8F0;border-radius:14px;padding:16px 18px;box-shadow:0 12px 40px rgba(11,17,32,.35);display:flex;gap:14px;align-items:center;flex-wrap:wrap;font-family:var(--body);font-size:13.5px;line-height:1.5}
.ca-consent p{margin:0;flex:1 1 260px}
.ca-consent a{color:var(--cyan);text-decoration:underline}
.ca-consent-btns{display:flex;gap:8px}
.ca-consent button{font-family:var(--body);font-weight:600;font-size:13px;border-radius:100px;padding:8px 16px;cursor:pointer;border:1.5px solid transparent}
.ca-consent-accept{background:linear-gradient(135deg,var(--blue),var(--blue-dark));color:#fff;border:none}
.ca-consent-decline{background:none;color:#CBD5E1;border-color:#334155}
.ca-consent-decline:hover{color:#fff;border-color:#64748B}

/* ---------------- Accessibility hardening (audit P1-2, P2-3, P2-4) ---------------- */

/* P1-2 — white text on --green #10B981 computes to 2.54:1, well under the 4.5:1
   floor. This darker green gives 5.4:1 with white while staying on-brand.
   Use --green-solid wherever white sits on green; keep --green for tints/fills
   where nothing is layered on top. */
:root{--green-solid:#047857}

/* P2-3 — the site runs 27 infinite animations. Four reduced-motion blocks
   existed and correctly covered the logo reel, but decorative twinkle/spin/
   pulse/sweep kept running. This catches everything that was missed. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.01ms!important;
    animation-iteration-count:1!important;
    transition-duration:.01ms!important;
    scroll-behavior:auto!important;
  }
}

/* P2-4 — WCAG 2.2.2: motion running over 5s needs a pause mechanism.
   Reduced-motion only helps users who set the OS flag; this covers everyone
   else by pausing the marquee on hover or keyboard focus. */
.h-track:hover,.h-track:focus-within,
.reel-track:hover,.reel-track:focus-within{animation-play-state:paused}

/* ---------------- Breadcrumbs (audit P3) ----------------
   Scoped to .site-breadcrumb so the glossary's own .breadcrumb rules, which
   load before this file, keep their existing look rather than being overridden.
   Trails are generated from each page's BreadcrumbList schema, so the visible
   path and the structured data cannot drift apart. */
.site-breadcrumb{padding:14px 0 0;font-size:13.5px;color:var(--muted)}
.site-breadcrumb a{color:var(--blue);font-weight:500;text-decoration:none;display:inline-block;padding:5px 0;min-height:24px;transition:color .2s var(--ease)}
.site-breadcrumb a:hover{color:var(--blue-dark)}
.site-breadcrumb .sep{margin:0 8px;opacity:.5}
.site-breadcrumb span:last-child{color:var(--ink)}
@media(max-width:620px){
  .site-breadcrumb{font-size:12.5px}
  .site-breadcrumb .sep{margin:0 5px}
}

/* Visually-hidden utility — used by the search page's field label and any
   other control that needs an accessible name without visible text. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ============================================================================
   FLASHY CTA SYSTEM
   ----------------------------------------------------------------------------
   Every call-to-action on the site, unified into one silhouette and one set of
   micro-interactions. Loaded last, so it wins on equal specificity against the
   per-page button rules without any of them needing to be edited.

   Four things happen on hover, in this order of visibility:
     1. the gradient travels    (background-position, 220% wide)
     2. a specular sheen sweeps across   (::after, skewed highlight)
     3. the glow blooms         (layered coloured shadow)
     4. the button lifts        (spring easing with a slight overshoot)

   The overshoot is what makes it feel alive rather than mechanical —
   cubic-bezier(.34,1.56,.64,1) passes its target and settles back.

   Accessibility is preserved throughout: contrast is unchanged (white on the
   same blue gradient, 5.17:1), focus rings are explicit and high-contrast, and
   the blanket prefers-reduced-motion rule above neutralises all of it.
   ============================================================================ */

:root{
  --cta-spring:cubic-bezier(.34,1.56,.64,1);
  --cta-smooth:cubic-bezier(.4,0,.2,1);
  --cta-radius:12px;
}

/* ---- shared shell: primary, secondary and nav CTAs alike ---- */
.btn,.btn-primary,.btn-ghost,.btn-white,.btn-outline,.btn-secondary,
.sh-cta,.sh-portal,.sh-mobile-ctas a,.tool-btn,.res-cta,.hub-cta{
  position:relative;
  isolation:isolate;                 /* keeps the sheen under the label */
  overflow:hidden;
  transform:translateZ(0);           /* stable paint layer, no hover flicker */
  transition:transform .28s var(--cta-spring),
             box-shadow .3s var(--cta-smooth),
             background-position .5s var(--cta-smooth),
             border-color .25s var(--cta-smooth),
             color .25s var(--cta-smooth);
}

/* the label and any icon must ride above the sheen */

/* ---- specular sweep ---- */
.btn::after,.btn-primary::after,.btn-white::after,.btn-outline::after,
.sh-cta::after,.sh-portal::after,.sh-mobile-ctas a::after,.tool-btn::after{
  content:'';
  position:absolute;
  top:-60%;
  left:-75%;
  width:45%;
  height:220%;
  z-index:-1;                        /* below the label, above the background */
  pointer-events:none;
  background:linear-gradient(100deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,.42) 50%,
    rgba(255,255,255,0) 100%);
  transform:skewX(-22deg);
  transition:left .62s var(--cta-smooth);
}
.btn:hover::after,.btn-primary:hover::after,.btn-white:hover::after,
.btn-outline:hover::after,.sh-cta:hover::after,.sh-portal:hover::after,
.sh-mobile-ctas a:hover::after,.tool-btn:hover::after,
.btn:focus-visible::after,.btn-primary:focus-visible::after,
.sh-cta:focus-visible::after{left:135%}

/* the sheen is white — on light-background buttons dial it right down */
.btn-ghost::after,.sh-portal::after,.m-ghost::after,.m-portal::after{
  background:linear-gradient(100deg,
    rgba(37,99,235,0) 0%,
    rgba(37,99,235,.14) 50%,
    rgba(37,99,235,0) 100%);
}

/* ---- primary: travelling gradient + blooming glow ---- */
.btn-primary,.sh-cta,.sh-mobile-ctas .m-primary,.tool-btn{
  /* Every stop clears 4.5:1 against white, checked individually — the brand
     --purple (#8B5CF6, 4.23:1) and a lighter blue (#4F7DF5, 3.76:1) were both
     tried first and both failed for label-sized text. These keep the same
     blue-to-violet travel while staying AA at any point in the sweep. */
  background-image:linear-gradient(120deg,
    var(--blue) 0%,      /* 5.17:1 */
    #4F46E5 24%,         /* 6.29:1 */
    #7C3AED 50%,         /* 5.70:1 */
    #4F46E5 76%,         /* 6.29:1 */
    var(--blue-dark) 100%); /* 6.70:1 */
  background-size:220% 100%;
  background-position:0% 50%;
  box-shadow:0 4px 14px rgba(37,99,235,.30),
             inset 0 1px 0 rgba(255,255,255,.22);
}
.btn-primary:hover,.sh-cta:hover,.sh-mobile-ctas .m-primary:hover,.tool-btn:hover{
  /* Page CSS declares the `background` SHORTHAND on :hover, which silently
     resets background-image and background-size back to their defaults and
     kills the travel. Re-declaring both here is what keeps the sweep alive.
     Inverted CTAs (.final .btn-primary, white on a dark band) guard themselves
     with !important and are deliberately left alone. */
  background-image:linear-gradient(120deg,
    var(--blue) 0%,#4F46E5 24%,#7C3AED 50%,#4F46E5 76%,var(--blue-dark) 100%);
  background-size:220% 100%;
  background-position:100% 50%;
  transform:translateY(-3px);
  box-shadow:0 10px 30px -4px rgba(37,99,235,.48),
             0 0 26px -6px rgba(139,92,246,.55),
             inset 0 1px 0 rgba(255,255,255,.30);
}

/* ---- secondary / ghost: gradient edge lights up ---- */
.btn-ghost:hover,.btn-outline:hover,.sh-portal:hover,
.sh-mobile-ctas .m-ghost:hover,.sh-mobile-ctas .m-portal:hover{
  transform:translateY(-3px);
  border-color:var(--blue);
  box-shadow:0 8px 24px -6px rgba(37,99,235,.30),
             inset 0 0 0 1px rgba(37,99,235,.10);
}

/* ---- press: settle, don't bounce ---- */
.btn:active,.btn-primary:active,.btn-ghost:active,.btn-white:active,
.btn-outline:active,.sh-cta:active,.sh-portal:active,
.sh-mobile-ctas a:active,.tool-btn:active{
  transform:translateY(-1px) scale(.985);
  transition-duration:.09s;
}

/* ---- icons lead the eye forward ---- */
.btn svg,.btn-primary svg,.sh-cta svg,.res-cta svg,.hub-cta svg{
  transition:transform .3s var(--cta-spring);
}
.btn:hover svg,.btn-primary:hover svg,.sh-cta:hover svg,
.res-cta:hover svg,.hub-cta:hover svg{transform:translateX(4px)}

/* ---- focus: unmissable, and never removed ---- */
.btn:focus-visible,.btn-primary:focus-visible,.btn-ghost:focus-visible,
.btn-white:focus-visible,.btn-outline:focus-visible,.sh-cta:focus-visible,
.sh-portal:focus-visible,.sh-mobile-ctas a:focus-visible,.tool-btn:focus-visible{
  outline:3px solid var(--cyan);
  outline-offset:3px;
  box-shadow:0 10px 30px -4px rgba(37,99,235,.45);
}

/* ---- one silhouette: same corner on every button ---- */
.btn,.btn-primary,.btn-ghost,.btn-white,.btn-outline,.btn-secondary,.tool-btn{
  border-radius:var(--cta-radius);
}
/* nav CTAs stay pills — that shape is doing brand work in the header */
.sh-cta,.sh-portal{border-radius:100px}

/* ---- optical alignment ----------------------------------------------------
   .btn was display:inline-block on 34 pages. Any icon inside then sits on the
   text baseline and rides visibly low — the eye reads it as "slightly off"
   without being able to name why. Flex centring fixes it everywhere, and the
   gap replaces the ad-hoc margins icons were using. */
.btn,.btn-primary,.btn-ghost,.btn-white,.btn-outline,.btn-secondary,
.sh-cta,.tool-btn,.res-cta,.hub-cta{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  line-height:1.2;
  text-align:center;
  vertical-align:middle;
}
/* Flex centring already fixes the baseline drift, so icons keep whatever size
   their page set — overriding that in em silently shrank the 18px icons. */
.btn svg,.btn-primary svg,.sh-cta svg,.btn-ghost svg,.btn-white svg{flex-shrink:0}

/* ---- cursor spotlight ------------------------------------------------------
   A soft highlight that tracks the pointer across primary CTAs. Coordinates
   come from site.js as --mx/--my; with no JS the gradient simply centres and
   nothing looks broken. Pointer-only, so touch devices skip the work. */
@media (hover:hover) and (pointer:fine){
  .btn-primary::before,.sh-cta::before,.tool-btn::before,
  .sh-mobile-ctas .m-primary::before{
    content:'';
    position:absolute;
    inset:0;
    z-index:-1;                      /* same reason as the sheen above */
    opacity:0;
    pointer-events:none;
    background:radial-gradient(170px circle at var(--mx,50%) var(--my,50%),
      rgba(255,255,255,.30), transparent 62%);
    transition:opacity .35s var(--cta-smooth);
  }
  .btn-primary:hover::before,.sh-cta:hover::before,
  .tool-btn:hover::before,.sh-mobile-ctas .m-primary:hover::before{opacity:1}
}

/* ---- the one CTA that breathes ---------------------------------------------
   Reserved for the hero's primary action only. A page where everything pulses
   has no hierarchy; a single breathing element pulls the eye exactly once.
   Stops permanently on hover so it never fights the hover state. */
@keyframes ctaBreathe{
  0%,100%{box-shadow:0 4px 14px rgba(37,99,235,.30),0 0 0 0 rgba(37,99,235,.36),inset 0 1px 0 rgba(255,255,255,.22)}
  50%    {box-shadow:0 6px 20px rgba(37,99,235,.38),0 0 0 12px rgba(37,99,235,0),inset 0 1px 0 rgba(255,255,255,.22)}
}
/* Four beats, then it settles — deliberately finite. A CTA that pulses forever
   stops being a signal and becomes wallpaper, and indefinite motion also drags
   WCAG 2.2.2 into scope. Four passes catch the eye on arrival and then get out
   of the way. */
.hero .btn-primary,#auditBtn{animation:ctaBreathe 3.4s var(--cta-smooth) 4}
.hero .btn-primary:hover,#auditBtn:hover{animation:none}

/* ---- form controls share the button's corner --------------------------------
   Inputs were sitting at 9px, 10px and 14px depending on the page, next to
   buttons at 12px. Inside a single form that mismatch is one of the few
   inconsistencies the eye catches unprompted, so they are unified here.
   The focus ring matches the CTA focus treatment for the same reason. */
.field input,.field textarea,.field select,
.nl-form input,.search-wrap input,.find input,.pane-search input,#sq{
  border-radius:var(--cta-radius);
  transition:border-color .22s var(--cta-smooth),
             box-shadow .22s var(--cta-smooth),
             background .22s var(--cta-smooth);
}
.field input:focus,.field textarea:focus,.field select:focus,
.nl-form input:focus,.search-wrap input:focus,.find input:focus,#sq:focus{
  outline:none;
  border-color:var(--blue);
  box-shadow:0 0 0 4px rgba(37,99,235,.13);
}
/* keyboard users still get a visible ring even where a page removes the border */
.field input:focus-visible,.field textarea:focus-visible,
.field select:focus-visible,#sq:focus-visible{
  outline:2px solid var(--blue);
  outline-offset:2px;
}

/* ---- links: the underline grows from the left, it doesn't just appear ------- */
.sr-empty a,.help a,.fallback a,.sf-col a,.foot-links a{
  background-image:linear-gradient(currentColor,currentColor);
  background-size:0% 1.5px;
  background-position:0 100%;
  background-repeat:no-repeat;
  text-decoration:none;
  transition:background-size .3s var(--cta-smooth),color .22s var(--cta-smooth);
}
.sr-empty a:hover,.help a:hover,.fallback a:hover,
.sf-col a:hover,.foot-links a:hover{background-size:100% 1.5px}

/* ---- cards lift as one family ---------------------------------------------
   Card hovers were defined per page with different distances and shadows.
   One shared curve makes the whole site feel like it was built by one hand. */
.res-card,.guide-item,.cs-card,.agg-card,.founder-card,.audit-card,
.who-card,.diff-card,.related-card,.sm-group{
  transition:transform .32s var(--cta-spring),
             box-shadow .32s var(--cta-smooth),
             border-color .32s var(--cta-smooth);
}
.res-card:hover,.guide-item:hover,.cs-card:hover,.agg-card:hover,
.audit-card:hover,.who-card:hover,.diff-card:hover,.related-card:hover{
  transform:translateY(-4px);
  box-shadow:0 14px 34px -12px rgba(11,17,32,.22);
}


/* ---- inverted CTAs ---------------------------------------------------------
   White buttons on the dark closing bands. A white sheen on a white button is
   invisible, so these get a blue-tinted sweep and a cool-toned glow instead.
   Their background is guarded by !important upstream and stays untouched. */
.final .btn-primary::after,.btn-white::after,.final .btn-primary::before{
  background:linear-gradient(100deg,
    rgba(37,99,235,0) 0%,
    rgba(37,99,235,.16) 50%,
    rgba(37,99,235,0) 100%);
}
.final .btn-primary:hover,.btn-white:hover{
  transform:translateY(-3px);
  box-shadow:0 12px 30px -6px rgba(0,0,0,.28),
             0 0 22px -8px rgba(255,255,255,.55);
}
/* ghost buttons sitting on dark bands need a light edge, not a blue one */
.final .btn-ghost:hover,.final .btn-outline:hover,.final .btn-outline-w:hover{
  border-color:rgba(255,255,255,.85);
  background:rgba(255,255,255,.12);
  box-shadow:0 10px 26px -8px rgba(0,0,0,.35);
}

/* ============================================================================
   CRAFT LAYER
   The details nobody names but everybody feels. Each is a small thing; the
   sum is the difference between "fine" and "considered".
   ============================================================================ */

/* ---- typographic ragging ---------------------------------------------------
   text-wrap:balance evens the line lengths of a heading so you never get a
   single orphaned word on the last line — the most common thing that makes an
   otherwise good headline look accidental. `pretty` does the lighter version
   for body copy. Both are ignored by browsers that don't support them, so
   there is no fallback to write. */
h1,h2,h3,.hero h1,.card h1,.sm-group h2{text-wrap:balance}
p,li,.sub,.sm-sub,.sr-desc{text-wrap:pretty}

/* ---- selection ------------------------------------------------------------
   The default browser selection is a flat system blue that clashes with any
   brand. Two lines to make highlighting feel like part of the site. */
::selection{background:rgba(37,99,235,.22);color:var(--navy)}
::-moz-selection{background:rgba(37,99,235,.22);color:var(--navy)}

/* ---- scrollbar ------------------------------------------------------------
   Slim, brand-tinted, and it darkens on hover so it reads as interactive.
   Firefox gets the standard property, WebKit the pseudo-elements. */
html{scrollbar-width:thin;scrollbar-color:#C3CEDF transparent}
::-webkit-scrollbar{width:11px;height:11px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{
  background:#C3CEDF;
  border-radius:100px;
  border:3px solid var(--white);   /* inset look, no extra markup */
}
::-webkit-scrollbar-thumb:hover{background:var(--muted)}

/* ---- a focus ring on everything, not just buttons -------------------------
   Anything focusable that hasn't been given its own treatment still gets a
   visible, high-contrast ring. Keyboard users never hit a dead end. */
a:focus-visible,button:focus-visible,summary:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible{
  outline:3px solid var(--blue);
  outline-offset:2px;
  border-radius:4px;
}
/* on dark bands the blue ring disappears — switch to cyan there */
.lens a:focus-visible,.final a:focus-visible,.site-footer a:focus-visible,
.lens button:focus-visible,.final button:focus-visible{
  outline-color:var(--cyan);
}

/* ---- media never breaks a layout ------------------------------------------ */
img,svg,video{max-width:100%}
img{height:auto}

/* ---- deliberately NOT clipping overflow globally ---------------------------
   The obvious move here is html,body{overflow-x:clip} to guarantee no sideways
   scroll. It is not safe on this site: the 122 glossary pages use
   position:sticky for .docs-bar and .pane-l, and an overflow value on an
   ancestor is exactly what stops sticky from sticking. 34 pages already set
   body{overflow-x:hidden} locally where they need it, which is the correct
   scope. Overflow is fixed at its source, not clipped globally. */

/* ---- numbers that don't jitter --------------------------------------------
   Tabular figures stop stat counters and prices shifting width as digits
   change — very visible on anything animated. */
.stat-num,.dash-metric-change,.sm-count,.final-price,.tier-badge{
  font-variant-numeric:tabular-nums;
}

/* ---- print ----------------------------------------------------------------
   Audit clients do print these pages. Drop the chrome, keep the content, and
   expose link targets so a printed page is still useful. */
@media print{
  .site-header,.sh-mobile,.sh-backdrop,.skip-link,.site-footer,
  .ca-consent,.h-track,.glow{display:none!important}
  body{padding-top:0}
  a[href^="http"]::after{content:" (" attr(href) ")";font-size:11px;color:#555}
  .btn,.btn-primary{box-shadow:none!important;background:none!important;color:#000!important;border:1px solid #999}
  *{animation:none!important;transition:none!important}
}

/* ---- card hover family, extended ------------------------------------------
   The service pages defined their own hover on these four components with three
   different travel distances (-3px, -4px, translateX(6px)). Folding them into
   the shared curve removes that divergence. */
.check-item,.deliv-item,.stat-card,.deliverable-item{
  transition:transform .32s var(--cta-spring),
             box-shadow .32s var(--cta-smooth),
             border-color .32s var(--cta-smooth);
}
.check-item:hover,.deliv-item:hover,.stat-card:hover,.deliverable-item:hover{
  transform:translateY(-4px);
  box-shadow:0 14px 34px -12px rgba(11,17,32,.22);
}

/* ---- breadcrumb alignment guard -------------------------------------------
   The injected trail becomes the first child of each page's hero <section>.
   Most heroes are text-align:center, so the breadcrumb INHERITED that centring
   and rendered as a stray centred line floating above the eyebrow instead of a
   trail sitting on the content column. A direct declaration always beats an
   inherited value, so this one line corrects every affected page at once.
   Pages that legitimately centre their own .breadcrumb are unaffected — this
   is scoped to .site-breadcrumb only. */
.site-breadcrumb{text-align:left}

/* Where the trail landed inside a container that is already a .wrap, the inner
   wrap doubled the 28px gutter and pushed the trail off the page's left rail. */
.wrap .site-breadcrumb>.wrap{max-width:none;padding-left:0;padding-right:0}

/* ---- CTA on a dark band ----------------------------------------------------
   The blog posts' closing CTA sits on a navy panel. Its buttons were inline-
   styled (no hover, no focus ring); converted to classes, they need a light
   treatment because the standard blue-on-navy edge is too low-contrast to read
   as a boundary. White at 15% over navy gives a 3:1+ surface edge, and the
   focus ring switches to cyan since blue disappears against navy. */
.btn-onnavy{
  background:rgba(255,255,255,.15);
  color:#fff;
  border:1.5px solid rgba(255,255,255,.45);
}
.btn-onnavy:hover{
  background:rgba(255,255,255,.26);
  border-color:rgba(255,255,255,.85);
  color:#fff;
  transform:translateY(-3px);
  box-shadow:0 10px 26px -8px rgba(0,0,0,.45);
}
.btn-onnavy:focus-visible{outline:3px solid var(--cyan);outline-offset:3px}
/* the shared sheen is white and would vanish on a light-ish translucent fill —
   keep it, but soften so it reads as a sweep rather than a flash */
.btn-onnavy::after{
  background:linear-gradient(100deg,
    rgba(255,255,255,0) 0%,rgba(255,255,255,.22) 50%,rgba(255,255,255,0) 100%);
}
/* .btn-white sits on the same dark band; give it a matching cyan focus ring */
.btn-white:focus-visible{outline:3px solid var(--cyan);outline-offset:3px}
