/* ============================================================
   Servora mobile refinements. Scoped to <=760px so desktop is
   untouched, except the reusable slideshow + pipeline components
   which are shared but only auto-animate on mobile (see mobile-ui.js).
   ============================================================ */
:root{ --pipe:#1e40af; }   /* dark blue for pipeline borders + connectors */

/* ---------- Reusable horizontal slideshow ---------- */
.mslide{position:relative}
.mslide__track{display:flex;gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;padding:2px 0}
.mslide__track::-webkit-scrollbar{display:none}
.mslide__track > *{scroll-snap-align:center;flex:0 0 100%;min-width:100%;box-sizing:border-box}
.mslide__dots{display:flex;gap:6px;justify-content:center;margin-top:14px}
/* The dot stays a 7px mark visually, but the <button> itself is padded out to a
   real tap target so a thumb can land on slide 3 without landing on 2 or 4.
   box-sizing:content-box overrides the page-wide border-box reset so that
   padding, which is invisible, adds around the 7px dot instead of shrinking it
   to nothing; background-clip keeps the painted color inside that original 7px
   box so the row's visual weight is unchanged. This grows the real flex item
   (laid out side by side with a real gap), not an absolutely-positioned
   overlay - at 6px between dots an overlay big enough to matter would have
   overlapped its neighbors and made mis-taps worse, not better. --line was
   also near-invisible against the page background; --slate-2 is the same
   "decoration only" token used elsewhere for borders that still need to read. */
.mslide__dot{
  box-sizing:content-box;width:7px;height:7px;border-radius:50%;
  background:var(--slate-2);background-clip:content-box;
  border:0;padding:18px 9px;cursor:pointer;
  transition:width .11s ease-out,background .11s ease-out;
}
.mslide__dot.on{background:var(--accent);width:22px;border-radius:4px}
/* Desktop shows the slides at once (no auto-advance). --wrap keeps a grid feel. */
@media(min-width:761px){
  .mslide__track > *{flex-basis:calc(33.333% - 10px);min-width:calc(33.333% - 10px)}
  .mslide--2 .mslide__track > *{flex-basis:calc(50% - 7px);min-width:calc(50% - 7px)}
  .mslide--wrap .mslide__track{overflow:visible;flex-wrap:wrap;scroll-snap-type:none}
  .mslide--wrap .mslide__dots{display:none}
  /* solo = always one slide at a time, even on desktop (used by funnel pages) */
  .mslide--solo .mslide__track > *{flex-basis:100%;min-width:100%}
}

/* ---------- Reusable pipeline (connected stops) ---------- */
.mpipe__node{border:2px solid var(--pipe);border-radius:18px;background:#fff;position:relative}
.mpipe__link{width:3px;height:30px;background:var(--pipe);margin:0 auto;border-radius:2px;opacity:.85}
.mpipe__note{text-align:center;font-size:13.5px;font-weight:600;color:var(--slate);max-width:34ch;margin:12px auto}
/* Homepage pipeline connectors (line between stops) */
.mpipe-conn{height:30px}
.mpipe-conn::before{content:'';display:block;width:3px;height:100%;margin:0 auto;background:var(--pipe);opacity:.85;border-radius:2px}
@media(max-width:760px){ #cmp{border:2px solid var(--pipe)!important} }

/* ---------- Animated pipeline: a glow + dot that travels the funnel to the CTA ---------- */
.fn__conn{position:relative}
.fn__conn::after{content:'';position:absolute;left:50%;top:0;transform:translateX(-50%);width:3px;height:0;border-radius:2px;
  background:var(--accent);box-shadow:0 0 10px 1px rgba(29,78,216,.55);transition:height .6s ease}
.fn__conn.is-lit::after{height:100%}
.fn__dot{position:absolute;left:50%;top:0;width:12px;height:12px;border-radius:50%;transform:translate(-50%,-3px);
  background:#fff;border:2px solid var(--accent);box-shadow:0 0 0 4px rgba(29,78,216,.16),0 0 12px 2px rgba(29,78,216,.55);
  opacity:0;transition:top .6s ease,opacity .35s;z-index:2}
.fn__conn.is-lit .fn__dot{opacity:1;top:calc(100% - 5px)}
.fn__node{transition:box-shadow .45s ease,border-color .45s ease}
.fn__node.is-lit{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent),0 20px 50px -38px rgba(29,78,216,.7)}
.fn__node--cta.is-lit{animation:fnCtaPulse 2.2s ease-in-out infinite}
@keyframes fnCtaPulse{0%,100%{box-shadow:0 0 0 1px var(--accent),0 0 0 0 rgba(29,78,216,.42)}50%{box-shadow:0 0 0 1px var(--accent),0 0 30px 5px rgba(29,78,216,.42)}}
@media(prefers-reduced-motion:reduce){
  .fn__conn::after,.fn__dot,.fn__node{transition:none}
  .fn__node--cta.is-lit{animation:none}
}

/* ============================================================
   THE DESKTOP LAYER
   ------------------------------------------------------------
   Every rule from here to the end of this section lives inside a
   min-width query. A 390x844 phone matches none of them, so the
   mobile design above cannot move. Read that as the contract: if
   a declaration is not inside a min-width block, it does not
   belong in this section.
   ============================================================ */

@media(min-width:1000px){
  /* A carousel is the right answer on a phone and the wrong one on a
     desktop. --solo forced ONE panel at a time at every width, which
     buried 10 of the 15 panels on /software (and 31 bullet lines with
     them, including the two features that justify the GC plan) behind a
     5.5s timer nobody waits out. Wide screens get the whole set at once.

     Killing the auto-advance takes no JavaScript: mobile-ui.js advances
     by writing track.scrollLeft, and a track with overflow:visible is not
     a scroll container, so the write lands on nothing and the panels sit
     still. The dots go with it, because they now index nothing. */
  .mslide--solo .mslide__track{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
    gap:30px 36px;overflow:visible;scroll-snap-type:none;padding:0}
  /* Panel counts on these pages are 2, 3 and 4. Three columns is the default;
     two and four both read better 2-up than as 2+1 or 3+1 with an orphan.
     If :has() ever failed everything would simply fall back to 3 columns,
     which is a layout, not a break. */
  .mslide--solo .mslide__track:has(> :nth-child(2):last-child),
  .mslide--solo .mslide__track:has(> :nth-child(4):last-child){grid-template-columns:repeat(2,minmax(0,1fr))}
  .mslide--solo .mslide__track > *{min-width:0;scroll-snap-align:none}
  .mslide--solo .mslide__dots{display:none}
}

@media(min-width:1080px){
  /* The FAQ was a 760px column of accordions centred in a 1920px page,
     which is the exact shape of "bland and blank". Two columns halve the
     scroll and fill the width. align-items:start stops an open answer
     from stretching the closed card beside it. */
  .mk-faq{max-width:1080px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:12px 18px;align-items:start}
  .mk-faq__item{margin-bottom:0}
}

@media(min-width:1100px){
  /* Pricing has room to breathe on a wide screen. */
  .mk-plans{max-width:960px;gap:var(--s5)}
  .mk-seats{max-width:960px}

  /* Blueprint texture on the alternating bands. The hero already draws
     this grid (.hero4__bp); repeating it faintly on every band is what
     ties the page together instead of leaving flat grey rectangles. It
     paints background-image only, so the band colour set in design.css
     is untouched. The :has() selector matches design.css's own so this
     lands after it in the cascade rather than fighting specificity. */
  body:has(#site-nav) .mk-band{
    background-image:
      linear-gradient(rgba(46,107,240,.05) 1px,transparent 1px),
      linear-gradient(90deg,rgba(46,107,240,.05) 1px,transparent 1px);
    background-size:128px 128px;
    background-position:center top;
  }
  /* Device mockups earn a little more presence when there is room. */
  .mk-peek__art .mk-window,.mk-hero__art .mk-window{transform:rotate(-.7deg)}
}

/* ============================================================
   THE DESKTOP COMPOSITION LAYER
   ------------------------------------------------------------
   Everything from here to the end of this section is gated TWICE:

     1. a min-width media query, so a 390x844 phone matches none
        of it, and
     2. `body.mkp`, the opt-in class. Any page that links this
        stylesheet and carries the class gets the whole layer; any
        page that links it without the class renders exactly as it
        did before. That is the switch, and it is one word.

   Note for whoever owns a page that still looks like a 1120px
   column of centred text: adding `mkp` to <body> only works if the
   page also links this file. As of 15 Aug 2026 these pages carry
   neither and need BOTH edits, not one: demo.html, security.html,
   policies.html, accessibility.html, book.html, 404.html,
   resources/contact.html and resources/getting-started.html.
   learn.html and resources.html already link it (learn.html at
   ?v=8 rather than ?v=9) and need only the class.

   Why the layer exists: at 1600px the old page was a 1120px
   column of centred text on white with 240px of nothing on each
   side, every section the same shape as the one above it. That
   reads as a document, not a product. The devices below give the
   page composition instead: a wider measure, an editorial head
   with a rule and a margin numeral, three distinct section
   materials (white sheet / recessed blueprint plate / navy plate)
   so the scroll has rhythm, and depth on the surfaces that were
   flat.

   The visual language is not invented here. It is the hero's:
   .hero4__bp draws a two-scale blueprint grid masked to an
   ellipse, and .hero4 is navy with a blue bloom. Those are
   restated on .mk-band and .mk-dark so the rest of the site
   speaks the same way the hero already does.

   Specificity note: several rules below are written
   `body.mkp:has(#site-nav) …` rather than `body.mkp …`. That is
   not decoration. design.css sets the band and canvas colours as
   `body:has(#site-nav) .mk-band{background:…}`, and :has() takes
   the specificity of its most specific argument, so that selector
   scores (1,1,1). A plain `body.mkp .mk-band` scores (0,2,1) and
   would lose. Matching the :has() puts these at (1,2,1).
   ============================================================ */

/* ---------- 1 · MEASURE. Give the page the screen it is on. ----------
   Line length is not at risk: heads, ledes and prose all carry their own
   ch-based caps. What widens is the grids, the plates and the gutters. */
@media(min-width:1080px){
  body.mkp .mk-wrap,body.mkp .hero4__in,body.mkp .mk-footer__in{max-width:1200px}
}
@media(min-width:1440px){
  body.mkp .mk-wrap,body.mkp .hero4__in,body.mkp .mk-footer__in{max-width:1280px}
}
@media(min-width:1720px){
  body.mkp .mk-wrap,body.mkp .hero4__in,body.mkp .mk-footer__in{max-width:1360px}
}

@media(min-width:1080px){

  /* ---------- 2 · TYPE. A scale that knows it is on a big screen ----------
     .mk-h2 topped out at 2.6rem, which is a sub-head on a 1600px monitor.
     Pages that set their own size inline (operator, gc, the services set)
     or in their own <style> (about) keep it: inline and later-sheet rules
     both out-rank these, which is deliberate, that work was considered. */
  body.mkp .mk-h1{font-size:clamp(2.8rem,3.7vw,4.3rem);line-height:1.02}
  body.mkp .mk-h2{font-size:clamp(2rem,2.5vw,3rem);line-height:1.06}
  body.mkp .mk-lede{font-size:1.18rem;line-height:1.55}
  body.mkp .mk-eyebrow{font-size:12px;letter-spacing:.18em}
  /* More air between stops, so the rhythm below has somewhere to breathe. */
  body.mkp .mk-section{padding-top:clamp(72px,6.2vw,120px);padding-bottom:clamp(72px,6.2vw,120px)}
  body.mkp .mk-cta-row .ds-btn:not(.ds-btn--sm){min-height:52px;font-size:16px;padding:0 26px}

  /* ---------- 3 · THE EDITORIAL HEAD ----------
     This is the single biggest change on the page. .mk-head was
     `text-align:center;max-width:660px;margin:0 auto` on every section of
     every page: the same 660px centred stack, twenty times down the site.
     On desktop it becomes a masthead instead: a hairline across the full
     column with an accent tab sitting on it, the eyebrow under that, then
     the headline on the left with the lede set beside it on the right.

     Flexbox rather than grid on purpose. A .mk-head can hold two children
     (index's FAQ head) or four (index's "Getting paid" head, which ends in
     a pill). Flex wrapping handles any child count and collapses to one
     column when the row cannot hold both bases; a fixed grid template
     would have to guess. */
  body.mkp .mk-head{
    position:relative;text-align:left;max-width:none;
    margin-left:0;margin-right:0;
    display:flex;flex-wrap:wrap;align-items:flex-end;
    column-gap:clamp(28px,4vw,64px);row-gap:12px;
    padding-top:26px;border-top:1px solid var(--line)}
  body.mkp .mk-head > *{flex:1 1 100%;margin:0}
  body.mkp .mk-head > .mk-h1,body.mkp .mk-head > .mk-h2{flex:1 1 min(100%,19ch)}
  body.mkp .mk-head > .mk-lede{flex:1 1 min(100%,32ch);max-width:46ch;padding-bottom:.4em}
  body.mkp .mk-head .mk-eyebrow{justify-content:flex-start}
  /* A head can hold something that is neither type nor a lede: the homepage's
     "fees $0.00 / 0% collected" pill sits in one. flex-basis:100% would stretch
     that pill's border the full 1232px. max-content clamps the used main size
     back to the thing's own width; the 100% basis still puts it on its own row. */
  body.mkp .mk-head > :not(.mk-eyebrow):not(.mk-h1):not(.mk-h2):not(.mk-lede){
    max-width:max-content}
  body.mkp .mk-head::after{content:"";position:absolute;left:0;top:-2px;
    width:72px;height:3px;border-radius:2px;background:var(--accent)}
  /* A page's opening head is a masthead, not a stop on the route: no rule
     above the first thing on the page. */
  body.mkp .mk-head:has(.mk-h1){border-top:0;padding-top:0}
  body.mkp .mk-head:has(.mk-h1)::after{display:none}
  /* A head inside a card already has the card's frame around it. */
  body.mkp .tree-node .mk-head,body.mkp .hiw2 .mk-head{border-top:0;padding-top:0}
  body.mkp .tree-node .mk-head::after,body.mkp .hiw2 .mk-head::after{display:none}
  body.mkp .mk-band .mk-head,body.mkp .bandx .mk-head{border-top-color:rgba(16,24,40,.14)}
  body.mkp .mk-dark .mk-head{border-top-color:rgba(255,255,255,.16)}
  body.mkp .mk-dark .mk-head::after{background:var(--accent-2)}

  /* ---------- 4 · BANDS AS RECESSED BLUEPRINT PLATES ----------
     .mk-band was one flat grey rectangle, repeated. Here it is pressed
     into the page: a highlight along the top edge, shadow raking in from
     both edges, and the hero's blueprint grid at two scales so a band
     reads as drafting paper rather than as "the grey one".

     .bandx is the same material on a section that is a plate ONLY on
     desktop. A page that wants one writes
        <section class="bandx"><div class="mk-wrap mk-section">…
     instead of the one-element <section class="mk-wrap mk-section">.
     Below 1080px .bandx is an unstyled <section>, which is display:block
     with no margin, border or padding, so the inner wrap lays out in
     exactly the position the single element occupied before. That is why
     this is a wrapper and not a 100vw pseudo-element: a full-bleed
     ::before sized in vw overflows by the width of the scrollbar and
     opens a horizontal scroll, and the fix for that (overflow-x:clip on
     the body) is a viewport-level change to buy a background colour. */
  body.mkp .bandx{border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
  body.mkp:has(#site-nav) .mk-band,
  body.mkp:has(#site-nav) .bandx{
    background-color:#F4F7FB;
    background-image:
      linear-gradient(rgba(29,78,216,.05) 1px,transparent 1px),
      linear-gradient(90deg,rgba(29,78,216,.05) 1px,transparent 1px),
      linear-gradient(rgba(29,78,216,.085) 1px,transparent 1px),
      linear-gradient(90deg,rgba(29,78,216,.085) 1px,transparent 1px);
    background-size:28px 28px,28px 28px,140px 140px,140px 140px;
    background-position:center top;
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,.9),
      inset 0 22px 40px -34px rgba(16,24,40,.55),
      inset 0 -22px 40px -34px rgba(16,24,40,.35)}

  /* ---------- 5 · DARK PLATES SPEAK THE HERO'S LANGUAGE ----------
     .mk-dark carried a single radial and nothing else, so the one place
     on the page with the product's actual visual identity was the hero.
     The grid here is .hero4__bp's, same two scales, same elliptical mask,
     so a dark band reads as the same material as the top of the site. */
  body.mkp .mk-dark{position:relative;isolation:isolate;
    background:radial-gradient(1200px 540px at 78% -12%,rgba(46,107,240,.3),transparent 62%),var(--ink)}
  body.mkp .mk-dark::before{content:"";position:absolute;inset:0;z-index:0;
    pointer-events:none;opacity:.6;
    background-image:
      linear-gradient(rgba(122,160,255,.08) 1px,transparent 1px),
      linear-gradient(90deg,rgba(122,160,255,.08) 1px,transparent 1px),
      linear-gradient(rgba(122,160,255,.15) 1px,transparent 1px),
      linear-gradient(90deg,rgba(122,160,255,.15) 1px,transparent 1px);
    background-size:26px 26px,26px 26px,130px 130px,130px 130px;
    -webkit-mask-image:radial-gradient(ellipse at 58% 22%,#000 20%,transparent 74%);
            mask-image:radial-gradient(ellipse at 58% 22%,#000 20%,transparent 74%)}
  body.mkp .mk-dark > *{position:relative;z-index:1}

  /* ---------- 6 · THREE BARE COLUMNS BECOME ONE PLATE ----------
     design.css already made this call once, for the services grid:
     "a connected hairline table, not floating cards". .mk-features never
     got it and stayed three unbounded columns of grey body copy, which is
     the exact shape of "bland". Child combinator throughout: index's
     feature blocks live in a .mslide track, not in .mk-features, and must
     not be caught by this. */
  body.mkp .mk-features{
    grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;
    background:var(--line);border:1px solid var(--line);
    border-radius:20px;overflow:hidden;
    box-shadow:0 34px 76px -60px rgba(16,24,40,.6)}
  body.mkp .mk-features > .mk-feature{background:#fff;padding:30px 32px 34px;
    transition:background .2s var(--ease)}
  body.mkp .mk-features > .mk-feature:hover{background:#F7F9FD}
  body.mkp .mk-features > .mk-feature h3{font-size:1.1rem;margin-bottom:8px}
  body.mkp .mk-features > .mk-feature p{font-size:15px}
  body.mkp .mk-features > .mk-feature .mk-feature__ico{width:46px;height:46px;border-radius:14px}

  /* Same treatment for the pricing add-on row. */
  body.mkp .mk-addons{max-width:none;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;
    background:var(--line);border:1px solid var(--line);border-radius:20px;overflow:hidden}
  body.mkp .mk-addon{border:0;border-radius:0;box-shadow:none;background:#fff;
    padding:26px 26px 28px;transition:background .2s var(--ease)}
  body.mkp .mk-addon:hover{background:#F7F9FD}
  body.mkp .mk-addon strong{font-size:16px;margin-bottom:4px}
  body.mkp .mk-addon span{font-size:14px;line-height:1.5}

  /* ---------- 7 · FAQ ----------
     mobile.css already went two-up at 1080px. It stays two-up, but fills
     the widened column and the open item now announces itself. */
  body.mkp .mk-faq{max-width:none;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 20px}
  body.mkp .mk-faq__item{margin-bottom:0;border-radius:16px;
    transition:border-color .18s var(--ease),box-shadow .18s var(--ease),background .18s var(--ease)}
  body.mkp .mk-faq__item:hover{border-color:#C7D3E8}
  body.mkp .mk-faq__item[open]{border-color:var(--accent);
    box-shadow:0 24px 50px -40px rgba(46,107,240,.75)}
  body.mkp .mk-faq__item summary{padding:19px 22px;font-size:15.5px}
  body.mkp .mk-faq__a{padding:0 22px 19px;font-size:15px}

  /* ---------- 8 · PRODUCT SURFACES GET AIR AND A BLOOM ----------
     The mockups are the only real imagery the site has. On desktop they
     sit in their own light instead of floating on flat white. */
  body.mkp .mk-peek{gap:clamp(40px,5vw,80px)}
  body.mkp .mk-peek__art{position:relative}
  body.mkp .mk-peek__art::before{content:"";position:absolute;inset:-14% -10%;z-index:0;
    border-radius:44px;pointer-events:none;
    background:radial-gradient(closest-side,rgba(46,107,240,.17),transparent 74%)}
  body.mkp .mk-peek__art > *{position:relative;z-index:1}
  body.mkp .mk-peek__art .mk-window{transform:rotate(-1deg)}

  /* ---------- 9 · THE STATEMENT AND THE TURN ----------
     operator, gc and two services pages open their middle act with a huge
     line and then two paragraphs stacked under it in a 42ch ribbon. Side
     by side, with the conclusion carrying the accent rule, that becomes a
     composition: the problem on the left, the answer on the right. */
  body.mkp .mk-statement{font-size:clamp(2.6rem,4.4vw,4.4rem);max-width:20ch}
  body.mkp .mk-statement--wide{max-width:26ch}
  body.mkp .mk-turn{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:clamp(28px,3.5vw,56px);align-items:center}
  body.mkp .mk-turn p{max-width:48ch;font-size:1.2rem;margin:0}
  body.mkp .mk-turn > p:last-child:not(:only-child){
    padding-left:26px;border-left:3px solid var(--accent);font-size:1.3rem}

  /* ---------- 10 · THE SIGN-OFF ----------
     The footer ended the site on a 1px grey line. */
  body.mkp .mk-footer{position:relative}
  body.mkp .mk-footer::before{content:"";position:absolute;left:0;right:0;top:0;height:3px;
    background:linear-gradient(90deg,var(--accent),rgba(46,107,240,0) 46%)}
  body.mkp .mk-footer h4{font-size:11.5px;letter-spacing:.14em;color:var(--slate-3)}
  body.mkp .mk-footer__in{gap:var(--s5)}
}

/* ---------- 11 · NUMERALS IN THE MARGIN ----------
   The gutter is the point. At 1560px the column is 1280px, so each side
   has 140px of nothing; the head sits 24px inside that, and the numeral
   hangs 74px to its left, which lands it 90px from the viewport edge with
   50px to spare. It can never reach the edge and never open a horizontal
   scrollbar, which is why this is its own breakpoint and not folded into
   the block above. */
@media(min-width:1560px){
  body.mkp{counter-reset:mkstop}
  body.mkp .mk-head:not(:has(.mk-h1)){counter-increment:mkstop}
  body.mkp .tree-node .mk-head,body.mkp .hiw2 .mk-head{counter-increment:none}
  body.mkp .mk-head:not(:has(.mk-h1))::before{
    content:counter(mkstop,decimal-leading-zero);
    position:absolute;left:-74px;top:19px;
    font-family:var(--font-display);font-weight:800;font-size:15px;
    color:var(--slate-2);font-variant-numeric:tabular-nums;letter-spacing:.02em}
  body.mkp .tree-node .mk-head::before,body.mkp .hiw2 .mk-head::before{content:none}
  body.mkp .mk-dark .mk-head::before{color:rgba(255,255,255,.36)}
}

/* ============================================================
   THE SHARED COMPONENT LAYER
   ------------------------------------------------------------
   Sections 1-11 above give the PAGE its material: measure, plates,
   dark bands, an editorial head. What follows gives the COMPONENTS
   their desktop, so a page that writes `<div class="mk-vstrip">`
   gets the right thing without writing a line of CSS for it.

   Specificity, and why it is written the way it is
   ------------------------------------------------------------
   Twenty-one other builders are writing page-scoped <style> blocks
   against these same class names right now, and their blocks sit
   before </body>, which is after this file. That only helps them if
   this file does not out-rank them. So every selector below is
   written `:where(body.mkp) .thing` and not `body.mkp .thing`.

   :where() contributes zero specificity, so `:where(body.mkp)
   .mk-vstrip b` scores (0,1,1): exactly what design.css's own
   `.mk-vstrip b` scores. This file loads after design.css, so these
   win there; a page block writing a bare `.mk-vstrip b` loads after
   this file, so the page wins here. The gate still gates. Nobody
   has to reach for !important, and nobody's page block dies
   silently because a shared sheet quietly out-specified it.

   Where a :has() test appears it is wrapped the same way
   (`.mk-fork:where(:has(...))`), because :has() otherwise inherits
   the specificity of its argument and would take the selector to
   (0,2,0) for no reason a page author could see coming.
   ============================================================ */

@media(min-width:1080px){

  /* ---------- 12 · SECONDARY TEXT ON A PLATE ----------
     The plate that section 4 builds is #F4F7FB, and --slate #667085
     measures 4.63:1 on it. That passes AA by 0.13, which is not a
     margin, it is a rounding error: every secondary line on every
     band on the site is one anti-aliasing decision away from
     failing. --slate-3 #5A6474 is the same "quiet" role and measures
     5.57:1 on the same plate, so the fix costs nothing but a token.

     Scoped to the plate on purpose. On white, --slate is 4.9:1 and
     is the right weight for a lede; darkening it everywhere would
     flatten the difference between a lede and a heading. This is a
     contrast correction, not a restyle. */
  :where(body.mkp) :where(.mk-band,.bandx) :is(.mk-lede,.mk-faq__a,.u-slate){color:var(--slate-3)}
  :where(body.mkp) :where(.mk-band,.bandx)
    :is(.mk-feature p,.mk-addon span,.mk-door p,.mk-clock__what span){color:var(--slate-3)}
  /* .mk-vstrip span is deliberately absent from that list: §13 sets it on
     every surface, so naming it again here would give the same declaration
     two homes and let a page override one of them without the other. */

  /* ---------- 13 · THE STAT STRIP CARRIES THE PAGE'S NUMBERS ----------
     .mk-vstrip is on six marketing pages and it is the one component
     a skimmer actually reads, because it is the only place the
     argument is made in digits. It was printing those digits at
     1.55rem (24.8px), which is smaller than the sub-head above it:
     the strip looked like a caption row rather than the evidence.

     40px is the display numeral on this site's scale. tabular-nums
     is not cosmetic here, it is what stops the four cells from
     shivering at different rates while the count in mobile-ui.js
     runs, and what keeps "94" and "48" optically the same width.

     One ambient shadow, not four card shadows: the strip is a single
     object with hairline seams, which is the same call section 6
     makes for .mk-features. */
  :where(body.mkp) .mk-vstrip{border-radius:20px;box-shadow:0 30px 70px -50px rgba(16,24,40,.5)}
  :where(body.mkp) .mk-vstrip>div{padding:30px 22px 26px}
  :where(body.mkp) .mk-vstrip b{font-size:40px;line-height:1.1;letter-spacing:-.03em;
    font-variant-numeric:tabular-nums;margin-bottom:6px}
  :where(body.mkp) .mk-vstrip span{font-size:13px;line-height:1.45;color:var(--slate-3)}

  /* ---------- 14 · THE TRUST ROW ----------
     Eight pages run this row directly under a hero or a CTA, at 13px,
     which is a footnote size doing a reassurance job. 14px on desktop,
     and the --ok dot gets a soft ring so it reads as a status light
     rather than a bullet. The dot is never the only signal: every item
     carries its own words, which is what makes it legible to anyone who
     cannot separate the green from the grey. */
  :where(body.mkp) .mk-trust{gap:10px 26px}
  :where(body.mkp) .mk-trust__item{font-size:14px}
  :where(body.mkp) .mk-trust__item::before{width:7px;height:7px;
    box-shadow:0 0 0 3px rgba(18,161,80,.13)}
}

@media(min-width:1200px){

  /* ---------- 15 · THE DOORS SCALE PAST TWO ----------
     .mk-fork is a two-up: `repeat(2,...)` capped at 900px, which is
     right for the two-door fork on why.html, gc.html and
     services/consulting.html and is deliberately left alone, because
     a centred pair is a composition and widening it to fill the
     screen would be the exact move the owner rejected.

     What it could not do is hold more than two, and the set it will
     be asked to hold is the portals. There are FOUR front-end
     surfaces, not five: app.html, portal.html, sub.html and
     employee.html. The "GC view" is the same contractor console with
     three extra rail tools and three extra job sections unlocked by
     plan === 'gc', so it is a plan, not a portal, and a page that
     draws it as a fifth door is describing software that does not
     exist. Four doors two-up is two clean rows; four doors three-up
     is a row of three and an orphan, which is why the rule below
     turns three columns on from the third door rather than the
     second.

     So the third column turns on for the counts where two columns
     leave an orphan, and only those: exactly three doors, or five and
     up. Four doors keep the two-up pair, because 2 + 2 is already two
     clean rows and forcing them into three columns would produce the
     3 + 1 this rule exists to prevent. That is why the selector is
     two selectors: "at least three and not at least four" for the
     three case, and "at least five" for the rest.

     The test counts DOORS, not children, and that distinction is the
     whole rule. `:has(> :nth-child(3))` was the obvious way to write
     it and it was wrong: why.html's fork is a heading plus two doors,
     which is three children and two doors, and the obvious version
     re-laid that section out from under its author. `.mk-door ~
     .mk-door ~ .mk-door` matches a third door specifically, wherever
     it sits and whatever else is in the box.

     Anything in a fork that is not a door is a heading or an intro
     line, so it spans the row rather than eating a column. why.html
     had already worked that out by hand for its own heading; this
     just means the next page does not have to.

     Five doors land as three and two. Centring that trailing pair is
     a page's own call: it needs an exact-count test that a shared
     sheet cannot make safely, and it is one line in a page block that
     knows its own markup.

     44ch on the cell paragraph is the measure ceiling for a card this
     size; without it a 15px paragraph in a 400px cell runs to 57ch. */
  :where(body.mkp) .mk-fork:where(:has(> .mk-door ~ .mk-door ~ .mk-door)):where(:not(:has(> .mk-door ~ .mk-door ~ .mk-door ~ .mk-door))),
  :where(body.mkp) .mk-fork:where(:has(> .mk-door ~ .mk-door ~ .mk-door ~ .mk-door ~ .mk-door)){
    grid-template-columns:repeat(3,minmax(0,1fr));max-width:none}
  /* These two are right at any count past two, so they are not split. */
  :where(body.mkp) .mk-fork:where(:has(> .mk-door ~ .mk-door ~ .mk-door)) > :not(.mk-door){
    grid-column:1/-1}
  :where(body.mkp) .mk-fork:where(:has(> .mk-door ~ .mk-door ~ .mk-door)) .mk-door p{max-width:44ch}
}

/* ---------- Mobile-only helpers + global fixes ---------- */
.mobile-only{display:none}
@media(max-width:760px){
  .mobile-only{display:block}
  .desktop-only{display:none!important}

  /* Guarantee edge safety without shrinking the design system's 22px. */
  .mk-wrap{padding-left:max(22px,env(safe-area-inset-left))!important;padding-right:max(22px,env(safe-area-inset-right))!important}

  /* Center major headings + their content. */
  .mk-section>.mk-head,.mk-band .mk-head{text-align:center!important}
  .mk-section>.mk-head>*,.mk-band .mk-head>*{margin-left:auto!important;margin-right:auto!important}
}
