/* ============================================================================
   payco-marketing.css — THE header for the public site. One file, one definition.

   There were three implementations and four heights. Measured at 1440px:

     index.html                 nav.nav        81px tall, 52px logo
     the 11 .mnav pages         nav.mnav       70px tall, 38px logo
     hardware.html              header.top     75px tall, 44px logo
     privacy / terms            header[style]  89px (163px on a phone), NOT sticky
     status.html                header.top     65px, NOT sticky, 3 links of 8

   So the first click off the homepage moved the bar 11px and shrank the logo 14px,
   the second moved it again, and two of the pages a search engine sends people to
   first did not look like the same website. Worse, the .mnav pages were not even
   uniform among themselves: marketing-core.css and marketing-pillar.css centred the
   link row with `position:absolute;left:50%`, while it-solutions.html and
   payco-secure.html carried an inline copy that centred it in flow — a different
   layout algorithm, which is why the row collided with the logo on some pages and
   not others between 900px and 1060px.

   This file is now the ONLY place the header is defined, and every public marketing
   page links it LAST. The per-page copies in marketing-core.css, marketing-pillar.css
   and the three inline <style> blocks are gone; there is nothing left to drift.

   The canonical numbers are the APP header's (payco.css .pc-header): 74px tall,
   frosted, gradient hairline under it, 44px logo. Matching them means the bar does
   not move when a visitor crosses from the marketing site into the product — the two
   halves finally read as one thing.

   Every var() carries a fallback on purpose: status.html, privacy.html, terms.html
   and 404.html load this file and nothing else, so no token may be assumed.
   ========================================================================== */

/* ---------- the box model ----------
   Stated for the whole header subtree, not inherited from a page reset. box-sizing does not
   inherit, so pinning it on .mnav alone left every CHILD on whatever the page happened to
   say: privacy.html and terms.html carry no `*{box-sizing:border-box}`, and there the 1px
   border on each pill sat outside its declared 44px, measuring the Sign In / Register
   buttons at 46px against 44px on the other fifteen pages. Same cause as the 75px bar.
   Scoped to the header so it cannot disturb anything else a page draws. */
.mnav, .mnav *, .mnav *::before, .mnav *::after { box-sizing: border-box; }

/* ---------- the bar ---------- */
.mnav {
  position: sticky; top: 0; z-index: 100;
  display: flex; align-items: center; gap: 20px;
  height: 74px; padding: 0 clamp(18px, 3vw, 40px);
  background: rgba(251, 252, 254, .86);
  backdrop-filter: saturate(140%) blur(5px);
  -webkit-backdrop-filter: saturate(140%) blur(5px);
  border-bottom: 1px solid var(--line, #dce3f0);
}
/* The gradient hairline. Each system drew its own at a different opacity; hardware
   and the legal pages had none at all. */
.mnav::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: linear-gradient(90deg, #0b2a8a, #1a4dd6, #3b82ff, #6dd5fa, #3b82ff, #1a4dd6, #0b2a8a);
  opacity: .4; pointer-events: none;
}

/* ---------- the logo ----------
   44px is the platform minimum tap target, and the reason the height is stated here
   rather than left to the <img> attributes: the image may be any height, the TARGET
   may not be under 44. Measured before: 52px on index, 38px on eleven pages, 44px on
   hardware, 30px on the homepage at 375px. */
.mnav .logo { flex: none; display: inline-flex; align-items: center; min-height: 44px; text-decoration: none;
  border-radius: 8px;
  transition: transform .22s cubic-bezier(.16,1,.3,1), filter .22s ease; }
.mnav .logo img { height: 44px; width: auto; display: block; max-width: 100%; }
@media (max-width: 600px) { .mnav .logo img { height: 34px; } }
/* The glow the console header has had all along on `.pc-home` — same drop-shadow pair, same
   easing, same 1px lift — so the mark behaves identically on both sides of the sign-in line.
   It was missing here only: the marketing logo was the one header control with no hover state
   at all, which read as "not a link" on the 58 front-end pages. drop-shadow rather than
   box-shadow because the mark is a transparent PNG: box-shadow would trace the img's RECTANGLE
   and paint a glowing box around the wordmark instead of around the letters. */
.mnav .logo:hover, .mnav .logo:focus-visible {
  transform: translateY(-1px);
  filter: drop-shadow(0 0 10px rgba(59,130,255,.5)) drop-shadow(0 0 3px rgba(109,213,250,.4));
}
.mnav .logo:active { transform: translateY(0); }

/* ---------- the link row ----------
   In flow, not absolutely centred. Absolute positioning put this row in a different
   layout system from the logo and the Sign In/Register cluster, so the three could
   only ever stack on each other: measured 46px of overlap at 901px, with "Company"
   printed underneath the Sign In pill. As a flex sibling it centres in the space
   actually left over and cannot collide with anything. */
.mnav .links { display: flex; align-items: center; gap: 6px; flex: 1 1 auto; min-width: 0; justify-content: center; }
.mnav .links > * { flex: none; }

/* The app header's pill, so the two halves of the site agree. */
.mnav .links > a,
.mnav .links .drop > a.dtop {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 13.5px; font-weight: 600; letter-spacing: -.005em;
  color: var(--ink-soft, #2a3a5c); text-decoration: none; white-space: nowrap;
  padding: 9px 14px; border-radius: 999px; background: #f2f5fa;
  border: 1px solid var(--line, #dce3f0);
  transition: background .22s cubic-bezier(.4,0,.2,1), color .18s ease, border-color .22s ease, box-shadow .22s ease;
}
.mnav .links > a:hover,
.mnav .links .drop > a.dtop:hover {
  background: linear-gradient(135deg, #0b2a8a 0%, #1a4dd6 35%, #3b82ff 70%, #6dd5fa 100%);
  border-color: #2255d4; color: #fff;
  box-shadow: 0 4px 14px rgba(26, 77, 214, .28);
}
/* Where you are. index.html had no current-page state at all, so the homepage nav
   never told you where you were, and the five pillar pages marked nothing either. */
.mnav .links > a[aria-current="page"],
.mnav .links .drop > a.dtop.on {
  background: linear-gradient(135deg, #0b2a8a 0%, #1a4dd6 35%, #3b82ff 70%, #6dd5fa 100%);
  border-color: #2255d4; color: #fff; font-weight: 700;
}

/* One step of tightening before the burger takes over, so the six items keep their
   own row down to the 900px breakpoint instead of being clipped for the last 160px. */
@media (max-width: 1060px) and (min-width: 901px) {
  .mnav { gap: 12px; }
  .mnav .links { gap: 2px; }
  .mnav .links > a,
  .mnav .links .drop > a.dtop { padding: 9px 10px; font-size: 13px; }
  /* AND THE CHEVRONS GO, because this is the band where the row has no slack left.
     Measured on products.html: the link row wants 514px of the 460px it is given at 901px
     — an overflow this bar has had for as long as it has had seven items, and not this
     lane's to fix — and it fits exactly, 609 into 609, at 1060. Seven arrows at 7px plus
     their 5px gaps is 72px, which turns "exactly fits" into 12px over at 1060 and makes
     the 901px case worse than it was. A decoration may not be the thing that pushes a row
     out of its box, so between 901 and 1060 the affordance is the hover itself. Above 1061
     the row has 348px of slack and the arrows cost nothing. */
  .mnav .drop > a.dtop::after,
  .mnav .links > a:not(.mob-only)::after { display: none; }
}

/* ---------- the dropdowns ----------
   ONE CARD PATTERN, TWO SOURCES. `.dropm` is the Services menu, which lives in page
   markup on all eighteen pages; `.mnavd` is the six menus payco-marketing.js injects
   for the other six top-level items (W9 LANE 9). They are the same object — same radius,
   same hairline, same shadow, same row — so the rules below NAME BOTH rather than being
   written twice. Anything that differs is stated once, further down, and only ever about
   .mnavd: where it is placed (JS measures it; .dropm centres itself on its own wrapper)
   and how it is revealed (a class, because .mnavd has no wrapper to hang :hover on).

   .mnavd IS NOT SPELLED `dropm`, AND THAT IS DELIBERATE. tests/navui.mjs takes the
   document's first `.drop`/`.dropm` pair and asserts it carries the five pillar hrefs and
   opens on keyboard focus. Products sits before Services in the row, so an injected panel
   wearing either class would take that pair over and answer a question about Services with
   the Products menu. Different class, same design.

   THE CHEVRON'S BOX IS RESERVED FOR ALL SIX, AND ONLY ITS INK IS SWITCHED ON. The
   `.mnavd-trig` class is added by a deferred script, i.e. possibly after first paint, so
   growing each pill by 7px of arrow plus a 5px gap at that moment is a layout shift in the
   header on every public page. The ::after therefore exists — and takes its width — from
   the first paint, at opacity 0; the script only makes it visible. Measured as 0.0000 CLS
   in tests/headerdrop-w9.mjs §8, boot and hover both. It also means a page whose
   script is blocked shows no arrow pointing at a menu that will never open. */
.mnav .drop { position: relative; display: inline-flex; }
.mnav .drop > a.dtop::after,
.mnav .links > a:not(.mob-only)::after {
  content: ""; width: 0; height: 0; border-left: 3.5px solid transparent;
  border-right: 3.5px solid transparent; border-top: 4px solid currentColor;
  opacity: .65; transition: transform .18s, opacity .18s;
}
.mnav .links > a:not(.mob-only)::after { opacity: 0; }
.mnav .links > a.mnavd-trig::after { opacity: .65; }
.mnav .drop:hover > a.dtop::after,
.mnav .drop:focus-within > a.dtop::after,
.mnav .links > a.mnavd-open::after { transform: rotate(180deg); }
/* ---- THE PANEL, AS A BUBBLE (2026-09-13 polish pass) --------------------------------------
   It opened by sliding 6px and fading over 160ms on plain `ease` — correct, and characterless.
   Three changes, all compositor-only:
     · it SCALES from .965 about its own TOP edge, which is what makes a panel read as unfolding
       from the trigger rather than arriving beside it. transform-origin is the whole trick;
       without it a scale reads as a zoom out of the middle of the card.
     · the curve is an out-quint, so it decelerates into place instead of stopping dead.
     · opacity leads and transform trails (.2s vs .26s) so the panel is legible before it has
       finished settling — a menu you cannot read for a quarter-second feels slow however fast
       it actually is.
   The CLOSE is faster than the open (.12s), deliberately: a menu that lingers on the way out
   feels sticky and gets in the way of the next thing you meant to click.

   EVERY TRANSFORM BELOW RESTATES translateX(-50%). It is not decoration — it is this panel's
   horizontal centring, and dropping it from any one of these rules throws the menu half its own
   width to the right. */
.mnav .dropm, .mnav .mnavd {
  position: absolute; top: 100%; left: 50%;
  transform: translateX(-50%) translateY(6px) scale(.965);
  transform-origin: 50% 0;
  background: #fff; border: 1px solid var(--line, #dce3f0); border-radius: 14px;
  padding: 8px; min-width: 236px; display: flex; flex-direction: column; gap: 1px;
  box-shadow: 0 1px 2px rgba(11,27,58,.04), 0 18px 44px rgba(11,27,58,.16);
  opacity: 0; visibility: hidden;
  transition: opacity .12s ease, transform .12s ease, visibility .12s; z-index: 300;
}
/* THE TAIL. A 9px square rotated 45deg, half outside the panel's top edge, carrying the panel's
   own border on its two exposed sides — so it reads as a pointer cut out of the same card rather
   than a triangle stuck underneath one. It is a child, so it inherits the panel's transform and
   needs no animation of its own.

   IT NEEDS ROOM TO BE SEEN, AND THAT ROOM COSTS SOMETHING. Measured at 1440: the panel settled
   2px below the trigger, so the tail — which reaches 5px above the panel's top edge — was drawn
   underneath the trigger pill and `elementFromPoint` at the tail's own coordinates returned the
   nav bar. It was invisible. The open position below is therefore 7px rather than 2px.
   A gap between a trigger and its menu is the classic way a hover menu becomes unusable: the
   pointer crosses dead space, `:hover` drops on both elements, and the menu closes under the
   cursor on its way down. `::after` is an invisible bridge spanning exactly that gap, so the
   pointer is never over nothing. It is transparent and has no pointer-events:none — being
   hittable is the entire point of it. */
.mnav .dropm::before {
  content: ""; position: absolute; top: -5px; left: 50%;
  width: 9px; height: 9px; margin-left: -4.5px;
  background: #fff;
  border-left: 1px solid var(--line, #dce3f0);
  border-top: 1px solid var(--line, #dce3f0);
  transform: rotate(45deg);
  border-radius: 2px 0 0 0;
  pointer-events: none;
}
.mnav .dropm::after {
  content: ""; position: absolute; top: -10px; left: 0; right: 0; height: 10px;
  background: transparent;
}
/* The six INJECTED panels are positioned in pixels by payco-marketing.js against the whole bar,
   not against their trigger, so a tail at 50% of the panel would point at the panel's own middle
   instead of at the thing that opened it. No tail there; the scale-from-top still reads right. */
.mnav .drop:hover .dropm,
.mnav .drop:focus-within .dropm {
  opacity: 1; visibility: visible;
  transform: translateX(-50%) translateY(7px) scale(1);
  transition: opacity .2s cubic-bezier(.16,1,.3,1), transform .26s cubic-bezier(.16,1,.3,1), visibility .26s;
}
/* Rows wake one after another rather than all at once. Six rows at 24ms is 144ms end to end,
   under the ~200ms threshold where a sequence stops reading as a single gesture. */
.mnav .drop .dropm a { opacity: 0; transform: translate3d(0, -3px, 0); }
.mnav .drop:hover .dropm a,
.mnav .drop:focus-within .dropm a { opacity: 1; transform: none; }
.mnav .drop:hover .dropm a:nth-child(1), .mnav .drop:focus-within .dropm a:nth-child(1) { transition-delay: .02s; }
.mnav .drop:hover .dropm a:nth-child(2), .mnav .drop:focus-within .dropm a:nth-child(2) { transition-delay: .044s; }
.mnav .drop:hover .dropm a:nth-child(3), .mnav .drop:focus-within .dropm a:nth-child(3) { transition-delay: .068s; }
.mnav .drop:hover .dropm a:nth-child(4), .mnav .drop:focus-within .dropm a:nth-child(4) { transition-delay: .092s; }
.mnav .drop:hover .dropm a:nth-child(5), .mnav .drop:focus-within .dropm a:nth-child(5) { transition-delay: .116s; }
.mnav .drop:hover .dropm a:nth-child(6), .mnav .drop:focus-within .dropm a:nth-child(6) { transition-delay: .14s; }

/* OFF ENTIRELY under the preference — including the row delays, which would otherwise hold a
   menu's last row invisible for 140ms after the visitor asked for no motion.

   THIS BLOCK DELIBERATELY DOES NOT MENTION `.mnavd`, AND THAT IS NOT AN OVERSIGHT. The
   pre-existing reduced-motion rule further up this file already zeroes `.mnav .dropm,
   .mnav .mnavd`, and tests/headerdrop-w9.mjs §12 M10 proves it does by deleting it and requiring
   `.mnavd.on` to start animating again. The first draft of this block restated that same pair —
   so with the original deleted the panels were STILL frozen, the mutation went uncaught, and a
   gate that had been real since W9 quietly stopped testing anything. Nothing here may cover
   another rule's property. What is listed below is only what this polish pass introduced: the
   hover-state transitions on `.dropm` (higher specificity than the original, so not reached by
   it), the row stagger, and the tail. */
@media (prefers-reduced-motion: reduce) {
  .mnav .drop:hover .dropm, .mnav .drop:focus-within .dropm {
    transition: none; transform: translateX(-50%);
  }
  .mnav .dropm::before { display: none; }
  .mnav .drop .dropm a,
  .mnav .drop:hover .dropm a, .mnav .drop:focus-within .dropm a {
    transition: none; transform: none; opacity: 1; transition-delay: 0s;
  }
}
.mnav .dropm a, .mnav .mnavd a {
  display: block; white-space: nowrap; font-size: 13.5px; font-weight: 500;
  color: var(--ink-soft, #2a3a5c); text-decoration: none;
  padding: 9px 12px; border-radius: 9px; background: none; border: 0; box-shadow: none;
  /* opacity and transform are here because this rule comes AFTER the stagger block above and
     would otherwise replace its transition wholesale — the rows would snap in at their delays
     instead of fading, which looks like a rendering fault rather than a sequence. Declared in
     one place so the two cannot disagree. */
  transition: background .15s, color .15s, opacity .18s ease, transform .18s ease;
}
.mnav .dropm a:hover, .mnav .mnavd a:hover,
.mnav .mnavd a:focus-visible { background: #eef2fb; color: var(--ink, #0a1628); box-shadow: none; }
.mnav .dropm a.all, .mnav .mnavd .mnavd-all {
  border-top: 1px solid #eef1f6; margin-top: 5px; padding-top: 11px; border-radius: 0 0 9px 9px; color: #1a4dd6; }

/* ---------- what is only true of the injected six ----------
   PLACED BY MEASUREMENT, NOT BY PERCENTAGE. .dropm can say `left:50%;translateX(-50%)`
   because it sits inside a `.drop` wrapper that is exactly as wide as its trigger.
   The six injected panels have no wrapper — they are SIBLINGS of their trigger, so that
   tests/overflow.mjs still finds `.mnav .links > a` where it left it, and so that Tab
   from the trigger lands on the first row with no tabindex anywhere — which means their
   containing block is .mnav, the whole bar. payco-marketing.js therefore reads the two
   boxes on every open and writes `left` in pixels, clamped 12px inside the bar. The
   declared left:12px below is the value a panel holds while it is still hidden, and it
   is what stops a hidden panel widening the document: visibility:hidden keeps layout, so
   an off-screen hidden box is horizontal overflow exactly like a visible one is. */
.mnav .mnavd {
  left: 12px; transform: translateY(8px);
  min-width: 236px; max-width: calc(100vw - 24px);
}
.mnav .mnavd.on { opacity: 1; visibility: visible; transform: translateY(2px); }

/* ---------- Industries: the large expanded panel ----------
   THE NUMBERS ARE THE APP PANEL'S. Width min(860px,92vw) and min(828px,94vw) below
   1280, three declared columns, 30px/28px falling to 24px/20px, and the caption at
   12px/800/.09em uppercase in --ink-mute are payco-nav.js's injectMegaCss() values,
   taken rather than re-chosen so the platform's two large panels are one component.
   The one thing NOT taken is that file's `@media(min-width:769px){max-height:none}`.
   It lifts payco.css's 74vh cap because seven groups of seven fit; nine categories of
   sixty-eight might not, so the cap stays and the panel would scroll in the worst case.
   Measured at 1440x900 and again at 901x900: three columns of 24/23/21 rows drawing
   580/591/581px, a 673px panel against 808px of room, so it does not scroll on the
   viewport this site is designed at — nor on the narrowest one this layout runs at.

   THREE COLUMNS, ASSIGNED BY THE SCRIPT AND NOT BY THE BROWSER. A CSS multi-column
   balancer splits on height and would cut a category away from its caption; a plain
   3-track grid with one category per cell shares its row tracks, so the panel would be
   max(row) + max(row) + max(row) tall rather than the tallest COLUMN. The script assigns
   the nine categories to three columns so as to minimise the tallest one, and each column
   is one .mnavd-col. The assignment is NOT contiguous and deliberately so — the best
   contiguous split of this data is 21.5/27.5/32.5 units against the chosen 27.0/27.5/27.0,
   a 244px stagger against an 11px one. Registry order survives INSIDE a column, which is
   the part a person scanning for a trade name relies on. */
.mnav .mnavd-mega { width: min(860px, 92vw); min-width: 0; padding: 18px 20px;
  max-height: calc(100vh - 92px); overflow-y: auto; overscroll-behavior: contain; }
.mnav .mnavd-cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 30px 28px; align-items: start; }
.mnav .mnavd-col { display: block; min-width: 0; }
.mnav .mnavd-sec { display: block; margin: 0 0 12px; }
.mnav .mnavd-sec:last-child { margin-bottom: 0; }
/* The caption is not a destination and is typed so it cannot be read as one. */
.mnav .mnavd-cap {
  font-size: 12px; line-height: 1.2; font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-mute, #5a6885); padding: 0 10px 7px; margin: 0;
}
.mnav .mnavd-items { display: block; }
/* A DIRECTORY ROW, NOT A MENU ROW. Sixty-eight of them at the .dropm rhythm — 9px of
   padding over a line box the PAGE sets — is 2.5 screens of panel, and the page's line
   height is not a constant: these eighteen files inherit anything from 1.5 to 1.7, so a
   row that does not state its own is a row whose height depends on which page you opened
   the menu from. Same type, same colour, same radius as every other row on this header;
   the line box and the vertical padding are the only things stated differently, and they
   are what puts the tallest column inside one viewport. */
.mnav .mnavd-mega a { padding: 2.5px 10px; line-height: 1.25; border-radius: 7px; white-space: normal; }
.mnav .mnavd-cats { display: none; }
.mnav .mnavd-mega .mnavd-all { margin-top: 12px; padding-top: 10px; }
@media (max-width: 1279px) and (min-width: 901px) {
  .mnav .mnavd-mega { width: min(828px, 94vw); padding: 16px; }
  .mnav .mnavd-cols { gap: 24px 20px; }
  .mnav .mnavd-cap { padding: 0 8px 7px; }
}

/* ---------- the two calls to action ----------
   Sign In quiet, Register loud, everywhere. index.html had two identical filled
   primaries competing with each other; the pillars used btn-w/btn-g; hardware and
   the legal pages used inline-styled anchors. Same pair, same weights, one bar.
   Fully specified rather than leaning on a page .btn class, because four of the
   pages that load this file define no .btn at all. */
.mnav .cta { margin-left: auto; flex: none; display: flex; gap: 8px; align-items: center; }
.mnav .cta > a {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 18px; border-radius: 999px;
  font-size: 13.5px; font-weight: 700; text-decoration: none; white-space: nowrap;
  border: 1px solid transparent;
  transition: transform .15s ease, box-shadow .2s ease, background .22s ease, color .18s ease;
}
/* quiet: the first of the pair */
.mnav .cta > a:first-child {
  background: #fff; color: var(--ink, #0a1628); border-color: var(--line, #dce3f0);
  box-shadow: 0 3px 12px rgba(11, 27, 58, .08);
}
.mnav .cta > a:first-child:hover {
  background: linear-gradient(135deg, #0b2a8a, #1a4dd6 35%, #3b82ff 70%, #6dd5fa);
  color: #fff; border-color: #2255d4;
}
/* loud: the last of the pair */
.mnav .cta > a:last-child {
  background: linear-gradient(135deg, #0b2a8a, #1a4dd6 35%, #3b82ff 70%, #6dd5fa);
  color: #fff; border-color: #2255d4;
}
.mnav .cta > a:hover { transform: translateY(-2px); box-shadow: 0 8px 22px rgba(26, 77, 214, .32); }

/* ---------- LANE ACT · E-026: the agent / partner door beside the customer pair ----------
   The header now carries three links, and the two rules above are written positionally —
   :first-child is the quiet white button and :last-child is the loud gradient one. Adding a third
   <a> made THE NEW ONE the loud button and demoted "Register", which is the opposite of E-026:
   customer signup stays front and centre.
   So the partner door opts out of the button treatment entirely and is a plain text link, which
   is also the right hierarchy — it is a door for the small number of people who already have a
   partner account, not a third call to action competing with the two that matter. The `:last-child`
   rule is re-pointed at .btn-g's sibling by name rather than by position, so the pair keeps its
   quiet/loud reading whether or not this third link is present on a given page.
   --line and --ink are payco.css's marketing tokens; #3856a8 on #fff is 6.6:1. */
.mnav .cta > a.partner-door {
  min-height: 0; padding: 0 4px; border-radius: 0; border-color: transparent;
  background: none; box-shadow: none;
  font-size: 12.5px; font-weight: 600; color: #3856a8; text-decoration: underline;
  text-underline-offset: 2px;
}
.mnav .cta > a.partner-door:hover {
  transform: none; box-shadow: none; background: none; color: var(--ink, #0a1628);
}
.mnav .cta > a.btn-g {
  background: linear-gradient(135deg, #0b2a8a, #1a4dd6 35%, #3b82ff 70%, #6dd5fa);
  color: #fff; border-color: #2255d4;
}
/* ---------- LANE ACT · F§6.1: the two apply actions under the partners "How to start" step --- */
.pt-steps .pt-apply { display: flex; flex-wrap: wrap; gap: 10px; margin: 12px 0 0; }
.pt-steps .pt-apply .btn { margin: 0; }

/* ---------- the burger and the phone menu ---------- */
.mnav-burger { display: none; margin-left: auto; flex-direction: column; justify-content: center; gap: 5px;
  width: 44px; height: 44px; padding: 8px; background: none; border: 0; cursor: pointer; }
.mnav-burger span { display: block; width: 100%; height: 2.5px; border-radius: 2px;
  background: var(--ink, #0a1628); transition: transform .25s, opacity .2s; }
.mnav .links .mob-only { display: none; }

@media (max-width: 900px) {
  /* NO `display` on .cta > a — only on .cta itself. Setting it on the anchors is what
     overlapped the wordmark at 375px last time (overflow.mjs: "nothing in the header
     overlaps the logo -> overlapping: Sign In"). The phone gets the two .mob-only
     entries inside the menu instead, which is why they exist. */
  .mnav .cta { display: none; }
  .mnav-burger { display: flex; }
  .mnav .links {
    position: fixed; left: 0; right: 0; top: 74px; transform: none;
    flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 2px;
    background: #fff; border-bottom: 1px solid var(--line, #dce3f0);
    padding: 10px 16px 18px; box-shadow: 0 20px 40px rgba(11, 27, 58, .12);
    max-height: 0; overflow: hidden; opacity: 0; pointer-events: none;
    transition: max-height .3s ease, opacity .2s ease;
  }
  /* overflow-y:auto is load-bearing. The base rule sets overflow:hidden to make the
     max-height collapse work, and that stays in effect when the menu opens — so with
     13 items at ~48px (~620px) against 80vh (~534px on a 667px iPhone SE) the last
     entries were clipped with no way to scroll to them. */
  .mnav.open .links { max-height: 80vh; overflow-y: auto; opacity: 1; pointer-events: auto; }
  .mnav .links > * { flex: none; width: 100%; }
  .mnav .links > a,
  .mnav .links .drop > a.dtop {
    display: flex; font-size: 16px; font-weight: 700; padding: 13px 14px; border-radius: 12px;
    background: none; border: 0;
  }
  .mnav .links .mob-only { display: flex; justify-content: center; margin-top: 4px; }
  .mnav .links .mob-only:last-child {
    background: linear-gradient(135deg, #0b2a8a, #1a4dd6); color: #fff; text-align: center;
  }
  /* Flattened inside the burger — always open, never hover-dependent. A phone has no
     hover, so a submenu here would be a tap target that hides five destinations. */
  .mnav .drop { display: block; width: 100%; }
  .mnav .drop > a.dtop::after { display: none; }
  .mnav .dropm {
    position: static; transform: none; opacity: 1; visibility: visible;
    background: none; border: 0; box-shadow: none; padding: 0 0 4px 14px; min-width: 0;
  }
  .mnav .drop:hover .dropm, .mnav .drop:focus-within .dropm { transform: none; }
  .mnav .dropm a { font-size: 15px; font-weight: 600; padding: 11px 12px; }
  /* "All services →" is the panel's way back to the hub when the panel is a hover menu.
     Flattened, it sits directly under the "Services" link that goes to the same page — two
     adjacent taps for one destination. */
  .mnav .dropm a.all { display: none; }

  /* ---------- the injected six, flattened into the sheet (W9 LANE 9) ----------
     SAME RULE, SAME REASON, WRITTEN OUT FOR .mnavd. payco-marketing.js builds all six
     the moment the burger opens and then leaves them alone: below 900px they are not
     menus that open, they are sections of one long sheet. A phone has no hover, and a
     submenu here would be a tap target that hides five destinations — which is the
     argument the .dropm block above already makes and the reason these are not a
     collapsible accordion instead.

     44px IS THE FLOOR AND IT IS STATED, NOT INHERITED. The desktop row is 37px of padding
     and line-box, which is under the platform minimum; tests/marketingui2.mjs opens the
     burger at 375 and fails the page for any anchor in it under 44. min-height plus a
     centred flex box is the only form that holds whether the label wraps to two lines or
     not, which the longer industry names do at 375. */
  .mnav .links > a.mnavd-trig::after { display: none; }
  .mnav .mnavd {
    position: static; left: auto; transform: none; opacity: 1; visibility: visible;
    background: none; border: 0; box-shadow: none; padding: 0 0 4px 14px;
    min-width: 0; max-width: none; width: 100%; max-height: none; overflow: visible;
  }
  .mnav .mnavd a, .mnav .mnavd-mega a {
    display: flex; align-items: center; min-height: 44px;
    font-size: 15px; font-weight: 600; padding: 6px 12px; border-radius: 9px;
    white-space: normal;
  }
  /* The way back to the hub is the top-level link itself, one row above. */
  .mnav .mnavd .mnavd-all { display: none; }
  /* One column, and the captions stay: nine of them are what makes sixty-eight rows
     navigable by thumb instead of being one undifferentiated list. */
  .mnav .mnavd-mega { width: 100%; padding: 0 0 4px 14px; }
  .mnav .mnavd-cols { display: none; }
  .mnav .mnavd-cats { display: block; }
  .mnav .mnavd-cats a { justify-content: space-between; }
  .mnav .mnavd-n {
    font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
    color: var(--ink-mute, #5a6885); padding-left: 10px;
  }
  .mnav.open .mnav-burger span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
  .mnav.open .mnav-burger span:nth-child(2) { opacity: 0; }
  .mnav.open .mnav-burger span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }
}

@media (prefers-reduced-motion: reduce) {
  .mnav .cta > a, .mnav-burger span, .mnav .links, .mnav .logo { transition: none; }
  .mnav .cta > a:hover { transform: none; }
  /* The glow stays — it is a colour change, not motion. Only the 1px lift goes. */
  .mnav .logo:hover, .mnav .logo:focus-visible { transform: none; }
  /* ABSOLUTELY, per the design law. The panels still appear and disappear — that is the
     function — but nothing slides, nothing rotates and nothing fades: the 8px-to-2px
     travel, the chevron's half-turn and the opacity ramp are all motion, and a menu is
     the surface where motion sickness is most reliably provoked because it is crossed
     dozens of times in a session. visibility is left in the transition list on neither,
     because with the durations gone it has nothing to delay. */
  .mnav .dropm, .mnav .mnavd,
  .mnav .drop > a.dtop::after, .mnav .links > a:not(.mob-only)::after { transition: none; }
  .mnav .mnavd { transform: none; }
  .mnav .mnavd.on { transform: none; }
  .mnav .drop:hover > a.dtop::after, .mnav .drop:focus-within > a.dtop::after,
  .mnav .links > a.mnavd-open::after { transform: none; }
}

/* ---------- dark ----------
   RULE 7: dark is [data-theme='dark'] and --pc-* tokens, never a second hardcoded palette.
   Every page that carries this header also carries css/payco-hud.css, which is where those
   tokens are declared on :root and re-declared under [data-theme='dark'] — except 404.html,
   which loads this file and the font and nothing else, so every var() below carries the
   hud sheet's own literal as its fallback and 404 renders exactly as it does today.

   THE WHOLE BAR MOVES, NOT ONLY THE PANELS. A dark dropdown hanging off a bar still
   painted rgba(251,252,254,.86) is not a dark theme, it is a bug with a switch on it. The
   gradients are deliberately NOT re-pointed: they run through the deep end of the brand
   blue and are used as fills behind white text, so they carry their own contrast with them
   — the one thing css/payco-system.css's dark block says to preserve across themes.

   INERT UNTIL SOMETHING SETS THE ATTRIBUTE. No public marketing page sets data-theme today
   (index.html suppresses the HUD's theme control outright), so this block changes nothing
   that is currently rendered; it is what the header does the day one of them does. */
[data-theme="dark"] .mnav {
  background: color-mix(in srgb, var(--pc-surface, hsl(220 18% 9%)) 86%, transparent);
  border-bottom-color: var(--pc-line, hsl(218 13% 26%));
}
[data-theme="dark"] .mnav .links > a,
[data-theme="dark"] .mnav .links .drop > a.dtop {
  background: var(--pc-surface-3, hsl(220 14% 18%));
  border-color: var(--pc-line, hsl(218 13% 26%));
  color: var(--pc-ink-soft, hsl(214 14% 80%));
}
[data-theme="dark"] .mnav .dropm,
[data-theme="dark"] .mnav .mnavd {
  background: var(--pc-surface-2, hsl(220 16% 13%));
  border-color: var(--pc-line, hsl(218 13% 26%));
  box-shadow: var(--pc-shadow-lg, 0 28px 80px hsl(220 30% 2% / .68), 0 4px 16px hsl(220 30% 2% / .5));
}
[data-theme="dark"] .mnav .dropm a,
[data-theme="dark"] .mnav .mnavd a { color: var(--pc-ink-soft, hsl(214 14% 80%)); }
[data-theme="dark"] .mnav .dropm a:hover,
[data-theme="dark"] .mnav .mnavd a:hover,
[data-theme="dark"] .mnav .mnavd a:focus-visible {
  background: var(--pc-accent-soft, hsl(218 100% 66% / .16));
  color: var(--pc-ink, hsl(210 22% 96%));
}
[data-theme="dark"] .mnav .dropm a.all,
[data-theme="dark"] .mnav .mnavd .mnavd-all {
  border-top-color: var(--pc-line-soft, hsl(219 14% 21%));
  color: var(--pc-accent, hsl(218 100% 66%));
}
[data-theme="dark"] .mnav .mnavd-cap { color: var(--pc-ink-mute, hsl(216 11% 64%)); }
[data-theme="dark"] .mnav-burger span { background: var(--pc-ink, hsl(210 22% 96%)); }
[data-theme="dark"] .mnav .cta > a:first-child {
  background: var(--pc-surface-3, hsl(220 14% 18%));
  color: var(--pc-ink, hsl(210 22% 96%));
  border-color: var(--pc-line, hsl(218 13% 26%));
}
@media (max-width: 900px) {
  [data-theme="dark"] .mnav .links { background: var(--pc-surface-2, hsl(220 16% 13%));
    border-bottom-color: var(--pc-line, hsl(218 13% 26%)); }
  [data-theme="dark"] .mnav .links > a,
  [data-theme="dark"] .mnav .links .drop > a.dtop { background: none; }
  [data-theme="dark"] .mnav .mnavd { background: none; }
}

/* ---------- focus ----------
   The panels' rows had no visible focus ring of their own: `.mnav .dropm a` clears
   background, border and box-shadow, so a browser default outline was the only mark and
   several of these pages reset it. Both menus now take the SAME ring, drawn inside the
   row's own radius so it cannot be clipped by the panel's overflow. */
.mnav .dropm a:focus-visible, .mnav .mnavd a:focus-visible,
.mnav .links > a:focus-visible, .mnav .links .drop > a.dtop:focus-visible {
  outline: 2px solid var(--pc-accent, #1a4dd6); outline-offset: 2px;
}

/* ---------- footer: the legal row is not optional on a registered MSP/ISO ---------- */
footer .legal-links a, footer a[href="privacy.html"], footer a[href="terms.html"] { white-space: nowrap; }

/* ---------- the right rail is furniture on this tier too (HUD v4, LANE B) ----------
   payco-hud.js draws its right-hand taskbar on any page that links css/payco-hud.css, and every
   page on this tier links it. It is a position:fixed column down the right edge, so a page that
   reserves nothing paints its own content underneath it.

   MEASURED at 1440, headless chromium, all 23 pages that do NOT link payco.css: three of them
   draw the rail — boarding-advisor.html and free-statement-audit.html already reserve 128px in
   their own <style> and clear it by 32px and 20px, and programs.html reserved nothing and ran its
   footer row 104px under the rail. This block is the reservation those two wrote by hand, made
   once for the tier so the next page to draw the rail does not have to know.

   THE NARROW RESERVATION ONLY — the rail and the standard air, never payco.css's 400px flyout
   lane. That lane exists so an anchored HUD panel can open BESIDE a console's content instead of
   over it; these are centred single-column marketing layouts where a panel over the page is the
   normal reading and a 528px right gutter would pull every hero off its own centre line. The
   trade is deliberate and it is the one difference between the two tiers' copies of this law.

   The numbers are payco-hud.js's own published inset plus payco.css's 28px gutter, restated here
   because this tier does not link that sheet. Above 1100px only — css/payco-hud.css removes both
   rails below it. */
@media (min-width: 1101px) {
  /* THE SWITCH, as payco.css states it: --pc-hud-right is the rail's occupancy, so min() makes it
     the presence test too — zero gutter exactly when the rail takes no space, including when it
     is in the DOM but display:none. A :has() on the element cannot tell those apart. */
  /* --pc-hud-right-open, not --pc-hud-right: the reservation is the rail's OPEN width in both
     states, so a collapse does not reflow the page (payco.css §lane, HUD v4.1 §2). Same switch —
     the token is 0px whenever the rail is not drawn — and the same 0px fallback for a page that
     never loaded the HUD. */
  :root { --pc-mkt-lane:min(calc(var(--pc-hud-right-open, var(--pc-hud-right, 0px)) * 100),
                            calc(var(--pc-hud-right-open, var(--pc-hud-right, 0px)) + 28px)); }
  html body { padding-right: var(--pc-mkt-lane); }
  /* A page that already pads itself for the same rail must not pay twice. */
  html body.pc-hud-inset, html body:has(> .pc-hud-inset) { padding-right: 0; }

  /* THE BAR AND THE FOOTER: BACKGROUND TO THE WINDOW EDGE, CONTENT IN THE LANE.
     Both are in normal flow — nav.mnav is position:sticky, which is — so the gutter cuts them
     short and the page's own background shows in the 156px beyond. And unlike the console tier's
     header, BOTH sit inside the rail's vertical span: payco-hud.js pins the right dock under the
     page chrome it can find, and it finds none here, so on programs.html the rail runs y0..740
     from the very top of the window. Restoring the bar whole put its "Register" button at
     [1307..1400] straight under a rail at x1312 — measured, and the reason this is not the same
     rule payco.css writes for header.pc-header.
     A TRANSPARENT BORDER DOES BOTH AT ONCE. background-clip defaults to border-box, so the band
     paints out to the window edge underneath its own border; box-sizing:border-box takes that
     border off the content box, so the content stops at the lane. And the band's OWN padding —
     40px on the bar, 24/32px on the footers — survives untouched inside it, which a padding-right
     written here would have had to replace with a number it cannot read. */
  html body nav.mnav, html body header.pc-header, html body > footer {
    margin-right: calc(-1 * var(--pc-mkt-lane));
    border-right: var(--pc-mkt-lane) solid transparent;
  }
}


/* ==================================================================================
   THE 44px TAP FLOOR ON THE PUBLIC SURFACE  (was css/payco-a11y.css, W8 lane 14)
   ----------------------------------------------------------------------------------
   MEASURED BEFORE: 112 controls under 44px high across the eleven public pages that
   link this sheet, at a 375px viewport, by tests/designfix.mjs's own algorithm
   (a,button,[role=button],summary,select; rect.height < 44; minus its inSentence()
   exemption). tests/a11yw8.mjs §7c proves the remedy: it opens each page, appends
   css/payco-a11y.css, re-runs that algorithm and gets an empty list.

   WHY THE RULES ARE HERE AND NOT THERE. css/payco-a11y.css is on disk and linked by
   ZERO pages — it needed a <link> in twelve <head>s (IR-A, docs/lane-reports/
   W8-LANE-14.md §5) and lane 14 owned no .html, so every rule in it has been dead
   text for two waves. This lane owns no .html either. A stylesheet that is already
   linked by all eleven of those pages is the one place the fix can land without one.
   The request to add the tag is still filed; if it lands, the tag's sheet declares
   the same values and nothing moves.

   THE `:root ` PREFIX IS THE WHOLE REASON THIS WORKS FROM HERE. css/payco-a11y.css
   was written to be the LAST sheet in <head>, because its selectors are at the same
   specificity as the page rules they override and several of those live inside the
   page's own `@media (max-width:560px)` block — which sits BELOW this <link> on
   eight of the eleven pages. `:root` is (0,1,0) and always matches <html>, so it
   changes no element and wins on specificity instead of on order.

   min-height, never padding: padding grows a box in BOTH axes and six pages in this
   tree already scroll sideways at 320px. `display:inline-flex` is what makes
   min-height apply at all to an inline link, and `align-items:center` keeps the
   label optically where it was. 767px, not 560px: a target does not stop needing a
   finger at 561px, and no browser suite in tests/ measures between the two.
   ================================================================================== */
@media (max-width: 767px) {

  /* 1. The shared marketing footer — 54 links across nine pages at 38.4px, plus the
        Privacy / Terms / Application status row at 17px. Authored as bare <a>
        children of <footer> and of the plain <div>s in it, so the direct-child
        combinator is the only handle, and it keeps this off links nested in prose. */
  :root footer > a,
  :root footer > div > a { display: inline-flex; align-items: center; min-height: 44px; }

  /* 2. Breadcrumb — `<nav class="crumb"><a>Home</a> > Pricing</nav>`, 15px, eight pages. */
  :root nav.crumb > a { display: inline-flex; align-items: center; min-height: 44px; }

  /* 3. 404.html's "where to go instead" list — already flex and full width, just 34px. */
  :root .where ul li > a { min-height: 44px; }

  /* 4. pricing.html's two comparison tables. `:only-child` IS designfix's inSentence()
        rule expressed in CSS: a cell that also holds prose keeps its inline link.
        Both tables sit in a `.tw` scroller, so a taller row cannot widen the page. */
  :root table.cmp td > a:only-child { display: inline-flex; align-items: center; min-height: 44px; }

  /* 5. advisor.html's own header — it links neither marketing sheet, so this pair is
        carried for the day its <head> gains one. `.adv-skip` is off-screen until
        focus, so it costs a keyboard user a target and everyone else nothing. */
  :root .adv-top a,
  :root a.adv-skip { display: inline-flex; align-items: center; min-height: 44px; }

  /* 6. company.html / partners.html contact and "read on" links — already inline-flex
        at 36px from `.co-card a.line` / `.pt-card a.line` (0,2,1), so the class is in
        the selector for RANK, not for scope. */
  :root .co-contact .co-card a.line,
  :root .pt-contact .pt-card a.line,
  :root a.pt-more,
  :root .co-aside > a { align-items: center; min-height: 44px; }

  /* 7. The card "arrow" links: a paragraph whose entire content is one link, on
        products.html and pricing.html. `:only-child` again. */
  :root .card > p > a:only-child { display: inline-flex; align-items: center; min-height: 44px; }
}
