/* ==========================================================================
   SHARED PAGE CHROME — nav bar, mobile menu, skip link, screen-reader helper.
   ==========================================================================
   Every one of these used to be pasted into all fourteen pages by hand, and
   that is what produced a week of defects that only showed on some of them:
   a nav with no background where --white was undeclared, links at 1.74:1
   where the recolour reached one file, and a mobile menu that rendered
   permanently open on the nine pages that shipped its markup and JS but not
   its CSS. One file, linked everywhere, so a nav fix is one edit again.

   It depends on these tokens being declared by the page: --white --paper
   --line --ink --ink-soft --navy --nav-bg --coral --coral-deep --head --t3
   --r-sm --e2 --t-fast --blue.
   ==========================================================================
   CACHE: the pages link this as chrome.css?v=<sha1 prefix of this file>. Edit
   the file and the query string must be regenerated, or every browser that has
   seen it keeps the old one -- which cost two debugging rounds: a nav with no
   background and a scroll-margin that "did not apply", both of them stale
   copies rather than broken CSS.
   ========================================================================== */

/* The bar height is stated once and everything that has to clear it reads it.
   The rest are DEFAULTS: a page that declares its own wins, because its inline
   <style> comes after this link. Declaring them here means this file cannot be
   broken by a page that never had the token -- which is exactly how the nav
   lost its background on three pages and its CTA hover on nine. */
:root{
  --nav-h:64px; --nav-rule:3px;
  /* ── ONE ELEVATION SCALE ────────────────────────────────────────────────
     Inventory before this: 17 distinct drop-shadow recipes across the site, in
     four different tints -- rgba(0,0,0,..), rgba(32,72,176,..), rgba(20,38,79,..)
     and rgba(30,58,138,..) -- which is four light sources in one room, and two
     of them pure black in a navy palette. The homepage had a proper e1/e2/e3
     ladder and never shared it; eleven pages had no lifted surface at all.
     One light, tinted navy, and the ratios stay physically plausible: as a
     thing rises its shadow softens, travels further and lightens its contact. */
  --e1:0 1px 2px rgba(20,38,79,.04), 0 4px 12px -4px rgba(20,38,79,.08);
  --e2:0 2px 4px rgba(20,38,79,.05), 0 12px 28px -12px rgba(20,38,79,.14);
  --e3:0 2px 6px rgba(20,38,79,.06), 0 24px 64px -24px rgba(20,38,79,.26);
  --e4:0 4px 10px rgba(20,38,79,.07), 0 40px 88px -32px rgba(20,38,79,.32);
  /* four roles, four radii */
  --r-xs:6px;
  --r-sm:10px;
  --r-md:16px;
  --r-lg:24px;
  --r-pill:999px;

  /* ── THE SPACING SCALE ──────────────────────────────────────────────────
     Thirteen steps, and it lived in a <style> block on ONE page. about and
     register hand-copied 7 of the 13 — and crucially not the mobile re-step,
     which is why they never breathed differently on a phone. The other eleven
     pages had no scale at all and hard-coded everything, so at 768px the site
     ran section rhythms of 128, 96, 69 and 52 simultaneously. */
  --s1:4px;  --s2:8px;   --s3:12px; --s4:16px; --s5:20px; --s6:24px;
  --s7:32px; --s8:40px;  --s9:48px; --s10:56px; --s11:72px; --s12:96px;
  --s13:128px;

  /* ── THE TYPE SCALE ─────────────────────────────────────────────────────
     Text ladder and display ladder, a perfect fourth apart. Same story: one
     page had it, thirteen declared a handful of tokens and then wrote literals
     anyway (pricing referenced ONE of the seven it declared), which is how 37
     distinct rendered sizes happen. */
  --t1:12.5px; --t2:14px;  --t3:15.5px; --t4:17.5px; --t5:19.5px; --t6:22px;
  /* The display end. Phase 4 found SIX different sizes for one role — the page H1 —
     ranging 50px to 57px at the top, plus four more for section H2. The hero keeps its
     own size (--d5) and stays the only element on step 6; everything below it steps
     down through these two. */
  /* THESE TWO WERE WRITTEN AS `--fs-h1:var(--fs-h1)` — a custom property that
     names itself is cyclic, so it is guaranteed-invalid and resolves to nothing.
     --fs-h2 was rescued by the real declaration three lines below; --fs-h1 never
     was, so from the day this ladder shipped SEVEN pages rendered their H1 at
     the inherited body size — /about, /pricing, /methodology, /security,
     /register, /insights and /sample-board-pack all measured 17.5px at 1440.
     /trust and /contact escaped only because they wrote var(--fs-h1,clamp(…)),
     whose fallback fired — which is the proof the token was never set. Found
     2026-09-10 measuring a new page's masthead against /about's. The display
     step is --d4, the one below the hero's --d5. */
  --fs-h1:clamp(34px,4.4vw,57px);
  --d1:24px;   --d2:32px;  --d3:43px;   --d4:57px;   --d5:76px;
  --fs-body:15.5px;
  --fs-lede:clamp(17px,1.7vw,19.5px);
  --fs-h2:clamp(26px,3.6vw,44px);
  --fs-h3:19.5px;

  /* Tracking is a property of the STEP, not of the page: eight pages applied one
     blanket value across a 3x size range, so display type was under-tracked and
     small caps over-tracked by the same number. Smaller caps need more. */
  --track-display:-0.032em; --track-head:-0.024em; --track-sub:-0.012em;
  --track-caps-xs:.14em; --track-caps-sm:.12em; --track-caps-md:.10em;

  /* Leading likewise. On /methodology 14px and 15px copy both landed on 21.7px,
     so the smaller text was the loosely-set one. */
  --lh-tight:1.5; --lh-body:1.62; --lh-loose:1.65;

  /* ── ONE MOTION SCALE ───────────────────────────────────────────────────
     Eight durations, six curves, four lift distances and three lifted-card
     shadows were in use for what is really three jobs. Two curves: things
     that arrive decelerate, things that change state do it evenly. */
  --t-base:220ms cubic-bezier(.2,.7,.25,1);   /* lifts, shadows, panels */
  --t-slow:560ms cubic-bezier(.2,.7,.25,1);   /* entrances and reveals */
  --e-out:cubic-bezier(.2,.7,.25,1);
  --t-mid:180ms cubic-bezier(.2,0,.2,1);
  /* two lifts, not five: a button rises 1.5px, a card 3px */
  --lift-btn:-1.5px; --lift-card:-3px;
  /* two button shadows, one hue -- five recipes in four tints before this */
  --btn-e1:0 1px 2px rgba(20,38,79,.06), 0 6px 16px -6px rgba(20,38,79,.20);
  --btn-e2:0 2px 4px rgba(20,38,79,.08), 0 12px 28px -8px rgba(20,38,79,.28);
  --t-fast:140ms cubic-bezier(.2,0,.2,1);
  --coral-ink:#A14926;
  /* the on-dark text tiers, so any page can put a footer or a panel on a
     dark ground without first having to own the palette */
  /* even steps: 17.4 and 15.4 L*, where tier 2 used to sit so close to tier 3
     that the lower gap was 58% of the upper one */
  --on-dark-1:#FFFFFF; --on-dark-2:#C2CFE6; --on-dark-3:#96A4C1;
  --navy-deep:#141C2E;
  /* every light surface step on the site measured 1.08-1.19:1 against its
     neighbour, so nothing sat ON anything -- a card on paper and the paper
     itself read as one plane. Two more steps inside the same cool ramp. */
  --paper-2:#EDF1F8;   /* section bands, ~1.14:1 on white */
  --mat:#E1E8F4;       /* inset grounds a card sits IN, ~1.26:1 */
}

/* ── TYPOGRAPHIC BASE ─────────────────────────────────────────────────────
   text-wrap:pretty shipped on the homepage only, so the other thirteen pages
   carried 21 single-word orphans — a line of prose ending on one stranded word,
   which is the cheapest-looking thing typography does. The browser does the
   work; it just had to be asked on more than one page. balance is for headings,
   pretty is for prose, and neither belongs in a page's own stylesheet. */
::selection{background:rgba(240,140,110,.35);}
h1,h2,h3,h4{text-wrap:balance;}
p,li,figcaption,blockquote,dd,dt,summary,caption{text-wrap:pretty;}

/* an inline link in running text is underlined, lightly, and at the text's own
   weight; before this none was, and they ran at three different weights */
article p a:not(.btn),.col p a:not(.btn),.about a,.methodbox a,.why p a,.roadmap a,.subp a,
.jp-copy p a:not(.btn){
  color:var(--blue,#2048B0);font-weight:inherit;text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:3px;
  text-decoration-color:rgba(32,72,176,.4);transition:text-decoration-color var(--t-fast);}
article p a:not(.btn):hover,.col p a:not(.btn):hover,.about a:hover,.methodbox a:hover,.why p a:hover,
.roadmap a:hover,.subp a:hover,.jp-copy p a:not(.btn):hover{text-decoration-color:var(--blue,#2048B0);}

.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;}
.skip-link{position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--navy);color:#fff;padding:12px 20px;border-radius:0 0 12px 0;
  font-family:var(--head);font-weight:700;}
.skip-link:focus{left:0;}

/* Anything an in-page link lands on has to clear the sticky bar. Only
   .loop-stage had this, so a footer link to #faq or #product dropped the
   heading behind 67px of nav. :where() keeps the specificity at zero, so any
   element that wants its own offset still wins. */
:where([id]){scroll-margin-top:calc(var(--nav-h) + var(--nav-rule) + 24px);}

#topnav, header.nav{position:sticky;top:0;z-index:80;background:var(--white);
  border-bottom:var(--nav-rule) solid var(--coral);
  backdrop-filter:none;-webkit-backdrop-filter:none;box-shadow:none;}
/* the base rule carries the transition, or only the REMOVAL animates and the
   shadow appears in one frame -- on the one piece of chrome every visitor
   scrolls past on all fourteen pages. And the tint is navy: this was the
   site's most-seen shadow and the only one still lit by pure black. */
#topnav, header.nav{transition:box-shadow 200ms var(--e-out);}
#topnav.scrolled, header.nav.scrolled{box-shadow:0 6px 20px -10px rgba(20,38,79,.26);
  border-bottom-color:var(--coral);}
.nav-inner, .nav-row{display:flex;align-items:center;gap:28px;height:var(--nav-h);}
/* the mark does not move -- .nav-inner already centres its children -- only
   the tap box grows, from 26x57 to a real 44px target */
/* flex:none, or the mark is the thing that gives. A flex item shrinks before a
   row overflows, so when the eighth nav item arrived the logo silently
   compressed from 74px to 3px between 1000 and 1060 -- and because nothing
   overflowed, document.scrollWidth stayed clean and every layout gate passed on
   a bar with no logo in it. The row must break the breakpoint, not the brand. */
.nav-logo{display:inline-flex;align-items:center;min-height:44px;flex:0 0 auto;}
.nav-logo img{flex:0 0 auto;}
/* 26px read small against a 64px bar and a 44px CTA — the mark was the least
   confident thing in the chrome (David, 2026-09-03). 34px still clears the bar
   with 15px of air above and below, and stays under the CTA's height. */
.nav-logo img{height:34px;width:auto;}
.nav-links{display:flex;gap:26px;align-items:center;}
/* FIVE GROUPS (2026-09-20, NAV_REVIEW). The bar had reached nine flat links and
   790px of row; between 1320 and 1440 that left 46px between "About" and "Sign
   in" — less air at the bar's widest than the 26px rhythm INSIDE it, so the
   links and the CTAs read as one run of nine-and-a-bit things. Grouping is what
   took the row back to a width a bar can rank; the exact figures are in the
   review. The gap no longer has to close on a breakpoint to make the row fit,
   so 26px is now the only value. */
.nav-item{position:relative;display:flex;align-items:center;height:var(--nav-h);}
#topnav .nav-links a, header.nav .nav-links a, .nav-trigger{
  font-family:var(--head);font-weight:600;font-size:var(--t3);color:var(--ink-soft);
  text-decoration:none;transition:color 140ms cubic-bezier(.2,0,.2,1);}
/* The thing that opens a panel is a <button>, not a link: it goes nowhere. It
   has to be un-styled back to a link by hand, because a button brings its own
   font, background and border and inherits none of the bar's. */
.nav-trigger{display:inline-flex;align-items:center;gap:6px;background:none;border:0;
  padding:0;cursor:pointer;line-height:1;}
.nav-caret{width:10px;height:6px;flex:none;opacity:.7;
  transition:transform var(--t-fast),opacity var(--t-fast);}
#topnav .nav-links a:hover, header.nav .nav-links a:hover,
.nav-trigger:hover{color:var(--coral-ink);}
.nav-trigger:hover .nav-caret{opacity:1;}
.nav-trigger[aria-expanded="true"]{color:var(--coral-ink);}
.nav-trigger[aria-expanded="true"] .nav-caret{transform:rotate(180deg);opacity:1;}
/* The current page marks its GROUP, so a visitor reading a paper can see they
   are somewhere under Research — which nine flat links could never show, because
   the page they were on was usually not one of them. */
#topnav .nav-links a[aria-current], header.nav .nav-links a[aria-current],
.nav-item.is-current > .nav-trigger{
  color:var(--ink);box-shadow:inset 0 -2px 0 0 var(--coral);}
#topnav .nav-links a[aria-current]:hover, header.nav .nav-links a[aria-current]:hover,
.nav-item.is-current > .nav-trigger:hover{color:var(--coral-ink);}

/* ── the drop panels ──────────────────────────────────────────────────────
   Hung off .nav-item, which is nav-height tall, so top:100% is the underside of
   the bar and the panel clears the coral rule rather than sitting on it. z-index
   is one above the header's own 80; the header is the stacking context. */
.nav-menu{position:absolute;top:100%;left:-14px;z-index:81;margin-top:var(--nav-rule);
  min-width:344px;padding:8px;background:var(--white);
  border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--e3);}
.nav-menu[hidden]{display:none;}
/* An animation, not a transition: the panel goes display:none between states, and
   a transition cannot run across that. This fires on the frame it is shown. */
@keyframes nav-menu-in{from{opacity:0;transform:translateY(-6px);}to{opacity:1;transform:none;}}
.nav-menu{animation:nav-menu-in 140ms var(--e-out);}
.nav-menu a{display:block;padding:9px 12px;border-radius:var(--r-sm);
  text-decoration:none;transition:background var(--t-fast);}
.nav-menu a b{display:block;font-family:var(--head);font-weight:650;font-size:var(--t3);
  color:var(--ink);letter-spacing:var(--track-sub);}
.nav-menu a span{display:block;margin-top:2px;font-size:var(--t2);line-height:1.45;
  color:var(--ink-faint,#5A657A);}
.nav-menu a:hover{background:var(--paper,#F4F6FA);}
.nav-menu a:hover b{color:var(--coral-ink);}
.nav-menu a[aria-current]{background:var(--paper,#F4F6FA);
  box-shadow:inset 2px 0 0 0 var(--coral);}
@media (prefers-reduced-motion:reduce){
  .nav-menu{animation:none;}
  .nav-caret{transition:none;}
}

.nav-cta{display:flex;align-items:center;gap:16px;margin-left:auto;}
.nav-cta .signin, header.nav .btn-ghost{color:var(--ink-soft) !important;
  background:transparent !important;border:0 !important;font-family:var(--head);
  font-weight:600;font-size:var(--t3);padding:0 !important;}
.nav-cta .signin:hover, header.nav .btn-ghost:hover{color:var(--ink) !important;}
/* the nav CTA is pinned rather than inherited: three pages add .btn-sm to the
   same markup, so it rendered 44px there and 50px everywhere else -- and 50px
   in a 64px bar leaves 7px of air either side. */
#topnav .nav-cta .btn-primary, header.nav .btn-primary{
  background:var(--coral) !important;color:var(--navy) !important;border:0 !important;
  font-family:var(--head);font-weight:700;font-size:var(--t3);
  height:44px !important;padding:0 20px !important;border-radius:999px;box-shadow:none !important;}
#topnav .nav-cta .btn-primary:hover:not(:active), header.nav .btn-primary:hover:not(:active){
  background:var(--coral-deep) !important;transform:none !important;}
#topnav .nav-cta .btn-primary:active, header.nav .btn-primary:active{
  background:var(--coral-deep) !important;transform:translateY(1px) scale(.988) !important;}
#topnav a:focus-visible, header.nav a:focus-visible, .nav-toggle:focus-visible{
  outline:2px solid var(--blue);outline-offset:2px;}

/* THE RING HAS TO BE VISIBLE ON THE GROUND IT LANDS ON. --blue measures 2.12:1
   on --navy-deep and 1.00:1 on --blue itself, so on every navy footer and every
   blue band the focus ring simply disappeared -- 78 anchors across the site.
   White clears 3:1 on both. */
footer :focus-visible,
.on-dark :focus-visible,
.on-blue :focus-visible,
.cta-band :focus-visible,
.bar :focus-visible,
.close :focus-visible{outline:2px solid #fff;outline-offset:2px;}

/* One baseline ring for any page that never declared its own. NO border-radius:
   the ring follows the element's own corner, and forcing 6px onto a 999px pill
   made twenty buttons visibly change shape the instant you tabbed to them. */
:focus-visible{outline:2.5px solid var(--blue);outline-offset:3px;}

/* ── the burger and its panel ─────────────────────────────────────────────
   These five rules travel WITH the markup now. Nine pages shipped the button,
   the <nav class="mobile-nav"> and the toggle script with none of this, so the
   panel had no display:none to start from and rendered open, always. */
.nav-toggle{display:none;width:44px;height:44px;flex:none;align-items:center;
  justify-content:center;border:1px solid var(--line);background:var(--white);
  border-radius:var(--r-sm);color:var(--ink);cursor:pointer;}
.nav-toggle{transition:background var(--t-fast),border-color var(--t-fast),transform 120ms cubic-bezier(.2,0,.2,1);}
.nav-toggle:hover{background:var(--paper,#F4F6FA);border-color:var(--ink-faint,#5A657A);}
.nav-toggle:active{transform:scale(.96);}
.nav-toggle svg{width:22px;height:22px;}
/* the three bars stayed three bars while the panel was open, so the control
   that opened it gave no sign it had. They cross now. */
.nav-toggle svg line{transform-origin:center;transform-box:fill-box;
  transition:transform var(--t-base),opacity 120ms linear;}
.nav-toggle[aria-expanded="true"] .b1{transform:translateY(5px) rotate(45deg);}
.nav-toggle[aria-expanded="true"] .b2{opacity:0;}
.nav-toggle[aria-expanded="true"] .b3{transform:translateY(-5px) rotate(-45deg);}
@media (prefers-reduced-motion:reduce){ .nav-toggle svg line{transition:none;} }
.mobile-nav{display:none;}

/* With the panel open at 390px, three identical coral "Book a call" pills were
   visible at once — the bar's, the panel's, and the page's own. The bar's is
   still there and still tappable at the top of the screen, so the panel's is
   the one that goes; the duplicate was never a second offer, only a second
   sighting of the same one. */
@media (max-width:839px){
  body.nav-open #topnav .nav-cta .btn-primary,
  body.nav-open header.nav .nav-cta .btn-primary{
    opacity:0;pointer-events:none;transition:opacity var(--t-fast);}
}
@media (prefers-reduced-motion:reduce){
  body.nav-open #topnav .nav-cta .btn-primary{transition:none;}
}

/* Sign in is the one nav item that has a home elsewhere -- it is duplicated in
   the mobile panel -- so it is the one that gives way when the row runs out of
   width. Below this, "Book a call" was wrapping to two lines and growing the
   pill to 69.6px inside a 64px row, so it overflowed the bar and bled onto the
   coral rule. Two selectors because two markup variants ship: .signin on ten
   pages, .btn-ghost on pricing/methodology/security. */
/* the re-step: the desktop rhythm is 128/96/72 and a phone cannot carry it */
@media (max-width:640px){
  :root{--s13:80px; --s12:64px; --s11:48px;}
}

@media (max-width:560px){
  .nav-cta .signin,
  header.nav .nav-cta .btn-ghost{display:none;}
}

/* THE BAR COLLAPSES AT 840px. It has moved three times, each time because an
   item was added: 900 with seven items, 999 with the eighth (Consultancy), 1071
   with the ninth (Guides) — at which point an iPad in landscape and a
   half-screen laptop window both got the burger, and the full nav was a
   privilege of the widest third of screens.

   Grouping reversed it. The row is gutter 28 + mark 74.5 + 28 + links 432.3 + 28
   + CTAs 185.2 + gutter 28 = 804px, against 1062 before, so the bar now shows
   from 840 (36px of slack, deliberately, because the trigger labels are the one
   part of this row that a font fallback can widen).

   2026-09-21 and the number barely moved: Pricing left the bar (-78px) and
   "Trust" became "Trust & method" (+73px), so 437.1 became 432.3 and 840 still
   holds with room. Re-measured rather than assumed, because the two changes
   cancelling out is exactly the coincidence that would have gone unnoticed. Measured at
   720/740/760/780/800/820/840/860/900/960/1000/1024/1071/1100/1152/1200/1440,
   reading document.scrollWidth and the mark's own width at each: the mark stays
   74.5px throughout, which is the failure the 1071 comment describes and the
   one a layout gate cannot see, because a squeezed flex item overflows nothing.

   ADDING A GROUP MOVES THIS NUMBER AGAIN — but a group, not a link: five
   triggers is the budget, and a sixth should replace one rather than join them.
   Measure the row before either. */
@media (max-width:839px){
  #topnav .nav-links, header.nav .nav-links{display:none;}
  #topnav .nav-toggle, header.nav .nav-toggle{display:inline-flex;}
  .mobile-nav{display:block;position:fixed;left:0;right:0;
    top:calc(var(--nav-h) + var(--nav-rule));z-index:79;background:var(--white);
    border-bottom:1px solid var(--line);box-shadow:var(--e2);padding:8px 0 16px;
    max-height:calc(100dvh - var(--nav-h) - var(--nav-rule));overflow-y:auto;
    opacity:0;visibility:hidden;transform:translateY(-10px);
    /* visibility is delayed to the END of the close and flipped INSTANTLY on
       open. Transitioning it symmetrically meant the panel's links were still
       visibility:hidden for 140ms after .open landed, and focus() on a hidden
       element fails silently -- so the menu opened and the keyboard stayed
       outside it. */
    transition:opacity var(--t-fast),transform var(--t-fast),visibility 0s var(--t-fast);}
  .mobile-nav.open{opacity:1;visibility:visible;transform:none;
    transition:opacity var(--t-fast),transform var(--t-fast),visibility 0s;}
  .mobile-nav a:not(.btn){display:flex;align-items:center;min-height:52px;
    padding:0 28px;color:var(--ink);font-family:var(--head);font-weight:600;
    font-size:var(--t3);border-bottom:1px solid var(--line);}
  .mobile-nav .mn-cta{display:block;padding:16px 28px 4px;border-bottom:none;}
  /* :not(.btn) above, so the pill keeps its own colour. It was inheriting
     --ink on --navy at 1.21:1 — an unreadable CTA eight pixels below an
     identical readable one in the bar. */
  .mobile-nav .mn-cta .btn-primary{width:100%;height:50px;
    background:var(--coral) !important;color:var(--navy) !important;
    display:flex;align-items:center;justify-content:center;border-bottom:0;}
  /* ── the panel's accordion ───────────────────────────────────────────
     Flat, the panel was twenty-one rows and 608px tall. On a 375x667 phone its
     own scroll box is 599px, so "Book a call" sat at y=611 — the primary CTA,
     below the fold of the menu that was meant to carry it. Collapsed it is five
     rows, Sign in and the pill: 382px, and the pill is visible the moment the
     menu opens on every phone the site sees. The group the visitor is already
     inside is rendered open (server-side, not by script), so the panel opens
     showing where they are rather than five closed doors. */
  .mn-trigger{display:flex;align-items:center;justify-content:space-between;
    width:100%;min-height:52px;padding:0 28px;background:none;border:0;
    border-bottom:1px solid var(--line);cursor:pointer;text-align:left;
    color:var(--ink);font-family:var(--head);font-weight:600;font-size:var(--t3);}
  .mn-trigger .nav-caret{width:12px;height:7px;opacity:.6;}
  .mn-trigger[aria-expanded="true"] .nav-caret{transform:rotate(180deg);opacity:1;}
  .mn-panel[hidden]{display:none;}
  /* Indented and set on paper, so a child row cannot be mistaken for a group.
     Smaller than its parent but never below the 44px target. */
  .mobile-nav .mn-panel{background:var(--paper,#F4F6FA);}
  .mobile-nav .mn-panel a{min-height:46px;padding:0 28px 0 44px;
    font-weight:550;font-size:var(--t2);color:var(--ink-soft);
    border-bottom:1px solid var(--white);}
  .mobile-nav .mn-panel a:last-child{border-bottom:1px solid var(--line);}
  .mobile-nav a[aria-current],.mobile-nav .mn-group.is-current > .mn-trigger{
    color:var(--coral-ink);}
  .mobile-nav .mn-panel a[aria-current]{box-shadow:inset 3px 0 0 0 var(--coral);}
  body.nav-open{overflow:hidden;}
}
@media (prefers-reduced-motion:reduce){ .mobile-nav{transition:none;} }

@media print{
  #topnav, header.nav, .nav-toggle, .mobile-nav, .skip-link{display:none !important;}
  /* THE FOOTER PRINTS TOO, AND IT SHOULD NOT. Hiding only the nav meant four columns of
     marketing links landed in anything printed from this site — first found in the legal
     PDFs, which are rendered from the live page and filed by a customer's DPO, where it
     pushed the Privacy Notice from three sheets to four. Fixed page-scoped in Phase 2;
     this is the same fix for every other page. The company block stays: registered office
     and company number belong at the foot of a printed page. */
  footer .foot-row{display:none !important;}
  footer{border-top:1px solid var(--line) !important;background:none !important;}
  footer .foot-base{color:var(--ink-faint) !important;display:block;text-align:left;}
  footer .foot-base span{display:block;}
}

/* one trailing arrow, one curve; four implementations before, two of which animated */
.arrow-link,.dl-go{display:inline-flex;align-items:center;gap:6px;}
.arrow-link::after{content:"\2192" / "";transition:transform var(--t-fast);}
.dl-go::after{content:"\2193" / "";transition:transform var(--t-fast);}
.arrow-link:hover::after{transform:translateX(3px);}
.dl a:hover .dl-go::after{transform:translateY(3px);}
@media (max-width:640px){ .arrow-link{min-height:44px;} }   /* seven 24.8px text CTAs on a phone */

/* ── SMALL SHARED PARTS ───────────────────────────────────────────────────
   The same SVG tick shipped under two class names with two wrappers and two
   baselines; four badge implementations ran at four heights, two of them on
   one page disagreeing about their own type size. */
.ticks{list-style:none;margin:0;padding:0;display:grid;gap:12px;}
.ticks li{display:flex;gap:11px;font-size:var(--t3);line-height:1.45;
  align-items:flex-start;color:var(--ink);}
.ticks li > svg{width:18px;height:18px;flex:none;margin-top:3px;}

.badge{display:inline-flex;align-items:center;height:24px;padding:0 10px;
  border-radius:999px;font-family:var(--head);font-weight:700;font-size:11px;
  letter-spacing:var(--track-caps-xs);text-transform:uppercase;}
.badge-lg{height:30px;padding:0 14px;font-size:11.5px;}

/* the citation line had four class names and three sizes; it is the product's
   own promise and should be recognisable as one thing */
.cite,.i-date,.scene-cite{font-size:var(--t1);line-height:1.6;color:var(--ink-faint);
  font-variant-numeric:tabular-nums;display:inline-flex;align-items:center;gap:7px;}
.cite::before,.i-date::before,.scene-cite::before{content:"";width:6px;height:6px;border-radius:50%;
  background:var(--coral);flex:none;}

/* ── THE ENTRANCE ─────────────────────────────────────────────────────────
   On pricing, methodology and security the only motion on the first screen
   was the scroll-reveal fading their cards in -- the heading and lede simply
   appeared, and the cards then arrived AFTER them, which is backwards. This is
   the homepage's own cascade, opt-in: put .enter on a page's first block and
   its children rise in order. Nothing happens under reduced motion. */
@media (prefers-reduced-motion:no-preference){
  @keyframes riseIn{from{opacity:0;transform:translateY(14px);} to{opacity:1;transform:none;}}
  .enter > *{animation:riseIn 560ms var(--e-out) both;}
  .enter > :nth-child(1){animation-delay:.04s} .enter > :nth-child(2){animation-delay:.12s}
  .enter > :nth-child(3){animation-delay:.20s} .enter > :nth-child(4){animation-delay:.28s}
  .enter > :nth-child(5){animation-delay:.36s}
}

/* ── THE REVEAL — one definition ──────────────────────────────────────────
   One class name, two implementations (.6s ease on four pages, .66s on a
   custom curve on the homepage) and no stagger anywhere, so a three-up card
   row arrived as one slab. The delay reads an index the page can set; where
   it does not, --rv-i is 0 and nothing changes. */
.reveal{opacity:0;transform:translateY(18px);
  transition:opacity var(--t-slow),transform var(--t-slow);
  transition-delay:calc(var(--rv-i,0) * 70ms);}
.reveal.in{opacity:1;transform:none;}
@media (prefers-reduced-motion:reduce){
  .reveal{opacity:1;transform:none;transition:none;transition-delay:0s;}
}

/* ── THE FOOTER — one definition ──────────────────────────────────────────
   Four footers shipped before this: a 22-link one on the homepage, a 14-link
   one on pricing/methodology/security, a ONE-link line on about, register,
   /insights and the six articles, and a document footer on the board pack.
   Ten of fourteen pages carried no legal link at all -- no privacy notice, no
   cookie policy, no sub-processors, no DPO address -- on a site whose whole
   pitch is that it handles other organisations' pay data carefully.

   The link set is the homepage's, because it was the superset. The heading
   markup is pricing's, because <h3> gives the footer a real outline where a
   styled <div> gave it none. Hrefs are absolute so the same block works on a
   page that is not the homepage. */
/* the sizes are literal, not tokens: --t1 is 12px on some pages and 12.5px on
   others, and the point of one footer is that it is one footer. */
footer{background:var(--navy-deep);color:var(--on-dark-3);
  padding:96px 0 40px;font-size:var(--t2);
  border-top:0;margin-top:0;line-height:1.55;}
footer .foot-row{display:grid;grid-template-columns:minmax(220px,1fr) 2fr;gap:72px;}
footer .foot-logo img{height:30px;width:auto;}
footer .foot-blurb{margin-top:16px;max-width:34ch;line-height:1.6;color:var(--on-dark-3);}
/* Cyber Essentials Certification Mark (certified 2026-09-07), per the scheme's guidelines:
   minimum 60px wide; an exclusion zone equal to the tick's width (~24px at 60px) on every
   side; placed directly on the colour ground, no added tile; never modified. The two lines
   beside it are the source's certification line and its detail (data/marketing_strings.json). */
footer .foot-cert{display:flex;align-items:center;gap:24px;margin-top:24px;padding:0;color:var(--on-dark-2);text-decoration:none;max-width:34ch;}
footer .foot-cert img{width:60px;height:auto;flex:none;}
footer .foot-cert b{display:block;font-weight:600;color:var(--on-dark-1);}
footer .foot-cert small{display:block;font-size:12px;line-height:1.5;color:var(--on-dark-3);overflow-wrap:anywhere;}
footer .foot-cert:hover b{text-decoration:underline;text-underline-offset:3px;}
/* the same mark beside the /security certifications row: 60px, its exclusion zone kept clear */
.cert-mark{float:left;width:60px;height:auto;margin:0 24px 24px 0;}
footer .foot-links{display:grid;grid-template-columns:repeat(4,1fr);gap:24px;}
footer .foot-col h3{font-family:var(--head);font-size:var(--t1);letter-spacing:.1em;
  text-transform:uppercase;color:var(--on-dark-1);margin:0 0 13px;font-weight:700;line-height:1.4;}
/* links sit ABOVE supporting copy, which is the right order; the blurb keeps
   tier 3 and these move to tier 2, so hovering to white is still a step */
footer .foot-col a{display:block;color:var(--on-dark-2);padding:5px 0;
  transition:color var(--t-fast);}
footer .foot-col a:hover{color:var(--on-dark-1);}
footer .foot-base{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;
  margin-top:56px;padding-top:24px;border-top:1px solid rgba(255,255,255,.16);
  font-size:var(--t1);color:var(--on-dark-3);}
@media (max-width:860px){ footer .foot-row{grid-template-columns:1fr;gap:40px;}
  footer .foot-links{grid-template-columns:1fr 1fr;} }
@media (max-width:520px){ footer .foot-links{grid-template-columns:1fr 1fr;gap:16px 20px;}
  footer .foot-col a{min-height:44px;display:flex;align-items:center;padding:0;} }
@media (prefers-reduced-motion:reduce){ footer .foot-col a{transition:none;} }

/* ── ONE GUTTER ───────────────────────────────────────────────────────────
   Three shipped: 28px on ten pages, 24px on pricing/methodology/security (a
   1124px column against 1132px, with the logo starting 4px further left), and
   16px below 421px on the article pages -- where every SIBLING container kept
   28px, so an h1 sat at x=16 and the first paragraph of its own article at
   x=28. One clamp, and every container that holds text reads it. */
:root{ --gutter:clamp(16px,5vw,28px); }
.wrap{max-width:1180px;margin:0 auto;padding:0 var(--gutter);}

/* ── ONE BUTTON ───────────────────────────────────────────────────────────
   Five heights rendered for the same role: 51.8px on the homepage, 50px on
   pricing/methodology/security, 47.8px on about/register, 46px and 44px on the
   board pack. Small buttons ran 43.8 against 44. The geometry lives here now;
   pages keep only what is genuinely theirs, which is the FILL -- navy on a
   paper ground, white on navy, coral in the hero.

   50/26/15.5 is pricing's, because it was the one that had been designed
   rather than accumulated. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;
  height:50px;padding:0 26px;border-radius:999px;white-space:nowrap;
  font-family:var(--head);font-weight:700;font-size:var(--t3);line-height:1;
  border:1.5px solid transparent;cursor:pointer;
  user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent;
  transition:transform var(--t-fast), box-shadow var(--t-mid), background var(--t-mid),
             color var(--t-mid), border-color var(--t-mid);}
.btn:hover:not(:active){transform:translateY(var(--lift-btn));}
/* A press has to beat its own hover, or the button does nothing when clicked --
   which is what happened on the headline CTA and on the nav CTA of thirteen
   pages: a 0-4-0 hover rule and a !important both outranked a bare .btn:active,
   so :active computed byte-for-byte identical to :hover. */
.btn:active{transform:translateY(1px) scale(.988);}
/* no page-level a:hover{text-decoration:underline} may reach a button */
.btn,.btn:hover,.btn:focus,.btn:active{text-decoration:none;}
.btn-sm{height:44px;padding:0 20px;font-size:var(--t2);}

.btn-primary{background:var(--blue,#2048B0);color:#fff;box-shadow:var(--btn-e1);}
.btn-primary:hover{background:var(--blue-deep,#1E3A8A);box-shadow:var(--btn-e2);}
/* an edge at 3.5:1 and a faint body: the .30 outline measured 1.53:1 on white and
   1.44:1 on paper, which is a hairline, not a control */
.btn-ghost{background:rgba(32,72,176,.045);color:var(--blue,#2048B0);border-color:rgba(32,72,176,.65);}
.btn-ghost:hover{border-color:var(--blue,#2048B0);background:rgba(32,72,176,.09);}
.btn-light{background:#fff;color:var(--navy,#1F2A44);}   /* the dark-band rule below supplies its shadow */
.btn-outline{background:transparent;border-color:rgba(255,255,255,.55);color:#fff;}
.btn-outline:hover{border-color:#fff;background:rgba(255,255,255,.10);}

/* the closing bands all render white-on-navy already; before this they did it
   through five different mechanisms -- a class, a raw inline style=, a class
   PLUS a redundant inline copy, a descendant rule, and an .on-dark override. */
/* The closing band is one component on ten pages and its heading rendered at
   54.28 / 40.12 / 38 / 34 / 32px with four different trackings. One size. The
   homepage keeps its own, deliberately -- it is the front door and its display
   scale is a step larger everywhere, not just here. */
/* `.cta-band` is the navy GROUND on the seven insights pages and `.close` is
   the same ground on the three document pages; the inner 720px column is
   `.inner` on all ten. Until 2026-09-02 `.cta-band` meant the ground on one
   family and the COLUMN on the other -- one class name, two opposite jobs. */
.cta-band h2,.close h2{color:#fff;font-size:var(--fs-h2);letter-spacing:-0.022em;}
.cta-band p,.close p{color:var(--on-dark-2);}

.cta-band .btn:not(.btn-outline),.close .btn-light,.on-dark .btn-primary{
  background:#fff;color:var(--navy,#1F2A44);box-shadow:var(--e3);}
.cta-band .btn:not(.btn-outline):hover,.close .btn-light:hover,.on-dark .btn-primary:hover{
  background:var(--paper,#F4F6FA);box-shadow:var(--e4);}

@media (prefers-reduced-motion:reduce){
  .btn,.btn:hover,.btn:active,.ins-card,.ins-card:hover,.card,.card:hover,.card:focus-within,
  .dl a,.dl a:hover,.domains a,.domains a:hover{transition:none !important;transform:none !important;}
  .arrow-link,.arrow-link::after,.dl-go,.dl-go::after{transition:none !important;transform:none !important;}
}
