/* ============================================================
   EFFERENT MEDIA · v3 ADDITIONS
   Loaded after efferent-base.css (v1 system) and
   efferent-v2.css (v2 additions). v3 is a copy and structure
   rewrite, not a redesign: no new colours, fonts, radii,
   shadows or easings. Every value below already exists in one
   of the two stylesheets above. Each block names the pattern
   it extends.
   ============================================================ */

/* ── TEMPLATE E TOKEN ────────────────────────────────────────
   The one tone the blog post template needs that no existing
   token carried: the Key Takeaways band, a lighter panel than
   --cream sitting between the hero and the body. Named here
   rather than written inline in four places, and declared in
   v3 rather than in efferent-base.css, which is generated from
   the v1 app and must not be hand-edited. */
:root{--cream-panel:#F6EFE6}

/* ── PLACEHOLDER TOKENS ──────────────────────────────────────
   Unfilled [TOKENS] must be unmistakable in a staging review
   and must not be mistaken for finished copy. Dashed orange at
   the same 55% the cards already use on hover. */
.ph{
  display:inline-block;font-family:var(--mono);font-weight:700;
  color:var(--orange);background:rgba(241,107,43,.07);
  border:1px dashed rgba(241,107,43,.55);
  padding:.12em .42em;letter-spacing:.04em;
}
.ph-block{display:block;width:100%}

/* ── INK TEXT-TILE GRIDS ─────────────────────────────────────
   Who We Work With (4 up) and How It Works (3 up). Same stack
   and hairline as .evo-col, column counts and gap from
   .cap-cards, heading step from .cap-body h4, body step from
   .evo-col p. Nothing new but the column counts. */
.grid-4,.grid-3{display:grid;gap:clamp(10px,1.1vw,16px);margin-top:clamp(36px,4.2vw,58px)}
.grid-4{grid-template-columns:repeat(4,1fr)}
.grid-3{grid-template-columns:repeat(3,1fr)}
.tile{border-left:1px solid var(--line-dark);padding-left:clamp(16px,1.7vw,26px)}
.tile .eyebrow{margin-bottom:12px}
.tile h3{font-size:clamp(15px,1.24vw,19px);color:var(--cream-hi);line-height:1.25}
.tile p{
  margin:12px 0 0;color:var(--on-dark);
  font-size:clamp(14.5px,1.16vw,16.5px);line-height:1.52;
}
/* Client attribution under a tile description. Face and colour are
   .foot-tag's, the existing muted mono caption on the ink ground. */
.tile-clients{
  margin:14px 0 0;font-family:var(--mono);font-weight:500;font-size:10.5px;
  letter-spacing:.12em;text-transform:uppercase;color:#8C8880;line-height:1.5;
}
.tile--cream .tile-clients{color:#6E6B63}
.tile--cream{border-left-color:var(--line-cream)}
.tile--cream h3{color:var(--ink)}
.tile--cream p{color:#4A4842}

/* ── FOUNDER BLOCK ───────────────────────────────────────────
   Cream section. Column ratio and the hairline-left aside are
   .pain-top's; the portrait uses .evo-media's object-fit
   treatment. */
.founder-grid{
  display:grid;grid-template-columns:1.06fr .94fr;
  gap:clamp(30px,4.2vw,70px);align-items:start;
  margin-top:clamp(34px,4vw,54px);
}
.founder-figure{margin:0}
/* The Citi Field photo is 1600x1200. The frame carries that exact ratio so
   `cover` crops nothing and no face is cut. Never swap in an image of a
   different shape without changing this number. */
.founder-figure img{width:100%;aspect-ratio:4/3;height:auto;object-fit:cover}
.founder-cap{
  margin:12px 0 0;font-family:var(--mono);font-size:11px;
  letter-spacing:.14em;text-transform:uppercase;color:#6E6B63;
}
.founder-copy p{
  margin:0 0 20px;color:#4A4842;
  font-size:clamp(15px,1.3vw,18.5px);line-height:1.55;max-width:56ch;
}
.founder-copy p:last-of-type{margin-bottom:0}
.founder-copy b{color:var(--ink);font-weight:700}

/* ── STEP NUMBER ─────────────────────────────────────────────
   How It Works. The numeral is the eyebrow face at the heading
   size, so it reads as a marker rather than a heading. */
.step-n{
  font-family:var(--mono);font-weight:700;font-size:clamp(21px,1.95vw,28px);
  letter-spacing:.02em;color:var(--orange);line-height:1;margin:0 0 14px;
}

/* ── FAQ ─────────────────────────────────────────────────────
   Native <details>, so it opens with JS off and is keyboard
   and screen-reader correct with no script. Rows are the
   --line-dark hairline the ink sections already use; the
   question is .cap-body h4's step, the answer .evo-col p's. */
.faq{margin-top:clamp(34px,4vw,54px);border-top:1px solid var(--line-dark)}
.faq details{border-bottom:1px solid var(--line-dark)}
.faq summary{
  display:flex;align-items:flex-start;justify-content:space-between;gap:24px;
  padding:clamp(18px,1.9vw,26px) 0;cursor:pointer;list-style:none;
  font-size:clamp(16px,1.42vw,21px);font-weight:700;letter-spacing:-.012em;
  color:var(--cream-hi);line-height:1.3;transition:color .18s;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--orange)}
.faq summary::after{
  content:"+";font-family:var(--mono);font-weight:400;font-size:21px;
  line-height:1;color:var(--orange);flex:0 0 auto;transition:transform .2s;
}
.faq details[open] summary::after{transform:rotate(45deg)}
.faq-a{
  margin:0;padding:0 0 clamp(20px,2.2vw,30px);color:var(--on-dark);
  font-size:clamp(14.5px,1.16vw,16.5px);line-height:1.55;max-width:74ch;
}

/* ── FOOTER META ─────────────────────────────────────────────
   Address, phone and hours join the existing .foot-right stack
   and inherit its face. Socials stay hidden until real URLs
   exist, so the page never ships a bare "#" link. */
.foot-meta{margin:0 0 14px}
.socials[hidden]{display:none}

/* ── HEADING WRAP ────────────────────────────────────────────
   text-wrap:balance evens the line lengths across a heading
   instead of leaving a one-word orphan on the last line. It is
   a wrapping hint only: no size, weight, colour or leading
   changes, and browsers without it fall back to normal
   wrapping. Applied to every heading level so the page is
   consistent rather than patched section by section. */
h1,h2,h3,.h-sec{text-wrap:balance}

/* ── RESPONSIVE ──────────────────────────────────────────────
   Breakpoints mirror efferent-base.css: 1040 / 860 / 560. */
@media (max-width:1040px){
  .grid-4{grid-template-columns:repeat(2,1fr);row-gap:clamp(26px,3vw,38px)}
  .founder-grid{grid-template-columns:1fr .9fr}
}
@media (max-width:860px){
  .grid-3{grid-template-columns:1fr;row-gap:clamp(26px,3vw,38px)}
  .founder-grid{grid-template-columns:1fr;gap:30px}
}
@media (max-width:560px){
  .grid-4{grid-template-columns:1fr}
  .tile{border-left:0;padding-left:0;border-top:1px solid var(--line-dark);padding-top:26px}
  .tile--cream{border-top-color:var(--line-cream)}
}

/* ── FOOTER · four-column layout ─────────────────────────────
   v1/v2 ran a three-column footer (brand | 2-up nav | address).
   v3 uses the column-groups shape: four labelled link groups,
   a hairline, brand + address + socials, a hairline, legal.

   The base rule makes .footer .wrap a 3-column grid, so it has
   to become a block before the new rows can stack inside it.
   Everything below is existing tokens: --line-dark hairlines,
   the .eyebrow group label, .cap-body .ar's orange arrow, and
   the two muted greys already used in this footer. */
.footer .wrap{display:block}

.foot-cols{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(24px,3vw,48px);
  padding-bottom:clamp(34px,4vw,54px);
}
.foot-col{display:flex;flex-direction:column;align-items:flex-start}
.foot-col .eyebrow{margin-bottom:20px}
.foot-col a{
  display:flex;align-items:baseline;gap:10px;
  padding:7px 0;color:#B4B0A8;
  font-size:clamp(14px,1.09vw,15.5px);line-height:1.35;
  transition:color .18s;
}
.foot-col a:hover{color:var(--orange)}
.foot-col .ar{
  flex:0 0 auto;font-style:normal;font-weight:600;font-size:14px;
  line-height:1;color:var(--orange);transition:transform .18s;
}
.foot-col a:hover .ar{transform:translateX(3px)}

.foot-mid{
  display:flex;flex-wrap:wrap;gap:28px;
  justify-content:space-between;align-items:flex-end;
  border-top:1px solid var(--line-dark);
  padding:clamp(30px,3.4vw,46px) 0;
}
.foot-id .foot-tag{margin:16px 0 14px}
.foot-addr{
  margin:0 0 6px;font-family:var(--mono);font-weight:500;font-size:11px;
  letter-spacing:.09em;color:#8C8880;line-height:1.7;
}
.foot-addr a{border-bottom:1px solid var(--line-dark);transition:color .18s}
.foot-addr a:hover{color:var(--orange)}

/* Socials become circular chips to match the column layout.
   Geometry is .testi-nav button's, scaled to the footer. */
.socials{margin:0;gap:12px}
.socials a{
  width:40px;height:40px;border-radius:50%;
  border:1px solid var(--line-dark);display:grid;place-items:center;
  transition:color .18s,border-color .18s;
}
.socials a:hover{border-color:var(--orange)}

.foot-legal{
  display:flex;flex-wrap:wrap;justify-content:center;
  gap:clamp(18px,2.4vw,40px);
  border-top:1px solid var(--line-dark);
  padding-top:clamp(22px,2.4vw,32px);
  font-family:var(--mono);font-weight:500;font-size:11px;
  letter-spacing:.14em;text-transform:uppercase;color:#8C8880;
}
.foot-legal a{transition:color .18s}
.foot-legal a:hover{color:var(--orange)}

/* Social profiles sit flush with the right end of the legal row, so the last
   icon lines up with the end of the hairline above it (Joe, 2026-09-25).
   The right margin used to be 76px of clearance for the chat launcher; that
   clearance now lives on .footer's padding-bottom instead, which moves the
   whole legal row above the launcher rather than indenting one element out
   from under it. Changing either one means re-checking the other: the
   launcher is 72px tall and sits up to 24px off the bottom edge, so the
   footer needs at least 96px below the legal row for them not to collide.
   padding-left is a floor on the gap to SITEMAP — margin-left:auto alone
   collapses to the row's flex gap once the row is full at narrow widths.
   Below 860px the row goes left-aligned (see the query further down) and
   the icons wrap under it. */
.foot-legal .socials{margin:0;margin-left:auto;padding-left:clamp(28px,3vw,56px);gap:10px}
.foot-legal .socials a{width:34px;height:34px}
.foot-legal .socials svg{width:15px;height:15px}
/* The chat launcher is position:fixed, so at the bottom of the page it lands
   on whatever the footer put in that corner. Base sets padding-bottom to
   clamp(34px,3.8vw,50px), which is less than the launcher's 96px footprint
   (72px tile + up to 24px offset), so the legal row sat underneath it. This
   holds the row clear instead of indenting the icons out of the way. */
.footer{padding-bottom:clamp(112px,8vw,130px)}
@media (max-width:860px){
  /* The launcher is bottom-right at every width, so the clearance has to
     survive the mobile override. Zeroing the right margin here put it back
     on top of the last icon. */
  .foot-legal .socials{margin:12px 76px 0 0}
}

@media (max-width:1040px){
  .foot-cols{grid-template-columns:repeat(2,1fr);row-gap:clamp(30px,4vw,44px)}
}
@media (max-width:560px){
  .foot-cols{grid-template-columns:1fr}
  .foot-mid{align-items:flex-start}
  .foot-legal{justify-content:flex-start}
}

/* ── NAVIGATION · dropdown panels ────────────────────────────
   Ported from the v1 React nav (Radix NavigationMenu) into
   plain CSS + a small script, because the new site is static.
   Visual treatment is v1's exactly: the cream popover
   (--popover #F6EEE4), 6px radius, hairline border, item rows
   with a 13px semibold title over a 12.5px muted description,
   and #E3D7C6 on hover. The trigger keeps .nav a's ink-at-rest,
   orange-on-hover, orange underline. */
.nav{position:relative;align-items:center}
.nav-item{position:relative;display:flex;align-items:center}
.nav-trigger{
  display:inline-flex;align-items:center;gap:6px;
  background:none;border:0;cursor:pointer;
  font-family:inherit;font-weight:inherit;font-size:inherit;
  letter-spacing:inherit;text-transform:inherit;color:inherit;
  padding:6px 0;border-bottom:1px solid transparent;
  transition:border-color .18s,color .18s;
}
.nav-trigger::after{
  content:"";width:0;height:0;
  border-left:3.5px solid transparent;border-right:3.5px solid transparent;
  border-top:4px solid currentColor;
  transition:transform .2s;opacity:.7;
}
.nav-item:hover .nav-trigger,
.nav-trigger[aria-expanded="true"]{border-color:var(--orange);color:var(--orange)}
.nav-item:hover .nav-trigger::after,
.nav-trigger[aria-expanded="true"]::after{transform:rotate(180deg)}

.nav-panel{
  position:absolute;top:100%;left:-14px;z-index:40;
  margin-top:10px;padding:6px;
  background:#F6EEE4;border:1px solid var(--line-cream);border-radius:6px;
  box-shadow:0 10px 30px rgba(0,0,0,.14);
  display:grid;gap:2px;
  opacity:0;visibility:hidden;transform:translateY(-4px);
  transition:opacity .18s,transform .18s,visibility .18s;
}
.nav-panel--wide{grid-template-columns:1fr 1fr;width:520px}
.nav-panel--single{width:300px}
.nav-item:hover .nav-panel,
.nav-item:focus-within .nav-panel,
.nav-panel[data-open]{opacity:1;visibility:visible;transform:translateY(0)}
.nav-panel a{
  display:block;padding:9px 11px;border-radius:4px;
  text-transform:none;letter-spacing:normal;font-family:var(--sans);
  transition:background .15s;
}
.nav-panel a:hover,.nav-panel a:focus-visible{background:#E3D7C6}
.nav-panel b{display:block;font-size:13px;font-weight:600;line-height:1.25;color:#1A1D1C}
.nav-panel span{
  display:block;margin-top:3px;font-size:12.5px;font-weight:400;
  line-height:1.35;color:#6A675F;
}
@media (max-width:860px){.nav-panel{display:none}}

/* ── INTERIOR PAGE HERO ──────────────────────────────────────
   Interior pages reuse the cream .pain section for their hero
   rather than the homepage's photo split, so every page opens
   on the same ground with the same eyebrow, headline and lede
   rhythm. No new type, no new colour. */
.phero{padding:clamp(46px,5vw,76px) 0 clamp(40px,4.4vw,64px)}
.phero h1{font-size:clamp(34px,4.3vw,62px);max-width:18ch}
.phero .lede{margin:24px 0 0;max-width:58ch;color:#4A4842}
.phero-actions{display:flex;flex-wrap:wrap;gap:13px;margin:30px 0 0}
.phero-actions .btn:not(.btn--solid){border-color:var(--line-cream);color:var(--ink)}
.phero-actions .btn:not(.btn--solid):hover{border-color:var(--ink);background:var(--ink);color:var(--cream)}

/* Prose block for long-form interior copy. Sizes are .pain-note's. */
.prose p{margin:0 0 20px;font-size:clamp(15px,1.3vw,18.5px);line-height:1.6;max-width:68ch}
.prose p:last-child{margin-bottom:0}
.caps .prose p{color:var(--on-dark)}
.pain .prose p{color:#4A4842}
.prose b{color:inherit;font-weight:700}

/* Interior pages reuse .hero purely as the header bar, so the homepage
   photograph and its cream wash are switched off. Without this a sliver
   of the hero image paints behind the nav on every interior page. */
.hero--bar{min-height:0}
.hero--bar::before,.hero--bar::after{display:none}
/* The pill is cream-on-photo on the homepage. With the photo gone it has to
   take the ink treatment the base stylesheet already uses below 860px. */
.hero--bar .btn--pill{border-color:var(--line-cream);color:var(--ink)}
.hero--bar .btn--pill:hover{background:var(--orange);border-color:var(--orange);color:#14100E}

/* ── FIX · dropdown panel was being clipped on interior pages ─
   .hero carries overflow:hidden from the base stylesheet, which
   is right on the homepage (it clips the background photograph)
   and wrong on an interior page, where .hero is only the header
   bar and the dropdown panel has to hang below it. */
.hero--bar{overflow:visible}
.hero-frame:has(.hero--bar){overflow:visible}

/* ── FIX · open dropdown painted UNDER the page's first section ─
   Escaping .hero's overflow (above) let the panel hang out; it did
   not let it rank. .hero sets isolation:isolate, so it is a stacking
   context at z-index:auto, and .topbar's z-index:20 only ranks the
   header against its siblings INSIDE .hero -- it cannot reach the
   page. Anything later in the document that makes its own stacking
   context therefore paints over the open panel, and opacity is
   enough to make one: .cs-crumb is opacity:.7 and .cs-dek is .85,
   so on a case study the breadcrumb drew straight through the panel.
   Raising the bar itself carries every descendant with it, which a
   z-index on .topbar cannot do from inside the isolate. Below the
   .stickybar (90), the drawer (900) and the chat launcher (610). */
.hero--bar{z-index:20}

/* ── FIX · CTA photograph was being upscaled ─────────────────
   Stretching the photo to the form column's height forced a tall
   portrait crop out of a 1536x1024 landscape source, so only
   ~930 of its 1536 pixels spanned the frame: 0.64x of retina
   density at 1440, and it read soft. Pinning the frame to the
   source's own 3:2 means the full 1536px width is used.
   Measured after: 1.18x at 1280, 1.05x at 1440. */
.cta-grid{align-items:center}
.cta-img{aspect-ratio:3/2;height:auto;min-height:0}
@media (max-width:860px){.cta-img{aspect-ratio:16/10}}

/* Footer grew to five groups so every page on the site is reachable from it.
   Column counts step down on the same breakpoints as the rest of the page. */
.foot-cols{grid-template-columns:repeat(5,1fr)}
@media (max-width:1280px){.foot-cols{grid-template-columns:repeat(3,1fr);row-gap:clamp(30px,4vw,44px)}}
@media (max-width:860px){.foot-cols{grid-template-columns:repeat(2,1fr)}}
@media (max-width:560px){.foot-cols{grid-template-columns:1fr}}

/* ── FOOTER · tightened ──────────────────────────────────────
   Was five ragged columns and 40 links, 880px tall on desktop
   and 2096px on mobile. Now four columns capped at eight, with
   each group heading linking to its own hub so the "All X" rows
   are gone. Per-case-study, tool and utility links live on
   /sitemap/, which the legal row carries. */
.foot-cols{grid-template-columns:repeat(4,1fr);gap:clamp(20px,2.4vw,40px)}
.foot-col .eyebrow a{color:var(--orange);transition:opacity .18s}
.foot-col .eyebrow a:hover{opacity:.7}
.foot-col a{padding:6px 0;font-size:clamp(13.5px,1.02vw,15px)}
.brand--foot{--wm:168px}
.foot-mid{align-items:flex-start}
.foot-cta{text-align:right}
.foot-cta .eyebrow{margin-bottom:14px}
.foot-legal{align-items:center;gap:clamp(14px,1.8vw,28px)}
.foot-copy{color:#6E6B63}
@media (max-width:1040px){.foot-cols{grid-template-columns:repeat(2,1fr);row-gap:clamp(28px,3.6vw,40px)}}
@media (max-width:560px){
  .foot-cols{grid-template-columns:1fr}
  .foot-cta{text-align:left}
}

/* ════════════════════════════════════════════════════════════
   v3.1 · EDITORIAL LAYER
   Added 2026-09-24 for the 47-page content build: answer-first
   blocks, scroll stories, photography bands, figures (charts,
   diagrams and interface mocks), stat strips and pull quotes.

   Same rule as the rest of this file: no new colours, no new
   type families, no new radii. Every value composes from
   --ink / --ink-2 / --cream / --cream-hi / --orange /
   --line-dark / --line-cream / --sans / --mono, and every
   block is built to render on BOTH grounds (.caps ink and
   .pain cream) because the page alternates.
   ════════════════════════════════════════════════════════════ */

/* ── ANSWER BLOCK ────────────────────────────────────────────
   Sits directly under the hero. One short, quotable paragraph
   that answers the page's question outright, then the three
   facts that back it. Written this way on purpose: an AI answer
   engine lifts the first self-contained paragraph under the
   heading, and a human skimming gets the same thing. */
.answer{padding:clamp(34px,3.6vw,52px) 0 clamp(34px,3.6vw,52px)}
.answer-box{
  border-left:3px solid var(--orange);
  padding-left:clamp(20px,2.2vw,34px);
  max-width:80ch;
}
.answer-q{
  margin:0 0 14px;font-family:var(--mono);font-weight:700;
  font-size:clamp(10px,.86vw,12px);letter-spacing:.17em;
  text-transform:uppercase;color:var(--orange);
}
.answer-a{
  margin:0;font-size:clamp(17px,1.62vw,23px);line-height:1.48;
  font-weight:500;letter-spacing:-.012em;
}
.caps .answer-a{color:var(--cream-hi)}
.pain .answer-a{color:var(--ink)}
.answer-facts{
  list-style:none;margin:clamp(22px,2.4vw,32px) 0 0;padding:0;
  display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,1.6vw,26px);
}
.answer-facts li{
  padding-top:14px;border-top:1px solid var(--line-cream);
  font-size:clamp(14px,1.1vw,15.5px);line-height:1.5;
}
.caps .answer-facts li{border-top-color:var(--line-dark);color:var(--on-dark)}
.pain .answer-facts li{color:#4A4842}
.answer-facts b{display:block;margin-bottom:5px;font-weight:700}
.caps .answer-facts b{color:var(--cream-hi)}
.pain .answer-facts b{color:var(--ink)}

/* ── SCROLL STORY ────────────────────────────────────────────
   A sticky heading column beside a stepped narrative. The
   sticky half is the only thing that moves differently from
   the page, so the effect is structural rather than animated.

   Reveal is opt-in from script: .story-step starts fully
   visible, and site.js adds [data-reveal] to the section only
   when IntersectionObserver exists. With JS off, or under
   prefers-reduced-motion, every step is simply there. */
.story-grid{
  display:grid;grid-template-columns:.42fr .58fr;
  gap:clamp(30px,4.4vw,78px);align-items:start;
  margin-top:clamp(18px,2vw,30px);
}
.story-stick{position:sticky;top:clamp(24px,4vw,64px)}
.story-stick h2{margin-bottom:clamp(16px,1.8vw,24px)}
.story-lede{
  margin:0 0 clamp(20px,2.2vw,30px);max-width:40ch;
  font-size:clamp(14.5px,1.16vw,16.5px);line-height:1.55;
}
.caps .story-lede{color:var(--on-dark)}
.pain .story-lede{color:#4A4842}
.story-rail{
  display:flex;align-items:center;gap:12px;
  font-family:var(--mono);font-weight:700;font-size:11px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--orange);
}
.story-bar{
  position:relative;flex:1 1 auto;height:2px;max-width:200px;
  background:var(--line-cream);
}
.caps .story-bar{background:var(--line-dark)}
.story-bar i{
  position:absolute;inset:0 auto 0 0;display:block;
  width:var(--story-p,0%);background:var(--orange);
  transition:width .35s ease;
}
.story-steps{list-style:none;margin:0;padding:0;display:grid;gap:clamp(30px,3.6vw,56px)}
.story-step{
  padding-left:clamp(18px,2vw,30px);
  border-left:1px solid var(--line-cream);
}
.caps .story-step{border-left-color:var(--line-dark)}
.story-step h3{
  font-size:clamp(19px,1.72vw,26px);line-height:1.2;margin:0 0 12px;
  letter-spacing:-.022em;
}
.caps .story-step h3{color:var(--cream-hi)}
.pain .story-step h3{color:var(--ink)}
.story-step p{
  margin:0;font-size:clamp(15px,1.24vw,17.5px);line-height:1.58;max-width:58ch;
}
.caps .story-step p{color:var(--on-dark)}
.pain .story-step p{color:#4A4842}
.story-step .step-n{margin-bottom:10px}
.story-step-note{
  margin:16px 0 0;padding-top:14px;border-top:1px solid var(--line-cream);
  font-family:var(--mono);font-size:11px;letter-spacing:.09em;
  text-transform:uppercase;line-height:1.7;
}
.caps .story-step-note{border-top-color:var(--line-dark);color:#8C8880}
.pain .story-step-note{color:#6E6B63}
.story-step.is-on{border-left-color:var(--orange)}

[data-reveal] .story-step{
  opacity:.45;transform:translateY(14px);
  transition:opacity .5s ease,transform .5s ease,border-color .3s ease;
}
[data-reveal] .story-step.is-in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  [data-reveal] .story-step{opacity:1;transform:none;transition:none}
  .story-bar i{transition:none}
}

/* ── PHOTO BAND ──────────────────────────────────────────────
   Photograph beside copy. The frame is pinned to 3/2 because
   every photograph in /assets/people/ is exported at 3/2, so
   `cover` crops nothing and the full file width spans the
   frame (the resolution trap this site already paid for). */
.pband-grid{
  display:grid;grid-template-columns:1.02fr .98fr;
  gap:clamp(26px,3.6vw,64px);align-items:center;
  margin-top:clamp(20px,2.4vw,34px);
}
.pband-fig{margin:0}
.pband-fig img{width:100%;aspect-ratio:3/2;height:auto;object-fit:cover}
.pband--flip .pband-fig{order:2}
.pband-cap,.fig-cap{
  margin:12px 0 0;font-family:var(--mono);font-size:11px;
  letter-spacing:.12em;text-transform:uppercase;line-height:1.6;
}
.caps .pband-cap,.caps .fig-cap{color:#8C8880}
.pain .pband-cap,.pain .fig-cap{color:#6E6B63}
.pband-copy h2{margin-bottom:clamp(16px,1.8vw,24px)}
.pband-copy p{
  margin:0 0 18px;font-size:clamp(15px,1.3vw,18px);line-height:1.58;max-width:52ch;
}
.pband-copy p:last-of-type{margin-bottom:0}
.caps .pband-copy p{color:var(--on-dark)}
.pain .pband-copy p{color:#4A4842}
.pband-copy b{font-weight:700}
.caps .pband-copy b{color:var(--cream-hi)}
.pain .pband-copy b{color:var(--ink)}
.pband-actions{margin-top:clamp(22px,2.4vw,30px)}

/* Wide photograph used as a section rule between two blocks. */
.pstrip{padding:0;background:var(--ink)}
.pstrip img{width:100%;aspect-ratio:3/1;height:auto;object-fit:cover;object-position:center 42%}

/* ── FIGURES · charts, diagrams and interface mocks ──────────
   Everything in here is DRAWN, not captured. Each figure says
   so in its own caption, and any slot that needs a real number
   carries the .ph placeholder rather than an invented one. */
.fig{
  margin:clamp(26px,3vw,40px) 0 0;
  border:1px solid var(--line-cream);padding:clamp(18px,2vw,30px);
}
.caps .fig{border-color:var(--line-dark);background:var(--ink-2)}
.pain .fig{background:rgba(255,255,255,.42)}
.fig-head{
  display:flex;flex-wrap:wrap;gap:10px 18px;align-items:baseline;
  justify-content:space-between;margin-bottom:clamp(16px,1.8vw,24px);
}
.fig-title{
  margin:0;font-size:clamp(15px,1.24vw,18px);font-weight:700;
  letter-spacing:-.018em;line-height:1.25;
}
.caps .fig-title{color:var(--cream-hi)}
.pain .fig-title{color:var(--ink)}
.fig-kind{
  font-family:var(--mono);font-weight:700;font-size:10px;
  letter-spacing:.17em;text-transform:uppercase;color:var(--orange);
}
.fig svg{display:block;width:100%;height:auto}

/* Stacked "what the results page looks like" diagram. */
.serp{display:grid;gap:8px}
.serp-row{
  display:grid;grid-template-columns:auto 1fr auto;gap:14px;align-items:center;
  border:1px solid var(--line-cream);padding:12px 14px;
}
.caps .serp-row{border-color:var(--line-dark)}
.serp-row[data-own="yes"]{border-color:rgba(241,107,43,.55);background:rgba(241,107,43,.06)}
.serp-tag{
  font-family:var(--mono);font-weight:700;font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--orange);white-space:nowrap;
}
.serp-lines{display:grid;gap:6px}
.serp-lines i{display:block;height:7px;background:var(--line-cream)}
.caps .serp-lines i{background:var(--line-dark)}
.serp-lines i:first-child{width:52%;height:9px;background:rgba(241,107,43,.42)}
.serp-note{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;
  text-align:right;line-height:1.5;max-width:20ch;
}
.caps .serp-note{color:#8C8880}
.pain .serp-note{color:#6E6B63}

/* Horizontal bar chart. Values are placeholders by default. */
.bars{display:grid;gap:clamp(12px,1.3vw,18px)}
.bar-row{display:grid;grid-template-columns:minmax(90px,.30fr) 1fr auto;gap:14px;align-items:center}
.bar-lab{
  font-family:var(--mono);font-weight:500;font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;line-height:1.4;
}
.caps .bar-lab{color:#B4B0A8}
.pain .bar-lab{color:#4A4842}
.bar-track{height:14px;background:var(--line-cream)}
.caps .bar-track{background:var(--line-dark)}
.bar-track i{display:block;height:100%;background:var(--orange);width:var(--w,0%)}
.bar-track i[data-mute]{background:#8C8880}
.bar-val{font-family:var(--mono);font-weight:700;font-size:11px;letter-spacing:.06em;color:var(--orange)}

/* Interface mock. A drawn screen, never a capture. */
.screen{border:1px solid var(--line-cream)}
.caps .screen{border-color:var(--line-dark);background:var(--ink)}
.pain .screen{background:var(--cream-hi)}
.screen-bar{
  display:flex;align-items:center;gap:7px;padding:9px 12px;
  border-bottom:1px solid var(--line-cream);
}
.caps .screen-bar{border-bottom-color:var(--line-dark)}
.screen-bar u{width:8px;height:8px;border-radius:50%;background:var(--line-cream);text-decoration:none}
.caps .screen-bar u{background:var(--line-dark)}
.screen-bar span{
  margin-left:8px;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.1em;text-transform:uppercase;
}
.caps .screen-bar span{color:#8C8880}
.pain .screen-bar span{color:#6E6B63}
.screen-body{padding:clamp(14px,1.6vw,22px)}
.screen table{width:100%;border-collapse:collapse;font-size:13px}
.screen th{
  text-align:left;padding:0 10px 10px 0;font-family:var(--mono);font-weight:700;
  font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--orange);
  white-space:nowrap;
}
.screen td{
  padding:10px 10px 10px 0;border-top:1px solid var(--line-cream);
  font-size:13px;line-height:1.4;vertical-align:top;
}
.caps .screen td{border-top-color:var(--line-dark);color:var(--on-dark)}
.pain .screen td{color:#4A4842}
.screen .yes{color:var(--orange);font-weight:700}
.screen .no{color:#8C8880}
.screen-scroll{overflow-x:auto}

/* ── STAT STRIP ──────────────────────────────────────────────
   Big figures in a row. Deliberately placeholder-tolerant: a
   .ph inside .stat-n must not stretch the column, which is why
   the selector below is a direct child. */
.statstrip{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(16px,2vw,34px);margin-top:clamp(28px,3.2vw,44px)}
.stat-c{border-top:1px solid var(--line-cream);padding-top:clamp(14px,1.6vw,20px)}
.caps .stat-c{border-top-color:var(--line-dark)}
.stat-n{
  margin:0 0 8px;font-weight:900;letter-spacing:-.04em;line-height:.95;
  font-size:clamp(30px,3.3vw,48px);
}
.caps .stat-n{color:var(--cream-hi)}
.pain .stat-n{color:var(--ink)}
.stat-c > p:last-child{
  margin:0;font-size:clamp(13.5px,1.05vw,15px);line-height:1.5;
}
.caps .stat-c > p:last-child{color:var(--on-dark)}
.pain .stat-c > p:last-child{color:#4A4842}

/* ── PULL QUOTE ──────────────────────────────────────────────
   Used for what a business owner actually says on a call, not
   for a testimonial we do not have. Anything attributed to a
   named client stays a placeholder until Joe supplies it. */
.pull{
  margin:clamp(28px,3.2vw,46px) 0 0;padding-left:clamp(20px,2.2vw,34px);
  border-left:3px solid var(--orange);max-width:64ch;
}
.pull p{
  margin:0;font-size:clamp(18px,1.85vw,27px);line-height:1.38;
  font-weight:500;letter-spacing:-.018em;
}
.caps .pull p{color:var(--cream-hi)}
.pain .pull p{color:var(--ink)}
.pull cite{
  display:block;margin-top:16px;font-style:normal;font-family:var(--mono);
  font-size:11px;letter-spacing:.14em;text-transform:uppercase;
}
.caps .pull cite{color:#8C8880}
.pain .pull cite{color:#6E6B63}

/* ── CHECK LIST ──────────────────────────────────────────────
   Two-column list used for scope ("what is included") on the
   service pages. Marker is the same orange arrow the footer
   columns use. */
.checks{list-style:none;margin:clamp(24px,2.8vw,38px) 0 0;padding:0;
        display:grid;grid-template-columns:1fr 1fr;gap:clamp(10px,1.2vw,18px) clamp(24px,3vw,48px)}
.checks li{
  display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:baseline;
  padding-bottom:clamp(10px,1.2vw,16px);border-bottom:1px solid var(--line-cream);
  font-size:clamp(14px,1.1vw,16px);line-height:1.5;
}
.caps .checks li{border-bottom-color:var(--line-dark);color:var(--on-dark)}
.pain .checks li{color:#4A4842}
.checks li::before{content:"\2192";color:var(--orange);font-weight:600}

/* ── PHOTO CREDITS ───────────────────────────────────────────
   Unsplash does not require attribution. We print it anyway,
   in one place, so the provenance of every photograph on the
   site is checkable. */
.credits{
  margin-top:clamp(26px,3vw,40px);padding-top:clamp(18px,2vw,26px);
  border-top:1px solid var(--line-dark);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;
  line-height:1.9;color:#8C8880;
}

/* ── RESPONSIVE ──────────────────────────────────────────────
   Same 1040 / 860 / 560 steps as everything above. */
@media (max-width:1040px){
  .answer-facts{grid-template-columns:1fr 1fr}
  .statstrip{grid-template-columns:repeat(2,1fr);row-gap:clamp(22px,3vw,32px)}
}
@media (max-width:860px){
  .story-grid{grid-template-columns:1fr;gap:clamp(26px,3.4vw,38px)}
  .story-stick{position:static}
  .pband-grid{grid-template-columns:1fr;gap:26px}
  .pband--flip .pband-fig{order:0}
  .checks{grid-template-columns:1fr}
  .pstrip img{aspect-ratio:2/1}
}
@media (max-width:560px){
  .answer-facts{grid-template-columns:1fr}
  .statstrip{grid-template-columns:1fr}
  .fig{padding:16px}
  .serp-row{grid-template-columns:1fr;gap:9px}
  .serp-note{text-align:left;max-width:none}
  .bar-row{grid-template-columns:1fr;gap:7px}
}

/* ── STICKY HEADER ───────────────────────────────────────────
   A second, independent bar rather than position:fixed on
   .topbar. The real topbar is a grid child of .hero, which on
   the homepage sits on the background photograph; pulling it out
   of flow shifts the whole hero up by its own height. This bar
   starts off-screen and stays out of the accessibility tree and
   out of tab order (visibility:hidden) until site.js reveals it,
   so a page with JS off is exactly what it was before.

   Contents are the topbar's markup verbatim, which is why the
   mobile treatment needs no rules of its own: .nav already goes
   display:none below 860px, leaving logo + button. */
:root{--stuck-h:62px}
html{scroll-padding-top:calc(var(--stuck-h) + 14px)}

.stickybar{
  position:fixed;top:0;left:0;right:0;z-index:90;
  display:flex;align-items:center;gap:clamp(14px,2.4vw,32px);
  padding:11px clamp(18px,3vw,44px);
  /* The bar has to separate itself from a DARK section as well as a
     cream one. Over cream the edge is obvious; over .caps (near the
     same ink) a 1px hairline vanishes and a headline reads as sliced
     in half by nothing. The shadow is what carries the seam there. */
  background:var(--ink);border-bottom:1px solid rgba(246,238,228,.22);
  box-shadow:0 10px 26px rgba(0,0,0,.45);
  color:var(--cream-hi);
  transform:translateY(-100%);visibility:hidden;
  transition:transform .28s ease,visibility .28s;
  will-change:transform;
}
.stickybar.is-on{transform:none;visibility:visible}

.stickybar .brand{--wm:138px;flex:0 0 auto}
.stickybar .nav{flex:1 1 auto;padding-left:clamp(8px,2vw,28px);color:var(--on-dark)}
.stickybar .btn--pill{
  margin-left:auto;flex:0 0 auto;
  border-color:rgba(246,238,228,.62);color:var(--cream-hi);
  padding:10px 18px;font-size:11px;
}
.stickybar .btn--pill:hover{background:var(--orange);border-color:var(--orange);color:#14100E}
.stickybar .btn--pill .ar{font-size:13px}
/* The panel hangs off a 62px bar, not the tall header, so it needs
   less clearance than .nav-panel's default. */
.stickybar .nav-panel{margin-top:19px}

@media (max-width:860px){
  .stickybar{padding:10px var(--gut)}
  .stickybar .brand{--wm:112px}
  .stickybar .btn--pill{font-size:9px;letter-spacing:.05em;padding:9px 11px;gap:6px}
  .stickybar .btn--pill .ar{font-size:11px}
}

/* Reduced motion keeps the behaviour and drops the slide. The bar
   still appears and disappears, it just does not travel. */
@media (prefers-reduced-motion:reduce){
  .stickybar{transition:none}
}

/* ── WHO WE WORK WITH: PROOF BAND ────────────────────────────
   Replaced the four .tile-clients captions on 2026-09-24. The
   hairline, mono face, letter-spacing and muted colour are
   .tile-clients' own; the 3-up grid and gap are .grid-3's. The
   only new value is the top padding, which matches .grid-4's
   own gap so the band reads as part of the same stack. */
.who-band{
  margin-top:clamp(30px,3.4vw,46px);
  padding-top:clamp(18px,1.8vw,24px);
  border-top:1px solid var(--line-dark);
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(10px,1.1vw,16px);
}
.who-band-item{
  font-family:var(--mono);font-weight:500;font-size:10.5px;
  letter-spacing:.12em;text-transform:uppercase;color:#8C8880;line-height:1.6;
  padding-left:clamp(16px,1.7vw,26px);border-left:1px solid var(--line-dark);
}
.who-band-item b{display:block;color:var(--cream-hi);font-weight:700;margin-bottom:5px}
@media (max-width:860px){
  .who-band{grid-template-columns:1fr;gap:16px}
}

/* A section lede placed directly under a section heading needs the gap the
   heading does not carry. Same step as .caps-aside's, so the two read alike. */
.h-sec + .story-lede{margin-top:clamp(18px,2vw,26px)}

/* ── CTA PHOTOGRAPH · portrait on desktop ────────────────────
   The form column is taller than a 3/2 photograph, so pinning
   the frame to 3/2 left a letterboxed band of ink above and
   below it. Stretching the 3/2 file instead would crop it to
   roughly half its width and land under 1x density at 1440,
   which is the resolution trap this site already paid for.
   The fix is a second crop of the same photograph at 4/5,
   served to desktop only, with the 3/2 file still serving the
   phone layout where the frame really is landscape. */
.cta-img picture{display:block;width:100%;height:100%}
.cta-img{aspect-ratio:4/5}
.cta-img img{width:100%;height:100%;object-fit:cover}
@media (max-width:860px){.cta-img{aspect-ratio:16/10}}

/* ── FIX · section aside on the cream ground ─────────────────
   .caps-aside sets colour for the ink ground (--on-dark). The
   same head/aside pair is reused inside .pain sections for the
   stat strips and tile grids, where that grey sits at roughly
   1.9:1 against cream and is effectively unreadable. Same step,
   correct colour, per ground. */
.pain .caps-aside p{color:#4A4842}
.pain .caps-head h2{color:var(--ink)}

/* ── FIX · FAQ on the cream ground ───────────────────────────
   The FAQ block was written for the ink ground only: the
   question is --cream-hi and the hairlines are --line-dark,
   which on cream is near-white text on near-white paper. The
   interior pages alternate grounds, so half of them landed the
   FAQ on cream and the questions vanished. Same sizes, same
   spacing, correct colours per ground. */
.pain .faq{border-top-color:var(--line-cream)}
.pain .faq details{border-bottom-color:var(--line-cream)}
.pain .faq summary{color:var(--ink)}
.pain .faq summary:hover{color:var(--orange)}
.pain .faq-a{color:#4A4842}

/* ── FIX · contrast on the cream ground ──────────────────────
   Measured across all 47 pages at 1440 with a computed
   foreground-over-nearest-opaque-background check, not by eye.

   Two families failed AA and both are fixed here:

   1. The muted mono caption #6E6B63 reads 4.31:1 on cream,
      just under the 4.5 small-text threshold. #66635B is the
      same grey two steps darker and reads 4.85:1. Used for
      figure captions, photo captions, step notes, the founder
      caption and the tile client line.
   2. Orange table headings inside a drawn interface read
      2.66:1 on the cream screen ground. --orange at 10px was
      never going to pass there, so the figure tables take a
      darker orange (#A8400C, 5.37:1) which still reads as the
      accent and is legible.

   The footer copyright was 3.46:1 on ink and takes the grey
   the footer already uses one line above it.

   NOT changed here, deliberately: .eyebrow is --orange on
   cream at 2.47:1 across the whole site, v1 and v2 included.
   That is the brand's signature treatment and darkening it
   changes the look of every page, so it is Joe's call rather
   than a fix to slip in. One line does it when he wants it. */
.pain .fig-cap,
.pain .pband-cap,
.pain .serp-note,
.pain .story-step-note,
.pain .pull cite,
.founder-cap,
.tile--cream .tile-clients{color:#66635B}
.pain .screen th{color:#A8400C}
.foot-copy{color:#8C8880}
/* The figure's kind label is new in v3.1, so it takes the accessible orange
   rather than inheriting the eyebrow's known 2.47:1. */
.pain .fig-kind{color:#A8400C}

/* ── SAMPLE FIGURES ──────────────────────────────────────────
   A number that is made up has to say so on the page, because
   the screenshot outlives the caveat. Two parts, and both are
   required: the figure itself carries a dotted orange rule so
   it is visibly not a plain number, and the block it sits in
   carries a chip naming it. Neither is loud enough to spoil
   the layout, which is the point: it has to survive being
   left in for weeks without anyone wanting to remove it.

   Deliberately NOT the .ph treatment. A dashed orange box says
   "nothing here yet". This says "a real-shaped example". Two
   different claims, two different appearances. */
.sd{border-bottom:1px dotted rgba(241,107,43,.75);padding-bottom:.04em}
.stat-n .sd{border-bottom-width:2px;padding-bottom:.02em}
.sd-tag{
  display:inline-block;margin-right:10px;
  font-family:var(--mono);font-weight:700;font-size:9.5px;
  letter-spacing:.14em;text-transform:uppercase;
  color:var(--orange);border:1px solid rgba(241,107,43,.5);
  border-radius:2px;padding:2px 6px;vertical-align:middle;
  white-space:nowrap;
}
.pain .sd-tag{color:#A8400C;border-color:rgba(168,64,12,.55)}
.eyebrow .sd-tag{margin-left:4px}
.fig-kind .sd-tag{margin-right:8px}

/* ── CLIENT PORTAL · ROI CARD ────────────────────────────────
   The Journey portal's "did marketing pay for itself" card,
   rebuilt in this site's palette rather than screenshotted.
   Layout follows the live surface: a question, four columns,
   a breakeven scale, and the customers-won tile beneath.
   Colour does NOT follow it. The portal is blue and green;
   pasting that onto a cream-and-orange page reads as a foreign
   object, and the caption already names the product. */
.roi-q{
  display:flex;align-items:center;gap:9px;margin:0 0 clamp(16px,1.8vw,24px);
  font-family:var(--mono);font-weight:700;font-size:11px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--orange);
}
.pain .roi-q{color:#A8400C}
.roi-q i{width:7px;height:7px;border-radius:50%;background:var(--orange);flex:0 0 auto}
.pain .roi-q i{background:#A8400C}

.roi-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:0}
.roi-c{padding:0 clamp(12px,1.4vw,20px);border-left:1px solid var(--line-cream)}
.caps .roi-c{border-left-color:var(--line-dark)}
.roi-c:first-child{padding-left:0;border-left:0}
.roi-lab,.roi-sub{
  margin:0;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.1em;text-transform:uppercase;line-height:1.5;
}
.pain .roi-lab,.pain .roi-sub{color:#66635B}
.caps .roi-lab,.caps .roi-sub{color:#8C8880}
.roi-n{
  margin:8px 0 6px;font-weight:900;letter-spacing:-.035em;line-height:1;
  font-size:clamp(20px,2.1vw,31px);
}
.pain .roi-n{color:var(--ink)}
.caps .roi-n{color:var(--cream-hi)}

.roi-scale{
  display:flex;justify-content:space-between;align-items:baseline;gap:12px;
  margin-top:clamp(20px,2.4vw,30px);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;
}
.pain .roi-scale{color:#66635B}
.caps .roi-scale{color:#8C8880}
.roi-verdict{font-weight:700;color:var(--orange)}
.pain .roi-verdict{color:#A8400C}
.roi-bar{position:relative;margin-top:8px}
.roi-bar i{
  display:block;height:9px;
  background:linear-gradient(90deg,rgba(241,107,43,.45),var(--orange));
}
.roi-bar b{
  display:block;margin-top:7px;text-align:center;
  font-family:var(--mono);font-weight:500;font-size:10px;
  letter-spacing:.12em;text-transform:uppercase;
}
.pain .roi-bar b{color:#66635B}
.caps .roi-bar b{color:#8C8880}

.roi-won{
  margin-top:clamp(22px,2.6vw,34px);padding-top:clamp(18px,2vw,26px);
  border-top:1px solid var(--line-cream);position:relative;
}
.caps .roi-won{border-top-color:var(--line-dark)}
.roi-big{
  margin:10px 0 4px;font-weight:900;letter-spacing:-.04em;line-height:.95;
  font-size:clamp(38px,4.2vw,60px);
}
.pain .roi-big{color:var(--ink)}
.caps .roi-big{color:var(--cream-hi)}
.roi-trend{
  position:absolute;right:0;bottom:2px;
  font-family:var(--mono);font-weight:700;font-size:11px;letter-spacing:.08em;
  color:var(--orange);
}
.pain .roi-trend{color:#A8400C}

@media (max-width:860px){
  .roi-grid{grid-template-columns:1fr 1fr;row-gap:clamp(18px,2.4vw,26px)}
  .roi-c:nth-child(3){padding-left:0;border-left:0}
  .roi-trend{position:static;display:block;margin-top:10px}
}
@media (max-width:560px){
  .roi-grid{grid-template-columns:1fr}
  .roi-c{padding-left:0;border-left:0;border-top:1px solid var(--line-cream);padding-top:14px}
  .roi-c:first-child{border-top:0;padding-top:0}
  .roi-scale{flex-wrap:wrap}
}

/* ═══════════════════════════════ BLOG (2026-09-24) ═══════════════════════════
   Ported from vitalitymmg.com's blog layout (~/code/vmmg-site globals.css .vb-*)
   onto Efferent tokens. Prefix is .eb- so nothing here can collide with the .vb-
   rules on that property or with the v1/v2 layers archived under /v1 and /v2.
   No new colours and no new type sizes: every value composes from --ink, --cream,
   --orange, --line-cream, --sans, --mono.
   ========================================================================== */

.eb{background:var(--cream);color:var(--ink);padding:0 0 var(--pad)}

/* The hub's own prose, under the lede on a term page's first page only.
   Wider measure than .lede's 58ch because this is running text rather than a
   standfirst, and a hair smaller than body so the h1 and lede still lead. */
.eb-termnote{margin:26px 0 0;max-width:72ch}
.eb-termnote p{margin:0;font-size:clamp(14.5px,1.05vw,16px);line-height:1.62;color:var(--on-cream)}
.eb-wrap{width:min(var(--max),calc(100% - 2*var(--gut)));margin-inline:auto}
.eb-sec-h{font-size:clamp(22px,2.1vw,30px);margin:clamp(40px,4vw,64px) 0 22px;letter-spacing:-.01em}
.eb-empty{color:#6B6860;font-size:15px;padding:18px 0}

/* index hero: headline left, standfirst right, collapsing under 900px */
.eb-idx-hero{display:grid;grid-template-columns:1.3fr .7fr;gap:clamp(24px,4vw,64px);align-items:end}
.eb-idx-side{margin:0;color:#4A4842;font-size:clamp(15px,1.2vw,17px);line-height:1.6;max-width:44ch}

/* editorial top: featured post + the three after it. Fixed, never filtered. */
.eb-top{display:grid;grid-template-columns:1.55fr .45fr;gap:clamp(24px,3vw,46px);
  padding:clamp(32px,3.4vw,52px) 0 0;align-items:start}
.eb-feat{display:grid;gap:12px;text-decoration:none;color:inherit}
.eb-feat-img,.eb-card-img{display:block;overflow:hidden;border-radius:4px;background:#E3D7C6;
  aspect-ratio:1200/630}
.eb-feat-img img,.eb-card-img img{width:100%;height:100%;object-fit:cover;display:block}
.eb-feat-t{font-size:clamp(26px,2.7vw,40px);line-height:1.1;letter-spacing:-.015em;font-weight:700;
  max-width:20ch}
.eb-feat:hover .eb-feat-t,.eb-card:hover .eb-card-t{color:var(--orange-dk)}
.eb-latest{display:grid;gap:0;align-content:start;
  border-left:1px solid var(--line-cream);padding-left:clamp(18px,1.8vw,26px)}
.eb-lat{display:grid;gap:5px;text-decoration:none;color:inherit;padding:15px 0;
  border-bottom:1px solid var(--line-cream)}
.eb-lat:last-child{border-bottom:0}
.eb-lat-c{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--orange-dk)}
.eb-lat-t{font-size:16px;line-height:1.3;font-weight:600}
.eb-lat:hover .eb-lat-t{color:var(--orange-dk)}
.eb-lat-d{font-size:12px;color:#6B6860}

/* filters */
.eb-filters{display:grid;gap:10px;margin:clamp(34px,3.6vw,56px) 0 0;
  padding:20px 0;border-top:1px solid var(--line-cream);border-bottom:1px solid var(--line-cream)}
.eb-filterrow{display:flex;flex-wrap:wrap;gap:7px;align-items:center}
.eb-filterlbl{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  color:#6B6860;width:72px;flex:none}
.eb-chipwrap{display:inline-flex;align-items:stretch}
.eb-chip{font:inherit;font-size:13px;cursor:pointer;background:transparent;color:#4A4842;
  border:1px solid var(--line-cream);border-radius:999px;padding:5px 13px;line-height:1.35;
  display:inline-flex;align-items:center;gap:6px}
.eb-chip i{font-style:normal;font-family:var(--mono);font-size:11px;color:#8B8880}
.eb-chip:hover{border-color:var(--ink);color:var(--ink)}
.eb-chip.is-on{background:var(--ink);border-color:var(--ink);color:var(--cream-hi)}
.eb-chip.is-on i{color:var(--cream-hi);opacity:.65}
.eb-chip:focus-visible,.eb-chip-go:focus-visible{outline:2px solid var(--orange);outline-offset:2px}
.eb-chip-go{display:inline-flex;align-items:center;padding:0 8px;margin-left:-1px;
  border:1px solid var(--line-cream);border-left:0;border-radius:0 999px 999px 0;
  color:#8B8880;text-decoration:none;font-size:13px}
.eb-chip-go:hover{color:var(--orange-dk);border-color:var(--ink)}
.eb-chipwrap .eb-chip{border-radius:999px 0 0 999px}
.eb-chipwrap .eb-chip:only-child{border-radius:999px}

/* card grid */
.eb-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(20px,2.2vw,32px)}
.eb-card{display:grid;gap:9px;align-content:start;text-decoration:none;color:inherit;
  padding-bottom:22px;border-bottom:1px solid var(--line-cream)}
.eb-card[hidden]{display:none}
.eb-card-cat,.eb-cat{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--orange-dk)}
.eb-card-t{font-size:19px;line-height:1.28;font-weight:700;letter-spacing:-.01em}
.eb-card-s{font-size:14.5px;line-height:1.55;color:#4A4842}
.eb-card-m{font-family:var(--mono);font-size:11px;color:#6B6860}
.eb-termcount{font-family:var(--mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase;
  color:#6B6860;padding:clamp(28px,3vw,44px) 0 18px;margin:0}

/* feed strip */
.eb-feedstrip{background:var(--cream);border-top:1px solid var(--line-cream);padding:22px 0}
.eb-feedstrip .wrap{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap}
.eb-feedstrip p{margin:0;font-family:var(--mono);font-size:11.5px;color:#6B6860;letter-spacing:.04em}
.eb-feedlinks a{color:var(--ink);text-decoration:underline;text-underline-offset:3px}
.eb-feedlinks a:hover{color:var(--orange-dk)}

/* ── post page · TEMPLATE E (2026-09-24) ─────────────────────────────────────
   Rebuilt against efferent-blog-template-E/reference-design-E.html. The comp is
   a 1440px static mockup carrying its own hex values and its own header; what is
   reproduced here is the LAYOUT, drawn with this site's tokens, inside this
   site's header and footer. Nothing below introduces a font or a colour the
   site did not already have, except --cream-panel, which is the one tone the
   comp needs that no token carried: the Key Takeaways band.
   ========================================================================== */
.eb-crumb{display:flex;gap:8px;flex-wrap:wrap;align-items:center;padding:clamp(26px,2.8vw,40px) 0 0;
  font-family:var(--mono);font-size:11px;letter-spacing:.06em;color:#6B6860}
.eb-crumb a{color:#6B6860;text-decoration:none}
.eb-crumb a:hover{color:var(--orange-dk)}

/* hero: no image. The featured image is a generated card with this same
   headline printed on it, so above the H1 it said the same thing twice. It
   lives in the rail's share block now. */
.eb-head{padding:clamp(20px,2.2vw,30px) 0 0}
.eb-cat{font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--orange-dk);margin:0}
.eb-h1{font-size:clamp(32px,4.2vw,60px);line-height:1.04;letter-spacing:-.03em;margin:16px 0 0;
  max-width:1060px;font-weight:800}
/* dek left, byline bottom-right on desktop. flex-end so the two baselines meet
   at the bottom of the block however many lines the dek runs to. */
.eb-headrow{display:flex;justify-content:space-between;align-items:flex-end;gap:clamp(24px,3.4vw,48px);
  margin:22px 0 0;flex-wrap:wrap}
.eb-standfirst{font-size:clamp(16px,1.4vw,20px);line-height:1.55;color:#3D3833;margin:0;
  max-width:720px;flex:1 1 380px}
.eb-standfirst:empty{display:none}
.eb-byline{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:0;
  font-size:14px;color:#4A443E;flex:0 0 auto}
.eb-byline a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--line-cream)}
.eb-byline a:hover{color:var(--orange-dk);border-color:var(--orange-dk)}
.eb-dot{color:#A8A5A0}
.eb-avatar{display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:40px;height:40px;border-radius:50%;background:#CDBFAE;color:#3A3833;
  font-family:var(--mono);font-size:12px;letter-spacing:.06em;line-height:1}
.eb-avatar--lg{width:52px;height:52px;font-size:14px}
.eb-masthead{margin:22px 0 0;font-size:12.5px;line-height:1.5;color:#6B6860;max-width:62ch;
  padding-top:0}

/* key takeaways: full bleed, its own ground, dark rule over and light rule
   under. Hidden entirely when the post carries no `key_takeaways`. */
.eb-kt{background:var(--cream-panel);margin:clamp(24px,2.6vw,36px) 0 0;
  padding:clamp(26px,2.6vw,34px) 0 clamp(28px,2.8vw,36px)}
.eb-kt-h{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:#6B6860;margin:0 0 14px}
.eb-kt-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  border-top:1px solid var(--ink);border-bottom:1px solid var(--line-cream)}
.eb-kt-i{display:flex;flex-direction:column;gap:10px;padding:24px 24px 26px 0}
.eb-kt-n{font-family:var(--mono);font-size:11px;letter-spacing:.14em;color:var(--orange-dk)}
.eb-kt-t{font-size:16px;line-height:1.4;font-weight:600;color:var(--ink)}

/* two columns: 760px article, 340px rail, 100px gutter, per the comp.
   minmax(0,760px) rather than 760px so the article can shrink between the
   breakpoint and the width the comp was drawn at instead of overflowing. */
.eb-layout{display:grid;grid-template-columns:minmax(0,760px) 340px;
  gap:clamp(40px,7vw,100px);padding:clamp(34px,3.6vw,56px) 0 0;align-items:start}
.eb-body{min-width:0}

/* ONLY the contents block sticks. A sticky rail taller than the viewport can
   never scroll its own tail into view, so the author card, the related posts
   and the share block below would be unreachable on a laptop. */
.eb-aside{display:grid;gap:34px;align-content:start;min-width:0}
.eb-toc{position:sticky;top:96px;z-index:3;display:grid;gap:16px;margin:0;
  background:var(--cream);padding-bottom:18px;border-bottom:1px solid var(--line-cream)}
.eb-toc-h{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--orange-dk);margin:0}
.eb-toc-bar{height:2px;background:var(--line-cream)}
.eb-toc-bar span{display:block;height:2px;width:0;background:var(--orange);
  transition:width .15s linear}
.eb-toc ol{margin:0;padding:0;list-style:none;display:grid;gap:14px}
.eb-toc a{display:flex;gap:12px;text-decoration:none;font-size:15px;line-height:1.4;color:#6B6860}
.eb-toc-n{font-family:var(--mono);font-size:11px;padding-top:3px;color:inherit;flex:none}
.eb-toc a:hover{color:var(--ink)}
.eb-toc a.is-on{color:var(--ink);font-weight:600}
.eb-toc a.is-on .eb-toc-n{color:var(--orange)}
@media (prefers-reduced-motion:reduce){
  .eb-toc-bar span{transition:none}
  /* html{scroll-behavior:smooth} is set site-wide in efferent-base.css, which
     is generated from the v1 app and must not be hand-edited, so the override
     lives here. Every in-page anchor on the site is covered, not just the
     contents block: a reader who asked for no motion asked once. */
  html{scroll-behavior:auto}
}

/* mobile contents: a dropdown pinned under the hero, shown only where the rail
   has collapsed under the article and the desktop block is out of reach. */
.eb-toc-m{display:none;border:1px solid var(--line-cream);border-radius:6px;
  padding:0 16px;margin:clamp(22px,3vw,30px) 0 0;background:var(--cream-hi)}
.eb-toc-m>summary{cursor:pointer;list-style:none;padding:14px 0;
  font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--orange-dk);display:flex;justify-content:space-between;align-items:center}
.eb-toc-m>summary::-webkit-details-marker{display:none}
.eb-toc-m>summary::after{content:'+';font-size:15px;color:#6B6860}
.eb-toc-m[open]>summary::after{content:'\2212'}
.eb-toc-m ol{margin:0 0 16px;padding:0;list-style:none;display:grid;gap:12px;
  border-top:1px solid var(--line-cream);padding-top:14px}
.eb-toc-m a{display:flex;gap:12px;text-decoration:none;font-size:15px;line-height:1.4;color:#4A4842}
.eb-toc-m a:hover{color:var(--orange-dk)}

/* author card, keep reading, share */
.eb-authorcard{display:flex;gap:14px;align-items:center;padding-top:4px}
.eb-authorcard-txt{display:flex;flex-direction:column;gap:4px;min-width:0}
.eb-authorcard-n{font-size:15px;font-weight:700;color:var(--ink);text-decoration:none}
.eb-authorcard-n:hover{color:var(--orange-dk)}
.eb-authorcard-r{font-size:13px;color:#5B554E;line-height:1.35}
.eb-railblock{display:grid;gap:14px;align-content:start;min-width:0}
.eb-rail-h{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:#6B6860;margin:0}
.eb-keepreading{display:grid;gap:0}
.eb-keepreading a{font-size:15px;line-height:1.4;font-weight:600;color:var(--ink);
  text-decoration:none;padding-bottom:14px;margin-bottom:14px;
  border-bottom:1px solid var(--line-cream)}
.eb-keepreading a:last-child{margin-bottom:0}
.eb-keepreading a:hover{color:var(--orange-dk)}
.eb-share-img{display:block;overflow:hidden;border-radius:6px;background:var(--ink);
  aspect-ratio:16/10}
.eb-share-img img{width:100%;height:100%;object-fit:contain;display:block}
.eb-share-btns{display:flex;gap:10px}
.eb-share-b{flex:1 1 0;min-width:0;min-height:44px;padding:0 8px;
  border:1px solid #CDBFAE;border-radius:4px;background:transparent;
  display:flex;align-items:center;justify-content:center;gap:6px;
  font:inherit;font-size:13px;font-weight:600;color:var(--ink);
  text-decoration:none;cursor:pointer;line-height:1.2;text-align:center}
.eb-share-b:hover{border-color:var(--ink);color:var(--orange-dk)}
.eb-share-b.is-copied{border-color:var(--orange);color:var(--orange-dk)}
.eb-share-b svg{flex:none}

/* in-article audit card, injected after the first H2 section */
.eb-incta{background:var(--ink);border-radius:6px;padding:clamp(24px,2.4vw,32px);
  margin:34px 0 38px;display:flex;justify-content:space-between;align-items:center;
  gap:24px;flex-wrap:wrap}
.eb-incta-copy{display:flex;flex-direction:column;gap:8px;min-width:0}
.eb-incta-eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--orange);margin:0}
.eb-incta-h{margin:0;font-size:clamp(20px,1.8vw,24px);line-height:1.15;letter-spacing:-.02em;
  font-weight:800;color:var(--cream-hi);max-width:24ch}
.eb-incta-btn{flex:none;background:var(--orange);color:#14100E;text-decoration:none;
  font-family:var(--mono);font-weight:700;font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  padding:16px 20px;border-radius:4px;white-space:nowrap;
  display:inline-flex;align-items:center;gap:10px}
.eb-incta-btn:hover{background:var(--orange-dk);color:#fff}
.eb-incta-btn .ar{font-family:var(--sans);font-weight:600;font-size:14px;line-height:1}

/* end CTA band */
.eb-endcta{padding:clamp(48px,5vw,72px) 0 0}
.eb-endcta-in{background:var(--ink);border-radius:6px;padding:clamp(32px,3.8vw,56px);
  display:flex;justify-content:space-between;align-items:flex-end;gap:clamp(24px,3.4vw,48px);
  flex-wrap:wrap}
.eb-endcta-copy{display:flex;flex-direction:column;gap:16px;max-width:640px}
.eb-endcta-eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--orange);margin:0}
.eb-endcta-h{margin:0;font-size:clamp(28px,3.4vw,44px);line-height:1.04;letter-spacing:-.03em;
  font-weight:800;color:var(--cream-hi)}
.eb-endcta-btn{flex:none;background:var(--orange);color:#14100E;text-decoration:none;
  font-family:var(--mono);font-weight:700;font-size:12px;letter-spacing:.12em;text-transform:uppercase;
  padding:18px 26px;border-radius:4px;white-space:nowrap;
  display:inline-flex;align-items:center;gap:10px}
.eb-endcta-btn:hover{background:var(--orange-dk);color:#fff}
.eb-endcta-btn .ar{font-family:var(--sans);font-weight:600;font-size:15px;line-height:1}

/* Focus is visible on every control this template adds, including the ones that
   are links dressed as buttons. */
.eb-toc a:focus-visible,.eb-toc-m a:focus-visible,.eb-toc-m>summary:focus-visible,
.eb-share-b:focus-visible,.eb-keepreading a:focus-visible,.eb-incta-btn:focus-visible,
.eb-endcta-btn:focus-visible,.eb-authorcard-n:focus-visible,.eb-byline a:focus-visible,
.eb-crumb a:focus-visible{outline:2px solid var(--orange);outline-offset:3px;border-radius:2px}

/* article body */
.eb-prose{font-size:clamp(16px,1.25vw,18px);line-height:1.72;color:#2E2A26}
.eb-prose>*:first-child{margin-top:0}
.eb-prose p{margin:0 0 22px}
.eb-prose h2{font-size:clamp(24px,2.5vw,34px);line-height:1.12;letter-spacing:-.02em;
  font-weight:800;margin:56px 0 20px;scroll-margin-top:110px}
.eb-prose h3{font-size:clamp(18px,1.5vw,21px);line-height:1.3;margin:32px 0 12px;scroll-margin-top:110px}
.eb-prose h4{font-size:16.5px;margin:26px 0 10px}
.eb-prose ul,.eb-prose ol{margin:0 0 22px;padding-left:22px;display:grid;gap:9px}
.eb-prose li{line-height:1.65}
.eb-prose a{color:var(--ink);text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:var(--orange)}
.eb-prose a:hover{color:var(--orange-dk)}
.eb-prose strong{font-weight:700;color:var(--ink)}
.eb-prose blockquote{margin:30px 0;padding:0 0 0 22px;border-left:2px solid var(--orange);
  font-size:clamp(17px,1.35vw,20px);line-height:1.5;color:var(--ink)}
.eb-prose blockquote p{margin:0}
.eb-prose hr{border:0;border-top:1px solid var(--line-cream);margin:38px 0}
.eb-prose code{font-family:var(--mono);font-size:.88em;background:#E3D7C6;padding:2px 6px;border-radius:3px}
.eb-prose pre{background:var(--ink);color:var(--cream-hi);padding:18px;border-radius:6px;
  overflow-x:auto;margin:0 0 22px}
.eb-prose pre code{background:none;padding:0;color:inherit;font-size:13px}
/* Wide tables scroll inside their own container so the page body never does. */
.eb-table{overflow-x:auto;margin:0 0 22px;border:1px solid var(--line-cream);border-radius:6px}
.eb-table table{border-collapse:collapse;width:100%;font-size:14.5px}
.eb-table th,.eb-table td{text-align:left;padding:11px 14px;border-bottom:1px solid var(--line-cream)}
.eb-table th{font-family:var(--mono);font-size:11px;letter-spacing:.07em;text-transform:uppercase;
  color:#6B6860;white-space:nowrap}
.eb-table tr:last-child td{border-bottom:0}
.eb-table td{font-variant-numeric:tabular-nums}

/* Images inside an imported post body. The legacy archive carries them at every
   shape WordPress happened to insert, so the frame is sized by the file rather
   than pinned to a ratio: an aspect-ratio here would crop art it was never
   measured against. Centred, never wider than the column, never upscaled past
   its own pixels. */
.eb-fig{margin:30px 0;text-align:center}
.eb-fig img{max-width:100%;width:auto;height:auto;border-radius:6px;
  border:1px solid var(--line-cream);vertical-align:middle}

/* faq */
.eb-faq{margin:48px 0 0;border-top:1px solid var(--line-cream);padding-top:30px}
.eb-faq h2{font-size:clamp(22px,1.9vw,28px);margin:0 0 20px;letter-spacing:-.01em}
.eb-faq dl{margin:0;display:grid;gap:20px}
.eb-faq dt{font-weight:700;font-size:16.5px;line-height:1.35;margin:0 0 7px}
.eb-faq dd{margin:0;font-size:15.5px;line-height:1.65;color:#4A4842}

/* related band */
.eb-related{background:var(--cream);border-top:1px solid var(--line-cream);
  margin-top:clamp(46px,5vw,76px);padding:clamp(34px,3.6vw,54px) 0}
.eb-related h2{font-size:clamp(20px,1.8vw,26px);margin:0 0 22px;letter-spacing:-.01em}
.eb-rel-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(18px,2vw,30px)}
.eb-rel{display:grid;gap:8px;align-content:start;text-decoration:none;color:inherit;
  border-top:2px solid var(--ink);padding-top:14px}
.eb-rel-cat{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--orange-dk)}
.eb-rel-t{font-size:17px;line-height:1.3;font-weight:700}
.eb-rel:hover .eb-rel-t{color:var(--orange-dk)}
.eb-rel-d{font-family:var(--mono);font-size:11px;color:#6B6860}

/* author page */
.eb-authorwrap{display:grid;grid-template-columns:minmax(0,1fr) 280px;
  gap:clamp(28px,4vw,72px);padding:clamp(34px,3.6vw,54px) 0 0;align-items:start}
.eb-author-bio{max-width:68ch;font-size:clamp(15.5px,1.15vw,17px);line-height:1.7;color:#2C2A26}
.eb-author-bio p{margin:0 0 20px}
.eb-author-role{font-family:var(--mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--orange-dk)}
.eb-disclose{border-left:2px solid var(--orange);padding-left:18px;font-size:14.5px;color:#4A4842}
.eb-disclose a{color:var(--ink)}
.eb-author-side{border:1px solid var(--line-cream);border-radius:6px;padding:18px}
.eb-covers{margin:0;padding-left:18px;display:grid;gap:8px;font-size:14px;line-height:1.45;color:#4A4842}
/* padding-top rather than 0: .eb-sec-h's top margin was collapsing out of
   the section and the gap showed the ink <body> through between two cream
   bands. Padding contains it; the heading's own margin is zeroed here. */
.eb-authorposts{padding-top:clamp(30px,3.2vw,48px)}
.eb-authorposts .eb-sec-h{margin-top:0}

@media (max-width:1200px){
  .eb-layout{grid-template-columns:minmax(0,1fr) 300px;gap:clamp(32px,4vw,56px)}
}
/* Template E collapses the post rail at 1024, one step earlier than the rest of
   the blog, because 760 + 340 + a 100px gutter stops fitting before 1000 does. */
@media (max-width:1023px){
  .eb-layout{grid-template-columns:1fr}
  .eb-aside{display:grid;grid-template-columns:repeat(2,1fr);gap:32px;align-items:start}
  .eb-toc{display:none}
  .eb-toc-m{display:block}
  .eb-kt-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .eb-kt-i{padding-right:20px}
  .eb-headrow{flex-direction:column;align-items:flex-start;gap:20px}
  .eb-standfirst{max-width:none;flex:none}
}
@media (max-width:1000px){
  .eb-authorwrap{grid-template-columns:1fr}
  .eb-grid,.eb-rel-grid{grid-template-columns:repeat(2,1fr)}
  .eb-top{grid-template-columns:1fr}
  .eb-latest{border-left:0;padding-left:0;border-top:1px solid var(--line-cream);padding-top:8px}
  .eb-idx-hero{grid-template-columns:1fr;align-items:start}
}
@media (max-width:660px){
  .eb-grid,.eb-rel-grid,.eb-aside{grid-template-columns:1fr}
  .eb-filterlbl{width:auto}
  .eb-kt-grid{grid-template-columns:1fr}
  .eb-kt-i{padding:20px 0 22px;border-top:1px solid var(--line-cream)}
  .eb-kt-i:first-child{border-top:0;padding-top:20px}
  .eb-incta,.eb-endcta-in{flex-direction:column;align-items:flex-start}
  .eb-incta-btn,.eb-endcta-btn{width:100%;justify-content:center}
  .eb-share-b{font-size:12px}
}

/* ════════════════════════════════════════════════════════════
   MOBILE NAVIGATION
   Added 2026-09-24. Until now `.nav` was display:none below
   860px, inherited from v1, which was survivable on a one-page
   site and is not on 47 pages plus a blog: a phone could reach
   an interior page only through the footer.

   Built by site.js from the EXISTING .nav markup rather than
   from a second copy in the generator. One nav, two renderings.
   A second markup block is a second thing to forget to update,
   and this site already carries a nav whose hub URLs live only
   in the generator (hence data-hub).

   Z-INDEX, stated once because three fixed things will end up
   on this page and two of them are not here yet:

       2147483647   consent widget (Consential, max int, theirs)
       900          this drawer
       800          drawer backdrop
       90           .stickybar
       40           .nav-panel

   The drawer sits BELOW the consent widget on purpose. A
   navigation panel must never cover a consent choice. When the
   chat launcher lands it goes below this and above the sticky
   bar, and it has to clear the consent card's own box at
   right:16px / bottom:16px / 380px wide, which is what makes a
   bottom-right launcher unclickable if you skip it.
   ════════════════════════════════════════════════════════════ */

/* The trigger. Hidden entirely on desktop, where the real nav runs. */
.navbtn{
  display:none;position:relative;
  width:42px;height:42px;padding:0;
  background:none;border:1px solid var(--line-cream);border-radius:999px;
  cursor:pointer;color:var(--ink);
}
.stickybar .navbtn{border-color:rgba(246,238,228,.4);color:var(--cream-hi)}
.navbtn i{
  position:absolute;left:11px;right:11px;height:1.5px;background:currentColor;
  transition:transform .22s ease,opacity .18s ease;
}
.navbtn i:nth-child(1){top:15px}
.navbtn i:nth-child(2){top:20px}
.navbtn i:nth-child(3){top:25px}
.navbtn[aria-expanded="true"] i:nth-child(1){transform:translateY(5px) rotate(45deg)}
.navbtn[aria-expanded="true"] i:nth-child(2){opacity:0}
.navbtn[aria-expanded="true"] i:nth-child(3){transform:translateY(-5px) rotate(-45deg)}

.navdrawer-back{
  position:fixed;inset:0;z-index:800;background:rgba(15,18,19,.55);
  opacity:0;visibility:hidden;transition:opacity .22s ease,visibility .22s ease;
}
.navdrawer-back[data-open]{opacity:1;visibility:visible}

.navdrawer{
  position:fixed;z-index:900;top:0;right:0;bottom:0;
  width:min(420px,100vw);
  background:var(--cream);color:var(--ink);
  display:flex;flex-direction:column;
  transform:translateX(100%);visibility:hidden;
  transition:transform .26s ease,visibility .26s ease;
  overflow-y:auto;overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
}
.navdrawer[data-open]{transform:none;visibility:visible}
@media (prefers-reduced-motion:reduce){
  .navdrawer,.navdrawer-back,.navbtn i{transition:none}
}

.navdrawer-top{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:18px var(--gut);border-bottom:1px solid var(--line-cream);
  position:sticky;top:0;background:var(--cream);z-index:1;
}
.navdrawer-top .brand{--wm:150px}
.navdrawer-close{
  width:42px;height:42px;flex:0 0 auto;
  background:none;border:1px solid var(--line-cream);border-radius:999px;
  cursor:pointer;color:var(--ink);font-family:var(--sans);font-size:20px;line-height:1;
}
.navdrawer-close:hover{border-color:var(--ink)}

.navdrawer-body{padding:8px var(--gut) 28px}
.navdrawer-group{border-bottom:1px solid var(--line-cream);padding:20px 0}
.navdrawer-group:last-of-type{border-bottom:0}
.navdrawer-group > a.navdrawer-hub{
  display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  font-family:var(--mono);font-weight:700;font-size:12px;
  letter-spacing:.17em;text-transform:uppercase;color:var(--orange);
  padding-bottom:4px;
}
.navdrawer-group > a.navdrawer-hub .ar{font-family:var(--sans);font-size:14px}
.navdrawer-sub{display:grid;margin-top:10px}
.navdrawer-sub a{
  display:block;padding:11px 0;
  border-bottom:1px solid rgba(15,18,19,.07);
  font-size:clamp(15px,4.2vw,17px);font-weight:600;letter-spacing:-.012em;
  color:var(--ink);
}
.navdrawer-sub a:last-child{border-bottom:0}
.navdrawer-sub a span{
  display:block;margin-top:3px;font-size:13px;font-weight:400;
  letter-spacing:normal;color:#5F5C55;
}
.navdrawer-sub a:active{color:var(--orange)}

.navdrawer-foot{
  margin-top:auto;padding:22px var(--gut) calc(22px + env(safe-area-inset-bottom));
  border-top:1px solid var(--line-cream);display:grid;gap:14px;
}
.navdrawer-foot .btn--solid{justify-content:center}
.navdrawer-tel{
  font-family:var(--mono);font-size:12px;letter-spacing:.1em;
  text-transform:uppercase;color:#5F5C55;text-align:center;
}
.navdrawer-tel a{color:var(--ink);border-bottom:1px solid var(--line-cream)}

/* Stop the page scrolling behind an open drawer, without the layout shift a
   plain overflow:hidden causes when the scrollbar disappears. */
body[data-navlock]{overflow:hidden}

@media (max-width:860px){
  .navbtn{display:block}
  .topbar{grid-template-columns:auto 1fr auto}
  /* The pill and the burger both live on the right of a narrow bar. The pill
     already shrinks at this breakpoint in the base stylesheet. */
  .topbar .btn--pill{margin-right:8px}
}
@media (min-width:861px){
  .navdrawer,.navdrawer-back{display:none}
}

/* ─────────────────────── LIVE OPENINGS (2026-09-24) ────────────────────────
   /careers/ lists Vitality's live postings, fetched at page load from the
   EFFVIT careers system. Cream ground only — the block always sits directly
   under the hero, which is cream. No new colours and no new type sizes; every
   value below composes from the v1 tokens.                                  */
.openings{margin-top:clamp(28px,3.2vw,44px)}

.op-list{display:grid;gap:0;border-top:1px solid var(--line-cream)}

.op-card{
  display:grid;grid-template-columns:1.55fr .45fr;
  gap:clamp(20px,3vw,48px);align-items:start;
  padding:clamp(24px,2.8vw,38px) 0;
  border-bottom:1px solid var(--line-cream);
}
.op-card-body{min-width:0}

.op-meta{
  font-family:var(--mono);font-weight:700;font-size:clamp(10px,.86vw,12px);
  letter-spacing:.17em;text-transform:uppercase;color:var(--orange);
  margin:0 0 10px;
}
.op-card h3{
  margin:0;font-size:clamp(24px,2.6vw,38px);line-height:1.12;
  color:var(--ink);letter-spacing:-.01em;
}
.op-card h3 a{color:inherit;text-decoration:none}
.op-card h3 a:hover{color:var(--orange-dk)}

.op-where{
  margin:10px 0 0;color:#6E6B63;
  font-size:clamp(14.5px,1.16vw,16.5px);line-height:1.5;
}
.op-pitch{
  margin:14px 0 0;color:#4A4842;
  font-size:clamp(15px,1.3vw,18.5px);line-height:1.55;max-width:56ch;
}

/* Buttons stack in their own column on desktop and sit under the copy on
   phones, where the two-column grid collapses below. */
.op-actions{display:flex;flex-direction:column;align-items:flex-start;gap:12px;margin:0}

.op-note{
  margin:clamp(20px,2.2vw,30px) 0 0;color:#6E6B63;
  font-size:clamp(13.5px,1.05vw,15px);line-height:1.6;max-width:62ch;
}
.op-note a,.op-empty a{color:var(--ink);text-decoration:underline;text-underline-offset:3px}
.op-note a:hover,.op-empty a:hover{color:var(--orange-dk)}

/* The state that ships in the file: no JS, a blocked fetch or a 503 all land
   here rather than on an empty list. */
.op-empty{
  border-top:1px solid var(--line-cream);border-bottom:1px solid var(--line-cream);
  padding:clamp(24px,2.8vw,38px) 0;
}
.op-empty p{
  margin:0;color:#4A4842;
  font-size:clamp(15px,1.3vw,18.5px);line-height:1.6;max-width:62ch;
}

@media (max-width:860px){
  .op-card{grid-template-columns:1fr;gap:20px}
  .op-actions{flex-direction:row;flex-wrap:wrap;align-items:center}
}

/* ════════════════════════════════════════════════════════════
   JULIAN · WEBSITE CHAT
   The same receptionist who answers (631) 867-0900. Server side
   at /api/chat; nothing about him is in this stylesheet or in
   the browser bundle.

   Z-INDEX, continuing the scale declared with the mobile drawer:

       2147483647   consent widget (Consential, max int, theirs)
       900 / 800    nav drawer / its backdrop
       610 / 600    this panel / this launcher
       90           .stickybar

   Chat sits BELOW consent deliberately. A chat bubble must never
   obscure a consent choice, and Consential's own card lands at
   right:16px / bottom:16px / min(380px,100vw-32px) at max int —
   a launcher parked in that corner renders underneath it and
   stops being clickable, which looks completely fine in a
   screenshot. --chat-lift is set by site.js from the consent
   card's real height when it appears, and is 0 until then.
   ════════════════════════════════════════════════════════════ */
:root{--chat-lift:0px}

/* ── the launcher ─────────────────────────────────────────────────────────
   One orange tile, three states, ported from Joe's
   final-widget-eyes-blink-between-buttons.html on 2026-09-24. It replaced
   the 20-concept picker the same day, which replaced the "Ask Julian" pill.

     at rest    three typing dots
     on hover   a pair of eyes peeking up over the bottom edge
     open       the same eyes, centred, following the cursor, slammed shut
                the moment the pointer leaves the widget, and blinking once
                each time it crosses from one action to another

   The ground stays the same orange in every state. That is what makes the
   three read as one creature rather than three icons, so a state that also
   changes the background is not a variation of this, it is a different
   widget.

   The eyes are built from real boxes rather than an emoji or an SVG because
   only a DOM node can have its height driven to 2px for a blink and carry a
   pupil that tracks a pointer. Every number here is tuned to the 72px tile
   and the 18x25px eye: the pupil's left:5.5px centres it, the peek's
   margin-bottom:17px sets how far the eyes clear the bottom edge, and the
   2px blink height is the closed lid. Resize the tile and re-tune all three.
   ───────────────────────────────────────────────────────────────────────── */
.jl-launch{
  position:fixed;z-index:600;
  right:clamp(14px,2.2vw,24px);
  bottom:calc(clamp(14px,2.2vw,24px) + var(--chat-lift));
  width:72px;height:72px;padding:0;border:0;border-radius:22px;
  background:var(--orange);color:var(--cream-hi);cursor:pointer;
  display:grid;place-items:center;overflow:hidden;
  box-shadow:0 15px 34px rgba(15,18,19,.26);
  transition:transform .18s ease,box-shadow .18s ease,bottom .22s ease;
}
.jl-launch:hover{transform:translateY(-2px);box-shadow:0 18px 38px rgba(15,18,19,.30)}
/* Ink, not orange: an orange ring on an orange tile is not a focus ring. */
.jl-launch:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.jl-launch[hidden]{display:none}

.jl-eye{
  width:18px;height:25px;flex:0 0 auto;
  background:var(--cream-hi);border-radius:50%;position:relative;
}
.jl-pupil{
  width:7px;height:7px;background:var(--ink);border-radius:50%;
  position:absolute;left:5.5px;top:9px;
}

/* at rest */
.jl-dots{display:flex;gap:6px;transition:opacity .16s ease,transform .16s ease}
.jl-dots i{
  width:9px;height:9px;display:block;border-radius:50%;
  background:var(--cream-hi);animation:jl-type 1.15s infinite;
}
.jl-dots i:nth-child(2){animation-delay:.14s}
.jl-dots i:nth-child(3){animation-delay:.28s}
@keyframes jl-type{0%,60%,100%{transform:translateY(0);opacity:.45}30%{transform:translateY(-7px);opacity:1}}

/* on hover */
.jl-peek{
  position:absolute;inset:0;
  display:flex;justify-content:center;align-items:flex-end;
  opacity:0;transform:translateY(18px);
  transition:opacity .18s ease,transform .22s cubic-bezier(.2,.8,.2,1);
}
.jl-peek .jl-eyes{display:flex;gap:7px;margin-bottom:17px}
.jl-root:not(.is-open) .jl-launch:hover .jl-dots{opacity:0;transform:translateY(-5px)}
.jl-root:not(.is-open) .jl-launch:hover .jl-peek{opacity:1;transform:translateY(0)}

/* open */
.jl-watch{
  position:absolute;inset:0;
  display:flex;justify-content:center;align-items:center;gap:7px;
  opacity:0;transform:scale(.9);
  transition:opacity .18s ease,transform .18s ease;
}
.jl-watch .jl-eye{
  overflow:hidden;
  transition:height .09s cubic-bezier(.2,.9,.2,1),transform .09s ease;
}
.jl-watch .jl-pupil{transition:transform .06s linear,opacity .09s ease;will-change:transform}
.jl-root.is-open .jl-dots,.jl-root.is-open .jl-peek{opacity:0!important}
.jl-root.is-open .jl-watch{opacity:1;transform:scale(1)}
.jl-root.is-open.pointer-in .jl-watch .jl-eye{height:25px;transform:scaleX(1)}
.jl-root.is-open.pointer-in .jl-watch .jl-pupil{opacity:1}
/* The lid. !important because it has to beat pointer-in, which is still on
   the root during a blink: a blink is a momentary override of open eyes,
   not a state of its own. */
.jl-root.is-open.pointer-out .jl-watch .jl-eye,
.jl-root.is-open.quick-blink .jl-watch .jl-eye{height:2px!important;transform:scaleX(1.08)}
.jl-root.is-open.pointer-out .jl-watch .jl-pupil,
.jl-root.is-open.quick-blink .jl-watch .jl-pupil{opacity:0!important}

/* The refusal. Once the card is open, a pointer that has left the widget gets
   a gesture rather than a blank stare: lids stay down and the tile shakes no
   until the pointer is back inside (pointer-in) or the card closes (is-open
   drops). Both of those remove this selector, and .jl-launch's own
   transition:transform eases the tile back to rest instead of snapping.

   Pivot at 50% 88% so it reads as a head turning on a neck rather than a box
   spinning about its centre. It cannot fight .jl-launch:hover, because a
   pointer on the tile is a pointer inside the widget, which is pointer-in by
   definition. The cycle gestures for ~1.2s and holds still for the rest of the
   1.6s: a tile vibrating without pause stops reading as a gesture and starts
   reading as a fault.

   The hop rides in the SAME transform as the rotation. Two animations cannot
   both drive transform -- the later one wins outright and the rotation
   vanishes with no error -- so every keyframe carries both.

   It bounces right to left and back, tipping onto a DIFFERENT bottom corner
   each hop, which is what makes it read as a creature refusing rather than a
   box sliding. transform-origin is animatable, so leaving it to interpolate
   would drag the pivot across the tile mid-hop and bend the arc. Each swap is
   therefore a pair of keyframes 0.01% apart, placed at a landing where the
   tile is square and level: the pivot moves in a frame nobody can see. It
   travels 16px at most and only leftward, so it never leaves the corner or
   crosses the viewport edge. */
@keyframes jl-nope{
  /* hop 1: tips onto its bottom-right corner and travels left */
  0%{transform-origin:100% 100%;transform:translate(0,0) rotate(0deg)}
  10%{transform-origin:100% 100%;transform:translate(-8px,-8px) rotate(-10deg)}
  20%{transform-origin:100% 100%;transform:translate(-16px,0) rotate(0deg)}
  /* the pivot swaps to the bottom-left corner at the landing, where the tile
     is square and level, so the swap cannot be seen */
  20.01%{transform-origin:0% 100%;transform:translate(-16px,0) rotate(0deg)}
  /* hop 2: pushes off that corner and travels back right */
  30%{transform-origin:0% 100%;transform:translate(-8px,-7px) rotate(9deg)}
  40%{transform-origin:0% 100%;transform:translate(0,0) rotate(0deg)}
  40.01%{transform-origin:100% 100%;transform:translate(0,0) rotate(0deg)}
  /* hop 3, smaller, left again */
  50%{transform-origin:100% 100%;transform:translate(-5px,-5px) rotate(-7deg)}
  58%{transform-origin:100% 100%;transform:translate(-10px,0) rotate(0deg)}
  58.01%{transform-origin:0% 100%;transform:translate(-10px,0) rotate(0deg)}
  /* hop 4, smallest, home */
  66%{transform-origin:0% 100%;transform:translate(-4px,-3px) rotate(5deg)}
  74%{transform-origin:0% 100%;transform:translate(0,0) rotate(0deg)}
  100%{transform-origin:0% 100%;transform:translate(0,0) rotate(0deg)}
}
.jl-root.is-open.pointer-out .jl-launch{
  animation:jl-nope 1.6s ease-in-out infinite;
}

/* A visitor who asked for less motion gets the tile and the eyes, and none
   of the idling, peeking, blinking or cursor tracking. site.js reads the
   same query and never starts the pointer work, so nothing here has to
   fight a transform written by script. */
@media (prefers-reduced-motion:reduce){
  .jl-launch,.jl-launch *{animation:none!important;transition:none!important}
  .jl-menu{transition:none}
}

/* ── the menu card ─────────────────────────────────────────────────────── */
.jl-menu{
  position:fixed;z-index:610;
  right:clamp(14px,2.2vw,24px);
  bottom:calc(clamp(14px,2.2vw,24px) + 86px + var(--chat-lift));
  width:min(320px,calc(100vw - 28px));
  padding:16px;
  background:var(--cream-hi);color:var(--ink);
  border:1px solid var(--line-cream);
  box-shadow:0 18px 50px rgba(15,18,19,.30);
  /* visibility, not opacity alone: opacity:0 leaves every chip inside
     tabbable and in the accessibility tree. Same reason as .jl-panel. */
  opacity:0;visibility:hidden;transform:translateY(10px);
  transition:opacity .2s ease,transform .2s ease,visibility .2s ease,bottom .22s ease;
}
.jl-menu[data-open]{opacity:1;visibility:visible;transform:none}
.jl-menu h3{
  margin:0 0 4px;font-family:var(--sans);font-size:18px;font-weight:800;
  letter-spacing:-.015em;line-height:1.25;
}
.jl-menu p{margin:0 0 12px;font-size:13px;line-height:1.45;color:#66635B}
.jl-act{
  display:flex;align-items:center;gap:11px;width:100%;
  margin-top:8px;padding:12px 13px;text-align:left;text-decoration:none;
  border:1px solid var(--line-cream);background:var(--cream);color:var(--ink);
  font-family:var(--sans);font-size:14px;font-weight:700;cursor:pointer;
}
.jl-act:hover{border-color:var(--ink)}
.jl-act:focus-visible{outline:2px solid var(--orange);outline-offset:2px}
.jl-act--primary{background:var(--orange);border-color:var(--orange);color:#14100E}
.jl-act--primary:hover{background:var(--orange-dk);border-color:var(--orange-dk);color:#fff}
.jl-act i{flex:0 0 auto;font-style:normal;font-size:17px;line-height:1}
.jl-act span{flex:1 1 auto;min-width:0}
.jl-act small{
  display:block;margin-top:3px;font-family:var(--mono);font-weight:500;
  font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;opacity:.72;
}
/* The availability dot. It is drawn BESIDE the words rather than instead of
   them: a bare green dot means nothing to a screen reader and nothing to
   anyone who does not already hold the convention, so it is aria-hidden and
   "Agents available" carries the meaning on its own. The halo is the only
   thing that moves, and it stops under reduced motion. */
.jl-live{
  display:inline-block;width:7px;height:7px;margin-right:6px;
  border-radius:50%;background:#18A558;vertical-align:middle;position:relative;top:-1px;
  animation:jl-live 2.4s ease-out infinite;
}
@keyframes jl-live{
  0%{box-shadow:0 0 0 0 rgba(24,165,88,.55)}
  70%{box-shadow:0 0 0 6px rgba(24,165,88,0)}
  100%{box-shadow:0 0 0 0 rgba(24,165,88,0)}
}
@media (prefers-reduced-motion:reduce){.jl-live{animation:none}}

@media (max-width:560px){
  .jl-menu{right:14px;left:14px;width:auto}
}

.jl-panel{
  position:fixed;z-index:610;
  right:clamp(14px,2.2vw,24px);
  bottom:calc(clamp(14px,2.2vw,24px) + var(--chat-lift));
  width:min(384px,calc(100vw - 28px));
  height:min(560px,calc(100vh - 110px - var(--chat-lift)));
  display:flex;flex-direction:column;
  background:var(--cream);color:var(--ink);
  border:1px solid var(--line-cream);
  box-shadow:0 18px 50px rgba(15,18,19,.30);
  /* visibility, not opacity alone: opacity:0 leaves every control inside
     tabbable and in the accessibility tree. */
  opacity:0;visibility:hidden;transform:translateY(10px);
  transition:opacity .2s ease,transform .2s ease,visibility .2s ease,bottom .22s ease;
}
.jl-panel[data-open]{opacity:1;visibility:visible;transform:none}
@media (prefers-reduced-motion:reduce){
  .jl-panel,.jl-launch{transition:none}
}

.jl-head{
  display:flex;align-items:center;gap:11px;
  padding:14px 14px 14px 16px;border-bottom:1px solid var(--line-cream);
}
.jl-avatar{
  width:32px;height:32px;border-radius:50%;flex:0 0 auto;
  background:var(--ink);color:var(--cream-hi);
  display:grid;place-items:center;font-weight:900;font-size:14px;
}
.jl-who{flex:1 1 auto;min-width:0}
.jl-who b{display:block;font-size:14px;font-weight:700;letter-spacing:-.01em;line-height:1.2}
.jl-who span{
  display:block;margin-top:2px;font-family:var(--mono);font-size:10px;
  letter-spacing:.12em;text-transform:uppercase;color:#66635B;
}
.jl-x{
  width:32px;height:32px;flex:0 0 auto;border:1px solid var(--line-cream);
  border-radius:999px;background:none;cursor:pointer;color:var(--ink);
  font-family:var(--sans);font-size:17px;line-height:1;
}
.jl-x:hover{border-color:var(--ink)}

.jl-log{
  flex:1 1 auto;overflow-y:auto;overscroll-behavior:contain;
  padding:16px;display:flex;flex-direction:column;gap:11px;
}
.jl-msg{
  max-width:86%;padding:10px 13px;
  font-size:14.5px;line-height:1.5;white-space:pre-wrap;word-wrap:break-word;
}
.jl-msg--them{align-self:flex-start;background:#F6EEE4;border:1px solid var(--line-cream);color:var(--ink)}
.jl-msg--me{align-self:flex-end;background:var(--ink);color:var(--cream-hi)}
.jl-msg a{text-decoration:underline;text-underline-offset:2px}
/* Queue notices. Centred, monospaced and unbubbled so they read as the ROOM
   talking rather than as somebody in it - "Julian joined the chat" is not a
   message from Julian and must not look like one. */
.jl-sys{
  align-self:center;max-width:92%;text-align:center;
  font-family:var(--mono);font-weight:500;font-size:9.5px;
  letter-spacing:.1em;text-transform:uppercase;color:#8C8880;
}
.jl-sys b{color:var(--ink);font-weight:700}
.jl-typing{align-self:flex-start;display:flex;gap:4px;padding:12px 13px}
.jl-typing i{
  width:6px;height:6px;border-radius:50%;background:#8C8880;
  animation:jlpulse 1.1s infinite ease-in-out;
}
.jl-typing i:nth-child(2){animation-delay:.16s}
.jl-typing i:nth-child(3){animation-delay:.32s}
@keyframes jlpulse{0%,60%,100%{opacity:.28}30%{opacity:1}}
@media (prefers-reduced-motion:reduce){.jl-typing i{animation:none;opacity:.6}}

.jl-form{
  display:flex;gap:9px;align-items:flex-end;
  padding:12px;border-top:1px solid var(--line-cream);
}
.jl-form textarea{
  flex:1 1 auto;resize:none;max-height:110px;
  font-family:var(--sans);font-size:14.5px;line-height:1.45;color:var(--ink);
  background:#F6EEE4;border:1px solid var(--line-cream);border-radius:0;
  padding:10px 11px;
}
.jl-form textarea:focus{outline:none;border-color:rgba(241,107,43,.6)}
.jl-send{
  flex:0 0 auto;width:40px;height:40px;
  border:0;background:var(--orange);color:#14100E;cursor:pointer;
  font-family:var(--sans);font-size:17px;line-height:1;
}
.jl-send:hover{background:var(--orange-dk);color:#fff}
.jl-send[disabled]{opacity:.45;cursor:default}
.jl-foot{
  margin:0;padding:0 12px 11px;text-align:center;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;
  text-transform:uppercase;color:#66635B;
}
.jl-foot a{color:var(--ink);border-bottom:1px solid var(--line-cream)}

@media (max-width:560px){
  .jl-panel{
    right:0;left:0;bottom:0;width:100%;
    height:min(78vh,calc(100vh - 64px));
    border-left:0;border-right:0;border-bottom:0;
  }
  .jl-launch{padding:11px 15px 11px 12px;font-size:11px}
}

/* ── blog pagination ──────────────────────────────────────────────────────
   .eb-grid is repeat(3,1fr) and a page is 15 cards, so five rows of three.
   The pager sits under the grid on every paginated surface. */
.eb-pager{display:flex;align-items:center;justify-content:space-between;gap:16px;
  flex-wrap:wrap;margin-top:44px;padding-top:26px;border-top:1px solid var(--line-cream);
  font-family:var(--mono);font-size:12px}
.eb-pager[hidden]{display:none}
.eb-pg-nums{display:flex;align-items:center;gap:4px;flex-wrap:wrap}
.eb-pg-n,.eb-pg-cur,.eb-pg-gap{display:inline-flex;align-items:center;justify-content:center;
  min-width:30px;height:30px;padding:0 7px;border-radius:5px}
.eb-pg-n{color:#4A4842;text-decoration:none;border:1px solid var(--line-cream)}
.eb-pg-n:hover{background:#E3D7C6;color:var(--ink)}
.eb-pg-cur{background:var(--ink);color:var(--cream);font-weight:700}
.eb-pg-gap{color:#8B8880;min-width:16px;padding:0}
.eb-pg-step{text-decoration:none;color:var(--orange-dk);font-weight:700;
  letter-spacing:.02em;white-space:nowrap}
.eb-pg-step:hover{text-decoration:underline}
.eb-pg-step.is-off{color:#B5B0A6;pointer-events:none}
.eb-pg-of{font-family:var(--mono);font-size:11px;font-weight:400;color:#6B6860;
  letter-spacing:.06em;text-transform:uppercase;white-space:nowrap}
@media (max-width:760px){
  .eb-pager{justify-content:center}
  .eb-pg-nums{order:-1;width:100%;justify-content:center}
}

/* .eb is padding:0 0 var(--pad), so a first child carrying a top MARGIN
   collapses that margin out of the section and the ink <body> shows through as
   a black band. On /blog/page/2/ and beyond there is no editorial top block, so
   .eb-filters is that first child. Padding contains it, same fix as .eb-sec-h. */
.eb > .wrap > .eb-filters:first-child{margin-top:0;padding-top:clamp(34px,3.6vw,56px)}

/* ═══════════════════ WORK: STAGE + FILMSTRIP ═══════════════════════════════
   One browser window, six thumbnails under it, the window swaps on click.
   Rendered by b_work() in build/gen_blocks.py, driven by site.js.

   Composes from the existing tokens only. The stage is the one place on this
   site that carries a real screen capture rather than a drawn figure.
   ========================================================================= */
.wk-stage{
  border:1px solid var(--line-dark);background:#0B0E0F;border-radius:4px;
  overflow:hidden;margin-top:clamp(30px,3.4vw,46px);
}
.pain .wk-stage{border-color:var(--line-cream);background:#FFF}

.wk-bar{
  display:flex;align-items:center;gap:7px;padding:10px 14px;
  border-bottom:1px solid var(--line-dark);
}
.pain .wk-bar{border-bottom-color:var(--line-cream)}
.wk-dot{width:8px;height:8px;border-radius:50%;background:rgba(246,238,228,.22);flex:0 0 auto}
.pain .wk-dot{background:rgba(15,18,19,.18)}
.wk-url{
  font-family:var(--mono);font-size:11.5px;letter-spacing:.04em;color:var(--grey);
  margin-left:10px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;
}

/* The capture is the full page, so the window shows the top of it and slides
   the rest up on hover. --wk-scroll is measured in JS, because the distance
   depends on the rendered width. */
.wk-view{position:relative;height:clamp(260px,34vw,470px);overflow:hidden;background:#0B0E0F}
.pain .wk-view{background:#FFF}
.wk-shot{
  position:absolute;top:0;left:0;width:100%;height:auto;
  transition:opacity .34s ease,transform 6s cubic-bezier(.22,.61,.36,1);
}
.wk-stage:hover .wk-shot{transform:translateY(var(--wk-scroll,0))}
.wk-shot.is-swapping{opacity:0}

.wk-foot{
  padding:clamp(18px,1.9vw,24px) clamp(18px,2vw,26px);
  border-top:1px solid var(--line-dark);
  display:flex;align-items:flex-end;justify-content:space-between;gap:24px;
}
.pain .wk-foot{border-top-color:var(--line-cream)}
.wk-kind{
  font-family:var(--mono);font-weight:700;font-size:10.5px;letter-spacing:.15em;
  text-transform:uppercase;color:var(--orange);margin:0 0 9px;
}
.wk-name{
  margin:0 0 6px;font-size:clamp(19px,1.7vw,24px);font-weight:900;letter-spacing:-.028em;
  color:var(--cream-hi);
}
.pain .wk-name{color:var(--ink)}
.wk-line{margin:0;font-size:clamp(13.5px,1.05vw,15px);color:var(--on-dark);max-width:58ch;line-height:1.5}
.pain .wk-line{color:#4A4842}
.wk-visit{
  font-family:var(--mono);font-size:10.5px;font-weight:700;letter-spacing:.13em;
  text-transform:uppercase;color:var(--orange);white-space:nowrap;
  border:1px solid rgba(241,107,43,.42);padding:11px 15px;border-radius:2px;
  transition:background-color .24s ease,border-color .24s ease;
}
.wk-visit:hover{background:rgba(241,107,43,.11);border-color:var(--orange)}

.wk-strip{display:grid;grid-template-columns:repeat(6,1fr);gap:clamp(9px,.95vw,14px);margin-top:14px}
.wk-thumb{
  position:relative;display:block;padding:0;cursor:pointer;overflow:hidden;
  border:1px solid var(--line-dark);border-radius:3px;background:#0B0E0F;
  aspect-ratio:480/300;
  transition:border-color .24s ease,transform .24s ease;
}
.pain .wk-thumb{border-color:var(--line-cream);background:#FFF}
.wk-thumb img{width:100%;height:100%;object-fit:cover;object-position:top center;
              opacity:.45;transition:opacity .24s ease}
.wk-thumb:hover{transform:translateY(-3px)}
.wk-thumb:hover img{opacity:.82}
.wk-thumb[aria-selected="true"]{border-color:var(--orange)}
.wk-thumb[aria-selected="true"] img{opacity:1}
.wk-thumb:focus-visible{outline:2px solid var(--orange);outline-offset:2px}
.wk-thumb-lbl{
  position:absolute;left:0;right:0;bottom:0;padding:9px 10px;text-align:left;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.07em;color:var(--cream-hi);
  line-height:1.25;background:linear-gradient(transparent,rgba(11,14,15,.93) 62%);
}

@media(max-width:780px){
  .wk-strip{grid-template-columns:repeat(3,1fr)}
  .wk-foot{flex-direction:column;align-items:flex-start;gap:16px}
}
@media(prefers-reduced-motion:reduce){
  .wk-shot,.wk-thumb,.wk-thumb img,.wk-visit{transition:none}
  .wk-stage:hover .wk-shot{transform:none}
}

/* ═══ Case studies — the Ledger layout ═══════════════════════════════════════
   Picked by Joe 2026-09-24 from five directions built as throwaway comps and
   deleted once he chose. Ledger was one of two with no photography.
   Cream throughout, no photography, the client wordmark as the identity and the
   metrics riding a sticky rail so a number is on screen the whole way down.

   The wordmark assets have their ground MULTIPLIED IN rather than carrying alpha
   (site/assets/logo-<slug>-cs.png for --cream, -cshi.png for --cream-hi). That is
   the same defence the logo marquee uses: mix-blend-mode:multiply dies silently
   under an animated or transformed ancestor, so it is never trusted here. The
   consequence is that a wordmark is correct for exactly ONE ground. Putting a
   -cshi asset on a --cream section paints a visible rectangle. Check the suffix
   against the section, and re-bake rather than reaching for a blend mode.        */

.cs-crumb{font:500 12px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;display:flex;gap:10px;align-items:center;opacity:.7;margin:0 0 24px}
.cs-crumb a{border-bottom:1px solid currentColor;padding-bottom:1px}
.cs-logo{height:76px;width:auto;display:block;margin:0 0 26px}
@media(max-width:640px){.cs-logo{height:56px}}

.cs-sec{padding:var(--pad) 0}
.cs-cream{background:var(--cream);color:var(--on-cream)}
.cs-creamhi{background:var(--cream-hi);color:var(--on-cream)}
.cs-eyebrow{font:600 11.5px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--orange);margin:0 0 16px}
.cs-h1{font-weight:800;font-size:clamp(33px,4.4vw,58px);line-height:1.05;letter-spacing:-.022em;margin:0 0 20px;max-width:17ch}
.cs-h2{font-weight:800;font-size:clamp(24px,2.6vw,36px);line-height:1.12;letter-spacing:-.018em;margin:0 0 24px}
.cs-h3{font-weight:700;font-size:19px;line-height:1.25;letter-spacing:-.01em;margin:0 0 9px}
.cs-dek{font-size:clamp(17px,1.5vw,21px);line-height:1.5;max-width:54ch;opacity:.85;margin:0}
.cs-p{font-size:16.5px;line-height:1.68;max-width:64ch;margin:0 0 18px}
.cs-p:last-child{margin-bottom:0}

.cs-meta{display:flex;flex-wrap:wrap;gap:8px 9px;margin:26px 0 0;padding:0;list-style:none}
.cs-meta li{font:500 11.5px/1 var(--mono);letter-spacing:.05em;text-transform:uppercase;border:1px solid currentColor;border-radius:999px;padding:7px 12px;opacity:.68}

.cs-stat-l{font:600 11.5px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;opacity:.6;margin:0 0 12px}
.cs-stat-b{font-weight:800;font-size:clamp(38px,4.3vw,56px);line-height:.95;letter-spacing:-.03em;color:var(--orange);margin:0}
.cs-stat-s{font-weight:700;font-size:15px;letter-spacing:-.01em;margin:7px 0 0}
.cs-stat-n{font-size:13.5px;line-height:1.5;opacity:.62;margin:9px 0 0;max-width:32ch}
/* Scope to the direct child. A descendant selector here also catches the
   <span class="ph"> placeholder nested inside a figure and stretches a dashed
   box across the rail, which is trap 7 on this property all over again.        */
.cs-stack>.cs-stat+.cs-stat{margin-top:30px;padding-top:30px;border-top:1px solid color-mix(in srgb,currentColor 18%,transparent)}
.cs-note{font:500 12px/1.55 var(--mono);letter-spacing:.03em;opacity:.52;margin:22px 0 0;max-width:60ch}
.cs-pull{font-weight:700;font-size:clamp(20px,2.1vw,27px);line-height:1.3;letter-spacing:-.015em;border-left:2px solid var(--orange);padding-left:22px;margin:36px 0;max-width:40ch}
.cs-pull cite{display:block;margin:14px 0 0;font:500 13px/1.4 var(--mono);letter-spacing:.02em;font-style:normal;opacity:.62}
/* Composed media band on a case study: a wide plate with a still inset over its
   lower right. Mobile stacks them and the inset goes full width, which is why
   the plate is cropped clean in the file rather than relying on the overlap. */
.cs-media{position:relative;margin:0;padding-bottom:28px;background:var(--cream);color:var(--on-cream)}
.cs-media-plate{line-height:0}
.cs-media--solo{padding-bottom:0}
.cs-media-plate img{width:100%;height:clamp(220px,38vw,520px);object-fit:cover;object-position:50% 38%;display:block}
.cs-media-inset{margin:-40px 20px 0;max-width:420px}
.cs-media-still{position:relative;line-height:0;border-radius:3px;overflow:hidden;
  box-shadow:0 18px 44px -12px rgba(0,0,0,.45),0 0 0 6px var(--cream)}
.cs-media-still img{width:100%;height:auto;display:block}
.cs-media-cap{margin:14px 0 0;font:500 12px/1.4 var(--mono);letter-spacing:.06em;
  text-transform:uppercase;opacity:.6}

@media(min-width:900px){
  .cs-media-inset{position:absolute;left:6vw;bottom:72px;margin:0;width:min(26vw,380px);max-width:none}
  .cs-media-cap{position:absolute;left:0;top:calc(100% + 12px);white-space:nowrap}
  .cs-media{padding-bottom:120px}
  .cs-media--solo{padding-bottom:0}
}
.cs-steps{counter-reset:s;list-style:none;padding:0;margin:0}
.cs-steps>li{counter-increment:s;padding:28px 0;border-top:1px solid color-mix(in srgb,currentColor 18%,transparent)}
.cs-steps>li::before{content:counter(s,decimal-leading-zero);font:700 12px/1 var(--mono);letter-spacing:.1em;color:var(--orange);display:block;margin:0 0 13px}

@media(min-width:900px){
  .cs-rail{display:grid;grid-template-columns:300px minmax(0,1fr);gap:clamp(40px,5vw,80px);align-items:start}
  .cs-rail>aside{position:sticky;top:96px}
}
/* Below 900 the rail stops being a column and becomes the block above the
   narrative, so the note that closes it lands directly against "The Problem"
   with nothing between them. The sticky desktop layout hides this entirely:
   there the gap is the grid's, not the note's.                               */
@media(max-width:899px){.cs-rail>aside{margin-bottom:var(--pad)}}

/* Index cards. The wordmark sits on --cream-hi inside the card, so these use the
   -cshi bake while the page band around them is --cream.                        */
.cs-cards{display:grid;gap:26px;margin:0;padding:0;list-style:none}
@media(min-width:720px){.cs-cards{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1080px){.cs-cards{grid-template-columns:repeat(3,1fr)}}
.cs-card{display:flex;flex-direction:column;height:100%;background:var(--cream-hi);border:1px solid var(--line-cream);border-radius:12px;overflow:hidden;transition:border-color .18s ease}
.cs-card:hover,.cs-card:focus-visible{border-color:var(--orange)}
.cs-card-mark{display:flex;align-items:center;min-height:132px;padding:26px 26px 0}
.cs-card-mark img{height:64px;width:auto;max-width:100%;object-fit:contain}
.cs-card-body{padding:22px 26px 26px;display:flex;flex-direction:column;gap:8px;flex:1}
.cs-card-body b{font-weight:800;font-size:19px;letter-spacing:-.012em}
.cs-card-body p{margin:0;font-size:14.5px;line-height:1.55;opacity:.72}
.cs-card-fig{margin-top:auto;padding-top:16px;font:700 13px/1.35 var(--mono);letter-spacing:.02em;color:var(--orange)}

/* Long-form legal copy. One block carries the whole page, so its sections are
   h2 under the phero h1, and .prose had to grow headings, lists and links: it
   was paragraphs only until the privacy policy landed on 2026-09-24.
   .prose p.legal-meta is written at the same specificity as .caps .prose p and
   sits later in the file, so it wins the colour on both grounds.              */
.prose--legal{max-width:70ch}
.prose h2{margin:clamp(34px,3.4vw,50px) 0 14px;font-size:clamp(19px,1.7vw,24px);line-height:1.25;
  letter-spacing:-.015em;max-width:44ch}  /* .pain h2 caps at 13ch for display headings */
.prose h2:first-child{margin-top:0}
.caps .prose h2{color:var(--cream-hi)}
.pain .prose h2{color:var(--ink)}
.prose ul{margin:0 0 20px;padding:0 0 0 21px;max-width:68ch}
.prose li{margin:0 0 9px;font-size:clamp(15px,1.3vw,18.5px);line-height:1.6}
.prose li:last-child{margin-bottom:0}
.prose li::marker{color:var(--orange)}
.caps .prose li{color:var(--on-dark)}
.pain .prose li{color:#4A4842}
.prose a{color:var(--orange-dk);text-decoration:underline;text-underline-offset:3px}
.caps .prose a{color:var(--orange)}
.prose a:hover{text-decoration-thickness:2px}
.prose p.legal-meta{font:700 12px/1.6 var(--mono);letter-spacing:.09em;text-transform:uppercase;
  color:var(--orange);margin:0 0 clamp(24px,2.6vw,34px);max-width:none}


/* ── HOW WE WORK · TWO COLUMNS ───────────────────────────────────────
   The /how-we-work/ page argues one thing repeatedly: the report that
   stops at the lead, beside the report that counts the customer. Left
   column muted, right column full contrast, an orange rule between.
   Tokens only: --ink, --cream, --orange, --line-cream, --line-dark. */
.cmp-legend{display:grid;grid-template-columns:1fr 1fr;gap:clamp(18px,3vw,56px);
  margin:0 0 clamp(6px,1vw,14px);padding-bottom:clamp(20px,2.4vw,30px)}
.cmp-legend b{display:block;font-family:var(--mono);font-size:10.5px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;margin-bottom:8px}
.cmp-legend div:first-child b{color:#8C8880}
.cmp-legend div:last-child b{color:var(--orange)}
.cmp-legend p{margin:0;font-size:14px;line-height:1.5;color:#4A4842;max-width:38ch}

.cmp-row{display:grid;grid-template-columns:1fr 1px 1fr;border-top:1px solid var(--line-cream)}
.cmp-rule{background:var(--line-cream)}
.cmp-row:hover .cmp-rule{background:var(--orange)}
.cmp-side{padding:clamp(26px,3vw,46px) clamp(18px,2.4vw,40px) clamp(26px,3vw,46px) 0}
.cmp-side--them{opacity:.62}
.cmp-side--us{padding-left:clamp(18px,2.4vw,40px);padding-right:0}
.cmp-tag{margin:0 0 12px;font-family:var(--mono);font-size:10px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:#8C8880}
.cmp-side--us .cmp-tag{color:var(--orange)}
.cmp-side h3{font-size:clamp(20px,2.1vw,30px);line-height:1.12;letter-spacing:-.035em;
  margin-bottom:13px;color:var(--ink)}
.cmp-side p{margin:0 0 12px;font-size:14.5px;line-height:1.58;color:#4A4842;max-width:44ch}
.cmp-side p:last-child{margin-bottom:0}
.cmp-side b{color:var(--ink);font-weight:700}
.cmp-num{display:block;font-size:clamp(28px,3.2vw,44px);font-weight:900;letter-spacing:-.045em;
  line-height:1;color:var(--orange);margin:0 0 10px}
.cmp-side--them .cmp-num{color:#8C8880}

/* Ink band carrying the real portal screens. */
.scr{background:var(--ink);color:var(--cream-hi);padding:clamp(46px,5vw,84px) 0}
.scr h2{font-size:clamp(26px,2.9vw,44px);max-width:18ch;margin-bottom:16px;color:var(--cream-hi)}
.scr > .wrap > p{margin:0 0 15px;font-size:clamp(15px,1.24vw,17.5px);line-height:1.62;
  max-width:60ch;color:var(--on-dark)}
.scr b{color:var(--cream-hi);font-weight:700}
.scr-frame{margin:clamp(26px,3vw,42px) 0 0;border:1px solid var(--line-dark)}
.scr-bar{display:flex;align-items:center;gap:8px;padding:10px 15px;
  border-bottom:1px solid var(--line-dark)}
.scr-bar u{width:8px;height:8px;border-radius:50%;background:var(--line-dark);text-decoration:none}
.scr-bar span{margin-left:8px;font-family:var(--mono);font-size:10.5px;letter-spacing:.07em;
  color:#8C8880}
.scr-frame img{width:100%;height:auto;display:block}
.scr .scr-cap{margin:11px 0 0;font-family:var(--mono);font-size:10.5px;line-height:1.6;
  letter-spacing:.05em;color:#8C8880;max-width:80ch}
.scr-pair{display:grid;grid-template-columns:1fr 1fr;gap:clamp(14px,2vw,28px);
  margin-top:clamp(26px,3vw,42px)}
.scr-pair .scr-frame{margin-top:0}

@media (max-width:900px){
  .cmp-row{grid-template-columns:1fr}
  .cmp-rule{height:1px;width:100%}
  .cmp-side{padding:clamp(20px,3vw,30px) 0}
  .cmp-side--us{padding-left:0}
  .cmp-side--them{padding-bottom:6px}
  .cmp-legend{grid-template-columns:1fr;gap:18px}
  .scr-pair{grid-template-columns:1fr}
}

/* Second sentence of a two-part headline, carried in orange. Normal style
   because <em> is being used for emphasis, not for italics. */
.phero h1 em{font-style:normal;color:var(--orange)}


/* ── CASE STUDY CARDS · result line, affordance, legend ──────────────
   The result line used to be flat orange mono, which is this site's
   PLACEHOLDER signal: /work/ tells the reader in its own copy that
   "anything in orange is a placeholder being pulled from the accounts."
   So every real carried-across figure was wearing the costume of an
   unfilled one. The figure now reads as ink with an orange rule above
   it, and flat orange goes back to meaning only `.ph`. */
.cs-card-fig{margin-top:auto;padding-top:14px;border-top:1px solid var(--line-cream);
  font:800 14.5px/1.3 var(--sans);letter-spacing:-.015em;color:var(--ink)}
.cs-card-fig span{display:block;margin-bottom:7px;font:700 9.5px/1 var(--mono);
  letter-spacing:.17em;text-transform:uppercase;color:var(--orange)}

/* A card with nothing published keeps the rule and says so in words, so
   the grid stays even and the gap reads as deliberate rather than broken.
   Deliberately NOT a dashed .ph box: repeated across a grid that reads as
   a broken page, which is the call recorded in cases.py. */
.cs-card-fig--none{color:#6E6B63;font-weight:600;font-size:13.5px}

.cs-card-go{margin-top:16px;font:700 10.5px/1 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--orange);display:flex;align-items:center;gap:8px}
.cs-card-go i{font-style:normal;transition:transform .18s ease}
.cs-card:hover .cs-card-go i,.cs-card:focus-visible .cs-card-go i{transform:translateX(4px)}
.cs-card{transition:border-color .18s ease,transform .18s ease}
.cs-card:hover,.cs-card:focus-visible{transform:translateY(-2px)}

/* How to read the figures on this page. Same two-column device as
   /how-we-work/, scoped to provenance rather than to argument. */
.cs-legend{display:grid;gap:clamp(16px,2.6vw,48px);margin:clamp(30px,3.4vw,46px) 0 0;
  padding-top:clamp(20px,2.4vw,28px);border-top:1px solid var(--line-cream)}
@media(min-width:820px){.cs-legend{grid-template-columns:1fr 1fr}}
.cs-legend b{display:block;margin-bottom:8px;font:700 10.5px/1 var(--mono);
  letter-spacing:.16em;text-transform:uppercase}
.cs-legend div:first-child b{color:var(--orange)}
.cs-legend div:last-child b{color:#8C8880}
.cs-legend p{margin:0;font-size:14px;line-height:1.55;color:#4A4842;max-width:40ch}

/* ═══════════════════════════════════════════════════════════════════════════
   /services/paid-search/ — the one service page that is not content_page().
   Joe picked this layout out of three comps on 2026-09-24 (build/paidsearch.py).

   Everything here is namespaced .ps* and additive: no selector above is
   touched, so the other 46 pages come out of the build unchanged. Every colour
   is an existing token.
   ═══════════════════════════════════════════════════════════════════════════ */

/* A section lede or an argument paragraph above a figure. */
.ps-lede{
  margin:0 0 16px;max-width:62ch;
  font-size:clamp(15.5px,1.3vw,18px);line-height:1.6;opacity:.78;
}
/* .h-sec carries no bottom margin, so the first lede under a heading sits on
   its baseline. The gap belongs to the paragraph, not to the heading, because
   the heading is shared with every other section on the site. */
.h-sec + .ps-lede{margin-top:clamp(18px,2vw,26px)}
.ps-lede:last-of-type{margin-bottom:0}

/* The source line under a figure. Mono and quiet on purpose: it is there to be
   checked, not to be read first. */
.ps-src{
  font-family:var(--mono);font-size:11px;letter-spacing:.06em;line-height:1.6;
  margin:16px 0 0;opacity:.62;
}
.ps-src b{font-weight:700;opacity:1}
.ps-src a{color:inherit;text-decoration:underline;text-underline-offset:3px}
.ps-src a:hover{color:var(--orange)}
.caps .ps-src{color:var(--cream-hi)}
.pain .ps-src{color:var(--ink)}

/* ── figure card ───────────────────────────────────────────────────────────
   Figures run FULL WIDTH, never two to a row. A half-width column renders the
   900-unit viewBox at roughly 330 CSS px, which drops the 10px mono labels
   under legibility and collides them with the bars. Two side by side was a
   layout decision the charts could not carry. */
.psfig{
  border:1px solid var(--line-dark);border-radius:14px;padding:clamp(20px,2.4vw,34px);
  background:rgba(246,238,228,.028);
}
.pain .psfig{border-color:var(--line-cream);background:rgba(15,18,19,.022)}
.psfig-h{
  display:flex;align-items:baseline;justify-content:space-between;gap:20px;
  flex-wrap:wrap;margin:0 0 clamp(18px,2vw,28px);
}
.psfig-h h3{margin:0;font-size:clamp(17px,1.5vw,21px);font-weight:700;letter-spacing:-.01em}
.psfig-tag{
  font-family:var(--mono);font-weight:700;font-size:10px;letter-spacing:.17em;
  text-transform:uppercase;color:var(--orange);white-space:nowrap;
}
.psfig-scroll{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch}
.psfig svg{display:block;width:100%;height:auto;overflow:visible}
@media (max-width:760px){
  .psfig-scroll{padding-bottom:12px}
  .psfig-scroll svg{min-width:820px}
}

/* ── the Journey capture, in a browser frame ──────────────────────────────── */
.psport{
  border:1px solid var(--line-dark);border-radius:12px;overflow:hidden;
  background:#0B0E0F;box-shadow:0 30px 70px rgba(0,0,0,.42);
}
.pain .psport{border-color:var(--line-cream);box-shadow:0 26px 60px rgba(15,18,19,.16)}
.psport-bar{
  display:flex;align-items:center;gap:8px;padding:11px 16px;
  border-bottom:1px solid var(--line-dark);background:#12181A;
}
.psport-bar u{width:9px;height:9px;border-radius:50%;background:rgba(246,238,228,.22);display:block}
.psport-bar u:first-child{background:var(--orange)}
.psport-bar span{
  margin-left:12px;font-family:var(--mono);font-size:11px;letter-spacing:.06em;
  color:rgba(246,238,228,.6);
}
.psport img{display:block;width:100%;height:auto}
/* A missing capture renders as a visible dashed panel rather than a broken
   image, so an asset that never landed cannot be mistaken for a design choice. */
.psport-empty{
  aspect-ratio:1552/648;display:grid;place-content:center;gap:12px;text-align:center;
  padding:30px;color:rgba(246,238,228,.5);font-family:var(--mono);font-size:12px;
  letter-spacing:.1em;line-height:2;
  background:repeating-linear-gradient(135deg,rgba(246,238,228,.028) 0 12px,transparent 12px 24px);
}
.psport-empty b{display:block;color:var(--orange);font-size:11px;letter-spacing:.18em}
/* Pins are positioned as a percentage of the CAPTURE, so they have to be
   re-derived whenever the capture is re-cropped. */
.psport-wrap{position:relative}
.psport-pin{
  position:absolute;display:flex;align-items:center;gap:9px;transform:translate(-50%,-50%);
  font-family:var(--mono);font-weight:700;font-size:11px;letter-spacing:.1em;
  color:#14100E;background:var(--orange);border-radius:999px;padding:6px 13px 6px 6px;
  box-shadow:0 8px 22px rgba(0,0,0,.35);white-space:nowrap;
}
.psport-pin i{
  width:20px;height:20px;border-radius:50%;background:#14100E;color:var(--orange);
  display:grid;place-content:center;font-style:normal;font-size:11px;
}

/* ── hero ──────────────────────────────────────────────────────────────────
   Ink, and a two-column grid. The right half of this hero used to be empty on
   the cream .phero every other service page uses. */
.pshero{background:var(--ink);color:var(--cream-hi);padding:clamp(48px,5vw,78px) 0 var(--pad)}
.pshero-grid{
  display:grid;grid-template-columns:1.08fr .92fr;
  gap:clamp(34px,4.4vw,72px);align-items:end;
}
.pshero .eyebrow{color:var(--orange)}
.pshero h1{
  font-size:clamp(40px,5.4vw,78px);line-height:.96;letter-spacing:-.035em;
  margin:0 0 clamp(20px,2.2vw,30px);max-width:15ch;
}
.pshero h1 em{font-style:normal;color:var(--orange)}
.pshero .lede{
  font-size:clamp(16.5px,1.42vw,20px);line-height:1.55;max-width:44ch;
  opacity:.82;margin:0 0 28px;
}
.pshero-actions{display:flex;gap:12px;flex-wrap:wrap}

/* ── the published-figures board ─────────────────────────────────────────── */
.psboard{
  border:1px solid var(--line-dark);border-radius:14px;overflow:hidden;
  background:rgba(246,238,228,.03);
}
.psboard-h{
  display:flex;justify-content:space-between;align-items:center;gap:14px;
  padding:13px 18px;border-bottom:1px solid var(--line-dark);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
}
.psboard-h b{color:var(--orange);font-weight:700}
.psboard-h span{opacity:.55}
.psboard-rows{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line-dark)}
/* A board carries as many published figures as the account actually has. Four
   is a 2x2; three is two on top and one spanning, which reads as deliberate
   where a dangling third cell reads as a missing fourth. Never invent a figure
   to square the grid. */
.psboard-rows--3 > :last-child{grid-column:1 / -1}
.psboard-row{background:var(--ink);padding:clamp(16px,1.7vw,22px)}
.psboard-row p{
  margin:0 0 10px;font-family:var(--mono);font-size:10px;letter-spacing:.15em;
  text-transform:uppercase;opacity:.58;
}
.psboard-row b{
  display:block;font-size:clamp(26px,3vw,40px);font-weight:800;line-height:1;
  letter-spacing:-.03em;font-variant-numeric:tabular-nums;
}
.psboard-row span{display:block;margin-top:9px;font-size:12.5px;line-height:1.45;opacity:.66}
.psboard-f{
  padding:13px 18px;border-top:1px solid var(--line-dark);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;opacity:.55;
}

/* ── the client's sentence, beside the page's one photograph ─────────────── */
.pssplit{display:grid;grid-template-columns:1fr 1fr;gap:clamp(22px,2.6vw,38px);align-items:start}
.psquote{
  border-left:2px solid var(--orange);padding-left:clamp(22px,2.4vw,34px);
  font-size:clamp(21px,2.3vw,32px);line-height:1.28;letter-spacing:-.02em;
  font-weight:600;margin:0;
}
.psquote cite{
  display:block;margin-top:20px;font-style:normal;font-family:var(--mono);
  font-size:11px;letter-spacing:.15em;text-transform:uppercase;color:var(--orange);
}
.psquote-after{
  margin:28px 0 0;font-size:15.5px;line-height:1.62;opacity:.78;max-width:42ch;
}
.psphoto{border-radius:12px;overflow:hidden}
.psphoto img{display:block;width:100%;height:auto}

@media (max-width:1000px){
  .pshero-grid,.pssplit{grid-template-columns:1fr}
  .psphoto img{max-width:560px}
}
@media (max-width:620px){
  .psboard-rows{grid-template-columns:1fr}
  .psport-pin{display:none}
}

/* ── PROGRAMMATIC & STREAMING ────────────────────────────────
   /services/programmatic-streaming/ only. Built from existing
   tokens: no new colours, no new type sizes beyond the two
   scales already in the sheet.

   `.st-h` exists because `.pain h2` caps display headings at
   13ch at up to 76px, which is right for a four-word headline
   and wrong for a sentence. Specificity: `.pain .st-h` is
   (0,2,0) against `.pain h2` at (0,1,1), so the scoped rule
   wins without moving any page that does not carry it. */
.st-h,.pain .st-h{
  font-size:clamp(29px,3.5vw,52px);max-width:23ch;letter-spacing:-.022em;
}
.st-p{
  margin:0 0 clamp(14px,1.5vw,20px);max-width:70ch;
  font-size:clamp(15px,1.24vw,17.5px);line-height:1.62;
}
.caps .st-p{color:var(--on-dark)}
.pain .st-p{color:#4A4842}
.st-h + .st-p{margin-top:clamp(18px,2vw,26px)}
.st-note{
  margin:clamp(22px,2.4vw,32px) 0 0;max-width:78ch;
  font-size:12px;line-height:1.7;color:#6E6B63;
}
.st-sr{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

/* Hero. This page used to carry its own single-column `.sthero`
   with a three-mark row under the lede. Removed 2026-09-24 when
   Joe asked for one hero shape across the services: it now uses
   `.pshero` / `.psboard` above, same as the five rich service
   pages. The rules were deleted rather than left orphaned,
   because dead CSS reads as a live alternative to the next
   person who greps for a hero. */

/* The pinned diagram. Four layers, lit in order by site.js as
   each step becomes active. Dimming is OPT-IN from script (the
   [data-reveal] gate the story block already uses), so with JS
   off every layer renders and the drawing is complete. */
.st-grid{grid-template-columns:.52fr .48fr}
.st-stick{display:grid;gap:clamp(16px,1.8vw,24px);min-width:0}
/* The SVG's own viewBox supplies the 4/3 ratio, so `height:auto`
   is all the sizing this needs. Putting `aspect-ratio` on the DIV
   instead broke it: as a stretched grid item it took a definite
   height from the row, derived its width from the ratio, and came
   out 403px wide inside a 350px column - 33px of horizontal page
   scroll on a phone, on a page that measured clean at 1440. */
.st-fig{position:relative;width:100%;max-width:540px;min-width:0}
.st-fig svg{display:block;width:100%;height:auto}
.pain .st-fig svg{color:var(--ink)}
.caps .st-fig svg{color:var(--cream-hi)}
.st-legend{
  display:flex;flex-wrap:wrap;gap:8px 22px;margin:0;
  font-family:var(--mono);font-weight:500;font-size:10.5px;
  letter-spacing:.11em;text-transform:uppercase;
}
.pain .st-legend{color:#6E6B63}
.caps .st-legend{color:#8C8880}
.st-legend span{display:inline-flex;align-items:center;gap:8px}
.st-key{width:10px;height:10px;border-radius:50%;display:inline-block}
.st-key--in{background:var(--orange)}
.st-key--out{border:1.6px solid var(--line-cream)}
.caps .st-key--out{border-color:var(--line-dark)}
[data-reveal] .st-l{opacity:.14;transition:opacity .55s ease}
[data-reveal] .st-l.is-lit{opacity:1}

/* Photo band. 3/2 because every file in /assets/people/ is
   exported at 3/2, so `cover` crops nothing (trap 4). */
.st-band{
  display:grid;grid-template-columns:1.2fr 1fr;
  gap:clamp(30px,4vw,64px);align-items:center;
}
.st-photo{border-radius:12px;overflow:hidden;aspect-ratio:3/2}
.st-photo img{display:block;width:100%;height:100%;object-fit:cover}
.st-band-links{
  display:flex;flex-wrap:wrap;gap:10px 28px;margin:clamp(22px,2.4vw,32px) 0 0;
  font-family:var(--mono);font-weight:700;font-size:11.5px;
  letter-spacing:.1em;text-transform:uppercase;
}
.st-band-links a{color:var(--orange);text-decoration:none;border-bottom:1px solid transparent}
.st-band-links a:hover{border-bottom-color:var(--orange)}

/* The do / do-not ledger. A rule we hold is a light card on
   cream; a rule we refuse is an ink card, so the two halves
   cannot be skim-read as one list of features. */
/* Two columns by MEANING, not by row flow: the rules we hold on
   the left, the ones we refuse on the right. A single row-flow
   grid put a refusal in the middle of the kept rules and the
   whole thing skim-read as one list of features. */
.st-rules{
  margin:clamp(28px,3.2vw,44px) 0 0;
  display:grid;grid-template-columns:1fr 1fr;gap:clamp(14px,1.8vw,26px);
  align-items:start;
}
.st-rulecol{list-style:none;margin:0;padding:0;display:grid;gap:12px;align-content:start}
.st-rule-h{
  font-family:var(--mono);font-weight:700;font-size:11px;
  letter-spacing:.15em;text-transform:uppercase;color:var(--orange);
  padding-bottom:4px;
}
.st-rule{
  display:flex;align-items:flex-start;gap:14px;
  padding:clamp(16px,1.7vw,22px);border-radius:10px;
  font-size:clamp(14.5px,1.16vw,16px);line-height:1.55;
}
.st-rule--do{background:var(--cream-hi);border:1px solid var(--line-cream);color:var(--ink)}
.st-rule--not{background:var(--ink);color:var(--cream-hi)}
.st-rule-k{
  flex:0 0 22px;height:22px;display:grid;place-items:center;
  border-radius:50%;font-size:11px;font-weight:700;
}
.st-rule--do .st-rule-k{background:var(--orange);color:#14100E}
.st-rule--not .st-rule-k{color:var(--orange);background:rgba(241,107,43,.14)}

/* The network shelf. Every mark sits on its own white tile, so
   the ground under it is white by construction rather than by a
   mix-blend-mode that dies under an animated ancestor (trap 1).
   Each mark is capped by its OWN shape: cap both dimensions on
   one rule and the square lockups read as timid beside the long
   wordmarks. */
.st-shelf{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(5,1fr);gap:12px;
}
.st-shelf--yt{grid-template-columns:repeat(2,minmax(0,220px))}
.st-tile{
  display:flex;align-items:center;justify-content:center;
  height:104px;padding:16px 20px;border-radius:10px;
  background:#fff;border:1px solid var(--line-cream);
  transition:border-color .3s ease;
}
.caps .st-tile{border-color:transparent}
.st-tile:hover{border-color:rgba(15,18,19,.28)}
/* Every cap is min(<shape>, 100%). A bare pixel max-width on the
   mark is MORE specific than base's `img{max-width:100%}`, so it
   removes the only thing stopping a 148px wordmark from hanging
   out of a 129px tile - which is exactly what the two-column
   phone layout does. min() keeps the shape cap and the tile. */
.st-mk{display:block;width:auto;height:auto}
.st-mk--wide{max-height:34px;max-width:min(148px,100%)}
.st-mk--std{max-height:42px;max-width:min(126px,100%)}
.st-mk--tall{max-height:62px;max-width:min(100px,100%)}

/* The four reads that answer the incrementality question. */
.st-evs{
  list-style:none;margin:clamp(28px,3.2vw,44px) 0 0;padding:0;
  display:grid;grid-template-columns:1fr 1fr;gap:clamp(14px,1.6vw,20px);
}
.st-ev{
  padding:clamp(22px,2.4vw,32px);border-radius:10px;
  background:rgba(246,238,228,.045);border:1px solid var(--line-dark);
}
.st-ev-n{
  display:block;font-family:var(--mono);font-weight:700;font-size:14px;
  letter-spacing:.16em;color:var(--orange);
}
.st-ev h3{
  margin:12px 0 0;font-size:clamp(18px,1.6vw,23px);line-height:1.22;
  letter-spacing:-.02em;color:var(--cream-hi);
}
.st-ev p{margin:12px 0 0;font-size:15px;line-height:1.6;color:var(--on-dark)}
.st-close{
  margin:clamp(28px,3vw,40px) 0 0;max-width:72ch;
  font-size:clamp(15px,1.24vw,17.5px);line-height:1.6;
  font-weight:600;color:var(--cream-hi);
}

/* Three roles in sequence. */
.st-roles{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,1.6vw,20px)}
.st-role{
  padding:clamp(22px,2.4vw,32px);border-radius:10px;
  background:var(--cream-hi);border:1px solid var(--line-cream);
}
.st-role h3{
  margin:0;font-size:clamp(18px,1.55vw,22px);line-height:1.22;
  letter-spacing:-.02em;color:var(--ink);
}
.st-role p{margin:12px 0 0;font-size:15px;line-height:1.6;color:#4A4842}

/* The first flight, as a spec sheet rather than a paragraph. */
.st-specs{
  margin:clamp(28px,3.2vw,44px) 0 clamp(26px,3vw,38px);max-width:920px;
  border-radius:10px;background:var(--cream-hi);
  border:1px solid var(--line-cream);
}
.st-spec{
  display:grid;grid-template-columns:11rem 1fr;gap:8px 28px;
  padding:clamp(20px,2.2vw,28px);
}
.st-spec + .st-spec{border-top:1px solid var(--line-cream)}
.st-spec dt{
  margin:0;font-family:var(--mono);font-weight:700;font-size:11.5px;
  letter-spacing:.13em;text-transform:uppercase;color:var(--orange);
}
.st-spec dd{margin:0;font-size:clamp(14.5px,1.16vw,16.5px);line-height:1.6;color:#4A4842}

/* Bars that grow when the figure arrives. Opt-in from script
   (`data-grow`), so with JS off every bar renders at its width
   rather than at zero. */
[data-grow] .bar-track i{width:0;transition:width .85s cubic-bezier(.22,.61,.36,1)}
[data-grow].is-grown .bar-track i{width:var(--w,0%)}

@media (prefers-reduced-motion:reduce){
  [data-reveal] .st-l{opacity:1;transition:none}
  [data-grow] .bar-track i{width:var(--w,0%);transition:none}
}

@media (max-width:1000px){
  .st-grid{grid-template-columns:1fr}
  .st-band{grid-template-columns:1fr}
  .st-photo{max-width:620px}
  .st-roles{grid-template-columns:1fr}
  .st-shelf{grid-template-columns:repeat(3,1fr)}
  .st-fig{max-width:460px;margin-inline:auto}
}
@media (max-width:640px){
  .st-rules,.st-evs{grid-template-columns:1fr}
  .st-rules{gap:clamp(20px,4vw,28px)}
  .st-shelf{grid-template-columns:repeat(2,1fr)}
  .st-spec{grid-template-columns:1fr}
  .st-tile{height:88px;padding:12px 14px}
}

/* ── HOMEPAGE PROOF CARDS ────────────────────────────────────────────
   The homepage proof block is .pillars of .pillar.cs-card, so it picks up
   v3's /case-studies/ card chrome (cream-hi fill, hairline, 12px radius)
   while its padding still comes from v1's .pillar, which pads the LEFT
   only because v1 had no card behind the text. With placeholders in it
   that read as fine; with real copy the text sits on the border on three
   sides. Pad the card and drop the rule the fill replaced.

   .pillar p is capped at 21ch, correct for a bare v1 column and wrong
   inside a ~360px card: it empties a third of the card and doubles the
   height. Uncapped here only, so /industries/ and the other .pillars
   grids keep the cap. */
.pillars--cs .cs-card{border-left:0;padding:clamp(22px,2vw,28px)}
.pillars--cs .cs-card p{max-width:none}
.pillars--cs .cs-card h3{margin-bottom:6px}
.pillars--cs .cs-card-go{margin-top:14px;text-decoration:none}

/* The figure's own qualifier, in the same mono face .fig-cap uses but
   sentence case, because it is a sentence. margin-top:auto pins it and
   the link below it to the bottom of the card, so three cards of unequal
   copy still line their footers up. */
/* Specificity note: `.cs-card p + p{margin-top:12px}` in v2 is (0,1,2) and
   outranks a bare `.cs-home-note`, which silently kept the 12px and left the
   three card footers at three different heights. Qualify past it. */
.pillars--cs .cs-card .cs-home-note{margin-top:auto;padding-top:14px;font-family:var(--mono);
  font-size:11px;letter-spacing:.04em;line-height:1.55;color:#6E6B63}

/* ═══════════════════════════════════════════════════════════════════════════
   INDUSTRIES — the "Job Site" layout
   Joe picked this out of three comps on 2026-09-24 and made it the theme for
   the whole Industries section.

   Namespaced `.ind*`, purely additive. Everything composes from the inherited
   tokens except ONE new colour: --hivis. It is the marker for "the one thing
   that decides this account" and it is load-bearing in the comp Joe approved,
   so it is a deliberate addition rather than drift. Nothing else here invents
   a colour or a type size.
   ═══════════════════════════════════════════════════════════════════════════ */
:root{--hivis:#FFD53D}

/* ---------- hero: copy left, photo right, stat plate over the photo ---------- */
.indhero{position:relative;overflow:hidden;background:var(--cream)}
.indhero-grid{display:grid;gap:0}
.indhero-copy{padding:44px 0 36px}
.indhero-photo{position:relative;margin:0 calc(-1*var(--gut));min-height:300px;background:var(--cream-hi)}
.indhero-photo img{width:100%;height:100%;object-fit:cover;object-position:50% 40%;
  position:absolute;inset:0}
@media(min-width:960px){
  .indhero-grid{grid-template-columns:1.02fr .98fr;align-items:stretch;gap:48px}
  .indhero-copy{padding:76px 0 82px}
  .indhero-photo{margin:0 calc(-1*var(--gut)) 0 0;min-height:560px}
}
.indhero h1{color:var(--ink)}
.indhero h1 .mark{color:var(--orange)}
.indhero .lede{max-width:44ch;margin-top:22px;color:var(--on-cream)}
.indhero-actions{display:flex;flex-wrap:wrap;gap:12px;margin-top:30px}
.indhero-actions .btn{flex:1 1 200px;justify-content:center}
@media(min-width:560px){.indhero-actions .btn{flex:0 0 auto}}

.indplate{position:absolute;left:0;bottom:0;background:var(--ink);color:var(--cream-hi);
  padding:20px 24px;max-width:322px;border-top:4px solid var(--orange)}
.indplate b{display:block;font-size:34px;font-weight:900;letter-spacing:-.04em;line-height:1;
  color:var(--hivis)}
.indplate span{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--on-dark);margin-top:9px;line-height:1.5}

/* ---------- the chip rail ---------- */
.indchips{border-top:1px solid var(--line-cream);border-bottom:1px solid var(--line-cream);
  background:var(--cream-hi);padding:18px 0}
.indchips-in{display:flex;align-items:center;gap:10px;overflow-x:auto;scrollbar-width:none;
  -webkit-overflow-scrolling:touch}
.indchips-in::-webkit-scrollbar{display:none}
@media(min-width:1000px){.indchips-in{flex-wrap:wrap;overflow:visible;row-gap:10px}}
.indchips-lbl{font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--on-cream);font-weight:700;white-space:nowrap;padding-right:6px}
.indchip{display:inline-flex;align-items:center;gap:8px;white-space:nowrap;background:var(--cream);
  border:1px solid var(--line-cream);padding:9px 15px;font-size:13px;font-weight:600;
  color:var(--ink);transition:background .16s,color .16s,border-color .16s,transform .16s}
.indchip:hover{background:var(--ink);color:var(--cream-hi);border-color:var(--ink);
  transform:translateY(-1px)}
.indchip i{width:6px;height:6px;background:var(--orange);display:block;border-radius:50%;flex:none}

/* ---------- client logo grid ---------- */
.indlogos-h{display:flex;flex-wrap:wrap;gap:16px 40px;align-items:baseline;margin-bottom:34px}
.indlogos-h h2{font-size:clamp(21px,2.3vw,28px);letter-spacing:-.03em;max-width:22ch}
.indlogos-h p{margin:0;font-size:14px;color:var(--on-cream);max-width:38ch}
/* The separators used to be the CONTAINER showing through a 1px gap. That
   works until the last row is ragged - 15 logos in a 4-up grid - and then the
   leftover cell paints as a solid block of separator colour, which reads as a
   missing logo. The column count changes at every breakpoint, so a filler cell
   is wrong at two widths out of three. Draw the separator on the CELL instead
   and let the container be the page ground: a short row is then simply empty. */
/* No border on the CONTAINER. It frames the leftover of a ragged count as an
   empty cell, which is the thing the paragraph above says it will not do: at 7
   and at 19 the grid drew a bordered blank. The cells' own rings already draw
   the perimeter, so a short last row simply ends. */
.indlogos{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--cream)}
.indlogos > *{box-shadow:0 0 0 1px var(--line-cream)}
@media(min-width:620px){.indlogos{grid-template-columns:repeat(3,1fr)}}
@media(min-width:1000px){.indlogos{grid-template-columns:repeat(4,1fr)}}
.indlogo{background:var(--cream);display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:12px;padding:30px 20px;min-height:132px;transition:background .18s}
.indlogo:hover{background:var(--cream-hi)}
.indlogo img{max-height:44px;max-width:100%;width:auto;object-fit:contain}
.indlogo img.is-sq{max-height:58px}
.indlogo span{font-family:var(--mono);font-size:11px;letter-spacing:.11em;text-transform:uppercase;
  color:var(--on-cream);text-align:center;line-height:1.5}
.indlogo--more{background:var(--cream-hi);text-align:center}
.indlogo--more b{font-size:26px;font-weight:900;letter-spacing:-.03em;display:block;color:var(--ink)}

/* The client quote, under the grid and inside the same section. Option 2 of
   five comps (2026-09-25); the other four are at /_templates/nycbs-quote/.
   The payoff sentence carries the display size and the setup runs small above
   it, so the largest type on the band is the strongest claim on it. */
.indquote{margin:40px 0 0;padding:34px clamp(20px,3vw,40px) 6px;
  border-top:1px solid var(--line-cream);text-align:center}
.indq-pre{margin:0 auto 22px;max-width:54ch;font-size:clamp(15px,1.5vw,17px);line-height:1.5;
  color:var(--on-cream)}
.indq-hit{margin:0;font-size:clamp(26px,4.2vw,50px);font-weight:900;letter-spacing:-.035em;
  line-height:1.08;color:var(--ink)}
/* His own capitalisation, so the emphasis is his rather than ours. */
.indq-hit em{font-style:normal;color:var(--orange)}
.indq-cite{display:flex;align-items:center;justify-content:center;gap:18px;flex-wrap:wrap;
  margin-top:30px}
.indq-cite img{max-height:30px;width:auto}
/* Direct child, never a descendant: a bare `span` here also matches a nested
   one, which is the .stat span defect two sections up. */
.indq-cite > span{text-align:left;border-left:1px solid var(--line-cream);padding-left:18px}
.indq-cite b{display:block;font-size:14px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.indq-cite i{display:block;font-style:normal;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.11em;text-transform:uppercase;color:var(--on-cream)}
@media(max-width:560px){.indq-cite > span{border-left:0;padding-left:0;text-align:center}}

/* ---------- the decision timeline ---------- */
.indtl{margin-top:44px;border:1px solid var(--line-dark);padding:clamp(20px,3vw,34px)}
.indtl-h{display:flex;justify-content:space-between;align-items:baseline;gap:20px;margin-bottom:22px;
  font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--on-dark)}
.indtl-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.indtl-scroll svg{width:100%;height:auto;display:block}
@media(max-width:760px){.indtl-scroll svg{min-width:720px}}
.indtl-legend{display:grid;gap:16px;margin-top:26px;padding-top:22px;border-top:1px solid var(--line-dark)}
@media(min-width:760px){.indtl-legend{grid-template-columns:repeat(3,1fr);gap:30px}}
.indtl-legend b{display:block;font-size:15px;font-weight:800;letter-spacing:-.02em;margin-bottom:5px;
  color:var(--cream-hi)}
.indtl-legend p{margin:0;font-size:14px;line-height:1.5;color:var(--on-dark)}

/* ---------- trade cards ---------- */
/* Same ragged-row defect as .indlogos: five cards in a 3-up grid leaves a
   sixth cell painting the separator colour. Separator on the cell, ground on
   the container. */
.indcards{display:grid;gap:1px;background:var(--cream);border-top:1px solid var(--line-cream);
  border-bottom:1px solid var(--line-cream)}
.indcards > *{box-shadow:0 0 0 1px var(--line-cream)}
@media(min-width:640px){.indcards{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1020px){.indcards{grid-template-columns:repeat(3,1fr)}}
.indcard{background:var(--cream);display:flex;flex-direction:column}
.indcard-img{aspect-ratio:16/10;overflow:hidden;background:var(--cream-hi)}
.indcard-img img{width:100%;height:100%;object-fit:cover;
  transition:transform .5s cubic-bezier(.2,.7,.3,1)}
.indcard:hover .indcard-img img{transform:scale(1.045)}
.indcard-body{padding:26px 24px 30px;flex:1;display:flex;flex-direction:column}
.indcard-n{font-family:var(--mono);font-size:11px;letter-spacing:.17em;color:var(--orange);
  font-weight:700;margin-bottom:12px;text-transform:uppercase}
.indcard h3{font-size:clamp(19px,2.2vw,25px);letter-spacing:-.025em;line-height:1.15;
  margin:0 0 10px;color:var(--ink)}
.indcard p{font-size:14.5px;color:var(--on-cream);margin:0 0 18px;line-height:1.55}
.indcard-key{margin-top:auto;font-family:var(--mono);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink);border-top:1px solid var(--line-cream);
  padding-top:14px;display:flex;gap:9px;align-items:flex-start;line-height:1.55}
.indcard-key::before{content:"";width:9px;height:9px;background:var(--hivis);
  border:1.5px solid var(--ink);flex:none;margin-top:3px}

/* The interior hero is cream, so a `.btn` here inherits a colour meant for the
   homepage's photo hero and the secondary action renders as near-invisible
   orange-on-cream. Same class of defect as `.hero--bar` having to re-colour the
   pill button. State the colour rather than inheriting it. */
.indhero .btn{color:var(--ink);border-color:var(--line-cream)}
.indhero .btn:hover{border-color:var(--ink)}
.indhero .btn--solid{color:#14100E;border-color:var(--orange)}
.indhero .btn--solid:hover{color:#fff;border-color:var(--orange-dk)}

/* A grid carries as many clients as the industry has. Four cells with one
   empty is a page asking why, and padding it with a logo that is not a client
   of THIS industry is the thing the module refuses to do. Cap the columns at
   the count instead. Same rule as the service boards: never invent a cell to
   square the grid. */
.indlogos--1{grid-template-columns:1fr;max-width:420px}
@media(min-width:620px){
  .indlogos--2{grid-template-columns:repeat(2,1fr)}
  .indlogos--3{grid-template-columns:repeat(3,1fr)}
}
@media(min-width:1000px){
  .indlogos--2{grid-template-columns:repeat(2,1fr);max-width:720px}
  .indlogos--3{grid-template-columns:repeat(3,1fr)}
}
/* Logos differ wildly in aspect. A single max-height makes a tall badge tiny
   next to a long wordmark, so the square-ish ones get their own ceiling. */
.indlogo img.is-sq{max-height:62px}
.indlogo img.is-wide{max-height:38px}

/* A card that navigates has to say so. The trade cards on a child page are
   description; the five on the hub are the section's actual navigation. */
a.indcard{text-decoration:none;color:inherit}
a.indcard:hover{background:var(--cream-hi)}
.indcard-go{margin-top:14px;font-family:var(--mono);font-size:11px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--orange);display:flex;align-items:center;gap:9px}
.indcard-go i{font-style:normal;font-family:var(--sans);font-size:15px;line-height:1;
  transition:transform .18s}
a.indcard:hover .indcard-go i{transform:translateX(4px)}

/* ── TESTIMONIAL MONOGRAM ────────────────────────────────────
   Replaces .testi-face. The three headshot files were one grey
   stock avatar repeated, and a stock face beside a named
   person's words is a claim about who that person is. Initials
   claim nothing. Geometry is .testi-face's, which is itself
   .testi-nav button's, so the round elements in this row still
   match. */
.testi-mono{
  display:grid;place-items:center;width:46px;height:46px;border-radius:50%;
  border:1px solid var(--line-cream);margin:0 0 18px;
  font-family:var(--mono);font-weight:500;font-size:13px;letter-spacing:.06em;
  color:#6E6B63;
}

/* ── FIRST IMPRESSION REPORT (/first-impression/) ────────────
   Comp A ("The Tape") shipped 2026-09-25; these rules were
   lifted from fir-comp.css, the same path .ps* took from
   ps-comp.css. Namespaced .fi*, purely additive. Every color
   is an existing token. */
.fi-hero{background:var(--ink);color:var(--cream-hi);padding:clamp(46px,5vw,76px) 0 clamp(30px,3.6vw,52px)}
.fi-hero-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:clamp(34px,4.6vw,76px);align-items:center}
.fi-hero h1{font-size:clamp(40px,5.4vw,78px);line-height:.98;letter-spacing:-.035em;margin:0 0 26px;max-width:15ch}
.fi-hero .lede{font-size:clamp(16.5px,1.42vw,20px);line-height:1.56;max-width:48ch;opacity:.82;margin:0 0 30px}

.fi-log{
  border:1px solid var(--line-dark);border-radius:10px;background:rgba(246,238,228,.035);
  font-family:var(--mono);overflow:hidden;
}
.fi-log-h{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:14px 18px;border-bottom:1px solid var(--line-dark);
}
.fi-log-h b{font-size:11px;font-weight:700;letter-spacing:.2em;text-transform:uppercase;color:var(--orange)}
.fi-log-rows div{
  display:grid;grid-template-columns:86px 118px 1fr auto;gap:12px;align-items:baseline;
  padding:13px 18px;border-bottom:1px dashed rgba(246,238,228,.16);
  font-size:11px;letter-spacing:.04em;
}
.fi-log-rows div:last-child{border-bottom:none}
.fi-log-rows span{opacity:.72;white-space:nowrap}
.fi-log-rows span:nth-child(2){font-weight:700;opacity:.92}
.fi-log-rows em{font-style:normal;font-weight:700;white-space:nowrap}
.fi-bad{color:var(--orange)}
.fi-good{color:#7FB89B}
.fi-log footer{padding:14px 18px;font-size:10.5px;line-height:1.7;letter-spacing:.04em;opacity:.6}

.fi-wave{display:block;width:100%;height:auto;margin-top:clamp(30px,3.6vw,52px);color:var(--cream-hi)}

.fi-kit{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(16px,1.8vw,26px)}
.fi-kit--3{grid-template-columns:repeat(3,1fr)}
.fi-kit-card{
  border:1px solid var(--line-cream);border-radius:12px;
  padding:clamp(20px,2.2vw,30px);background:rgba(15,18,19,.022);
}
.caps .fi-kit-card{border-color:var(--line-dark);background:rgba(246,238,228,.028)}
.fi-kit-card b{
  display:block;font-family:var(--mono);font-size:10.5px;font-weight:700;
  letter-spacing:.18em;text-transform:uppercase;color:var(--orange);margin:0 0 16px;
}
.fi-kit-card h3{margin:0 0 12px;font-size:clamp(17px,1.5vw,21px);line-height:1.22;letter-spacing:-.02em}
.fi-kit-card p{margin:0;font-size:13.5px;line-height:1.6;opacity:.76}

.fi-ai{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(26px,3.2vw,54px);align-items:start}
/* A grid item's min-width is auto, so the chart's 820px phone scroller would
   stretch its column and drag the text column past the viewport with it. Zero
   it so the scroller scrolls inside its cell instead of widening the page. */
.fi-ai>*{min-width:0}
.fi-ai h3{margin:0 0 16px;font-size:clamp(20px,2vw,28px);line-height:1.18;letter-spacing:-.02em}
.fi-ai p{margin:0 0 14px;font-size:14.5px;line-height:1.64;opacity:.8;max-width:52ch}

.fi-human{display:grid;grid-template-columns:.86fr 1.14fr;gap:clamp(26px,3.2vw,54px);align-items:center}
.fi-human img{display:block;width:100%;height:auto;border-radius:12px}
.fi-human h2{font-size:clamp(30px,3.6vw,52px);line-height:1.03;letter-spacing:-.03em;margin:0 0 20px;max-width:15ch}
.fi-human p{font-size:clamp(15.5px,1.32vw,18px);line-height:1.6;opacity:.8;margin:0 0 16px;max-width:46ch}

.fi-close{text-align:center}
.fi-close .h-sec{margin-left:auto;margin-right:auto}
.fi-close .ps-lede{margin-left:auto;margin-right:auto}

.fi-sticky{
  position:fixed;right:clamp(14px,2vw,28px);bottom:clamp(14px,2vw,28px);z-index:55;
  display:inline-flex;align-items:center;gap:10px;
  background:var(--orange);color:#14100E;text-decoration:none;
  font-family:var(--mono);font-weight:700;font-size:12px;letter-spacing:.12em;
  text-transform:uppercase;padding:14px 22px;border-radius:999px;
  box-shadow:0 10px 30px rgba(15,18,19,.35);
}
.fi-sticky:hover{filter:brightness(1.06)}
.fi-sticky[hidden]{display:none}

@media (max-width:1000px){
  .fi-hero-grid,.fi-ai,.fi-human{grid-template-columns:1fr}
  .fi-kit,.fi-kit--3{grid-template-columns:repeat(2,1fr)}
  .fi-human img{max-width:560px}
}
@media (max-width:620px){
  .fi-kit,.fi-kit--3{grid-template-columns:1fr}
  .fi-log-rows div{grid-template-columns:74px 1fr auto;grid-auto-rows:auto}
  .fi-log-rows div span:nth-child(3){display:none}
}


/* ═══════════════════════════════════════════════════════════════════════════
   /case-studies/ — "The Board". Joe picked it out of three comps 2026-09-25.
   Lifted here from site/cs-comp.css when it shipped; the comp copy was deleted
   rather than left behind, because a second copy of a live page's rules reads
   as a live alternative to whoever greps for them next.

   THE LOGO BAKE. Both bakes carry a ground: logo-<c>.png for --cream and
   logo-<c>-cshi.png for --cream-hi. Neither survives an ink ground, and Sky
   Organics only has the -cshi bake. So the mark sits in a --cream-hi PLAQUE,
   one rule that works on every ground.

   `.bd-tile>img` is a DIRECT-CHILD selector on purpose. As a descendant it
   also caught the plaque's logo, absolutely positioned it over the tile and
   painted the client's wordmark across the photograph (the same trap .stat
   span already paid for).
   ═══════════════════════════════════════════════════════════════════════════ */

.plaque{
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--cream-hi);border-radius:8px;padding:10px 16px;
  width:142px;height:58px;box-sizing:border-box;
}
.plaque img{display:block;max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain}

.cx-note{
  font-family:var(--mono);font-size:11.5px;line-height:1.75;letter-spacing:.02em;
  opacity:.62;max-width:78ch;margin:0;
}

/* ═══════════════════════════════════════════════════════════════════════
   COMP C — "The Board". Ink. The figure is the card. Photo sits behind it
   at low weight so the number, not the logo, is what the eye lands on.
   ═══════════════════════════════════════════════════════════════════════ */
.bd-hero{background:var(--ink);color:var(--cream-hi);padding:clamp(52px,5.2vw,90px) 0 clamp(30px,3vw,46px)}
.bd-hero h1{font-size:clamp(40px,5.7vw,82px);line-height:.95;letter-spacing:-.036em;margin:0 0 20px;max-width:15ch}
.bd-hero h1 em{font-style:normal;color:var(--orange)}
.bd-hero-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:clamp(28px,4vw,64px);align-items:end}
.bd-hero p{font-size:16.5px;line-height:1.64;opacity:.8;margin:0 0 18px;max-width:50ch}
.bd-rule{display:flex;gap:26px;flex-wrap:wrap;border-top:1px solid var(--line-dark);padding-top:18px;margin-top:28px}
.bd-rule div{font-family:var(--mono);font-size:11px;letter-spacing:.13em;text-transform:uppercase;opacity:.62}
.bd-rule b{color:var(--orange);font-weight:700}

.bd-sec{background:var(--ink);color:var(--cream-hi);padding:0 0 var(--pad)}
.bd-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.bd-tile{position:relative;display:block;overflow:hidden;border-radius:16px;text-decoration:none;color:var(--cream-hi);
  background:var(--ink-2);border:1px solid var(--line-dark);min-height:330px;isolation:isolate}
.bd-tile--wide{grid-column:span 2}
.bd-tile>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.26;
  transition:opacity .45s ease,transform .7s ease;z-index:0}
.bd-tile::after{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(15,18,19,.42) 0%,rgba(15,18,19,.78) 52%,rgba(15,18,19,.94) 100%)}
.bd-tile:hover>img{opacity:.42;transform:scale(1.04)}
.bd-in{position:relative;z-index:2;display:flex;flex-direction:column;justify-content:space-between;
  height:100%;min-height:330px;padding:24px}
.bd-top{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
.bd-top .plaque{width:112px;height:46px;padding:8px 12px}
.bd-cat{font-family:var(--mono);font-size:10px;letter-spacing:.15em;text-transform:uppercase;opacity:.55;text-align:right;max-width:14ch}
.bd-fig{display:block;font-size:clamp(30px,3.1vw,46px);line-height:1.02;letter-spacing:-.032em;font-weight:700;
  color:var(--orange);margin:0 0 12px;max-width:17ch}
.bd-tile--wide .bd-fig{font-size:clamp(36px,4.3vw,64px);max-width:14ch}
.bd-qual{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;opacity:.6;margin:0 0 16px}
.bd-who{font-size:15px;line-height:1.5;opacity:.86;margin:0}
.bd-who b{font-weight:600}
.bd-who span{display:block;opacity:.6;font-size:13px;margin-top:3px}
.bd-none .bd-fig{color:var(--cream-hi);opacity:.64;font-size:clamp(19px,1.8vw,24px);font-weight:600;letter-spacing:-.012em}
.bd-tile--quiet{background:var(--ink-3)}
.bd-tile--quiet::after{background:linear-gradient(180deg,rgba(15,18,19,.6) 0%,rgba(15,18,19,.92) 100%)}

/* the offer tile: the only tile that is not a client */
.bd-tile--offer{background:var(--orange);border-color:var(--orange)}
.bd-tile--offer::after{display:none}
.bd-tile--offer,.bd-tile--offer .bd-who,.bd-tile--offer .bd-cat,.bd-tile--offer .bd-qual{color:#14100E}
.bd-tile--offer .bd-cat{opacity:.72;text-align:left;max-width:none}
.bd-tile--offer .bd-qual{opacity:.74}
.bd-fig--offer{color:#14100E!important;max-width:15ch}
.bd-tile--offer .bd-who span{opacity:.72}
.bd-tile--offer:hover{filter:brightness(.94)}

/* ═══ narrow ═══ */
@media (max-width:900px){
  .bd-hero-grid{grid-template-columns:1fr}
  .bd-grid{grid-template-columns:1fr 1fr}
  .bd-tile--wide{grid-column:span 2}
}
@media (max-width:760px){
  .bd-grid{grid-template-columns:1fr}
  .bd-tile--wide{grid-column:span 1}
  .bd-tile,.bd-in{min-height:280px}
}

/* ── FREE TOOLS NAV PANEL ────────────────────────────────────
   The one two-column feature dropdown (2026-09-25): link rows
   left, sample-report card right. Anchored right so the wide
   panel cannot run past the viewport from the nav's last slot.
   The drawer reads only the card's <b> and first <span>; the
   <u>/<i> problem list is desktop-only detail. */
.nav-panel--feat{grid-template-columns:280px 260px;width:570px;left:auto;right:-14px;gap:6px}
.nav-tools-list{display:grid;gap:2px;align-content:start}
.nav-feat{
  background:rgba(15,18,19,.035);border:1px solid var(--line-cream);
  border-radius:6px;
}
.nav-feat img{
  display:block;width:100%;height:auto;border-radius:4px;
  border:1px solid var(--line-cream);margin:0 0 10px;
}
.nav-feat-probs{display:block;text-decoration:none;margin-top:10px;padding-top:10px;
  border-top:1px dashed rgba(15,18,19,.18)}
.nav-feat-probs em{
  display:block;font-style:normal;font-family:var(--mono);font-weight:700;
  font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--orange-dk);margin:0 0 5px;
}
.nav-feat-probs i{
  display:block;font-style:normal;font-size:12px;line-height:1.35;
  color:#6A675F;padding:2.5px 0 2.5px 15px;position:relative;
}
.nav-feat-probs i::before{
  content:"\2192";position:absolute;left:0;top:2.5px;
  color:var(--orange-dk);font-size:10.5px;
}

/* ── OWNERSHIP SCAN (/tools/ownership-scan/) ─────────────────
   The .os* layer (2026-09-25): the scan form and the results
   panel the endpoint's checks render into. Status colors reuse
   the delta-chart pair ps-comp established (#2F7D5B / #B3452A)
   plus the tokens. */
.os-tool .form-actions{margin-top:18px}
.os-form-grid{display:grid;grid-template-columns:1.2fr 1fr 1fr;gap:14px}
@media (max-width:860px){.os-form-grid{grid-template-columns:1fr}}

.os-res{margin-top:clamp(28px,3.2vw,44px)}
.os-wait{font-family:var(--mono);font-size:12.5px;letter-spacing:.04em;opacity:.75}
.os-res-h{padding:0 0 14px;border-bottom:1px solid var(--line-dark);margin:0 0 6px}
.os-res-h--mid{margin-top:34px}
.os-res-h b{display:block;font-size:clamp(18px,1.7vw,24px);font-weight:800;letter-spacing:-.01em}
.os-res-h span{display:block;margin-top:6px;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.08em;text-transform:uppercase;opacity:.6;line-height:1.7}
.os-row{display:grid;grid-template-columns:118px 1fr;gap:16px;align-items:start;
  padding:16px 0;border-bottom:1px dashed rgba(246,238,228,.16)}
.os-pill{justify-self:start;font-family:var(--mono);font-weight:700;font-size:9.5px;
  letter-spacing:.12em;text-transform:uppercase;padding:4px 9px;border-radius:3px;
  border:1px solid var(--line-dark);opacity:.9;white-space:nowrap;margin-top:2px}
.os-row--ok .os-pill{color:#7FB89B;border-color:rgba(127,184,155,.4)}
.os-row--flag .os-pill{color:var(--orange);border-color:rgba(241,107,43,.5)}
.os-row--info .os-pill{color:var(--cream-hi);border-color:var(--line-dark)}
.os-row--unknown .os-pill{color:var(--cream-hi);opacity:.5}
.os-row--checklist .os-pill{background:var(--orange);color:#14100E;border-color:var(--orange)}
.os-row-body b{display:block;font-size:15px;font-weight:700;letter-spacing:-.01em}
.os-row-body i{display:block;font-style:normal;font-family:var(--mono);font-size:11.5px;
  letter-spacing:.03em;color:var(--orange);margin:4px 0 6px;overflow-wrap:anywhere}
.os-row--ok .os-row-body i{color:#7FB89B}
.os-row--unknown .os-row-body i{color:var(--cream-hi);opacity:.6}
.os-row-body p{margin:0;font-size:13px;line-height:1.6;opacity:.72;max-width:62ch}
.os-check-link{display:inline-flex;align-items:center;gap:8px;margin-top:10px;
  font-family:var(--mono);font-weight:700;font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--orange);text-decoration:none}
.os-check-link:hover{text-decoration:underline;text-underline-offset:4px}
@media (max-width:620px){.os-row{grid-template-columns:1fr;gap:8px}}

/* ── Case study rail artifact ──────────────────────────────────────────────
   The thing a figure counts, shown beside the figure. Nicolock's catalog sits
   under "Catalog downloads". The frame's aspect-ratio comes from the source
   file via --cs-art-ar, so object-fit never crops a ratio it was not built for. */
.cs-art{margin:26px 0 0}
.cs-art img{display:block;width:100%;height:auto;aspect-ratio:var(--cs-art-ar,600/510);
  object-fit:cover;border:1px solid var(--line-cream);border-radius:3px}
.cs-art figcaption{font:500 12px/1.55 var(--mono);letter-spacing:.03em;opacity:.52;
  margin:10px 0 0;max-width:42ch}
@media(max-width:899px){.cs-art{max-width:320px}}

/* A sticky rail taller than the space it sticks in can never be fully read: its
   bottom stays below the fold at every scroll position. site.js measures and adds
   this class, so the column falls back to normal flow and scrolls with the page.
   No JS means the existing sticky behaviour, which is what shipped before. */
@media(min-width:900px){.cs-rail>aside.cs-aside--flow{position:static}}


/* ═══════════════════════════════════════════════════════════════════════════
   /case-studies/ — the band under the board. "The Receipt", recommended out of
   five CTA options rendered at /_templates/case-studies-cta/ and shipped
   2026-09-25. The board above it is untouched, offer tile included.

   Its whole job is the question the board creates: the reader now believes the
   results and does not know what asking actually costs them. Every line of the
   copy is published verbatim on /growth-audit/ rather than written here, so the
   band and the page it sends people to cannot drift.

   GROUND. The board is ink and the FAQ below is .pain (--cream), so this band
   is --cream-hi. Three different grounds in a row rather than two the same.
   ═══════════════════════════════════════════════════════════════════════════ */
.csr{background:var(--cream-hi);color:var(--ink);padding:var(--pad) 0}
.csr-grid{display:grid;grid-template-columns:.86fr 1.14fr;gap:clamp(30px,4.4vw,72px);align-items:start}
.csr-h{font-size:clamp(28px,3vw,44px);line-height:1.04;letter-spacing:-.028em;margin:0 0 16px;max-width:15ch}
.csr-s{font-size:15.5px;line-height:1.62;opacity:.78;margin:0 0 28px;max-width:44ch}
.csr-fine{font-family:var(--mono);font-size:11.5px;line-height:1.8;letter-spacing:.03em;
  opacity:.56;margin:20px 0 0;max-width:38ch}
.csr-list{list-style:none;counter-reset:r;padding:0;margin:0;border-top:1px solid var(--line-cream)}
.csr-list li{counter-increment:r;border-bottom:1px solid var(--line-cream);
  padding:22px 0 22px 54px;position:relative}
.csr-list li::before{content:"0" counter(r);position:absolute;left:0;top:24px;
  font-family:var(--mono);font-weight:700;font-size:12px;letter-spacing:.12em;color:var(--orange)}
.csr-list b{display:block;font-size:18px;letter-spacing:-.016em;margin-bottom:7px}
.csr-list span{display:block;font-size:14.5px;line-height:1.62;opacity:.72;max-width:58ch}
@media (max-width:900px){
  .csr-grid{grid-template-columns:1fr}
  .csr-fine{max-width:52ch}
}

/* ── TRAITS GRID ─────────────────────────────────────────────
   /careers/ "who this is for". Composition only: the 1px-gap-
   over-a-line-coloured-ground is .steps' pattern from v1, the
   heading step is .tile h3's, the body step is .evo-col p's,
   and the mono index is .step-n. No new colour, size or easing.
   Scoped on .pain because b_traits renders .pain for cream and
   .caps for ink, same as every other block. */
.tr-grid{
  display:grid;grid-template-columns:repeat(3,1fr);gap:1px;
  background:var(--line-dark);border:1px solid var(--line-dark);
  margin-top:clamp(34px,4vw,54px);
}
.pain .tr-grid{background:var(--line-cream);border-color:var(--line-cream)}
.tr-cell{background:var(--ink);padding:26px 24px 30px}
.pain .tr-cell{background:var(--cream)}
.tr-n{
  margin:0;font-family:var(--mono);font-weight:700;font-size:10.5px;
  letter-spacing:.18em;color:var(--orange);
}
.tr-cell h3{
  margin:16px 0 0;font-size:clamp(17px,1.5vw,20px);line-height:1.18;
  letter-spacing:-.014em;color:var(--cream-hi);
}
.pain .tr-cell h3{color:var(--ink)}
/* Direct child: a descendant `p` would also catch a nested placeholder span's
   wrapper if one is ever dropped in here. Same trap as .stat span. */
.tr-cell>p:not(.tr-n){margin:12px 0 0;color:var(--on-dark);font-size:15px;line-height:1.55}
.pain .tr-cell>p:not(.tr-n){color:#4A4842}
@media(max-width:1000px){.tr-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.tr-grid{grid-template-columns:1fr}}
