/* =============================================================================================
 * css/payco-industries-depth.css — THE ONE SKIN FOR THE SIXTY-EIGHT INDUSTRY PAGES.
 *
 * OWNER: W9 lane 8 (industries). Linked by all 68 of industries/<slug>.html and by nothing else.
 * css/payco-industries.css remains the skin for industries.html and industries/_template.html;
 * the two sheets share values and share nobody's selectors — see THE SEAM below.
 *
 * ---------------------------------------------------------------------------------------------
 * WHY THIS FILE IS NOW THE WHOLE SKIN AND NOT A "DEPTH LAYER"
 * ---------------------------------------------------------------------------------------------
 * W8 shipped the 68 pages from three lanes working in parallel, and the presentation ended up in
 * SIXTY-EIGHT INLINE <style> BLOCKS in five mutually incompatible dialects. Measured at 23bba6d:
 *
 *     20 pages  ../payco.css                              + one <style>   (.ind-page/.ind-rail)
 *     17 pages  ../vendor/inter + css/payco-industries.css + two <style>  (.ind-panel/.ind-item)
 *     13 pages  fonts.googleapis.com + ../payco.css        + one <style>  (.ind-card/.ind-bar)
 *     10 pages  fonts.googleapis.com + css/payco-industries.css + <style>
 *      8 pages  ../vendor/inter                            + two <style>
 *
 * Five type scales, five card treatments, three hairline weights, two font delivery mechanisms
 * (one of them a third-party CDN), and NO SITE HEADER on any of them: an industry page opened
 * from search did not look like payco.ai. The inline blocks are gone; this file replaced them.
 * A page that ships its own <style> again re-forks the design, and tests/industries-b.mjs §3 and
 * tests/industriesw8b.mjs D.nolocalcss both fail it.
 *
 * ---------------------------------------------------------------------------------------------
 * DERIVE, DO NOT INVENT.
 * ---------------------------------------------------------------------------------------------
 * Every value below is quoted from a sheet that already ships, with the source named inline:
 *
 *     type scale, hero      marketing-core.css   h1 clamp(34px,5.4vw,58px)/1.05/-.04em
 *     section heading       css/payco-industries.css  .pci-h2  clamp(24px,3.6vw,38px)/1.12/-.03em
 *     eyebrow               css/payco-industries.css  .pci-eyebrow  12px/800/.2em/uppercase
 *     rhythm                css/payco-industries.css  --pci-pad / --pci-gap / --pci-band
 *     hairline              css/payco-industries.css  --pci-rule-w: 1.5px  ("one hair thicker")
 *     radius, shadow        payco.css  --radius / --radius-sm / --shadow-sm / --shadow-md
 *     motion                css/payco-industries.css  cubic-bezier(.32,.72,0,1), .18s / .42s
 *     column                marketing-core.css   .wrap  max-width:1120px
 *     header                payco-marketing.css  .mnav — linked by the pages, NOT restated here
 *
 * NO HARDCODED HEX, ANYWHERE IN THIS FILE (rule 7). Every colour is a --pc-* token with a
 * legacy-token fallback, so the sheet works whether or not css/payco-hud.css resolved:
 *     var(--pc-<role>, var(--<payco.css role>))
 * Dark is a token flip on [data-theme="dark"] plus §8, which carries only the things a token
 * swap cannot express — shadow weight on a dark ground, and the marketing header's own bar.
 *
 * ---------------------------------------------------------------------------------------------
 * THE SEAM, STATED ONCE (this is the W7 failure this file exists to end)
 * ---------------------------------------------------------------------------------------------
 * THE IMAGE CONTRACT. Exactly one shape, baked at authoring time, never resolved at run time:
 *
 *     <img class="…" src="{imageSrc(bySlug(slug))}" alt="" aria-hidden="true"
 *          width="{entry.imageWidth}" height="{entry.imageHeight}" …>
 *
 * `imageSrc(bySlug(slug))` from industries/registry.js is the ONLY source of that string, and the
 * same string is repeated in <meta property="og:image">, <meta name="twitter:image"> and the
 * JSON-LD primaryImageOfPage. Baked, because og:image is read by a crawler that runs no
 * JavaScript, and because /industries/registry.js is not matched by the middleware's
 * PUBLIC_INDUSTRY pattern (`[a-z0-9-]+` admits no dot) — it 401s for the anonymous visitor these
 * pages exist for, so a run-time hero never paints for the audience. width/height are the
 * registry's own imageWidth/imageHeight: the box is reserved before the photograph arrives, so
 * the hero does not shift the page as it loads. alt="" + aria-hidden because the placeholder
 * photograph's SUBJECT is unverified (industries/registry.js says so at its head), and a caption
 * would be a claim about a picture nobody has looked at. tests/industriesw8b.mjs §4 re-derives
 * all four copies from the registry, so a drift is a red suite and not a dead hero.
 *
 * CLASS OWNERSHIP. This sheet paints `.ind-*`, `.pc-ind-*`, `.pcw8-*` and `.pc-tip`, and nothing
 * else. css/payco-industries.css paints `.pci-*` and nothing else. No selector appears in both
 * files, so neither can perturb the other, and industries.html keeps its own suite.
 *
 *   §1 tokens   §2 shell + header + footer   §3 hero   §4 sections and headings
 *   §5 cards and grids   §6 guide, FAQ, tools   §7 form and closing   §8 dark   §9 reveal
 *   §10 mobile floors  (§10 IS LAST ON PURPOSE — a rule appended below it would win on source
 *   order and silently revert the 12px type and 44px tap floors it raises.)
 * ============================================================================================= */


/* =============================================================================================
 * §1  TOKENS — the only block in this file allowed to name a token from another sheet.
 * ============================================================================================= */
:root {
  /* ---- ink ---- */
  --ind-ink:        var(--pc-ink,        var(--ink));
  --ind-soft:       var(--pc-ink-soft,   var(--ink-soft));
  --ind-mute:       var(--pc-ink-mute,   var(--ink-mute));
  --ind-invert:     var(--pc-ink-invert, var(--white));

  /* ---- paper ---- */
  --ind-bg:         var(--pc-bg,         var(--paper-warm));
  --ind-card-bg:    var(--pc-surface,    var(--white));
  --ind-recess:     var(--pc-surface-2,  var(--paper));

  /* ---- brand ---- */
  --ind-brand:      var(--pc-brand,      var(--blue));
  --ind-brand-deep: var(--pc-brand-deep, var(--blue-deep));
  --ind-accent:     var(--pc-accent,     var(--blue));
  --ind-focus:      var(--pc-focus,      var(--blue-electric));
  --ind-ramp:       var(--pc-ramp,       var(--gradient));
  --ind-sliver:     var(--pc-sliver,     var(--sliver));
  --ind-tint:       var(--pc-accent-soft, var(--info-bg));

  /* ---- semantic ---- */
  --ind-ok:         var(--pc-ok,         var(--ok));
  --ind-bad:        var(--pc-bad,        var(--warn));
  --ind-bad-bg:     var(--pc-bad-bg,     var(--warn-bg));

  /* ---- edges. ONE hairline weight on this whole surface, and it is one hair thicker than the
     site's 1px: on a 2x screen 1.5px is a crisp three device pixels, on a 1x screen the browser
     rounds it to 2. Quoted from css/payco-industries.css --pci-rule-w. ---- */
  --ind-hair:       1.5px;
  --ind-line:       var(--pc-line,       var(--line));
  --ind-line-soft:  var(--pc-line-soft,  var(--line-soft));

  /* ---- elevation. ONE shadow for a resting box, ONE for a lifted one. ---- */
  --ind-lift:       var(--pc-shadow-sm,  var(--shadow-sm));
  --ind-lift-hi:    var(--pc-shadow-md,  var(--shadow-md));

  /* ---- geometry. ONE radius, and its small partner for controls. ---- */
  --ind-radius:     var(--pc-radius,     var(--radius));
  --ind-radius-sm:  var(--pc-radius-sm,  var(--radius-sm));
  --ind-radius-lg:  var(--pc-radius-lg,  var(--radius-lg));

  /* ---- the column. marketing-core.css .wrap, so an industry page is the same width as
     pricing.html and products.html and the reader crosses between them without the text
     column moving. ---- */
  --ind-maxw:       1120px;
  --ind-pad:        clamp(20px, 3.4vw, 34px);
  --ind-gap:        clamp(14px, 2vw, 22px);
  --ind-band:       clamp(46px, 7vw, 86px);

  /* ---- motion. ONE curve for the whole surface. ---- */
  --ind-ease:       var(--ease-std, cubic-bezier(.32, .72, 0, 1));   /* W5 POLISH: one curve */
  --ind-fast:       var(--dur-fast, .16s);   /* W5 POLISH: was .18s */
  --ind-slow:       var(--dur-slow, .34s);   /* W5 POLISH: was .42s */

  /* ---- floors. §10 raises --ind-tap and never lowers it. ---- */
  --ind-tap:        44px;
}


/* =============================================================================================
 * §2  THE SHELL — page ground, the centred column, and the two site rails.
 *
 * SYMMETRY IS BY CONSTRUCTION. There is exactly one width and one horizontal padding on this
 * page, declared on the band, so nothing inside a band can drift off axis. Five dialects each
 * had their own wrapper class; all five now resolve to the same box.
 * ============================================================================================= */
html { scroll-behavior: smooth; }
/* TWO DECLARATIONS, BOTH LOAD-BEARING, IN THIS ORDER — marketing-core.css's own note applies
   verbatim: `hidden` makes html and body scroll containers and kills every position:sticky
   (which is what the header is); `clip` prevents the same sideways scroll without doing that.
   A browser too old for `clip` discards the second line and keeps the first, which is the
   lesser failure. Delete neither, and do not reorder them. */
html, body { max-width: 100%; overflow-x: hidden; overflow-x: clip; }

body {
  margin: 0;
  background: var(--ind-bg);
  color: var(--ind-ink);
  font-family: var(--pc-font, var(--font, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif));
  font-size: 15.5px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
}
.ind-page, .ind-wrap, .ind-page img, .ind-wrap img { box-sizing: border-box; }
body img, body svg { max-width: 100%; }

/* The centred column. `main` and `.ind-wrap` are the two wrappers the five dialects shipped;
   both are this box. `.ind-wrap` nests inside itself on two of the shapes, and a nested copy
   must not re-pad — hence the reset on the inner one. */
main,
.ind-wrap {
  width: 100%;
  max-width: var(--ind-maxw);
  margin-inline: auto;
  padding-inline: clamp(16px, 4vw, 32px);
}
main .ind-wrap,
.ind-wrap .ind-wrap { max-width: none; padding-inline: 0; }
main { display: block; padding-bottom: var(--ind-band); }

/* The skip link. Same geometry as payco.css .pc-skip so it behaves identically on both sides of
   the sign-in line; restated here because 25 of the 68 do not link a sheet that carries it. */
.ind-skip {
  position: absolute; left: 12px; top: -80px; z-index: 200;
  display: inline-flex; align-items: center; min-height: var(--ind-tap);
  padding: 12px 16px; border-radius: 0 0 var(--ind-radius-sm) var(--ind-radius-sm);
  background: var(--ind-card-bg); color: var(--ind-brand-deep);
  border: var(--ind-hair) solid var(--ind-line); border-top: 0;
  font-size: 13px; font-weight: 700; text-decoration: none;
  box-shadow: var(--ind-lift-hi);
  transition: top var(--ind-fast) var(--ind-ease);
}
.ind-skip:focus { top: 0; }

/* THE BREADCRUMB. One trail, under the site bar, on the same axis as everything else. Three
   dialects drew this three ways (a flex row with slashes, a nav of pills, a bare paragraph);
   this is marketing-core.css's `.crumb`, in tokens. */
.ind-crumb,
nav.ind-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  width: 100%; max-width: var(--ind-maxw); margin-inline: auto;
  padding: 14px clamp(16px, 4vw, 32px) 0;
  font-size: 12.5px; color: var(--ind-mute);
}
.ind-crumb a,
nav.ind-bar a { color: var(--ind-brand); text-decoration: none; font-weight: 600; }
.ind-crumb a:hover,
nav.ind-bar a:hover { text-decoration: underline; }
main > .ind-crumb, main > nav.ind-bar { padding-inline: 0; }

/* THE SITE FOOTER. marketing-core.css's `footer`, in tokens, so the foot of an industry page is
   the foot of pricing.html. */
body > footer {
  border-top: var(--ind-hair) solid var(--ind-line);
  margin-top: var(--ind-band);
  padding: 30px clamp(16px, 4vw, 32px);
  text-align: center; font-size: 12.5px; color: var(--ind-mute);
  background: var(--ind-recess);
}
body > footer a {
  display: inline-block; color: var(--ind-brand); text-decoration: none;
  font-weight: 600; margin: 0 9px; padding: 6px 10px; white-space: nowrap;
}
body > footer a:hover { text-decoration: underline; }
.ind-foot-row { margin-top: 4px; }
.ind-foot-row + .ind-foot-row { margin-top: 10px; }
.ind-foot-legal {
  margin: 14px auto 0; max-width: 900px;
  font-size: 12px; line-height: 1.6; color: var(--ind-mute);
}

/* The old per-page sign-off line, kept because the copy is good; it is now a caption above the
   real footer rather than a page's entire foot. */
.ind-foot {
  margin: var(--ind-band) 0 0; padding-top: 20px;
  border-top: var(--ind-hair) solid var(--ind-line);
  font-size: 12.5px; color: var(--ind-mute); text-align: center;
}

/* The HUD viewports are structural, not visual — they must not open a gap in the flow. */
[data-hud] { display: block; }


/* =============================================================================================
 * §3  THE HERO — one pattern, centred, with the photograph in a real frame.
 * ============================================================================================= */
.ind-hero {
  max-width: var(--ind-maxw); margin-inline: auto;
  padding: clamp(28px, 5vw, 56px) 0 clamp(6px, 1vw, 12px);
  text-align: center;
}
.ind-eyebrow {
  margin: 0 0 12px;
  font-size: 12px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase;
  color: var(--ind-brand);
}
.ind-hero h1,
main h1 {
  margin: 0 auto 18px; max-width: 18ch;
  font-size: clamp(34px, 5.4vw, 58px); line-height: 1.05; letter-spacing: -.04em;
  font-weight: 700; color: var(--ind-ink);
  text-wrap: balance;
}
.ind-lede {
  margin: 0 auto 26px; max-width: 62ch;
  font-size: clamp(15.5px, 1.6vw, 18px); line-height: 1.6; color: var(--ind-soft);
}

/* The hero actions. One primary, one quiet, centred under the lede. */
.ind-cta {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
  margin: 0 auto 26px;
}

/* THE PHOTOGRAPH. `.ind-shot` and `.ind-media` are the two names the dialects used; one frame.
   The aspect ratio is the registry's (16/9) so the box is the right shape before the bytes land,
   and the width/height attributes on the <img> reserve it even with CSS unavailable. */
.ind-shot,
.ind-media {
  position: relative; margin: 0 auto; overflow: hidden;
  max-width: var(--ind-maxw);
  border: var(--ind-hair) solid var(--ind-line);
  border-radius: var(--ind-radius-lg);
  background: var(--ind-recess);
  box-shadow: var(--ind-lift-hi);
}
.ind-shot img,
.ind-media img {
  display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover;
  background: var(--ind-recess);
}
/* A dead image id degrades to the brand ramp rather than to a broken-image glyph. */
.ind-shot.is-plain, .ind-media.is-plain { background: var(--ind-ramp); min-height: 180px; }
.ind-shot.is-plain img, .ind-media.is-plain img { display: none; }
.ind-shot figcaption,
.ind-media figcaption {
  padding: 11px 15px; font-size: 12.5px; color: var(--ind-mute); text-align: center;
}


/* =============================================================================================
 * §4  SECTIONS AND HEADINGS — one rhythm, one pair, centred.
 * ============================================================================================= */
main section { margin: var(--ind-band) 0; }
main section:first-of-type { margin-top: calc(var(--ind-band) * .7); }

/* `.ind-rail` is the small uppercase line above a section heading. It used to be drawn with a
   flex hairline running off to the right edge — an asymmetry on a page whose every other
   element is centred. It is now the same eyebrow the hero uses, which is the whole "one of
   each" rule: this page has one eyebrow, not two. */
.ind-rail {
  margin: 0 0 10px;
  font-size: 12px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase;
  color: var(--ind-brand); text-align: center;
}
main h2,
.pc-ind-guide__h {
  margin: 0 auto 12px; max-width: 24ch;
  font-size: clamp(24px, 3.6vw, 38px); line-height: 1.12; letter-spacing: -.03em;
  font-weight: 700; color: var(--ind-ink); text-align: center;
  text-wrap: balance;
}
.ind-sub {
  margin: 0 auto; max-width: 62ch;
  font-size: clamp(15px, 1.4vw, 17px); color: var(--ind-soft); text-align: center;
}
main h3 {
  margin: 0 0 8px;
  font-size: 17px; font-weight: 800; letter-spacing: -.02em; color: var(--ind-ink);
}
.ind-note { margin: 12px auto 0; max-width: 62ch; font-size: 13.5px; color: var(--ind-mute); text-align: center; }
.ind-updated { margin: 18px auto 0; font-size: 12.5px; color: var(--ind-mute); text-align: center; }

/* The section-level panel two dialects wrap a whole band in. It is a band, not a card: a page
   made of eight bordered boxes inside eight more bordered boxes is the "mismatched" the rebuild
   is for. It keeps the rhythm and drops the frame. */
.ind-panel {
  margin: var(--ind-band) 0;
  padding: 0;
  background: none;
  border: 0;
}


/* =============================================================================================
 * §5  CARDS AND GRIDS — THREES.
 *
 * Three boxes per row, and never four with one hanging. Two of the dialects ship a four-card
 * band, which in a three-track grid lays out 3 + 1 and orphans the fourth on its own line at
 * every desktop width; the quantity query below turns exactly-four into 2 x 2. Five becomes
 * 3 + 2 centred by the same rule set. A card's text is centred, like every other box here.
 * ============================================================================================= */
.ind-grid {
  display: grid;
  gap: var(--ind-gap);
  grid-template-columns: 1fr;
  align-items: stretch;
  margin-top: 26px;
  /* 58 OF THE 68 PAGES WRITE THIS ON A <ul>, and a <ul> carries a 40px UA
     `padding-inline-start`. The cards therefore sat 20px right of the centre of their own
     container on every one of those pages — measured at 1440 on every row of every grid, a
     constant +20.0px — which is a symmetry break you can see against the hero above it and
     cannot see in any single row on its own. Zeroed here rather than per-page. */
  padding: 0;
  list-style: none;
}
/* THE TRACK COUNT IS DOUBLE THE COLUMN COUNT AND EVERY CARD SPANS TWO. That is the whole
   mechanism, and it is here because a three-track grid cannot centre a trailing row: with
   `repeat(3,1fr)` a five-card band lays out 3 + 2 hard against the LEFT rail and a two-card
   band leaves the third track empty on the right — measured on all 68 pages before this
   rewrite, worst on the free-tool band, which is two cards on every page in the set. Six
   half-tracks give a trailing pair somewhere to start (track 2) and a trailing single somewhere
   to sit (track 3), so the last row is centred between the rails like everything else. */
@media (min-width: 640px)  {
  .ind-grid:not(.pc-ind-guide__body) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .ind-grid:not(.pc-ind-guide__body) > * { grid-column: span 2; }
  /* two per row here, so only a trailing SINGLE can be orphaned. */
  .ind-grid:not(.pc-ind-guide__body) > :nth-child(2n + 1):last-child { grid-column: 2 / span 2; }
}
@media (min-width: 960px)  {
  .ind-grid:not(.pc-ind-guide__body) { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .ind-grid:not(.pc-ind-guide__body) > * { grid-column: span 2; }
  /* RESET THE TWO-COLUMN CENTRING RULE FROM THE SMALLER BREAKPOINT FIRST. It is a
     `> :nth-child(2n+1):last-child` selector of the same 0,3,0 weight as the three-column rules
     below, so it is NOT overridden by them — it is only overridden by an equally weighted rule
     later in the source. Measured without this line: a category of exactly THREE laid out 2 + 1,
     because item 3 matched 2n+1:last-child, was sent to track 2, and could not fit beside the
     first two. The same defect is in css/payco-industries.css and is fixed there the same way. */
  .ind-grid:not(.pc-ind-guide__body) > :nth-child(2n + 1):last-child { grid-column: span 2; }
  /* trailing single -> the middle track pair. */
  .ind-grid:not(.pc-ind-guide__body) > :nth-child(3n + 1):last-child { grid-column: 3 / span 2; }
  /* trailing pair -> starts one half-track in, so the two of them straddle the centre. */
  .ind-grid:not(.pc-ind-guide__body) > :nth-child(3n + 1):nth-last-child(2) { grid-column: 2 / span 2; }
  .ind-grid:not(.pc-ind-guide__body) > :nth-child(3n + 2):last-child        { grid-column: 4 / span 2; }
}

/* EXACTLY FOUR CHILDREN -> 2 x 2, at every width where the grid is multi-track. :has() with a
   quantity selector: "there is a 4th child and it is the last one". Four in a three-column band
   is the "four with one hanging" the law names by hand, so it never gets three tracks. */
@media (min-width: 960px) {
  .ind-grid:not(.pc-ind-guide__body):has(> :nth-child(4):last-child) { grid-template-columns: repeat(4, minmax(0, 1fr)); max-width: 860px; margin-inline: auto; }
  .ind-grid:not(.pc-ind-guide__body):has(> :nth-child(4):last-child) > *                          { grid-column: span 2; }
  .ind-grid:not(.pc-ind-guide__body):has(> :nth-child(4):last-child) > :nth-child(3n + 1):last-child,
  .ind-grid:not(.pc-ind-guide__body):has(> :nth-child(4):last-child) > :nth-child(3n + 1):nth-last-child(2),
  .ind-grid:not(.pc-ind-guide__body):has(> :nth-child(4):last-child) > :nth-child(3n + 2):last-child { grid-column: span 2; }
}

/* THE CARD. `.ind-card` and `.ind-item` are the two names the dialects used; one card.
   The house sliver along the top edge is payco.css's `.card` treatment, so a card on an
   industry page is the same object as a card on products.html. */
.ind-card,
.ind-item {
  display: flex; flex-direction: column; gap: 8px;
  padding: var(--ind-pad);
  text-align: center;
  background:
    var(--ind-sliver) top center / 100% var(--sliver-h, 3px) no-repeat,
    var(--ind-card-bg);
  background-origin: border-box;
  border: var(--ind-hair) solid var(--ind-line);
  border-radius: var(--ind-radius);
  box-shadow: var(--ind-lift);
  transition: background-size var(--ind-fast) var(--ind-ease),
              box-shadow var(--ind-fast) var(--ind-ease),
              transform var(--ind-fast) var(--ind-ease),
              border-color var(--ind-fast) var(--ind-ease);
}
.ind-card > h3, .ind-item > h3 { margin: 0; }
.ind-card p, .ind-item p {
  margin: 0 auto; max-width: 46ch;
  font-size: 14.5px; color: var(--ind-soft);
}
@media (hover: hover) {
  .ind-card:hover, .ind-item:hover {
    --sliver-h: var(--sliver-h-hover, 4px);
    transform: translateY(-3px);
    box-shadow: var(--ind-lift-hi);
    border-color: var(--ind-line-soft);
  }
}

/* The draft marker two dialects use on a claim that is still with counsel. A quiet pill, not a
   highlighter stripe. */
.ind-draft {
  display: inline-block; align-self: center;
  margin-top: 4px; padding: 3px 10px;
  font-size: 12px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ind-bad); background: var(--ind-bad-bg);
  border-radius:999px;
}

/* THE TOOLTIP. One affordance, 17px on a pointer and a full tap target on a phone (§10).
   `all: unset` first, because it is a <button> and this is the only place a button is round. */
.pc-tip {
  all: unset;
  display: inline-grid; place-items: center; vertical-align: middle;
  /* 12px IN A 20px DISC, NOT 11px IN AN 18px ONE (W5 POLISH). This was the LAST sub-12px
     font-size declaration in the tree — the previous pass took 30 across 16 stylesheets down to
     this one — and it is the same defect css/payco-hud.css:703 already records and fixed there:
     tests/crmui.mjs measured `BUTTON.pc-tip @11px: ?` and failed the platform's 12px type floor.
     The disc grows with the glyph for the reason that sheet gives — the mark is a question mark,
     so at 12px in an 18px disc the "?" touches the ring. These are §6's numbers verbatim, so the
     69 industry pages now draw the SAME tip the consoles do rather than a second one. */
  width: 20px; height: 20px; margin-left: 6px;
  border: var(--ind-hair) solid var(--ind-line); border-radius:50%;
  background: var(--ind-card-bg); color: var(--ind-brand);
  font-size: 12px; font-weight: 800; line-height: 1; cursor: help;
  position: relative;
  transition: box-shadow var(--ind-fast) var(--ind-ease), border-color var(--ind-fast) var(--ind-ease);
}
.pc-tip:hover, .pc-tip:focus-visible {
  border-color: var(--ind-brand);
  box-shadow: 0 0 0 3px var(--ind-tint);
}
/* The bubble is drawn only while the HUD has not taken the tooltip over, and it is CENTRED on
   the trigger with a viewport-bounded width — the ::after that used to run off the right edge of
   four W7 pages is why `max-width` is in vw here and not in px. */
html:not(.pc-hud-ready) .pc-tip:hover::after,
html:not(.pc-hud-ready) .pc-tip:focus-visible::after {
  content: attr(data-tip);
  position: absolute; left: 50%; bottom: calc(100% + 9px); transform: translateX(-50%);
  width: max-content; max-width: min(268px, 72vw);
  padding: 8px 11px; border-radius: var(--ind-radius-sm);
  background: var(--ind-ink); color: var(--ind-bg);
  font-size: 12.5px; font-weight: 600; line-height: 1.45; text-align: left;
  box-shadow: var(--ind-lift-hi); z-index: 40; pointer-events: none;
}


/* =============================================================================================
 * §6  THE BUYING GUIDE, THE FAQ AND THE FREE TOOLS — the three shared blocks.
 *
 * These carry the seven contract class names every one of the 68 pages writes:
 *   .pc-ind-guide  .pc-ind-guide__h  .pc-ind-guide__body
 *   .pc-ind-faq    .pc-ind-faq__q    .pc-ind-faq__a
 *   .pc-ind-cta
 * tests/industries-b.mjs §3 and tests/industries-c.mjs §7 assert that this file defines all
 * seven and that no page defines any of them itself.
 * ============================================================================================= */

/* ---- the guide -----------------------------------------------------------------------------
   Read top to bottom once, not scanned, so it is one column with a wide measure and numbered
   steps — never a card grid. The numbers are drawn by CSS, so inserting a step renumbers
   nothing by hand. */
.pc-ind-guide { margin: var(--ind-band) 0; }
.pc-ind-guide__body {
  counter-reset: ind-step;
  display: grid; gap: var(--ind-gap);
  max-width: 820px; margin: 26px auto 0; padding: 0;
  list-style: none;
}
/* HALF THE SET WRITES `class="ind-grid pc-ind-guide__body"` AND HALF WRITES THE GUIDE CLASS
   ALONE, so before this rule the same block was a stacked numbered list on 34 pages and a
   three-across card band on the other 34 — two guide patterns, and on a five-step guide the
   card band was the 3 + 2 orphan the law forbids. The compound selector outranks `.ind-grid`
   inside its media queries on specificity, which is why no !important is needed and why the
   rule sits OUTSIDE a media query: it must hold at every width. */
.pc-ind-guide__body.ind-grid { grid-template-columns: minmax(0, 1fr); }
.pc-ind-guide__body.ind-grid > * { grid-column: auto; }
/* Belt and braces: §5's placement rules already exclude this block by selector
   (`.ind-grid:not(.pc-ind-guide__body)`) rather than by out-specifying it, because
   `.ind-grid > :nth-child(3n+1):nth-last-child(2)` is a 0,3,0 selector and the compound
   override above is only 0,2,0 — measured, the steps overlapped each other on all 34 pages
   that write both class names. Exclusion is the fix; this pair is the floor under it. */
.pc-ind-guide__body > li,
.pc-ind-guide__body > div,
.pc-ind-guide__body > article {
  counter-increment: ind-step;
  position: relative;
  padding: var(--ind-pad) var(--ind-pad) var(--ind-pad) calc(var(--ind-pad) + 42px);
  text-align: left;
  background: var(--ind-card-bg);
  border: var(--ind-hair) solid var(--ind-line);
  border-radius: var(--ind-radius);
  box-shadow: var(--ind-lift);
}
.pc-ind-guide__body > li::before,
.pc-ind-guide__body > div::before,
.pc-ind-guide__body > article::before {
  content: counter(ind-step);
  position: absolute; left: var(--ind-pad); top: calc(var(--ind-pad) + 1px);
  display: grid; place-items: center;
  width: 28px; height: 28px; border-radius:50%;
  background: var(--ind-ramp); color: var(--ind-invert);
  font-size: 13px; font-weight: 800; line-height: 1;
}
.pc-ind-guide__body h3 { margin: 0 0 6px; text-align: left; }
.pc-ind-guide__body p  { margin: 0; max-width: 62ch; font-size: 14.5px; color: var(--ind-soft); }
/* `.ind-steps` and `.ind-guide` are the dialects' own names for the same list. */
.ind-steps, .ind-guide { list-style: none; }

/* ---- the FAQ -------------------------------------------------------------------------------
   <details>/<summary>, so it works with JavaScript off and announces its own expanded state.
   One accordion, centred, at the reading measure. */
.pc-ind-faq { margin: var(--ind-band) 0; }
.ind-faq details,
.pc-ind-faq details {
  max-width: 820px; margin: 0 auto 12px;
  background: var(--ind-card-bg);
  border: var(--ind-hair) solid var(--ind-line);
  border-radius: var(--ind-radius);
  overflow: hidden;
  transition: border-color var(--ind-fast) var(--ind-ease);
}
.ind-faq details:first-of-type,
.pc-ind-faq details:first-of-type { margin-top: 26px; }
.pc-ind-faq details[open] { border-color: var(--ind-brand); }
.pc-ind-faq__q,
.ind-faq summary {
  display: flex; align-items: flex-start; gap: 12px;
  min-height: var(--ind-tap);
  padding: 15px 18px;
  font-size: 15.5px; font-weight: 700; color: var(--ind-ink);
  list-style: none; cursor: pointer;
}
.pc-ind-faq__q::-webkit-details-marker,
.ind-faq summary::-webkit-details-marker { display: none; }
.pc-ind-faq__q::after,
.ind-faq summary::after {
  content: "+"; margin-left: auto; flex: none;
  font-weight: 800; color: var(--ind-brand);
  transition: transform var(--ind-fast) var(--ind-ease);
}
details[open] > .pc-ind-faq__q::after,
.ind-faq details[open] > summary::after { transform: rotate(45deg); }
.pc-ind-faq__a,
.ind-faq .ind-a {
  margin: 0; padding: 0 18px 16px;
  font-size: 14.5px; color: var(--ind-soft);
}

/* ---- the free-tool block -------------------------------------------------------------------
   The two tools, side by side, in the same card as everything else. It used to be a narrow
   left-aligned box floating below the page's own footer line, in its own type scale. */
.pcw8-tools {
  margin: var(--ind-band) auto;
  padding: 0;
  background: none; border: 0;
  color: var(--ind-ink);
}
.pcw8-lead { margin: 0 auto; max-width: 62ch; font-size: clamp(15px, 1.4vw, 17px); color: var(--ind-soft); text-align: center; }
.pcw8-list {
  display: grid; gap: var(--ind-gap); grid-template-columns: 1fr;
  max-width: 820px; margin: 26px auto 0; padding: 0; list-style: none;
}
@media (min-width: 640px) { .pcw8-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.pcw8-list > li {
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  padding: var(--ind-pad); text-align: center;
  background: var(--ind-card-bg);
  border: var(--ind-hair) solid var(--ind-line);
  border-radius: var(--ind-radius);
  box-shadow: var(--ind-lift);
}
.pcw8-list span { font-size: 14.5px; color: var(--ind-soft); }
.pcw8-stamp { margin: 20px auto 0; font-size: 12.5px; color: var(--ind-mute); text-align: center; }

/* THE ONE BUTTON. `.pcw8-go`, `.ind-go`, `.ind-submit` and `.ind-cta a` are four names for the
   same pill; it is payco.css's `.btn` geometry with the house ramp. */
.pcw8-go,
.ind-go,
.ind-submit,
.ind-cta > a {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--ind-tap); padding: 11px 22px;
  border: var(--ind-hair) solid transparent; border-radius:999px;
  font: inherit; font-size: 14.5px; font-weight: 700; text-decoration: none;
  cursor: pointer;
  background: var(--ind-card-bg); color: var(--ind-brand-deep);
  border-color: var(--ind-line);
  box-shadow: var(--ind-lift);
  transition: transform var(--ind-fast) var(--ind-ease), box-shadow var(--ind-fast) var(--ind-ease),
              filter var(--ind-fast) var(--ind-ease);
}
.pcw8-go,
.ind-submit,
.ind-cta > a.is-primary,
.ind-cta > a:first-child {
  background: var(--ind-ramp); color: var(--ind-invert); border-color: transparent;
}
.pcw8-go:hover, .ind-go:hover, .ind-submit:hover, .ind-cta > a:hover {
  transform: translateY(-2px); box-shadow: var(--ind-lift-hi);
}
.pcw8-go:focus-visible, .ind-go:focus-visible, .ind-submit:focus-visible, .ind-cta > a:focus-visible {
  outline: 3px solid var(--ind-focus); outline-offset: 2px;
}
/* `.pc-ind-cta` is a CONTRACT class and lands on both a <section> and an <a> depending on the
   dialect. It must therefore carry no box of its own — only the link inside it is a control. */
a.pc-ind-cta { text-decoration: none; }


/* =============================================================================================
 * §7  THE LEAD FORM AND THE CLOSING PROMISE.
 * ============================================================================================= */
.ind-form {
  display: grid; gap: 14px; grid-template-columns: 1fr;
  max-width: 820px; margin: 26px auto 0;
  padding: var(--ind-pad);
  text-align: left;
  background: var(--ind-card-bg);
  border: var(--ind-hair) solid var(--ind-line);
  border-radius: var(--ind-radius);
  box-shadow: var(--ind-lift);
}
@media (min-width: 640px) {
  .ind-form { grid-template-columns: 1fr 1fr; }
  .ind-wide, .ind-span, .ind-form > .ind-msg, .ind-form > button { grid-column: 1 / -1; }
}
.ind-two { display: grid; gap: 14px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .ind-two { grid-template-columns: 1fr 1fr; } }
.ind-field { display: grid; gap: 6px; align-content: start; }
.ind-field label,
.ind-field > span { font-size: 12.5px; font-weight: 700; color: var(--ind-soft); }
.ind-field input,
.ind-field select,
.ind-field textarea {
  font: inherit; font-size: 16px;
  width: 100%; min-height: var(--ind-tap); padding: 11px 13px;
  color: var(--ind-ink); background: var(--ind-card-bg);
  border: var(--ind-hair) solid var(--ind-line); border-radius: var(--ind-radius-sm);
  transition: border-color var(--ind-fast) var(--ind-ease), box-shadow var(--ind-fast) var(--ind-ease);
}
.ind-field textarea { min-height: 110px; resize: vertical; }
.ind-field input:focus,
.ind-field select:focus,
.ind-field textarea:focus {
  outline: none; border-color: var(--ind-brand);
  box-shadow: 0 0 0 4px var(--ind-tint);
}
.ind-msg { margin: 0; min-height: 1.2em; font-size: 14px; color: var(--ind-soft); }
.ind-msg.ok  { color: var(--ind-ok); }
.ind-msg.err, .ind-msg.is-bad { color: var(--ind-bad); }
.ind-span { display: grid; gap: 8px; }

/* The closing promise. The one panel on the page that is a filled block rather than a card,
   because it is the last thing read and it is one sentence. */
.ind-close {
  max-width: 820px; margin: var(--ind-band) auto 0;
  padding: clamp(28px, 4vw, 40px) var(--ind-pad);
  text-align: center;
  background: var(--ind-recess);
  border: var(--ind-hair) solid var(--ind-line);
  border-radius: var(--ind-radius-lg);
  box-shadow: var(--ind-lift);
}
.ind-close p { margin: 0 auto; max-width: 62ch; color: var(--ind-soft); }
.ind-close h2 { margin-bottom: 10px; }
.ind-close strong { color: var(--ind-ink); }


/* =============================================================================================
 * §8  DARK.
 *
 * Almost nothing belongs here: --pc-* already flips on [data-theme="dark"] and every colour above
 * is one of those chains. This block carries only what a token swap cannot express — a drop
 * shadow reads as dirt on a dark ground, so the boxes trade elevation for a firmer edge — plus
 * the marketing header's own bar, which payco-marketing.css states as a light literal because
 * every other page that links it is light-only.
 * ============================================================================================= */
[data-theme="dark"] {
  --ind-lift:    none;
  --ind-lift-hi: 0 0 0 var(--ind-hair) var(--ind-line);
}
[data-theme="dark"] .ind-card,
[data-theme="dark"] .ind-item,
[data-theme="dark"] .pcw8-list > li,
[data-theme="dark"] .pc-ind-guide__body > li,
[data-theme="dark"] .pc-ind-guide__body > div,
[data-theme="dark"] .pc-ind-guide__body > article,
[data-theme="dark"] .ind-faq details,
[data-theme="dark"] .pc-ind-faq details,
[data-theme="dark"] .ind-form { background: var(--ind-recess); }

/* The site bar. `background` and `border` only — geometry stays payco-marketing.css's, so the
   header does not become a second implementation. */
[data-theme="dark"] .mnav {
  background: color-mix(in srgb, var(--ind-bg) 86%, transparent);
  border-bottom-color: var(--ind-line);
}
[data-theme="dark"] .mnav .links > a,
[data-theme="dark"] .mnav .links .drop > a.dtop {
  background: var(--ind-recess); color: var(--ind-soft); border-color: var(--ind-line);
}
[data-theme="dark"] .mnav .dropm { background: var(--ind-recess); border-color: var(--ind-line); }
[data-theme="dark"] .mnav .dropm a { color: var(--ind-soft); }
[data-theme="dark"] .mnav .btn-w { background: var(--ind-recess); color: var(--ind-ink); border-color: var(--ind-line); }
[data-theme="dark"] .mnav .mnav-burger span { background: var(--ind-ink); }

/* THE SIGN-IN PILL GOES INVISIBLE IN DARK, AND THE CAUSE IS TWO SHEETS AGREEING SEPARATELY.
   payco-marketing.css:168 paints the quiet half of the header pair
       .mnav .cta > a:first-child { background: white; color: var(--ink, <dark ink>); }
   and css/payco-system.css redefines the LEGACY `--ink` to a near-white under
   [data-theme="dark"]. A page that links only payco-marketing.css never sees it, because
   `--ink` is then undefined and its dark-ink fallback holds — which is why products.html is
   fine. A page that links BOTH gets light text on a hard-coded white pill. Measured on
   industries/coffee-shop.html at 1440 in dark: rgb(239,241,244) on rgb(255,255,255),
   contrast 1.13:1, against 18.13:1 for the same control on products.html.
   The real repair is one line in payco-marketing.css and that file is lane 7's — see the IR in
   docs/lane-reports/W9-LANE-8.md. This rule is the local floor until it lands: it out-specifies
   the 0,3,1 selector above with 0,4,1 and repaints BOTH halves of the pair from tokens. */
[data-theme="dark"] .mnav .cta > a:first-child {
  background: var(--ind-recess);
  color: var(--ind-ink);
  border-color: var(--ind-line);
  box-shadow: none;
}
[data-theme="dark"] .mnav .cta > a:first-child:hover {
  background: var(--ind-ramp);
  color: var(--ind-invert);
  border-color: transparent;
}

[data-theme="dark"] body > footer { background: var(--ind-recess); border-top-color: var(--ind-line); }


/* =============================================================================================
 * §9  REVEAL ON SCROLL — CSS only, and it can never hide anything.
 *
 * Driven by `animation-timeline: view()`, so there is no script, no IntersectionObserver, and no
 * new global asset to file an interface request for. Two properties of it are deliberate:
 *
 *   1. IT NEVER REACHES ZERO OPACITY. The floor is .35, not 0. A scroll-driven animation that
 *      starts at 0 leaves every below-the-fold element INVISIBLE in a full-page screenshot, in a
 *      print, in a find-in-page, and in any browser that computes the timeline late — which is a
 *      page that renders blank for the reader whose device is slow. Subtle is the requirement;
 *      disappearing is not.
 *   2. IT IS INSIDE @supports AND prefers-reduced-motion: no-preference. A browser without
 *      view() timelines gets the finished state, full stop, and a reader who has asked for less
 *      motion gets it too. Absolutely, as the rule says.
 * ============================================================================================= */
@keyframes ind-rise {
  from { opacity: .35; transform: translateY(16px); }
  to   { opacity: 1;   transform: none; }
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .ind-card,
    .ind-item,
    .pcw8-list > li,
    .pc-ind-guide__body > li,
    .pc-ind-guide__body > div,
    .pc-ind-guide__body > article,
    .ind-faq details,
    .pc-ind-faq details,
    .ind-shot,
    .ind-media,
    .ind-close,
    .ind-form {
      animation: ind-rise linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 26%;
    }
  }
}
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important;
      transition-duration: .001ms !important; scroll-behavior: auto !important; }
}


/* =============================================================================================
 * §10 MOBILE FLOORS — LAST IN THE FILE, ON PURPOSE.
 *
 * Nothing here is below 12px of type or 44px of tap target, at any width. This section is last
 * because a rule appended below it wins on source order and silently reverts both floors; that
 * has happened on this codebase before and it is why the section is named in the file header.
 * §10 RAISES and never lowers.
 * ============================================================================================= */
@media (max-width: 900px) {
  .ind-hero h1, main h1 { line-height: 1.12; }
}
@media (max-width: 560px) {
  body { font-size: 15.5px; -webkit-text-size-adjust: 100%; }

  /* 16px on every control, because anything smaller makes iOS zoom the page on focus. */
  input, select, textarea, button { font-size: 16px; }

  /* Nothing under 12px. The four smallest things on the page are raised together, so the scale
     stays a scale rather than becoming four exceptions. */
  .ind-crumb, nav.ind-bar, .ind-shot figcaption, .ind-media figcaption,
  .ind-foot, .ind-foot-legal, .ind-updated, .pcw8-stamp, .ind-note,
  body > footer, .ind-draft { font-size: 12.5px; }
  .ind-field label, .ind-field > span { font-size: 13px; }

  /* 44px on every target a finger has to hit. `.pc-tip` gets it through a padded box rather
     than by growing the dot — the ring stays 18px and the hit area is the floor, which is the
     fix the 24px-wide tooltip on every phone needed. */
  .pcw8-go, .ind-go, .ind-submit, .ind-cta > a,
  .pc-ind-faq__q, .ind-faq summary,
  .ind-crumb a, nav.ind-bar a, body > footer a, .ind-skip {
    min-height: var(--ind-tap);
    display: inline-flex; align-items: center;
  }
  .pc-ind-faq__q, .ind-faq summary { display: flex; }
  .ind-crumb a, nav.ind-bar a, body > footer a { padding: 8px 10px; }
  .ind-field input, .ind-field select, .ind-field textarea { min-height: var(--ind-tap); }

  .pc-tip {
    width: var(--ind-tap); height: var(--ind-tap);
    margin-left: 0;
    border: 0; background: none; box-shadow: none;
  }
  /* The ring stays 18px and is drawn UNDER the "?" by a pseudo-element, so the visible mark
     does not grow into a 44px disc while the hit area does. */
  .pc-tip::before {
    content: ""; position: absolute; left: 50%; top: 50%;
    width: 18px; height: 18px; margin: -9px 0 0 -9px;
    border: var(--ind-hair) solid var(--ind-line); border-radius:50%;
    background: var(--ind-card-bg);
    z-index: -1;
  }
  .pc-tip:hover::before, .pc-tip:focus-visible::before { border-color: var(--ind-brand); }

  /* The hero photograph loses its big radius on a phone: a 28px corner on a 343px-wide image
     eats a visible slice of the picture. */
  .ind-shot, .ind-media { border-radius: var(--ind-radius); }

  /* One column, everywhere, and the guide steps give back the number gutter. */
  .ind-grid, .ind-two, .pcw8-list, .ind-form { grid-template-columns: 1fr; }
  .pc-ind-guide__body > li,
  .pc-ind-guide__body > div,
  .pc-ind-guide__body > article { padding-left: calc(var(--ind-pad) + 38px); }
}
