/* capabilities.css — GENERATED by build-c2.mjs. Do not hand-edit.
   Design D, "everything, printed", picked by Preet 2026-09-04 (D-018).
   Reference: Klim Type Foundry's font index. Tokens are the live site's. */

.cx{
  --cx-navy:#0f054d;
  --cx-tint:#e5e4f0;
  --cx-ink:#000;
  --cx-body:#2c2c2c;
  --cx-accent:#e01820;
  --cx-hair:rgba(0,0,0,.13);
  --cx-hair-2:rgba(0,0,0,.28);
  --cx-page:1300px;
  --cx-gut:20px;
  /* ⚠⚠⚠ 84px IS THE LIVE STICKY HEADER, MEASURED 2026-09-04 AT BOTH 1440 AND 390.
     global.css section 27 makes the top-level .e-con position:sticky top:0
     z-index:999. Every sticky offset on this page is built on this one value; get
     it wrong and the finder bar slides UNDER the header and is simply gone. */
  --cx-stick:84px;
  /* the two stacked sticky bars, measured: .d-find is 1px border + 68px = 69,
     .d-jump is 1px + 48 + 1px = 50. Every offset below is built on the pair. */
  --cx-find-h:119px;
  --cx-sans:"IBM Plex Sans",-apple-system,"Segoe UI",Arial,sans-serif;
  font-family:var(--cx-sans);font-size:18px;font-weight:500;line-height:27px;
  color:var(--cx-ink);
}
.cx *,.cx *::before,.cx *::after{box-sizing:border-box}
.cx img{max-width:100%;display:block}
.cx a{color:inherit;text-decoration:none}
/* ⚠ THE FINDER HIDES WITH THE hidden ATTRIBUTE AND NOTHING ELSE, so this rule is
   what makes filtering work at all. (0,1,1) beats the UA sheet's bare [hidden]
   and every list rule below, none of which sets display. */
.cx [hidden]{display:none}

.cx-wrap{width:100%;max-width:var(--cx-page);margin-inline:auto;padding-inline:var(--cx-gut)}
.cx-sec{position:relative;padding-block:100px}
.cx-sec--white{background:#fff}
.cx-sec--navy{background:var(--cx-navy);color:#fff}

/* ---------- type ----------
   WARN text-transform:none is LOAD-BEARING and INVISIBLE in out/preview-capabilities.html,
   which links only capabilities.css. Live also loads webflow-core.css, whose bare
   h1 rule sets text-transform:uppercase at (0,0,1) and was the ONLY transform rule
   matching this heading - so the sentence-case hero shipped live as
   EVERYTHING WE RUN, IN ONE LIST. Same trap that hit the six service pages light
   hero. Never drop it. The same sheet also sets h1 to 199px and -5.986px tracking. */
.cx-h1{font-family:var(--cx-sans);font-size:clamp(40px,4.6vw,64px);font-weight:600;
  line-height:1.03;letter-spacing:-2.2px;margin:0;text-wrap:balance;
  text-transform:none;color:var(--cx-ink);max-width:15ch}
.cx-lede{font-size:18px;line-height:29px;color:var(--cx-body);margin:26px 0 0;max-width:66ch}
.cx-sec--navy .cx-close__h{color:#fff}
.cx-sec--navy .cx-close__l{color:rgba(255,255,255,.82)}

/* ---------- the masthead ---------- */
.d-mast{padding-block:88px 44px}
.d-facts{margin-top:36px;display:flex;flex-wrap:wrap;border-top:1px solid var(--cx-hair-2)}
.d-fact{padding:18px 34px 18px 0;margin-right:34px;border-right:1px solid var(--cx-hair)}
.d-fact:last-child{border-right:0;margin-right:0}
.d-fact b{display:block;font-size:34px;font-weight:600;line-height:1;letter-spacing:-1.2px;
  font-variant-numeric:tabular-nums}
.d-fact span{display:block;margin-top:6px;font-size:14px;line-height:20px;color:var(--cx-body)}
/* ⚠ D-002 lives here now. It used to sit under the vendor band, which design D
   deletes; it is the highest-stakes entry in DECISIONS.md and it does not get
   dropped because the section it happened to be under was redrawn. */
.d-note{margin:30px 0 0;font-size:15px;line-height:24px;color:var(--cx-body);max-width:74ch}
.d-note__t{display:block;font-size:13px;font-weight:700;letter-spacing:1.9px;
  text-transform:uppercase;color:rgba(0,0,0,.45);margin-bottom:7px}

/* ---------- the finder bar ----------
   ⚠⚠⚠ top IS THE LIVE HEADER'S HEIGHT, NOT 0. See --cx-stick above.
   ⚠ z-index sits BELOW the header's 999 on purpose: they never overlap while
   both are honoured, and if one day they do, the site header wins. */
.d-find{position:sticky;top:var(--cx-stick);z-index:8;background:#fff;
  border-top:1px solid var(--cx-hair-2)}
.d-find__in{display:flex;align-items:center;gap:20px;height:68px}
/* the label is for screen readers and for a browser with no placeholder support;
   the placeholder carries it visually. */
.d-find__lab{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
  white-space:nowrap}
/* ⚠⚠⚠ EVERY DECLARATION HERE IS UNDOING A SITEWIDE RULE, NOT STYLING.
   hello-elementor reset.css carries input[type=text]{border:1px solid #666;
   border-radius:3px;padding:.5rem 1rem;transition:all .3s;width:100%} at (0,1,1),
   which is a TIE with a one-class rule and would then be settled by load order.
   Two classes make it (0,2,1) and the tie disappears. webflow-core adds
   input{line-height:normal} and font:inherit. This is the FOURTH bare-element
   trap on this page and out/preview-capabilities.html cannot show you any of them. */
.d-find .d-find__i{flex:1;min-width:0;font:inherit;font-size:21px;font-weight:500;
  line-height:normal;border:0;border-radius:0;outline:0;background:transparent;
  color:var(--cx-ink);padding:0;margin:0;width:auto;transition:none;-webkit-appearance:none}
.d-find .d-find__i::placeholder{color:#8d8d99;opacity:1}
.d-find .d-find__i:focus-visible{outline:2px solid var(--cx-navy);outline-offset:6px}
.d-find__c{flex:none;margin:0;font-size:13px;font-weight:700;letter-spacing:1.9px;
  text-transform:uppercase;color:rgba(0,0,0,.45);font-variant-numeric:tabular-nums}
.d-find__c b{font-size:20px;letter-spacing:0;color:var(--cx-ink)}

/* the second sticky bar. It pins directly under the first, so the two read as one
   control; they are separate elements only so the phone can un-stick this half. */
.d-jump{position:sticky;top:calc(var(--cx-stick) + 69px);z-index:8;background:#fff;
  border-top:1px solid var(--cx-hair);border-bottom:1px solid var(--cx-hair-2)}
.d-jump__in{display:flex;align-items:center;gap:24px;height:48px;
  overflow-x:auto;scrollbar-width:none}
.d-jump__in::-webkit-scrollbar{display:none}
/* ⚠⚠⚠ TWO CLASSES, ALWAYS. .cx a{color:inherit} at the top of this file is
   (0,1,1); a single-class link rule is (0,1,0) and LOSES. Design C's closing CTA
   shipped as a blank white rectangle on exactly this.
   ⚠⚠ THE EIGHT NAMES CARRY NO COUNT, AND THAT IS A MEASUREMENT, NOT A TASTE.
   With a count each they run 1401px inside a 1260px rail, so "IT Hardware Supply"
   was cut in half at 1440 and read as a broken row rather than a scrollable one.
   Names alone are 1177px and fit with 83px to spare. The information the count
   carried is not lost: a family the current search does not reach goes faint. */
.d-jump a.d-jump__a{display:inline-flex;align-items:baseline;flex:none;
  font-size:14px;font-weight:600;color:var(--cx-body);white-space:nowrap;
  padding-bottom:2px;border-bottom:2px solid transparent}
.d-jump a.d-jump__a:hover{color:var(--cx-ink);border-bottom-color:var(--cx-accent)}
.d-jump a.d-jump__a:focus-visible{outline:2px solid var(--cx-navy);outline-offset:3px}
/* a family the current search does not reach. ⛔ DIMMED, NEVER HIDDEN: the row of
   eight has to stay the same eight so a reader can see the shape of the answer,
   including which families hold none of it. */
.d-jump a.d-jump__a.is-off{opacity:.3}
/* ⚠⚠ THE FAMILY THE READER IS ACTUALLY IN. Preet, 2026-09-04: the bar has to
   reflect the section you are on. ⛔⛔ SET BY THE SCRIPT AND NEVER PRINTED — a
   bar that ships one name already marked would be frozen on that name for a
   reader with no JavaScript, which is a lie where an untracked bar is merely
   quiet. A19 fails the build if the markup ever carries it.
   ⚠ It reuses the hover pair — ink plus the red rule — instead of inventing a
   third state. Hover is already a preview of "this is the one", and a bar that
   also dims eight names cannot carry a fourth colour and stay readable. */
.d-jump a.d-jump__a.is-here{color:var(--cx-ink);border-bottom-color:var(--cx-accent)}

/* ═══════════════════ THE BANDS ═══════════════════
   One full-bleed band per family. Its GROUND and its HEIGHT are computed from how
   many lines it has: the three deepest take the homepage's blue, the five
   thinnest stay white. ⛔ Never hard-code that list.
   ⛔⛔ THERE IS NO .d-band--navy AND THERE MUST NOT BE ONE AGAIN. Preet,
   2026-09-04: the blue sections take a different ground, read off the homepage.
   home.css section 27: "navy appears exactly ONCE so the CTA is the only dark
   stop on the page" — here that one stop is .cx-sec--navy on the close. Every
   white-on-navy override this block used to carry went with it; a band that
   somehow came back navy would now be unstyled white text on a white ground,
   which is why A15b fails the build rather than trusting this comment. */
.d-band{border-bottom:1px solid var(--cx-hair);scroll-margin-top:calc(var(--cx-stick) + var(--cx-find-h) + 8px)}
.d-band--white{background:#fff}
.d-band--tint{background:var(--cx-tint)}

.d-band__in{display:grid;grid-template-columns:352px minmax(0,1fr);column-gap:56px;
  padding-block:62px}
.d-band__l{min-width:0}
/* ⚠⚠ THE STICKY FAMILY NAME RELEASES AT THE NEXT BAND BECAUSE ITS PARENT IS THE
   BAND. Sticky travels only inside its own parent's box — that is the whole
   mechanism, and it is why .d-band__l must stay a grid item as tall as the band
   and must never be given a height. */
.d-band__stick{position:sticky;top:calc(var(--cx-stick) + var(--cx-find-h) + 24px)}
.d-band__r{min-width:0}

/* ⚠⚠⚠ webflow-core.css sets a bare h2 to Instrument Serif, 128px, -3.84px and
   color:var(--black). On a navy band that last one alone would paint the family
   name BLACK ON NAVY. Every property below is undoing one of those, and none of
   it shows in the local preview. Same for h3 at 96px on .d-sub__n. */
.d-name{font-family:var(--cx-sans);font-size:40px;font-weight:600;line-height:1.04;
  letter-spacing:-1.4px;margin:0;text-transform:none;color:inherit}
.d-say{margin:14px 0 0;font-size:16.5px;line-height:26px;color:var(--cx-body)}
.d-meta{margin:24px 0 0;padding-top:16px;border-top:1px solid var(--cx-hair);
  font-size:13.5px;line-height:22px;color:var(--cx-body);
  letter-spacing:1.2px;text-transform:uppercase;font-weight:600}
.d-meta b{font-size:20px;font-weight:700;color:var(--cx-ink);letter-spacing:0;
  font-variant-numeric:tabular-nums}

/* the vendors, inline, on the family they actually back */
.d-vend{margin:16px 0 0;font-size:14px;line-height:23px;color:var(--cx-body)}
.d-vend__i{display:block}
.d-vend__i b{font-weight:700;color:var(--cx-ink)}
.d-vend__x{font-style:normal;color:#75757f}

/* ⚠ columns:<width> <count> DEGRADES ON ITS OWN. At 852px the browser makes two
   404px columns; below about 640px of track it makes one, with no media query and
   no breakpoint to keep in sync. That is the point — the right column is a
   different width in every layout this page has. */
.d-lines{list-style:none;margin:0;padding:0;columns:300px 2;column-gap:44px}
.d-line{break-inside:avoid;font-size:17px;line-height:25px;padding:9px 0;
  border-bottom:1px solid var(--cx-hair);color:inherit}

.d-subs{margin-top:38px}
.d-sub{padding-top:26px;margin-top:26px;border-top:1px solid var(--cx-hair-2)}
.d-subs > .d-sub:first-child{margin-top:0}
.d-sub__n{font-family:var(--cx-sans);font-size:21px;font-weight:700;line-height:1.25;
  letter-spacing:-.3px;margin:0;text-transform:none;color:inherit}
.d-sub__d{margin:6px 0 0;font-size:15.5px;line-height:24px;color:var(--cx-body)}
.d-sub__b{list-style:none;margin:14px 0 0;padding:0;columns:290px 2;column-gap:44px}
.d-sub__b .d-line{font-size:16px;line-height:24px;padding:7px 0}
/* ⚠⚠ A HOLE INSIDE A SUB-SERVICE IS inline-block, AND THAT IS NOT SOFTENING IT.
   Stretched across the full 852px right column, three of them down the Hardware
   band read as three sections that failed to load rather than as three missing
   photographs. It is still a red dashed box in red capitals; it is now the size
   of the thing that is actually missing. */
.d-sub .cx-hole{margin-top:14px;display:inline-block}

/* ---------- the closing band ----------
   ⚠⚠ THE BUTTON MUST CARRY ITS OWN HEIGHT. The live site's .enq-cta with no
   modifier renders 18px tall, and a bare .cta here would inherit nothing at all -
   this page shares no stylesheet with the mock. */
.cx-close{padding-block:96px}
.cx-close .cx-wrap{text-align:center}
.cx-close__h{font-family:var(--cx-sans);font-size:clamp(34px,3.6vw,48px);font-weight:600;
  line-height:1.06;letter-spacing:-1.4px;margin:0;text-wrap:balance;text-transform:none}
.cx-close__l{font-size:18px;line-height:29px;margin:24px auto 0;max-width:640px}
/* ⚠⚠⚠ .cx .cx-close__cta, NOT .cx-close__cta. .cx a{color:inherit} near the top
   of this sheet is (0,1,1); a single class is (0,1,0) and LOSES, so the label
   inherited #fff from the navy band and the button shipped as a blank white
   rectangle. It rendered, it was the right size, and it said nothing. */
.cx .cx-close__cta{display:inline-flex;align-items:center;gap:10px;height:52px;padding:0 32px;
  margin-top:34px;border-radius:0;background:#fff;color:var(--cx-navy);text-decoration:none;
  font-size:17px;font-weight:600;letter-spacing:.17px;position:relative}
/* ---------- ONE HOVER FOR EVERY CTA ON THE SITE (D-023, 2026-09-04) -------
   A 2px accent rule (#e01820, var(--cx-accent) here) wipes in along the
   bottom edge and NOTHING ELSE MOVES. Preet picked it as option F off
   mockups/cta-hover-src/cta-hover.html.

   ⛔ The old hover -- background #f0eefb + translateY(-1px) -- is GONE ON
   PURPOSE. It was one of six different CTA hovers across five stylesheets.

   ⚠⚠ THE SAME RULE IS IN FIVE FILES and nothing links them: global.css
   section 20a, home.css (--project), v4-mock.html (.cta), this file and
   blog-single.css (.enqb-btn). Change one, change all five.

   ⚠⚠⚠ TWO CLASSES, same reason as the rule above it: .cx a{color:inherit}
   is (0,1,1) and a single class loses to it.

   ⛔ ::after, NEVER a background-image -- Elementor's lazy-load rule sets
   background-image:none !important below the 4th top-level container until
   it scrolls in. ⛔ scale, NOT transform: the house rule everywhere here. */
.cx .cx-close__cta::after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;
  background:var(--cx-accent);scale:0 1;transform-origin:left center;
  transition:scale .22s ease}
.cx .cx-close__cta:hover::after,
.cx .cx-close__cta:focus-visible::after{scale:1 1}
.cx .cx-close__cta:focus-visible{outline:2px solid #fff;outline-offset:3px}

/* ---------- more ---------- */
.cx-more{padding-block:80px}
.cx-more__list{list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:2px}
/* ⚠ height:100% is not cosmetic. The li IS the grid item and stretches; the
   anchor inside it does not, so a two-line card sat 24px shorter than the
   four-line card beside it and the row read as broken. */
.cx-more__list a{display:block;height:100%;padding:20px 22px;border:1px solid var(--cx-hair);
  transition:background-color .18s ease}
.cx-more__list a:hover{background:var(--cx-tint)}
.cx-more__list a:focus-visible{outline:2px solid var(--cx-navy);outline-offset:2px}
.cx-more__t{display:block;font-size:19px;font-weight:600;letter-spacing:-.3px;margin-bottom:5px}
.cx-more__d{display:block;font-size:15.5px;line-height:23px;color:var(--cx-body)}

/* ---------- THE HOLE ----------
   Deliberately loud. A page once built "all assertions pass" while printing
   "copy pending sign-off" twelve times. A hole that looks like design is the
   same bug wearing better clothes. */
.cx-hole{border:1px dashed rgba(224,24,32,.5);background:rgba(224,24,32,.045);
  padding:13px 15px;margin:0}
.cx-hole__h{margin:0;font-size:11.5px;font-weight:700;letter-spacing:1.4px;
  text-transform:uppercase;color:#8d1017}

/* ---------- reveals — joins the family already on the service pages ----------
   ⛔⛔⛔ THE HIDDEN STATE HANGS OFF data-rev, WHICH ONLY THE SCRIPT EVER SETS.
   The markup ships data-rev-target, which no rule touches. Delete the script and
   both sections are simply visible — the designed failure mode.
   ⛔⛔ THE EIGHT BANDS ARE NOT ARMED. Filtering promotes a band with no scroll,
   so an armed opacity-0 band could be pushed to the top and read as empty.
   ⛔⛔ THE TRANSITION LIVES ONLY ON .cx-in. Putting one on the hidden state makes
   ARMING fade the section out; a delay defers the HIDE even at 0s. */
.cx [data-rev]{opacity:0;transform:translateY(14px)}
.cx [data-rev].cx-in{opacity:1;transform:none;
  transition:opacity .5s ease,transform .5s cubic-bezier(.22,.61,.36,1)}
@media (prefers-reduced-motion:reduce){
  .cx [data-rev]{opacity:1;transform:none}
  .cx [data-rev].cx-in{transition:none}
  .cx-more__list a,.cx .cx-close__cta,.cx .cx-close__cta::after{transition:none}
}

/* ---------- narrow ----------
   The 352px sticky rail is the first thing to go: below 1080 there is not enough
   left for two line columns beside it, and a one-column list under a sticky name
   wastes the whole left third of the screen. */
@media (max-width:1080px){
  .d-band__in{grid-template-columns:1fr;column-gap:0;row-gap:30px;padding-block:52px}
  .d-band__stick{position:static}
  .d-name{font-size:34px;letter-spacing:-1.1px}
  .d-meta{margin-top:18px}
}
/* ⚠⚠ THE JUMP ROW LEAVES THE STICKY BAR ON A PHONE. Eight family names cannot
   share a 390px sticky bar with the field, and stacking them makes the bar 200px
   tall under an 84px header — a third of the screen, permanently. The bar keeps
   the field and the count; the eight links become a static two-column index
   directly under the masthead, which is where a reader looks for one anyway.
   ⚠ --cx-find-h drops to match, because every sticky offset is built on it. */
@media (max-width:760px){
  .cx{--cx-find-h:59px}
  .cx-sec{padding-block:64px}
  .d-mast{padding-block:56px 32px}
  .cx-lede{font-size:17px;line-height:27px;margin-top:22px}
  .d-facts{margin-top:28px;display:grid;grid-template-columns:1fr 1fr;border-top:0}
  .d-fact{padding:16px 16px 16px 0;margin-right:0;border-right:1px solid var(--cx-hair);
    border-top:1px solid var(--cx-hair-2)}
  .d-fact:nth-child(2n){border-right:0;padding-right:0}
  .d-fact b{font-size:28px}
  .d-note{margin-top:24px}
  /* ⚠ the bar has to close itself here: on a desktop its bottom edge is the jump
     bar pinned underneath it, and that bar is static on a phone. */
  .d-find{border-bottom:1px solid var(--cx-hair-2)}
  .d-find__in{height:58px;gap:14px}
  .d-find .d-find__i{font-size:17px}
  .d-find__c{font-size:11px;letter-spacing:1.2px}
  .d-find__c b{font-size:17px}
  /* ⛔⛔ THE INDEX STOPS BEING STICKY HERE, AND THAT IS THE WHOLE PHONE LAYOUT.
     A sticky element carries its children, so eight names inside the bar pinned
     310px of chrome under an 84px header — a third of the screen, for the whole
     page. Un-stuck, it is a two-column list sitting exactly where a reader looks
     for one: between the lede and the first band. */
  .d-jump{position:static;top:auto;border-top:0}
  .d-jump__in{height:auto;display:grid;grid-template-columns:1fr 1fr;gap:0;
    overflow:visible;align-items:stretch}
  .d-jump a.d-jump__a{align-items:flex-start;padding:13px 0;font-size:15px;
    white-space:normal;border-bottom:1px solid var(--cx-hair);border-top:0}
  .d-jump a.d-jump__a:nth-child(odd){border-right:1px solid var(--cx-hair);padding-right:16px}
  .d-jump a.d-jump__a:nth-child(even){padding-left:16px}
  /* ⚠ the bottom border is a ROW DIVIDER down here, not an underline, so neither
     hover nor the current-section mark may recolour it — the ink change is the
     whole signal. The index is above every band on a phone anyway, so it is only
     ever seen at the very top of the page. */
  .d-jump a.d-jump__a:hover{border-bottom-color:var(--cx-hair)}
  .d-jump a.d-jump__a.is-here{border-bottom-color:var(--cx-hair)}
  .d-band__in{padding-block:40px;row-gap:24px}
  .d-name{font-size:29px;letter-spacing:-.9px}
  .d-say{font-size:16px;line-height:25px}
  .d-line{font-size:16px;line-height:24px;padding:8px 0}
  .d-subs{margin-top:30px}
  .d-sub{padding-top:22px;margin-top:22px}
  .d-sub__n{font-size:19px}
  .cx-close{padding-block:60px}
  .cx-more{padding-block:56px}
  .cx-more__list{grid-template-columns:1fr}
}
