/* ═══════════════════════════════════════════════════════════════════
   SCALE AND BEYOND — v12

   Structure and assets from v11 (Pooja's build): logo lockups, the
   service ticker, the grain, the nav, the headline.
   Design language from Alt 6: oxblood plum committed on violet-leaning
   porcelain, citron reserved entirely for action, Bricolage Grotesque
   over Public Sans.

   Colour is authored in OKLCH. Hex fallbacks are measured from those
   values, never eyeballed. Nothing here is a neutral grey.
   ═══════════════════════════════════════════════════════════════════ */
:root{
  color-scheme:light;
  --paper:      oklch(0.968 0.006 310);
  --paper-2:    oklch(0.928 0.012 312);
  --card:       oklch(0.995 0.003 310);
  --plum:       oklch(0.300 0.115 348);   /* ink: text, borders, the marker */
  --plum-s:     oklch(0.300 0.115 348);   /* surface: the ticker, the close band */
  --plum-deep:  oklch(0.222 0.090 348);
  --plum-lift:  oklch(0.380 0.120 348);
  --citron:     oklch(0.860 0.170 118);
  --citron-dp:  oklch(0.760 0.155 118);
  /* Anything that sits ON citron. Citron is fixed across both themes, so
     its foreground must be fixed too — this token is deliberately NOT
     overridden in the dark block. It was: --ink was used instead, and in
     dark mode that made every primary button 1.32:1. */
  --on-citron:  oklch(0.215 0.045 340);
  --fault:      oklch(0.520 0.205 28);
  --ok:         oklch(0.450 0.095 190);
  --ink:        oklch(0.215 0.045 340);
  --ink-2:      oklch(0.430 0.035 340);
  --ink-3:      oklch(0.520 0.030 340);
  --on-plum:    oklch(0.965 0.012 330);
  --on-plum-2:  oklch(0.815 0.038 330);
  --hair:       oklch(0.215 0.045 340 / .15);
  --hair-2:     oklch(0.215 0.045 340 / .30);
  --hair-plum:  oklch(0.965 0.012 330 / .20);
  --ease:       cubic-bezier(.16,1,.3,1);
  --lift:       0 1px 2px oklch(0.30 0.06 348 / .16), 0 10px 26px oklch(0.30 0.06 348 / .13);
  --tint-r:     oklch(0.940 0.024 20);
  --tint-u:     oklch(0.940 0.026 175);
  --tint-t:     oklch(0.940 0.032 92);
  --amber:      oklch(0.430 0.100 70);
  --wrap:1240px;
  --r:6px;
}

/* ═══════════════════════════════════════════════════════════════════
   DARK

   Not a filter over the light theme — the two are authored separately
   and each was measured on its own. The plum inverts in role rather
   than in value: it stays a rich SURFACE for the ticker and the close
   band, and becomes a light rose as INK, because a 0.30-lightness text
   colour on a 0.17 ground is unreadable however handsome it looks.

   Citron does not move. It means "act" in both themes, and an action
   colour that changes with the lights is not a system.
   ═══════════════════════════════════════════════════════════════════ */
:root[data-theme="dark"]{
  color-scheme:dark;
  --paper:      oklch(0.178 0.026 340);
  --paper-2:    oklch(0.228 0.032 342);
  --card:       oklch(0.258 0.034 342);
  --plum:       oklch(0.790 0.095 350);
  --plum-s:     oklch(0.310 0.110 348);
  --plum-deep:  oklch(0.140 0.026 340);
  --plum-lift:  oklch(0.400 0.110 348);
  --citron:     oklch(0.860 0.170 118);
  --citron-dp:  oklch(0.700 0.140 118);
  --fault:      oklch(0.760 0.150 32);
  --ok:         oklch(0.780 0.105 180);
  --amber:      oklch(0.830 0.130 85);
  --ink:        oklch(0.960 0.008 330);
  --ink-2:      oklch(0.800 0.020 332);
  --ink-3:      oklch(0.690 0.020 332);
  --on-plum:    oklch(0.965 0.012 330);
  --on-plum-2:  oklch(0.830 0.032 330);
  --tint-r:     oklch(0.278 0.042 20);
  --tint-u:     oklch(0.278 0.040 175);
  --tint-t:     oklch(0.278 0.044 92);
  --hair:       oklch(0.960 0.008 330 / .16);
  --hair-2:     oklch(0.960 0.008 330 / .32);
  --hair-plum:  oklch(0.960 0.008 330 / .22);
  --lift:       0 1px 2px oklch(0.08 0.02 340 / .5), 0 10px 26px oklch(0.06 0.02 340 / .55);
}
@supports not (color: oklch(0 0 0)){
  /* measured from the OKLCH above */
  :root[data-theme="dark"]{
    --paper:#190d15;--paper-2:#271621;--card:#2f1d28;
    --plum:#eaa2c3;--plum-s:#550f3a;--plum-deep:#10050c;--plum-lift:#742253;
    --citron:#c8df4c;--citron-dp:#9cb333;--fault:#ff8c76;--ok:#60cdba;--amber:#eec05b;
    --ink:#f5f0f4;--ink-2:#c6b9c3;--ink-3:#a397a1;
    --on-plum:#f8f1f7;--on-plum-2:#d4c0d1;
    --tint-r:#3b2020;--tint-u:#0f2f27;--tint-t:#30280c;
    --hair:rgba(245,240,244,.16);--hair-2:rgba(245,240,244,.32);--hair-plum:rgba(245,240,244,.22);
    --lift:0 1px 2px rgba(10,4,8,.5),0 10px 26px rgba(8,3,6,.55)}
}
@supports not (color: oklch(0 0 0)){
  :root{--paper:#f6f3f7;--paper-2:#eae5ed;--card:#fdfcfe;
        --plum:#530838;--plum-deep:#360122;--plum-lift:#6f1a4c;
        --citron:#c8df4c;--citron-dp:#a9be39;--fault:#c31214;--ok:#00635f;--amber:#724400;
        --ink:#271020;--ink-2:#5d4856;--ink-3:#746070;--on-citron:#271020;
        --on-plum:#f8f1f7;--on-plum-2:#d1bace;
        --hair:rgba(39,16,32,.15);--hair-2:rgba(39,16,32,.30);--hair-plum:rgba(248,241,247,.2)}
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  .mtrack{animation:none!important}
  .pane{opacity:1!important}
}
body{background:var(--paper);color:var(--ink);
     font-family:'Public Sans',system-ui,-apple-system,sans-serif;
     font-size:17px;line-height:1.62;-webkit-font-smoothing:antialiased;
     /* clip, not hidden. overflow-x:hidden on body forces overflow-y to a
        scroll container, which is the classic way position:sticky quietly
        stops working — and this page has a sticky nav with an absolutely
        positioned panel hanging off it. overflow:clip gives the same
        protection against sideways scroll without creating that container. */
     overflow-x:clip}
img,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
:focus-visible{outline:3px solid var(--plum);outline-offset:3px;border-radius:3px}
.dark :focus-visible,.plum-region :focus-visible{outline-color:var(--citron)}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 clamp(18px,4vw,44px)}
.skip{position:absolute;left:-9999px;top:0;background:var(--plum-s);color:var(--on-plum);
      padding:12px 18px;font-weight:700;z-index:99}
.skip:focus{left:12px;top:12px}
.ar{display:inline-block;transition:transform .28s var(--ease)}
a:hover .ar,button:hover .ar,a:focus-visible .ar,button:focus-visible .ar{transform:translateX(4px)}

/* display voice, and the utility label */
.dsp{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.035em;line-height:1.03}
.ut{font-size:11.5px;font-weight:700;letter-spacing:.15em;text-transform:uppercase;color:var(--ink-2)}

/* v11's grain overlay is not carried over. A px-tiled hairline field is
   a recognisable generated-UI signature and it was fighting the serif-
   free reading sizes. The porcelain ground carries the warmth on its
   own; the element stays in the markup so it can be restored in one
   rule if Pooja wants it back. */
.grain{display:none}
.prog{position:fixed;top:0;left:0;right:0;height:3px;z-index:60;background:transparent}
.prog i{display:block;height:100%;width:100%;background:var(--plum);
        transform:scaleX(0);transform-origin:left}

/* ════════ NAV ════════════════════════════════════════════════════ */
/* Opaque, and no backdrop-filter. A blurred backdrop on a sticky element
   re-rasterises the full width of whatever is behind it on every scroll
   frame — the single most expensive paint on the page. It was buying an 8%
   see-through of two colours that differ by under 3 CIE units. */
.nav{position:sticky;top:0;z-index:40;background:var(--paper);
     border-bottom:1px solid var(--hair)}
:root[data-theme="dark"] .nav{background:var(--paper)}
/* ── NAV ────────────────────────────────────────────────────────
   Logo, links, one action. Links sit left, immediately after the
   mark, and the action is pushed right by auto margin — never
   "centred", because the logo and the button are different widths
   and anything centred between them reads as misaligned.

   The mobile CTA lives inside .links and is hidden on desktop by
   `.links .btn` (0,2,0), which beats the base `.btn` rule (0,1,0).
   The earlier `.m-only` version lost that fight and both actions
   rendered at once. That was the duplicate CTA.
   ─────────────────────────────────────────────────────────────── */
.nav-in{display:flex;align-items:center;gap:clamp(14px,2.2vw,30px);min-height:64px;padding:0}
/* 44px hit area around a 28px lockup: the logo is the primary way back
   to the homepage and was a 28px target on a phone. */
.brand{display:flex;align-items:center;flex:none;line-height:0;min-height:44px}
.brand img{height:28px;width:auto}

/* Light/dark lockup swap. Written as img.on-* (0,1,1) rather than .on-*
   (0,1,0) on purpose: a bare class here loses to any element+class rule
   like `.brand img`, and when it lost, both wordmarks rendered side by
   side in the nav. Keep the element in the selector. */
img.on-dark{display:none}
img.on-light{display:block}
:root[data-theme="dark"] img.on-light{display:none}
:root[data-theme="dark"] img.on-dark{display:block}

.links{display:none;align-items:center;gap:2px}
@media(min-width:1020px){.links{display:flex}}
/* > and .nav-svc > a : TOP-LEVEL items only. A descendant combinator here
   reaches into the services panel and styles every entry as a nav pill. */
.links > a:not(.btn),.links .nav-svc > a{display:inline-flex;align-items:center;height:38px;padding:0 12px;
      font-size:14.5px;font-weight:600;letter-spacing:-.005em;white-space:nowrap;
      border-radius:var(--r);color:var(--ink-2);
      transition:color .2s var(--ease),background .2s var(--ease)}
.links > a:not(.btn):hover,.links > a:not(.btn):focus-visible,
.links .nav-svc > a:hover,.links .nav-svc > a:focus-visible{color:var(--ink);background:var(--paper-2)}

.nav-act{display:flex;align-items:center;gap:10px;flex:none;margin-left:auto}

/* the in-menu action: full width on mobile, gone on desktop */
.links .btn{display:flex;justify-content:center;width:100%;margin-top:14px}
@media(min-width:1020px){.links .btn{display:none}}

.btn{display:inline-flex;align-items:center;gap:9px;min-height:50px;padding:14px 24px;border-radius:var(--r);
     font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:700;font-size:16px;
     letter-spacing:-.015em;background:var(--citron);color:var(--on-citron);border:0;cursor:pointer;
     box-shadow:0 3px 0 var(--citron-dp);
     transition:transform .16s var(--ease),box-shadow .16s var(--ease)}
.btn:hover,.btn:focus-visible{transform:translateY(-3px);box-shadow:0 6px 0 var(--citron-dp),var(--lift)}
.btn:active{transform:translateY(0);box-shadow:0 1px 0 var(--citron-dp)}
.btn.line{background:transparent;color:var(--ink);border:2px solid var(--ink);box-shadow:none}
.btn.line:hover,.btn.line:focus-visible{background:var(--ink);color:var(--paper);box-shadow:none}
:root[data-theme="dark"] .totop{background:var(--ink);color:var(--paper)}
.btn.sm{min-height:44px;padding:0 18px;font-size:14.5px;box-shadow:0 2px 0 var(--citron-dp)}
.nav-act .btn{display:none}
@media(min-width:1020px){.nav-act .btn{display:inline-flex}}
.btn.full{width:100%;justify-content:center;margin-top:20px}

.burger{display:flex;flex-direction:column;justify-content:center;gap:4px;
        width:44px;height:44px;padding:0 12px;border-radius:var(--r);
        background:none;border:2px solid var(--ink);cursor:pointer;flex:none}
.burger i{display:block;width:100%;height:2px;background:var(--ink);border-radius:2px;
          transition:transform .3s var(--ease),opacity .2s var(--ease)}
.burger[aria-expanded="true"] i:nth-child(1){transform:translateY(6px) rotate(45deg)}
.burger[aria-expanded="true"] i:nth-child(2){opacity:0}
.burger[aria-expanded="true"] i:nth-child(3){transform:translateY(-6px) rotate(-45deg)}
@media(min-width:1020px){.burger{display:none}}
.links[data-open="true"]{display:flex;position:fixed;inset:64px 0 auto 0;flex-direction:column;
      align-items:stretch;background:var(--paper);padding:12px 18px 24px;
      border-bottom:1px solid var(--hair);z-index:39;box-shadow:var(--lift)}
.links[data-open="true"] > a:not(.btn),.links[data-open="true"] .nav-svc > a{
      font-size:17px;height:auto;padding:14px 12px;min-height:50px;width:100%}

/* ════════ HERO ═══════════════════════════════════════════════════ */
/* Vertical rhythm is clamped against vh as well as vw. Width-only clamps
   sized this hero for a 27" monitor and cropped it on a 13" laptop, where
   the CSS width is similar but the height is 300px shorter. */
.hero{position:relative;z-index:2}
.hero-l{min-width:0}
.hero-in{display:grid;gap:clamp(22px,3vh,40px) clamp(34px,4.6vw,66px);align-items:start}
/* Three children in a two-column grid: .hero-l, .panel, .pills. Auto
   placement put the pills in row 2 / column 1 — under the left column AND
   under the panel, leaving a dead band across the middle of the hero.
   They are placed explicitly instead. The panel spans both rows; the left
   block hugs the bottom of row 1 and the pills the top of row 2, so any
   extra height the panel forces is split above and below the pair rather
   than opening a gap between them. DOM order is untouched, which is what
   keeps the pills below the questions on mobile. */
@media(min-width:1000px){
  .hero-in{grid-template-columns:minmax(0,1.06fr) minmax(0,.94fr);
           grid-template-rows:auto auto;align-items:center}
  .hero-l{grid-column:1;grid-row:1;align-self:end}
  .hero-in .pills{grid-column:1;grid-row:2;align-self:start;margin-top:0}
  .panel {grid-column:2;grid-row:1/span 2;align-self:center}
}
/* Sized so "Scale isn't bought." holds on ONE line in this column. It was
   wrapping, which turned a two-line headline into three and pushed the
   whole hero past the fold on a 728px laptop viewport. Capped against vh
   as well as vw so a short window shrinks it rather than cropping it. */
/* Display leading. Without this an h1 inherits body line-height (1.62),
   which at 58px is 94px a line — and once the spans became blocks that
   showed up as a canyon between the two lines of every internal hero. */
h1{font-size:clamp(30px,min(4.7vw,6.4vh),58px);text-wrap:balance;
   font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
   letter-spacing:-.035em;line-height:1.04}
/* nowrap belongs ONLY to the heroes, because those h1s carry explicit
   <span> blocks that set the line breaks by hand. On a bare h1 it means
   the heading cannot break at all — which is what was happening to every
   article title in the Learning Hub: 70-110 characters forced onto one
   unbreakable line, running straight past the column. */
.hero h1,.phead h1{text-wrap:nowrap}
@media(max-width:1000px){h1{font-size:clamp(32px,7.4vw,54px)}
  .hero h1,.phead h1{text-wrap:balance}}
h1 mark{background:var(--citron);color:var(--on-citron);padding:0 .1em;border-radius:3px}
.lede{font-size:clamp(16px,1.75vw,18.5px);color:var(--ink-2);max-width:46ch;
      margin-top:clamp(12px,1.8vh,20px)}

/* Opens the panel. The left column states what we do; this is the
   first thing the visitor reads on the right, and it hands over. */
.hand{font-size:15px;color:var(--ink-2);line-height:1.4;max-width:40ch}
.acts{display:flex;flex-wrap:wrap;gap:11px;margin-top:clamp(16px,2.2vh,24px)}

/* ════════ THE PANEL — replaces itself in place ═══════════════════
   One surface, two states. Choosing a symptom swaps the contents of
   this exact box rather than pointing at a diagram elsewhere. The
   height is driven by content, not animated, so nothing thrashes.
   ═════════════════════════════════════════════════════════════════ */
.panel{position:relative;background:var(--card);border:2px solid var(--ink);border-radius:12px;
       box-shadow:0 4px 0 var(--ink);overflow:hidden;min-height:340px}
/* On a short viewport the panel scrolls inside itself rather than pushing
   the page down. This MUST sit after the base rule: it was above it, and
   @media adds no specificity, so the base overflow:hidden won and the
   panel was height-capped with its overflow clipped and unreachable on
   any laptop window 820px tall or less. */
@media(min-width:1000px) and (max-height:820px){
  .panel{max-height:calc(100vh - 190px);overflow:auto;overscroll-behavior:contain}
}
.pane{padding:clamp(18px,2.4vw,26px);transition:opacity .2s var(--ease)}
.pane[data-on="false"]{display:none}
.pane.out{opacity:0}
.ph{font-size:clamp(19px,2.2vw,26px);margin:5px 0 clamp(12px,1.8vh,18px);max-width:20ch}
.ph mark{background:var(--citron);color:var(--on-citron);padding:0 .1em;border-radius:3px}

.syms{display:flex;flex-direction:column;gap:7px}

/* ONE definition for all five rows. .sym-last used to carry its own copy
   of this box and had drifted: 11px padding against 10, 46px min-height
   against 44, and a line-height on <small> the others never got. That is
   why the last row sat differently from the four above it. Only the two
   genuine differences are declared separately, below. */
.sym,.sym-last{display:block;width:100%;text-align:left;background:var(--paper);
     border:1.5px solid var(--hair-2);border-radius:var(--r);color:var(--ink);
     font:inherit;font-size:15.5px;font-weight:700;letter-spacing:-.015em;
     padding:10px 42px 10px 15px;cursor:pointer;min-height:44px;
     transition:transform .16s var(--ease),border-color .16s var(--ease),background .16s var(--ease)}
.sym:hover,.sym:focus-visible,.sym-last:hover,.sym-last:focus-visible{
     transform:translateX(4px);border-color:var(--plum);background:var(--card)}
.sym small,.sym-last small{display:block;font-size:13px;font-weight:400;color:var(--ink-2);
     margin-top:2px;letter-spacing:0;line-height:1.4}
.sym-last span{display:block}

.back{display:inline-flex;align-items:center;gap:8px;min-height:44px;background:none;border:0;
      cursor:pointer;font:inherit;font-size:14px;font-weight:700;color:var(--ink-2);padding:0;
      margin-bottom:14px}
.back:hover,.back:focus-visible{color:var(--plum)}
.back .ar{transition:transform .28s var(--ease)}
.back:hover .ar{transform:translateX(-4px)}
.pane .why{color:var(--ink-2);font-size:16px;max-width:52ch}
.fix{margin-top:18px;padding-top:16px;border-top:1px solid var(--hair)}
.fix .ut{color:var(--plum);margin-bottom:6px;display:block}
.fix p{font-size:16px;color:var(--ink);max-width:52ch}
.note{font-size:12.5px;color:var(--ink-3);margin-top:14px;max-width:48ch}

/* ════════ TICKER — v11's, unchanged in behaviour ═════════════════ */
/* Sits directly under the nav now. Plum rather than near-black, so the
   band reads as brand rather than as a rule across the page. */
.marquee{position:relative;z-index:2;display:flex;align-items:stretch;
         background:var(--plum-s);color:var(--on-plum)}

/* The fixed tag. The band was an unlabelled list of words scrolling past —
   handsome, but a visitor had to infer what the list WAS. A static label
   against a moving track is the device news tickers use, and it turns the
   band from decoration into a caption. It does not scroll, so it also gives
   the eye something still to measure the motion against. */
.mq-tag{flex:none;display:inline-flex;align-items:center;padding:0 clamp(14px,2.4vw,22px);
        background:var(--plum-deep);color:var(--on-plum);
        font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
        font-size:11px;letter-spacing:.16em;text-transform:uppercase;
        border-right:1px solid var(--hair-plum)}

/* The moving half. overflow lives here now, not on .marquee, so the tag is
   never clipped. The mask is the actual polish: without it, words guillotine
   at both viewport edges, which is the single thing that makes a marquee read
   as cheap. Constant-width fade rather than a percentage, so it looks the
   same on a phone as on a 27-inch display. */
.mq-view{flex:1;min-width:0;overflow:hidden;
         --fade:clamp(28px,6vw,72px);
         -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 var(--fade),#000 calc(100% - var(--fade)),transparent 100%);
                 mask-image:linear-gradient(90deg,transparent 0,#000 var(--fade),#000 calc(100% - var(--fade)),transparent 100%)}
.mtrack{display:flex;white-space:nowrap;width:max-content;animation:mq 32s linear infinite}
.mtrack span{display:inline-flex;align-items:center;font-family:'Bricolage Grotesque','Public Sans',sans-serif;
              font-size:12.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;padding:12px 0}
/* Separator was a 5px citron dot repeated twenty times on screen. Citron is
   the action colour — it means "this is clickable" everywhere else on the
   site — and this was the only place it was spent decoratively. A hairline
   rule separates just as well, reads quieter, and gives the colour back. */
.mtrack span::after{content:"";width:1.5px;height:12px;border-radius:1px;
                     background:var(--on-plum);opacity:.32;margin:0 clamp(20px,2.6vw,30px)}
@keyframes mq{from{transform:translateX(0)}to{transform:translateX(-50%)}}
.marquee.paused .mtrack,.marquee:hover .mtrack,.marquee:focus-within .mtrack{animation-play-state:paused}
@media(max-width:560px){.mq-tag{display:none}}

/* ════════ SECTIONS ═══════════════════════════════════════════════ */
/* ── BACKGROUND RHYTHM ──────────────────────────────────────────
   Colour is front-loaded: the plum ticker at the very top, then the
   page alternates paper / paper-2 the whole way down, and there is
   exactly ONE dark band — the closing call. Three coloured sections
   stacked at the bottom was what made the page feel bottom-heavy.

     ticker      plum
     hero        paper
     numbers     paper-2
     services    paper
     why us      paper-2
     pillars     paper
     founders    paper-2
     close       plum      ← the single dark moment
     footer      plum-deep
   ─────────────────────────────────────────────────────────────── */
.sec{position:relative;z-index:2;padding:clamp(52px,7vw,110px) 0}
.sec.tint{background:var(--paper-2)}
.sec.dark{background:var(--plum-deep);color:var(--on-plum)}
.big{font-size:clamp(28px,4.1vw,50px);max-width:19ch;text-wrap:balance}
/* The scale had a hole: .dsp alone is 1.5em (25.5px) with NO measure, and
   .big is up to 50px capped at 19ch. Every heading on the site was short
   enough for one or the other — except the About mission statement at 116
   characters, which fell to bare .dsp and ran the full 1240px container
   while the grid beneath it stayed constrained. That mismatch is what read
   as bad alignment. .mid is the step between: a real display size with a
   measure long copy can actually live in. */
.mid{font-size:clamp(23px,2.9vw,34px);max-width:34ch;text-wrap:balance}
.say{font-size:clamp(16px,1.7vw,18.5px);color:var(--ink-2);max-width:60ch;margin-top:18px}
.sec.dark .say{color:var(--on-plum-2)}
.head{display:grid;gap:14px clamp(34px,5vw,66px);align-items:end;margin-bottom:clamp(28px,3.6vw,46px)}
@media(min-width:940px){.head{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr)}}

/* ── the numbers band, from Pooja's template ─────────────────────
   Four cells, hairline separators, one rule around the whole thing.
   Sits where the ticker used to, so the top of the page reads:
   brand band → the promise and the question → the proof. */
.numbers{position:relative;z-index:2;background:var(--paper-2);
         padding:clamp(34px,4.4vw,64px) 0}
.nums{display:grid;gap:1px;background:var(--hair);
      border:1px solid var(--hair);border-radius:var(--r);overflow:hidden}
@media(min-width:600px){.nums{grid-template-columns:repeat(2,1fr)}}
@media(min-width:980px){.nums{grid-template-columns:repeat(4,1fr)}}
/* Top-aligned, with the link pinned to the bottom. Three of these four
   cells carry a "By vertical -->" line and the fourth does not, so
   justify-content:center placed that one's figure lower than its
   neighbours. Aligning from the top puts all four figures on one line
   whatever each cell contains. */
.n{background:var(--card);padding:clamp(24px,3vw,34px) clamp(16px,2vw,24px);text-align:center;
   display:flex;flex-direction:column;gap:8px;align-items:center;justify-content:flex-start}
a.n .go-n{margin-top:auto;padding-top:10px}
/* The whole cell is the target, not just the label — 4 large hit areas
   rather than 4 small links. Colour does not change on hover because
   citron means "act" and these are navigation, not the CTA. */
a.n{text-decoration:none;transition:background .2s var(--ease),transform .2s var(--ease)}
a.n:hover,a.n:focus-visible{background:var(--paper-2);transform:translateY(-2px)}
a.n .go-n{font-size:11.5px;font-weight:700;letter-spacing:.08em;color:var(--plum);
     opacity:0;transform:translateY(-3px);transition:opacity .2s var(--ease),transform .2s var(--ease)}
a.n:hover .go-n,a.n:focus-visible .go-n{opacity:1;transform:none}
/* gap:0, not .14em. Every text run inside this inline-flex becomes its own
   flex item, so the gap was not separating figure from suffix — it was
   splitting the figure itself: "$ 12 M+" instead of "$12M+". The suffix
   gets its own margin, which is the only place the space was wanted. */
.n b{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     font-size:clamp(30px,3.6vw,42px);letter-spacing:-.035em;line-height:1;color:var(--plum);
     display:inline-flex;align-items:baseline;gap:0}
.n b i{font-style:normal;font-size:.42em;font-weight:700;letter-spacing:0;color:var(--ink-2);
     margin-left:.16em}
/* Direct child only. `.n span` (0,1,1) also matched .num (0,1,0) inside
   the <b>, so every figure in this band rendered at 15px label size
   while the characters beside it rendered at 42px. */
.n > span{font-size:15px;color:var(--ink-2);line-height:1.45;max-width:26ch}

/* ── services: outlined cards, deliberate stagger ───────────────── */
.cards{display:grid;gap:14px}
@media(min-width:680px){.cards{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1060px){.cards{grid-template-columns:repeat(4,1fr)}}
/* The 20px/10px stagger that used to live here has gone. It read as a
   misalignment rather than as rhythm, and it also broke the one thing a
   card grid is for: scanning eight things against each other. */
.card{border:2px solid var(--plum);border-radius:14px;padding:clamp(20px,2.3vw,26px);
      background:var(--card);display:flex;flex-direction:column;gap:8px;
      transition:box-shadow .2s var(--ease)}
/* c1/c2/c3 used to rotate the border through --plum, --ok and --fault.
   Those last two are the SUCCESS and ERROR tokens: eight service cards
   were being outlined in green and red, which reads as status, not
   decoration. All eight now share one border and take plum on hover,
   matching the rows on the services index. The classes stay in the
   markup so nothing has to be re-tagged. */
.card .ut{color:var(--plum)}
.card h3,.card h2.card-h{font-size:clamp(18px,1.9vw,21px);letter-spacing:-.028em;line-height:1.15}
.card p{font-size:14.5px;color:var(--ink-2);line-height:1.5}
/* ── clients by vertical: a plain list, not cards. Redesigned 28 Aug —
   no box, no description. The vertical name sits above its brands on
   mobile and beside them from 860px up, where a fixed-width label
   column leaves the pills to wrap freely in the remaining space. */
.brand-list{margin-top:clamp(24px,3vw,38px);border-top:1.5px solid var(--hair)}
.brand-row{display:flex;flex-wrap:wrap;align-items:baseline;
     gap:10px clamp(20px,3vw,40px);padding:clamp(20px,2.6vw,28px) 0;
     border-bottom:1.5px solid var(--hair)}
.brand-row h2{flex:0 0 auto;width:100%;font-size:clamp(18px,1.9vw,21px);
     letter-spacing:-.028em;line-height:1.15;color:var(--ink)}
.brand-chips{display:flex;flex-wrap:wrap;gap:8px;flex:1 1 100%}
.brand-chips span{display:inline-flex;align-items:center;min-height:38px;padding:0 15px;
     border:1.5px solid var(--hair-2);border-radius:100px;background:var(--card);
     font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:700;
     font-size:14px;letter-spacing:-.01em;color:var(--ink-2);white-space:nowrap}
@media(min-width:860px){
  .brand-row{flex-wrap:nowrap;align-items:center}
  .brand-row h2{flex:0 0 250px;width:auto}
  .brand-chips{flex:1 1 auto}
}

/* ── why us ─────────────────────────────────────────────────────── */
.whys{display:grid;gap:1px;background:var(--hair);border:1px solid var(--hair)}
@media(min-width:820px){.whys{grid-template-columns:repeat(2,1fr)}}
.w{background:var(--paper-2)}

/* ── three pillars ──────────────────────────────────────────────── */
.pillars{display:grid;gap:14px}
@media(min-width:960px){.pillars{grid-template-columns:repeat(3,1fr)}}
.pil{border-radius:14px;padding:clamp(22px,2.6vw,30px);display:flex;flex-direction:column;gap:12px}
/* One lightness, low chroma, so the three read as a set rather than
   three unrelated colours. Hue still carries the meaning. */
.pil.r{background:var(--tint-r)}
.pil.u{background:var(--tint-u)}
.pil.t{background:var(--tint-t)}
.pil.r .ut,.pil.r h3{color:var(--plum)}
.pil.u .ut,.pil.u h3{color:var(--ok)}
.pil.t .ut,.pil.t h3{color:var(--amber)}
.pil h3{font-size:clamp(21px,2.4vw,27px);letter-spacing:-.03em;line-height:1.1}
.pil .d{font-size:15px;color:var(--ink-2)}
.pil ul{list-style:none;display:flex;flex-direction:column;gap:1px;margin-top:2px}
.pil li{border-top:1px solid var(--hair)}
.pil li a{display:block;padding:11px 0;font-size:15px;font-weight:700;color:var(--ink);min-height:44px}
.pil li a:hover,.pil li a:focus-visible{text-decoration:underline;text-underline-offset:3px}
.pil li em{display:block;font-style:normal;font-size:13px;font-weight:400;color:var(--ink-2);margin-top:2px}
.pil .go{margin-top:auto;padding-top:8px;font-weight:800;font-size:15px;display:inline-flex;
         align-items:center;gap:8px;min-height:44px;
         font-family:'Bricolage Grotesque','Public Sans',sans-serif;letter-spacing:-.015em}

/* ── founders ───────────────────────────────────────────────────── */
.who{display:grid;gap:24px;margin-top:clamp(26px,3.4vw,42px)}
@media(min-width:780px){.who{grid-template-columns:1fr 1fr;gap:38px}}
.wc{border-top:1px solid var(--hair-2);padding-top:16px}
/* Small on the homepage — this is the summary, the About page is where the
   portraits carry weight. */
.wc .shot{display:block;width:82px;height:82px;border-radius:10px;object-fit:cover;
          margin-bottom:14px;background:var(--paper-2)}
.wc b{font-size:19px;font-weight:800;letter-spacing:-.024em;display:block;
      font-family:'Bricolage Grotesque','Public Sans',sans-serif;color:var(--ink)}
.wc .r{font-size:13.5px;color:var(--ink-3);display:block;margin-bottom:10px}
.wc p{font-size:15.5px;color:var(--ink-2);max-width:44ch}

/* ── close ──────────────────────────────────────────────────────── */
.close{position:relative;z-index:2;background:var(--plum-s);color:var(--on-plum);
        padding:clamp(46px,5.4vw,76px) 0 clamp(46px,5.4vw,72px)}
.close .acts{align-items:center}
.copy-em{display:inline-flex;align-items:center;min-height:50px;padding:13px 18px;border-radius:var(--r);
         background:none;border:1.5px solid var(--hair-plum);color:var(--on-plum);
         font:inherit;font-size:15px;font-weight:600;cursor:pointer;
         transition:border-color .2s var(--ease)}
.copy-em:hover,.copy-em:focus-visible{border-color:var(--citron)}

/* ── footer ─────────────────────────────────────────────────────── */
/* Footer sits on the SAME plum as the ticker, not the deeper one.
   Pooja on the call: "below, just change the colour of it — the footer
   and this one." Top and bottom of the page now close on one value. */
footer{position:relative;z-index:2;background:var(--plum-deep);color:var(--on-plum-2);
        padding:clamp(40px,4.4vw,60px) 0 clamp(24px,2.6vw,34px);font-size:14.5px;
        border-top:1px solid var(--hair-plum)}
footer img.on-light{display:none}
footer img.on-dark{display:block}
@media(min-width:780px){.foot-grid{grid-template-columns:1.5fr 1fr 1fr}}
.lede-f{margin-top:12px;max-width:40ch}
/* footer .ut (0,1,1) not footer h4 (0,0,2): the column headings carry
   .ut, whose --ink-2 beat the bare element selector and rendered them
   at 1.7:1 on the plum ground. "The firm" and "Free to use" were
   invisible in both themes. */
footer h4,footer .ut{color:var(--on-plum);margin-bottom:12px}
footer a{min-height:32px;display:inline-flex;align-items:center}
footer a:hover,footer a:focus-visible{color:var(--citron)}

/* ── back to top ────────────────────────────────────────────────── */
.totop{position:fixed;right:20px;bottom:20px;z-index:50;width:48px;height:48px;border-radius:50%;
       background:var(--ink);color:var(--paper);border:0;cursor:pointer;display:grid;place-items:center;
       opacity:0;pointer-events:none;transform:translateY(8px);
       transition:opacity .25s var(--ease),transform .25s var(--ease)}
.totop.show{opacity:1;pointer-events:auto;transform:none}
.totop svg{width:19px;height:19px}

/* ═══════════════════════════════════════════════════════════════════
   DELIGHT LAYER

   THESIS: the page behaves like someone reading your account with you
   and marking what's actually wrong. That is one idea carried on three
   surfaces — the citron marker on "built", the highlighter that appears
   under a symptom on hover, and the cursor itself, which becomes that
   same marker over anything you can act on.

   ONE authored moment: the hero. Everything else is feedback. There are
   no scroll reveals — a page where every section performs its entrance
   reads as a template, not as arrival.
   ═══════════════════════════════════════════════════════════════════ */

/* ── the hero entrance ────────────────────────────────────────────
   Lines rise from behind their own baseline, then the marker sweeps
   across "built" left-to-right, the way you'd actually draw it. */
.rise{overflow:hidden}
/* The clip box has to sit BELOW the baseline or it cuts descenders: at
   line-height 1.04 the line box is shorter than the glyphs, so "bought"
   lost the tail of its g. Padding extends the box, the negative margin
   takes the space back, and the entrance travel goes to 124% so nothing
   peeks into the new area before it lands. */
.rise span{display:block;overflow:hidden;padding-bottom:.16em;margin-bottom:-.16em}
/* Keyframes, not a class the script has to land.
   The transition version held the headline at translateY(124%) — off its own
   clip box, invisible — until site.js had downloaded, parsed and run, which
   measured 390ms against an HTML response that finished at 207ms. A CSS
   animation starts the moment the element paints, so the words arrive with
   the page and arrive at all if the script never does. */
.js .rise span > b{display:block;font-weight:inherit;
                   animation:rise-up .52s var(--ease) both}
.js .rise span:nth-child(2) > b{animation-delay:.07s}
@keyframes rise-up{from{transform:translateY(124%)}to{transform:translateY(0)}}

/* the marker draws itself after the words land.
   The text stays --ink until the bar is actually behind it. In light that
   changes nothing (--ink and --on-citron are the same value); in dark it is
   the difference between 16.81:1 and 1.06:1 for the 620ms before the sweep
   starts — and for good if .in never lands. Never leave a word depending on
   an animation to become readable. */
.js h1 mark{background:transparent;position:relative;padding:0 .1em;
            animation:mark-ink .42s var(--ease) .34s both}
.js h1 mark::before{content:"";position:absolute;inset:0;background:var(--citron);
                    border-radius:3px;z-index:-1;transform-origin:left;
                    animation:mark-draw .42s var(--ease) .34s both}
@keyframes mark-draw{from{transform:scaleX(0)}to{transform:scaleX(1)}}
/* both fill mode holds --ink before the bar exists, so the word is never
   dark-on-dark waiting for its own highlight. */
@keyframes mark-ink{from{color:var(--ink)}to{color:var(--on-citron)}}

.js .rise-2,.js .rise-3,.js .rise-4{animation:rise-fade .42s var(--ease) both}
.js .rise-2{animation-delay:.16s}
.js .rise-3{animation-delay:.24s}
.js .rise-4{animation-delay:.12s}
@keyframes rise-fade{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}

/* ── feedback, everywhere ─────────────────────────────────────── */
/* nav: the marker language again, one hairline of citron */
.links > a:not(.btn),.links .nav-svc > a{position:relative}
.links > a:not(.btn)::after,.links .nav-svc > a::after{content:"";position:absolute;left:12px;right:12px;bottom:5px;height:2px;
        background:var(--citron);border-radius:2px;transform:scaleX(0);transform-origin:left;
        transition:transform .3s var(--ease)}
.links > a:not(.btn):hover::after,.links > a:not(.btn):focus-visible::after,
.links .nav-svc > a:hover::after,.links .nav-svc > a:focus-visible::after{transform:scaleX(1)}

/* symptom rows: the same highlighter, drawn under the sentence */
.sym{position:relative;overflow:hidden}
/* The affordance problem: four bordered boxes read as a list, not as
   controls. A permanent chevron is the cheapest honest signal — it says
   "this goes somewhere" without shouting. */
.sym::before,.sym-last::before{content:"";position:absolute;right:17px;top:50%;
     width:7px;height:7px;border-right:2px solid var(--ink-3);border-top:2px solid var(--ink-3);
     transform:translateY(-50%) rotate(45deg);
     transition:transform .2s var(--ease),border-color .2s var(--ease)}
.sym:hover::before,.sym:focus-visible::before,.sym-last:hover::before,.sym-last:focus-visible::before{
     border-color:var(--plum);transform:translateY(-50%) translateX(3px) rotate(45deg)}
.pick{font-size:12.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
     color:var(--ink-3);margin:0 0 10px}
.sym::after{content:"";position:absolute;left:15px;bottom:9px;width:calc(100% - 30px);height:2px;
        background:var(--citron);transform:scaleX(0);transform-origin:left;
        transition:transform .38s var(--ease)}
.sym:hover::after,.sym:focus-visible::after{transform:scaleX(1)}

/* service cards: settle, don't bounce */
.card{transition:transform .22s var(--ease),box-shadow .22s var(--ease)}
.card:hover{transform:translateY(-4px);box-shadow:0 6px 0 var(--ink)}
a.card{text-decoration:none;color:inherit}
a.card:focus-visible{outline:3px solid var(--plum);outline-offset:3px}

/* pillar rows: the arrow arrives rather than sitting there */
.pil li a{position:relative;padding-right:22px}
.pil li a::after{content:"→";position:absolute;right:2px;top:11px;opacity:0;
        transform:translateX(-5px);transition:opacity .22s var(--ease),transform .28s var(--ease)}
.pil li a:hover::after,.pil li a:focus-visible::after{opacity:1;transform:translateX(0)}

/* the numbers land, they don't just appear */
.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
.n b{transition:transform .5s var(--ease)}
.n.hit b{transform:scale(1)}
.js .n b{transform:scale(.94)}

/* ── THE CURSOR ───────────────────────────────────────────────────
   A plum ring that eases behind a precise dot. Over anything you can
   act on it fills; over a symptom it flattens into the highlighter.
   Fine pointers only, and the native cursor is only hidden once the
   custom one is actually running — a script that fails must never
   leave a visitor with no pointer at all. */
/* Two elements, two jobs. The outer one only ever carries position and
   is never transitioned, so following the pointer stays exact. The inner
   one carries the shape and IS transitioned — scaled on two axes rather
   than resized, so the morph never touches layout. */
.cur,.cur-dot{position:fixed;top:0;left:0;z-index:90;pointer-events:none;will-change:transform}
.cur{--x:0px;--y:0px;transform:translate(var(--x),var(--y)) translate(-50%,-50%)}
/* Two edges, not a blend. mix-blend-mode:difference inverts against the
   backdrop, which is perfect on paper and on plum but collapses on any
   mid-tone: invert #7c7c7c and you get #838383, a 1.10:1 ring nobody can
   see. A white stroke with a dark halo around it needs no backdrop to
   cooperate — one of the two edges always contrasts, on every ground. */
.cur i{display:block;width:18px;height:18px;border:1.5px solid #fff;border-radius:50%;
       box-shadow:0 0 0 1.5px rgba(18,8,14,.62);
       --sx:1;--sy:1;--p:1;
       transform:scale(calc(var(--sx) * var(--p)),calc(var(--sy) * var(--p)));
       transition:transform .3s var(--ease),border-radius .3s var(--ease),
                  background .22s var(--ease),border-color .22s var(--ease)}
.cur-dot{width:4px;height:4px;border-radius:50%;background:#fff;
     box-shadow:0 0 0 1.5px rgba(18,8,14,.62);
     transform:translate(var(--dx,0px),var(--dy,0px)) translate(-50%,-50%);
     transition:opacity .2s var(--ease)}
html.cursor-on,html.cursor-on *{cursor:none}
/* A modal <dialog> paints in the top layer, above every z-index in normal
   flow — so the custom ring sits *under* the form while cursor:none is
   still hiding the real pointer, and you are left with nothing at all.
   Give the native cursor back: a form wants an I-beam over its inputs
   more than it wants a decorative ring. */
html.lead-open,html.lead-open *{cursor:auto}
html.lead-open .cur,html.lead-open .cur-dot{opacity:0}

/* over something you can act on, the ring fills */
.cur.act i{--sx:1.4;--sy:1.4;background:rgba(255,255,255,.22)}
/* over a symptom, it flattens into the highlighter itself */
/* the highlighter state carries a real brand colour and needs no halo */
.cur.mark i{--sx:2.4;--sy:.5;border-radius:4px;background:var(--citron);
     border-color:var(--citron-dp);box-shadow:none}
.cur.press i{--p:.86}
.cur-dot.hide{opacity:0}
.cur.hidden,.cur-dot.hidden{opacity:0}
.cur{transition:opacity .25s var(--ease)}
@media (hover:none),(pointer:coarse){.cur,.cur-dot{display:none}}
@media (prefers-reduced-motion:reduce){
  .cur,.cur-dot{display:none}
  html.cursor-on,html.cursor-on *{cursor:auto}
  /* animation:none leaves the element at its own declared state, so each of
     these has to be given the finished state explicitly. */
  .js .rise span > b{animation:none;transform:none}
  .js h1 mark::before{animation:none;transform:scaleX(1)}
  .js h1 mark{animation:none;color:var(--on-citron)}
  .js .rise-2,.js .rise-3,.js .rise-4{animation:none;opacity:1;transform:none}
  .js .n b{transform:none!important}
  .js .lead[open] .lead-in{animation:none}
}

/* ── the theme toggle ─────────────────────────────────────────────
   Sits beside the action, same height as the small button. The icon
   shows what you'd get, not what you have — a sun when it's dark. */
.theme{display:grid;place-items:center;width:44px;height:44px;border-radius:var(--r);flex:none;
       background:none;border:1.5px solid var(--hair-2);color:var(--ink);cursor:pointer;
       transition:border-color .2s var(--ease),background .2s var(--ease)}
.theme:hover,.theme:focus-visible{border-color:var(--ink);background:var(--paper-2)}
.theme svg{width:18px;height:18px}
.theme .sun{display:none}
.theme .moon{display:block}
:root[data-theme="dark"] .theme .sun{display:block}
:root[data-theme="dark"] .theme .moon{display:none}

/* ═══════════════════════════════════════════════════════════════════
   INTERIOR PAGES — sections, hubs, and the reading system.
   Same tokens as the homepage; nothing new is invented here, so the
   whole site inverts with one theme attribute.
   ═══════════════════════════════════════════════════════════════════ */

/* ── page head ────────────────────────────────────────────────── */
/* Each span in a hero headline is a line. Without this they ran inline
   with no separating space — "Working papers,not a blog." shipped. */
.hero h1 > span,.phead h1 > span{display:block;line-height:1.04}
/* The crumb row is small type, but the links inside it are still links a
   thumb has to hit. The 44px lives on the anchor, not the row, so the
   separators stay tight against the words. */
.crumb{font-size:13px;color:var(--ink-3);margin-bottom:10px;display:flex;flex-wrap:wrap;
       gap:0 8px;align-items:center}
.crumb a{display:inline-flex;align-items:center;min-height:44px}
.crumb a:hover,.crumb a:focus-visible{color:var(--ink)}
.crumb span{opacity:.55}

/* ── generic section furniture ────────────────────────────────── */
/* one name for one job: .alt-bg was a second class painting the same
   --paper-2 as .sec.tint, which made the alternation impossible to
   read at a glance and hid a repeat on the homepage. */
.lbl{font-size:11.5px;font-weight:700;letter-spacing:.15em;text-transform:uppercase;color:var(--plum)}
/* On a plum surface the label must not be plum ink. In light mode --plum
   and --plum-s are the same value, so .lbl inside .close rendered at
   1.0:1 — invisible. The two-token rule again, this time the other way
   round: ink placed on its own surface. */
/* Was citron. That fixed a real 1.0:1 invisibility, but it paid for it
   with the action colour on a static label — every band on the site
   carried a citron word that could not be clicked. --on-plum-2 is the
   token that exists for exactly this: secondary text on a plum ground. */
.close .lbl,.plum-region .lbl,.sec.dark .lbl{color:var(--on-plum-2)}
.close .say,.close p:not(.lbl):not(.say){color:var(--on-plum-2)}
.intro{font-size:clamp(16px,1.7vw,18.5px);color:var(--ink-2);max-width:60ch;margin-top:16px}
.blocks{display:grid;gap:14px;margin-top:clamp(26px,3.4vw,40px)}
@media(min-width:640px){.blocks{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1000px){.blocks{grid-template-columns:repeat(3,1fr)}
  /* Four cards in a 3-column grid leaves one orphan on its own row, which
     is what the About principles were doing. Four divides by two, not three. */
  .blocks.four{grid-template-columns:repeat(2,1fr)}}
.blk{display:flex;flex-direction:column;gap:8px;padding:clamp(20px,2.4vw,26px);
     background:var(--card);border:2px solid var(--hair-2);border-radius:12px;
     transition:transform .22s var(--ease),box-shadow .22s var(--ease),border-color .22s var(--ease)}
a.blk:hover,a.blk:focus-visible{transform:translateY(-4px);border-color:var(--plum);box-shadow:0 6px 0 var(--hair-2)}
.blk .k{font-size:11.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--plum)}
.blk h3{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;letter-spacing:-.028em;
        font-size:clamp(18px,2vw,21px);line-height:1.18}
.blk p{font-size:14.5px;color:var(--ink-2);line-height:1.5}
.blk .m{margin-top:auto;padding-top:10px;font-size:12.5px;color:var(--ink-3)}
.more{display:inline-flex;align-items:center;gap:8px;min-height:44px;margin-top:24px;
      font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:700;font-size:15.5px;color:var(--ink)}
.more:hover,.more:focus-visible{color:var(--plum)}

/* ── the rule band, reused across pages ───────────────────────── */
.rule-box{margin-top:clamp(30px,4vw,52px);padding:clamp(24px,3.2vw,40px);
          background:var(--plum-s);color:var(--on-plum);border-radius:12px}
.rule-box p:first-child{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
        letter-spacing:-.032em;font-size:clamp(21px,3vw,34px);line-height:1.12;max-width:20ch}
.rule-box .why{color:var(--on-plum-2);max-width:56ch;margin-top:14px;font-size:15.5px}

/* ── hub list (tools, learning index) ─────────────────────────── */
.hub-nav{display:flex;flex-wrap:wrap;gap:8px;margin-top:24px;padding-top:20px;border-top:1px solid var(--hair)}
.hub-cta{margin:clamp(34px,4.4vw,60px) 0;padding:clamp(24px,3.2vw,40px);background:var(--paper-2);
         border-radius:12px;border-top:1px solid var(--hair-2)}
.hub-cta h2{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;letter-spacing:-.03em;
     font-size:clamp(20px,2.4vw,27px);max-width:22ch;margin-bottom:10px}
.hub-cta p{color:var(--ink-2);max-width:56ch;margin-bottom:22px}

/* ── the reading system ───────────────────────────────────────── */
.art{padding:clamp(30px,4.4vw,60px) 0 0}
.art h1{font-size:clamp(28px,3.5vw,44px);max-width:24ch;line-height:1.14;
     text-wrap:balance;letter-spacing:-.028em}
.stand{font-size:clamp(17px,1.9vw,21px);color:var(--ink-2);max-width:60ch;margin-top:20px;line-height:1.6}
/* Byline. Two things were wrong: the name ran at body size (16px) while
   the date ran at 13px, and they were centre-aligned — different sizes
   centred on a shared axis never sit on a common baseline, which is what
   read as misaligned. Everything is now one size, aligned on the
   baseline, and the name is distinguished by weight instead. The long
   credential line gets its own row rather than shoving the date out. */
/* Prefixed .by- because .who is TAKEN: it is the founders grid on the
   About page (display:grid, two columns above 780px). .byline .who only
   set colour and size, so the byline inherited display:grid and split
   "By", the name and ", Co-founder" into three grid cells across two
   columns. Same trap as .n on the services index. */
.byline{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 14px;margin-top:24px;
        padding-top:18px;border-top:1px solid var(--hair)}
.byline .by-who{display:inline;font-size:14.5px;font-weight:400;color:var(--ink-2);line-height:1.5}
.byline .by-who b{font-weight:700;color:var(--ink)}
.byline .by-d{display:inline;font-size:14.5px;color:var(--ink-3);line-height:1.5}
.byline .by-d::before{content:"\00b7";margin-right:14px;color:var(--hair-2)}

.art-grid{display:block;margin-top:clamp(28px,3.6vw,46px)}
@media(min-width:1080px){
  .art-grid{display:grid;grid-template-columns:212px minmax(0,1fr);gap:clamp(32px,4vw,60px);align-items:start}
  .toc{position:sticky;top:96px}
}
.toc{font-size:14px}
.toc summary{cursor:pointer;font-weight:700;padding:12px 0;min-height:44px;display:flex;align-items:center}
/* must come AFTER the base rule above, not inside an earlier media
   block -- @media does not raise specificity */
@media(min-width:1080px){.toc summary{display:none}}
.toc .t{font-size:11px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);
        margin-bottom:11px;display:block}
.toc ol{list-style:none;counter-reset:toc}
.toc li{border-left:2px solid var(--hair)}
.toc li.on{border-left-color:var(--plum)}
.toc li.on a{color:var(--ink);font-weight:700}

.body{max-width:68ch;font-size:19px;line-height:1.74}
.body p{margin-bottom:21px;color:var(--ink-2)}
.body h2{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;letter-spacing:-.03em;
   font-size:clamp(21px,2.6vw,29px);margin:clamp(34px,4vw,50px) 0 15px;color:var(--ink);scroll-margin-top:96px}
.body h3{font-weight:800;font-size:clamp(18px,2vw,21px);color:var(--ink)}
.body strong,.body b{color:var(--ink);font-weight:700}
.body ol,.body ul{margin:0 0 21px 20px;color:var(--ink-2)}
.body li{margin-bottom:10px;padding-left:5px}
/* :not(.btn) because .body a is (0,1,1) and .btn is (0,1,0) — the prose rule
   wins on specificity wherever a button sits inside article body copy, and
   repaints it --ink. That is invisible in light, where --ink and --on-citron
   are the same value, and 1.32:1 on citron in dark. */
.body a:not(.btn){color:var(--ink);text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--hair-2)}
.body a:not(.btn):hover,.body a:not(.btn):focus-visible{text-decoration-color:currentColor}

.tldr{background:var(--paper-2);border-radius:12px;padding:clamp(20px,2.6vw,28px);
      margin:0 0 clamp(28px,3.6vw,40px);border-top:1px solid var(--hair-2)}
.tldr .t{font-size:11px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
         color:var(--plum);margin-bottom:11px;display:block}
.tldr ul{list-style:none;margin:0}
.tldr li{padding:7px 0 7px 17px;position:relative;color:var(--ink);font-size:16px;line-height:1.5}
.tldr li::before{content:"";position:absolute;left:0;top:15px;width:6px;height:6px;
                 border-radius:50%;background:var(--plum)}
.ans{background:var(--card);border:1.5px solid var(--hair);border-radius:10px;padding:17px 19px;
     margin:0 0 21px;font-size:16px;line-height:1.55;color:var(--ink)}
.ans b{display:block;font-size:10.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
       color:var(--ink-3);margin-bottom:6px}
.pull{margin:clamp(26px,3.4vw,40px) 0;font-family:'Bricolage Grotesque','Public Sans',sans-serif;
      font-weight:800;letter-spacing:-.03em;font-size:clamp(19px,2.3vw,25px);color:var(--ink);
      line-height:1.3;max-width:44ch}
/* structural mark on a pull quote, not an action -> plum, not citron */
.pull::before{content:"";display:block;width:54px;height:4px;border-radius:2px;
              background:var(--plum);margin-bottom:17px}
.body table{border-collapse:collapse;width:100%;margin:26px 0 12px;font-size:15px}
.body caption{text-align:left;font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
              color:var(--ink-3);padding-bottom:11px}
.body th,.body td{text-align:left;padding:12px 14px 12px 0;border-bottom:1px solid var(--hair);vertical-align:top}
.body tbody th{font-weight:600;color:var(--ink);width:44%}
/* .y/.n were the original names; .n is the stats-band cell (card
   background, 34px padding, centred) and it was landing on every
   "No" in the platform table. Renamed so the table owns its own. */
.body td.yes{color:var(--ok);font-weight:700}
.body td.no{color:var(--ink-3);font-weight:700}
.body td.n{color:var(--ink-3)}
.tnote{font-size:14px;color:var(--ink-3);max-width:62ch;margin-bottom:21px}
.caveat{background:var(--paper-2);border-radius:12px;padding:clamp(20px,2.8vw,30px);
        margin:clamp(30px,4vw,48px) 0;max-width:68ch}
.caveat h2{margin-top:0;font-size:clamp(18px,2vw,22px)}
.caveat p,.caveat li{font-size:15px;color:var(--ink-2)}
.caveat li{margin-bottom:8px}
/* The article FAQs are marked up as dl/dt/dd for the schema, and had no
   rules at all — they rendered as browser-default definition lists.
   Same visual treatment as .q so both patterns look identical. */
.faq dl{margin:0}
.faq dt{border-top:1px solid var(--hair);padding-top:19px;margin:0 0 8px;
        font-family:'Bricolage Grotesque','Public Sans',sans-serif;
        font-weight:700;font-size:17px;letter-spacing:-.015em;color:var(--ink)}
.faq dd{margin:0 0 19px;color:var(--ink-2);font-size:16px;line-height:1.6;max-width:64ch}
.faq h2{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;letter-spacing:-.03em;font-size:clamp(21px,2.6vw,29px)}
/* The author block was a ROW flex — written for an avatar sitting beside
   a bio. The markup is three blocks (label, name, paragraph), so a row
   laid them out side by side across the column instead of stacking them.
   That is what read as misaligned. It also left the name as an unstyled
   h2, which picked up display leading far too tight for its size. */
.auth{display:flex;flex-direction:column;align-items:stretch;margin-top:clamp(30px,4vw,48px);
      padding-top:24px;border-top:2px solid var(--hair-2);max-width:68ch}
.auth .lbl{margin-bottom:10px}
.auth h2{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
      letter-spacing:-.028em;font-size:clamp(18px,2vw,21px);line-height:1.3;
      margin:0;color:var(--ink)}
.auth p{color:var(--ink-2);font-size:15px;line-height:1.62;margin:8px 0 0}
.auth p a{color:var(--ink);text-decoration:underline;text-underline-offset:3px;
      text-decoration-color:var(--hair-2)}
.end{border-top:1px solid var(--hair);margin-top:clamp(34px,4.4vw,54px);
     padding-top:clamp(24px,3.2vw,38px);max-width:68ch}
.end h2{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
        font-size:clamp(19px,2.2vw,24px);margin-bottom:11px;letter-spacing:-.028em}
.end p{color:var(--ink-2);margin-bottom:22px}
.back-link{display:inline-flex;align-items:center;gap:8px;min-height:44px;font-size:14px;
           font-weight:700;color:var(--ink-3);margin-top:26px}
.back-link:hover,.back-link:focus-visible{color:var(--plum)}
.rel{margin-top:clamp(30px,4vw,48px);padding-top:24px;border-top:1px solid var(--hair);max-width:68ch}

/* ── about ────────────────────────────────────────────────────── */
@media(min-width:760px){.pair{grid-template-columns:1fr 1fr;gap:34px}}
.svc-note a{color:var(--plum);font-weight:700}

/* ── remaining interior components ────────────────────────────── */
/* the argument block: a lifted statement beside its reasoning */
.arg-in{display:grid;gap:18px clamp(30px,4vw,56px);margin-top:clamp(22px,3vw,36px)}
@media(min-width:880px){.arg-in{grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);align-items:start}}
.stmt{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;letter-spacing:-.03em;
      font-size:clamp(20px,2.5vw,28px);line-height:1.16;color:var(--ink);max-width:22ch}
.side p{color:var(--ink-2);font-size:16px;max-width:56ch}
.side p + p{margin-top:14px}

/* founder cards on the About page */
/* Founder portraits. Square, not the old 1.6/1 plate: both photos are
   portrait or square at source, and matching shapes keeps the two blocks
   symmetrical. Capped at 260px because the smaller source is 421px — any
   wider and it stops being a 1.6x image on a retina screen and starts
   looking soft. */
.avatar{aspect-ratio:1/1;max-width:260px;border-radius:12px;background:var(--plum-s);
        position:relative;overflow:hidden;display:flex;align-items:flex-end}
.avatar img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
/* Both photographs have bright, busy backgrounds, so the specialism label
   needs its own ground rather than trusting the image behind it. */
.avatar span{position:relative;z-index:1;width:100%;padding:30px 15px 13px;
             font-weight:700;font-size:13.5px;color:var(--on-plum);
             background:linear-gradient(to top,oklch(0.130 0.024 340 / .90) 30%,transparent)}
/* The second founder gets a deeper ground, not --plum: --plum inverts to a
   light pink in dark mode, where --on-plum on it is 1.81:1. --plum-deep holds
   in both (15.97 light, 18.03 dark). */
.avatar.deep{background:var(--plum-deep)}
/* The role label and the rule between the two founders. Both of these lived in
   inline styles pointing at tokens (--mono, --text-dim, --line) that no longer
   exist; an undefined var makes the whole declaration invalid at computed-value
   time, which silently reset border-top-style to none and deleted the rule. */
.role{font-size:12.5px;text-transform:uppercase;letter-spacing:.05em;
      font-weight:600;color:var(--ink-3);margin-top:6px}
/* The two founder blocks. Previously the first carried its top margin in an
   inline style and the second carried a .founder-split class — two mechanisms
   for one relationship, which is why they sat at different heights and only
   one of them had a rule above it. One wrapper now owns the spacing, and the
   divider is the separator between siblings, which is what it always was. */
.founders{margin-top:clamp(34px,4vw,56px)}
.founders > .arg-in{margin-top:0}
.founders > .arg-in + .arg-in{margin-top:clamp(40px,5vw,64px);
      padding-top:clamp(34px,4vw,50px);border-top:1px solid var(--hair)}
.founders .avatar{margin-bottom:18px}
/* A name is not a statement. It was .stmt with an inline font-size override
   fighting .stmt's own clamp, and a <p>, so neither founder appeared in the
   document outline. */
.fname{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
       letter-spacing:-.03em;font-size:clamp(19px,2.1vw,22px);line-height:1.2;color:var(--ink)}
.badges{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
.badges span{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;font-weight:600;
             color:var(--ink-2);border:1px solid var(--hair-2);border-radius:100px;padding:6px 12px}
.badges span::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--plum)}

/* filed-under chips, and the empty state */
.empty{margin-top:clamp(28px,3.6vw,44px);padding:clamp(22px,3vw,32px);border-radius:12px;
       background:var(--paper-2);color:var(--ink-2);font-size:15.5px;max-width:64ch}
.empty b{color:var(--ink);display:block;margin-bottom:7px;font-weight:700}
.empty h2{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.028em;font-size:clamp(18px,2vw,21px);line-height:1.18;
     margin-bottom:9px;color:var(--ink)}

/* a lead entry sits slightly forward of the rest */
.blk.lead{border-color:var(--plum)}
em.em{font-style:normal}


/* ── the two quiet doors under the hero action ────────────────────
   Outlined, never filled: citron means "act" and these are not the
   action. The tag block borrows the ticker's surface so they read as
   part of the same family rather than as two loose buttons. */
.pills{display:flex;flex-wrap:wrap;gap:9px;margin-top:clamp(18px,2.8vh,30px)}
.pill{display:inline-flex;align-items:center;gap:11px;padding:5px;
      border:1.5px solid var(--hair-2);border-radius:100px;background:var(--card);
      min-height:48px;max-width:100%;
      transition:border-color .2s var(--ease),transform .2s var(--ease),box-shadow .2s var(--ease)}
.pill:hover,.pill:focus-visible{border-color:var(--plum);transform:translateY(-2px);box-shadow:var(--lift)}
.pill .tag{display:inline-flex;align-items:center;flex:none;height:30px;padding:0 11px;border-radius:100px;
      background:transparent;border:1.5px solid var(--hair-2);color:var(--ink-3);
      font-size:11px;font-weight:800;letter-spacing:.13em;text-transform:uppercase}
.pill .pt{font-size:14.5px;font-weight:600;letter-spacing:-.01em;color:var(--ink-2);
      line-height:1.25;padding-right:2px}
.pill .go{display:grid;place-items:center;flex:none;width:36px;height:36px;border-radius:50%;
      background:transparent;color:var(--ink-3);transition:transform .25s var(--ease),color .25s var(--ease)}
.pill .go svg{width:15px;height:15px}
.pill:hover .go,.pill:focus-visible .go{transform:translateX(3px);color:var(--plum)}
@media(max-width:520px){
  .pills{flex-direction:column}
  .pill{width:100%}
  .pill .pt{font-size:15px}
}

/* ── the way out of the picker ────────────────────────────────────
   Reads as an exit, not a sixth symptom: no border, no highlighter,
   and it goes straight to a person. Somebody whose problem isn't on
   the list should not have to pick the closest wrong answer. */
.sym-last{position:relative;overflow:hidden}

/* ═══════════════════════════════════════════════════════════════════
   THE BACKGROUND MARKS

   A hand-placed scatter of the tools of the trade — search, chart,
   cursor, envelope, funnel, target — sitting behind everything at a
   very low opacity. Deliberately NOT a repeating tile: a px-tiled
   field is one of the more recognisable generated-UI signatures.

   One variable controls it. --marks-o is the opacity; turn it to 0
   and the texture is gone without touching anything else.
   ═══════════════════════════════════════════════════════════════════ */
:root{ --marks-o:.055 }
/* Lower in dark, not higher. The mark colour is --plum, which inverts to
   a light rose against a 0.18 ground — the same opacity that reads as a
   whisper in light reads as a competing layer here. */
:root[data-theme="dark"]{ --marks-o:.032 }
.marks-bg{position:fixed;inset:0;z-index:0;pointer-events:none;
     color:var(--plum);opacity:var(--marks-o);
     mask-image:radial-gradient(ellipse 120% 90% at 50% 40%,#000 25%,transparent 82%);
     -webkit-mask-image:radial-gradient(ellipse 120% 90% at 50% 40%,#000 25%,transparent 82%)}
.marks-bg svg{width:100%;height:100%}
/* a section can carry a slightly stronger local scatter */
.marks{position:relative;overflow:hidden}
@media (prefers-reduced-motion:reduce){.marks-bg{opacity:calc(var(--marks-o) * .7)}}

/* ═══════════════════════════════════════════════════════════════════
   WHY US — the one section that reveals, and it uses the brand device
   ═══════════════════════════════════════════════════════════════════ */
.whys{display:grid;gap:1px;background:var(--hair);border:1px solid var(--hair);border-radius:12px;
      overflow:hidden;margin-top:clamp(24px,3vw,38px)}
@media(min-width:820px){.whys{grid-template-columns:repeat(2,1fr)}}
.w{background:var(--paper-2);padding:clamp(22px,2.8vw,34px);position:relative;
   transition:background .28s var(--ease)}
.w:hover{background:var(--card)}
.wn{display:block;font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
    font-size:13px;letter-spacing:.12em;color:var(--plum);margin-bottom:10px;
    opacity:0;transform:translateY(8px);
    transition:opacity .5s var(--ease),transform .5s var(--ease)}
.w h3{font-size:clamp(18px,2vw,22px);letter-spacing:-.028em;line-height:1.22;margin-bottom:10px;max-width:24ch}
/* the highlighter, drawn under the claim rather than faded in */
/* isolation, not decoration: ::before below carries z-index:-1, and a
   position:relative parent with z-index:auto does NOT create a stacking
   context. The marker was escaping to .sec and being painted over by
   .w's opaque background, so the why-us highlighter never appeared. */
.mk{position:relative;display:inline;isolation:isolate}
.mk::before{content:"";position:absolute;left:-.08em;right:-.08em;bottom:.02em;height:.42em;
     background:var(--citron);border-radius:2px;z-index:-1;
     transform:scaleX(0);transform-origin:left;transition:transform .62s var(--ease)}
/* In dark the highlighter drops below the baseline and becomes a rule.
   It cannot stay behind the text: the copy is near-white there, citron is
   fixed and light, and the bottom of every glyph would disappear. The
   colour keeps its meaning; only the geometry moves. */
:root[data-theme="dark"] .mk::before{bottom:-.12em;height:.16em;border-radius:2px}
.w p{font-size:15.5px;color:var(--ink-2);max-width:48ch;
     opacity:0;transform:translateY(10px);
     transition:opacity .55s var(--ease),transform .55s var(--ease)}

.js .whys.in .wn,.js .whys.in .w p{opacity:1;transform:none}
.js .whys.in .mk::before{transform:scaleX(1)}
/* capped stagger — four beats, then it stops */
.js .whys.in .w:nth-child(1) .wn{transition-delay:.02s} .js .whys.in .w:nth-child(1) p{transition-delay:.10s} .js .whys.in .w:nth-child(1) .mk::before{transition-delay:.06s}
.js .whys.in .w:nth-child(2) .wn{transition-delay:.11s} .js .whys.in .w:nth-child(2) p{transition-delay:.19s} .js .whys.in .w:nth-child(2) .mk::before{transition-delay:.15s}
.js .whys.in .w:nth-child(3) .wn{transition-delay:.20s} .js .whys.in .w:nth-child(3) p{transition-delay:.28s} .js .whys.in .w:nth-child(3) .mk::before{transition-delay:.24s}
.js .whys.in .w:nth-child(4) .wn{transition-delay:.29s} .js .whys.in .w:nth-child(4) p{transition-delay:.37s} .js .whys.in .w:nth-child(4) .mk::before{transition-delay:.33s}

@media (prefers-reduced-motion:reduce){
  .js .whys .wn,.js .whys .w p{opacity:1!important;transform:none!important}
  .js .whys .mk::before{transform:scaleX(1)!important}
}

/* Everything the visitor READS sits above the texture. Chrome does not
   belong in this list: .nav carries sticky/40 and .totop carries fixed/50,
   this rule sits ~35k later with equal specificity, and including them
   silently overwrote both. The nav stopped being sticky and fell to the
   hero's own layer — so any panel opened from it was painted over by the
   page — and the back-to-top button stopped being fixed. */
.marquee,.hero,.sec,.numbers,.close,footer{position:relative;z-index:2}
.prog{pointer-events:none}

/* ════════ LEARNING HUB ════════════════════════════════════════════
   Topic bars, not filter tags. Pranay on the call: "this just looks
   like a tagger, nothing else." A bar is a destination with a count
   and a piece of artwork; a tag is a label you can't act on. */
.topics{display:grid;gap:10px;margin:clamp(26px,3.4vw,40px) 0 0}
@media(min-width:640px){.topics{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1040px){.topics{grid-template-columns:repeat(4,1fr)}}
.topic{display:flex;align-items:center;gap:12px;padding:12px 14px;min-height:62px;
     border:1.5px solid var(--hair-2);border-radius:12px;background:var(--card);
     color:var(--ink);font:inherit;text-align:left;cursor:pointer;width:100%;
     transition:border-color .18s var(--ease),transform .18s var(--ease),background .18s var(--ease)}
.topic:hover,.topic:focus-visible{border-color:var(--plum);transform:translateY(-2px)}
.topic[aria-pressed="true"]{border-color:var(--plum);background:var(--paper-2);
     box-shadow:0 3px 0 var(--plum)}
.topic .ico{flex:none;width:40px;height:40px;border-radius:9px;
     display:grid;place-items:center;color:var(--on-plum);background:var(--plum-s);
     border:1px solid var(--plum-s)}
:root[data-theme="dark"] .topic .ico{border-color:var(--plum)}
/* The glyph is painted by CSS, not by the file.
   These icons are authored stroke="currentColor" and were loaded with <img>.
   An <img> renders in its own document and cannot inherit color from this
   one, so currentColor resolved to black: 1.46:1 on the plum tile, where
   color:var(--on-plum) above was meant to give 12.96:1. The mask makes the
   tile's own colour the ink, so it follows the theme and would still be
   right if the tile treatment ever changed. */
.topic .ico i{display:block;width:21px;height:21px;background:currentColor;
     -webkit-mask:var(--gi) center/contain no-repeat;
             mask:var(--gi) center/contain no-repeat}
.gi-organic{--gi:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round' role='img' aria-hidden='true'%3E%3Ccircle cx='10' cy='10' r='6'/%3E%3Cpath d='M14.5 14.5L20 20'/%3E%3C/svg%3E")}
.gi-paid{--gi:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round' role='img' aria-hidden='true'%3E%3Cpath d='M4 19V11M9 19V6M14 19v-9M19 19V8'/%3E%3C/svg%3E")}
.gi-social{--gi:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round' role='img' aria-hidden='true'%3E%3Ccircle cx='6' cy='7' r='2.6'/%3E%3Ccircle cx='18' cy='7' r='2.6'/%3E%3Ccircle cx='12' cy='17' r='2.6'/%3E%3Cpath d='M8.4 8.4l2.4 6.4M15.6 8.4l-2.4 6.4M8.6 7h6.8'/%3E%3C/svg%3E")}
.gi-native{--gi:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round' role='img' aria-hidden='true'%3E%3Crect x='3' y='5' width='18' height='14' rx='2'/%3E%3Cpath d='M6 9h7M6 12h9M6 15h5'/%3E%3C/svg%3E")}
.gi-content{--gi:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round' role='img' aria-hidden='true'%3E%3Cpath d='M6 3h8l4 4v14H6z'/%3E%3Cpath d='M14 3v4h4'/%3E%3Cpath d='M9 12h6M9 16h6'/%3E%3C/svg%3E")}
.gi-email{--gi:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round' role='img' aria-hidden='true'%3E%3Crect x='3' y='5' width='18' height='14' rx='2'/%3E%3Cpath d='M3 7l9 6 9-6'/%3E%3C/svg%3E")}
.gi-landing{--gi:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round' role='img' aria-hidden='true'%3E%3Crect x='4' y='3' width='16' height='18' rx='2'/%3E%3Cpath d='M4 8h16M8 12h8M8 16h5'/%3E%3C/svg%3E")}
.gi-build{--gi:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round' role='img' aria-hidden='true'%3E%3Crect x='3' y='4' width='18' height='16' rx='2'/%3E%3Cpath d='M3 8h18M7 6h.01M10 6h.01'/%3E%3Cpath d='M8 12h4v5H8z'/%3E%3Ccircle cx='16' cy='14' r='2.6'/%3E%3C/svg%3E")}
.topic .tx{min-width:0}
.topic .tn{display:block;font-size:14.5px;font-weight:700;letter-spacing:-.015em;line-height:1.25}
.topic .tc{display:block;font-size:12.5px;color:var(--ink-3);margin-top:1px}

.posts{display:grid;gap:16px;margin-top:clamp(26px,3.4vw,40px)}
@media(min-width:700px){.posts{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1060px){.posts{grid-template-columns:repeat(3,1fr)}}
.post{display:flex;flex-direction:column;border:1px solid var(--hair-2);border-radius:4px;
     background:var(--card);overflow:hidden;color:inherit;
     transition:transform .2s var(--ease),border-color .2s var(--ease)}
.post:hover,.post:focus-visible{transform:translateY(-3px);border-color:var(--plum)}
.post .shot{display:block;width:100%;aspect-ratio:640/300;object-fit:contain;color:var(--plum);
     background:var(--paper-2);border-bottom:1px solid var(--hair-2)}
.post .in{padding:18px 20px 22px;display:flex;flex-direction:column;gap:10px;flex:1}
.post .k{font-family:ui-monospace,Menlo,monospace;font-size:11.5px;font-weight:400;
     letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
.post h3,.post h2.post-h{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.028em;font-size:19px;line-height:1.22;color:var(--ink)}
.post h2.post-h i{font-style:normal;color:var(--plum);display:inline-block;
     transition:transform .22s var(--ease)}
.post:hover h2.post-h i,.post:focus-visible h2.post-h i{transform:translateX(4px)}
.post p{font-size:15px;color:var(--ink-2);line-height:1.55;flex:1}

.posts .post[hidden]{display:none}
.no-hits{display:none;padding:26px 0;color:var(--ink-2)}
.no-hits[data-on="true"]{display:block}

/* article hero art */
/* The banner was running the full 1240px wrap, which made it 581px tall
   before a word of the article. Capped near the body measure so it reads
   as a figure attached to the piece, not a hero image. */
/* Centred, not left-aligned. The banner sits above .art-grid so it spans
   the full 1240px wrap, while the prose below starts after the 212px
   contents column — capped at 580px and flush left it lined up with
   nothing on the page. margin-inline:auto gives it one axis to share
   with the rest of the article. */
.art-hero{margin:clamp(20px,2.4vw,28px) auto 0;border-radius:10px;overflow:hidden;
     border:1px solid var(--hair);background:var(--paper-2);color:var(--plum);
     line-height:0;max-width:580px}
.art-hero img{width:100%;height:auto;display:block}
/* same treatment for any figure that lands in the prose later */
.body figure{margin:clamp(24px,3vw,34px) auto;max-width:580px}
.body figure img,.body > img{display:block;width:100%;height:auto;margin-inline:auto;
     border-radius:10px;border:1px solid var(--hair)}
.body figcaption{margin-top:10px;font-size:13.5px;line-height:1.55;color:var(--ink-3);
     text-align:center}
.sources ul{margin:0;padding-left:0;list-style:none}
.sources li{position:relative;padding:0 0 8px 22px;color:var(--ink-2);font-size:15px}
.sources li::before{content:"";position:absolute;left:3px;top:.6em;width:6px;height:6px;
     border-radius:50%;background:var(--hair-2)}

/* ════════ ARTICLE LAYOUT — formatting pass ════════════════════════
   These pages are now 2,000-word documents with tables, lists and a
   long FAQ. The rhythm below is set once, in one place, so every
   article reads the same and nothing is styled per-page. */

/* Measure. Long-form body copy sits at 68ch; anything wider stops
   being readable however good the type is. */
.body > p,.body > ul,.body > ol{max-width:68ch}
.body > h2{max-width:26ch}
.body > h3{max-width:34ch}

/* Vertical rhythm: space belongs ABOVE a heading, not below it, so a
   heading stays attached to the text it introduces. */
.body h2{margin:clamp(40px,4.6vw,58px) 0 14px;scroll-margin-top:96px}
.body h2:first-child{margin-top:0}
.body h3{margin:clamp(26px,3vw,34px) 0 10px;scroll-margin-top:96px}
.body h2 + h3{margin-top:16px}
.body p{line-height:1.68}

/* Lists: the marker is drawn, not inherited, so it matches the site's
   dot vocabulary and lines up with the text above it. */
.body ul{list-style:none;margin:0 0 22px;padding:0}
.body ul > li{position:relative;padding:0 0 10px 24px;margin:0}
.body ul > li::before{content:"";position:absolute;left:4px;top:.66em;width:6px;height:6px;
     border-radius:50%;background:var(--ink-3)}
.body ol{margin:0 0 22px;padding-left:24px}
.body ol > li{padding-left:4px;margin-bottom:10px}
.body li > strong:first-child{color:var(--ink)}

/* Tables: ruled, not boxed. Numbers align, the header holds on scroll. */
.body table{border-collapse:collapse;width:100%;margin:clamp(22px,2.6vw,30px) 0;font-size:14.5px}
.body thead th{text-align:left;font-size:11px;font-weight:700;letter-spacing:.1em;
     text-transform:uppercase;color:var(--ink-3);padding:0 16px 10px 0;
     border-bottom:1.5px solid var(--hair-2);white-space:nowrap}
.body tbody td{padding:12px 16px 12px 0;border-bottom:1px solid var(--hair);
     color:var(--ink-2);vertical-align:top;line-height:1.5}
.body tbody tr:last-child td{border-bottom:0}
.body td:first-child{color:var(--ink);font-weight:600}
.t-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;margin-inline:-2px;padding-inline:2px}

/* The short answer, and the FAQ, are the two blocks AI assistants lift.
   Both get room and neither gets a coloured side stripe. */
.tldr{max-width:68ch;margin:0 0 clamp(30px,3.6vw,42px)}
.faq{max-width:68ch;margin-top:clamp(44px,5vw,64px)}
.faq h2{margin-bottom:6px}
.sources{max-width:68ch;margin-top:clamp(36px,4.2vw,52px)}
.sources h2{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.03em;font-size:clamp(19px,2.2vw,24px);margin-bottom:12px}
.hub-cta{max-width:68ch;margin-top:clamp(40px,4.6vw,58px)}

/* Contents rail: a list of places, so it looks like one. */
.toc ol{list-style:none;margin:0;padding:0;counter-reset:toc}
.toc li{counter-increment:toc;margin:0}
.toc a{display:block;padding:7px 0 7px 26px;position:relative;font-size:13.5px;
     line-height:1.35;color:var(--ink-2);transition:color .16s var(--ease)}
.toc a::before{content:counter(toc,decimal-leading-zero);position:absolute;left:0;top:7px;
     font-size:10.5px;font-weight:700;letter-spacing:.06em;color:var(--ink-3)}
.toc a:hover,.toc a:focus-visible{color:var(--plum)}
/* Contents rows measured 32px. Gated on pointer:coarse rather than a width,
   because this is about thumbs, not screens — a ten-item list at 44px would
   otherwise add 120px of scrolling to the desktop sidebar for no reason. */
@media (pointer:coarse){
  .toc a{display:flex;align-items:center;min-height:44px;padding-top:4px;padding-bottom:4px}
  .toc a::before{top:50%;transform:translateY(-50%)}
}
@media(min-width:1000px){.toc{max-height:calc(100vh - 140px);overflow:auto;overscroll-behavior:contain}}

/* ── internal page rhythm ──────────────────────────────────────────
   .hero + .sec stacked their paddings: up to 190px of nothing between
   the lede and the first real content. Halved and made continuous. */
.hero{padding:clamp(30px,4vh,54px) 0 clamp(22px,2.6vh,34px)}
/* The homepage hero is NOT an internal page header. Its padding is clamped
   against vh so the headline, lede, buttons and panel all clear the fold on
   a 13" laptop; the rule above was written for the .sub-style headers on the
   other 14 pages and was overriding it, adding 11px on top and taking 4 off
   the bottom. Two classes, so source order can never decide this again. */
.hero.home{padding:clamp(16px,2.8vh,48px) 0 clamp(20px,3vh,44px)}
.hero .sub{margin-top:14px;max-width:76ch}
.hero .lbl{margin-bottom:10px}
.hero .act{margin-top:clamp(18px,2.4vh,26px)}
.hero + .sec{padding-top:clamp(26px,3vw,44px)}
.sec .ut + .topics{margin-top:14px}
.topics + .posts{margin-top:clamp(22px,2.6vw,34px)}
@media(min-width:1000px){
  /* the hub headline is two lines by design; stop it running to 17ch */
  .hero h1{max-width:22ch}
}

/* ── CLOSING BAND + FOOTER ─────────────────────────────────────────
   Two surfaces, two values: the band is --plum-s, the footer is
   --plum-deep. Same family, clearly separate, so the page ends in two
   steps rather than one long block of colour. */
.close .wrap > h2{max-width:20ch;margin-bottom:12px}
.close .wrap > p{max-width:64ch;margin-bottom:0}
.close .lbl{margin-bottom:10px}
/* action row: the button and the address belong on one line */
.close .wrap > .btn{margin-top:clamp(20px,2.4vw,28px)}
.close .wrap > .btn + div{display:inline-block;margin-left:12px;vertical-align:middle}
@media(max-width:560px){
  .close .wrap > .btn + div{display:block;margin:12px 0 0}
}
.close .copy-em{background:transparent;border:1.5px solid var(--hair-plum);color:var(--on-plum);
     min-height:50px;padding:0 18px;border-radius:var(--r);font-weight:600;font-size:14.5px;
     cursor:pointer;transition:border-color .2s var(--ease),background .2s var(--ease)}
.close .copy-em:hover,.close .copy-em:focus-visible{border-color:var(--citron);background:var(--plum-lift)}

.foot-grid{display:grid;gap:clamp(24px,3vw,44px)}
@media(min-width:780px){.foot-grid{grid-template-columns:1.6fr 1fr 1fr;align-items:start}}
footer .lede-f{margin-top:14px;max-width:34ch;color:var(--on-plum-2);line-height:1.55}
footer h2.ut{font-size:11px;letter-spacing:.15em;margin-bottom:10px}
footer ul{margin:0}
footer li{list-style:none;padding:0}
footer li a{min-height:0;display:inline-block;padding:5px 0;line-height:1.4}
.foot-base{margin-top:clamp(30px,3.4vw,44px);padding-top:16px;border-top:1px solid var(--hair-plum);
     display:flex;flex-wrap:wrap;gap:10px 24px;justify-content:space-between;
     font-size:13px;color:var(--on-plum-2)}

/* ── Social links — small icons in the desktop nav, full row in the
   footer. Two contexts, two colour treatments: the nav sits on
   --paper/--card so it uses the ordinary --ink/--hair-2 pair the theme
   toggle already uses; the footer sits on --plum-deep, so it borrows
   --on-plum-2/--on-plum the same way footer.lede-f and .foot-base
   already do, with --citron for focus per the plum-region focus rule.
   Nav icons are desktop-only — small, mouse-precision controls, not a
   touch target, so they skip the 44px interactive-height floor that
   applies to anything a thumb has to hit (the footer versions don't
   skip it: 44px there, since footer is reachable on mobile). ─────── */
.soc{display:grid;place-items:center;border-radius:var(--r);flex:none;
     background:none;border:1.5px solid var(--hair-2);color:var(--ink-2);
     transition:border-color .2s var(--ease),background .2s var(--ease),color .2s var(--ease)}
.soc:hover{border-color:var(--ink);background:var(--paper-2);color:var(--ink)}
.soc:focus-visible{outline:3px solid var(--plum);outline-offset:3px}

.nav-social{display:none;align-items:center;gap:6px}
@media(min-width:1020px){.nav-social{display:flex}}
.nav-social .soc{width:36px;height:36px}
.nav-social .soc svg{width:16px;height:16px}

.foot-social{display:flex;gap:10px;margin-top:clamp(20px,2.6vw,28px)}
.foot-social .soc{width:44px;height:44px;border-color:var(--hair-plum);color:var(--on-plum-2)}
.foot-social .soc:hover{border-color:var(--on-plum);background:var(--plum-lift);color:var(--on-plum)}
.foot-social .soc:focus-visible{outline:3px solid var(--citron);outline-offset:3px}

/* ════════ SERVICES — one page, eight sections ═════════════════════
   Two layers collapsed into one. The rail is a table of contents for a
   single document, not navigation to eight thin pages, so it highlights
   the section you're in rather than the page you're on. */
.svc{padding:clamp(30px,3.6vw,46px) 0;border-top:1px solid var(--hair);scroll-margin-top:88px}
.svc:first-child{padding-top:0;border-top:0}
.svc .ut{margin-bottom:8px}
.svc h2{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.03em;font-size:clamp(23px,2.8vw,31px);line-height:1.1;margin-bottom:8px}
.svc > p{color:var(--ink-2);max-width:64ch;margin-bottom:0}
.svc-cols{display:grid;gap:clamp(18px,2.4vw,34px);margin-top:clamp(20px,2.4vw,28px)}
@media(min-width:720px){.svc-cols{grid-template-columns:1fr 1fr}}
.lbl-s{font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
     color:var(--ink-3);margin-bottom:10px}
.svc-cols ul{list-style:none;margin:0;padding:0}
.svc-cols li{position:relative;padding:0 0 11px 22px;color:var(--ink-2);font-size:15px;line-height:1.55}
.svc-cols li::before{content:"";position:absolute;left:3px;top:.62em;width:6px;height:6px;
     border-radius:50%;background:var(--ink-3)}
.svc-cols li b{color:var(--ink);font-weight:700}
.wont{margin-top:clamp(16px,2vw,22px);padding:14px 16px;border-radius:10px;
     background:var(--paper-2);color:var(--ink-2);font-size:14.5px;line-height:1.55;max-width:64ch}
.wont b{color:var(--ink)}
.svc-note{margin-top:clamp(26px,3vw,38px);padding-top:20px;border-top:1px solid var(--hair);
     font-size:15px;color:var(--ink-3);max-width:64ch}

.svc-all .svc{border-top:0;padding-top:0}
.svc-all .svc h2{font-size:clamp(20px,2.4vw,26px);margin-bottom:16px}
.svc-next{display:flex;flex-wrap:wrap;gap:10px;margin-top:clamp(30px,4vw,44px);
     padding-top:22px;border-top:1px solid var(--hair)}
.svc-next a{display:inline-flex;align-items:center;gap:8px;min-height:46px;padding:0 16px;
     border:1.5px solid var(--hair-2);border-radius:100px;font-size:14.5px;font-weight:600;
     transition:border-color .2s var(--ease),transform .2s var(--ease)}
.svc-next a:hover,.svc-next a:focus-visible{border-color:var(--plum);transform:translateY(-2px)}
.hero .crumb{margin-bottom:14px}

/* ── SERVICES: the index sits on top, not on a page of its own ──────
   Eight peers with a strip across the top of each. No landing page in
   the middle to click through, and no left rail eating a column on a
   page that is already narrow. */
.svc-bar{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:clamp(26px,3.2vw,40px);
     padding-bottom:clamp(22px,2.6vw,30px);border-bottom:1px solid var(--hair)}
.svc-bar a{display:inline-flex;align-items:center;min-height:44px;padding:0 15px;
     border:1.5px solid var(--hair-2);border-radius:100px;background:var(--card);
     font-size:13.5px;font-weight:600;letter-spacing:-.01em;color:var(--ink-2);white-space:nowrap;
     transition:border-color .16s var(--ease),color .16s var(--ease),background .16s var(--ease)}
.svc-bar a:hover,.svc-bar a:focus-visible{border-color:var(--plum);color:var(--ink)}
.svc-bar a[aria-current="page"]{background:var(--plum-s);border-color:var(--plum-s);color:var(--on-plum)}
@media(max-width:700px){
  .svc-bar{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;margin-inline:-2px;padding-inline:2px}
  .svc-bar::-webkit-scrollbar{display:none}
  .svc-bar a{flex:none}
}

/* NOTE ON THE CLASS NAMES: .n, .p and .c are already taken — .n is the
   stats-band cell (white card, 34px padding, centred text). The previous
   version of this list used .n for the service name and inherited all of
   that, which is why every row rendered as a centred card. Row parts are
   prefixed .s- so the collision cannot come back.

   ── the services index: three families, not eight identical lines ────
   Eight rows of name + one-liner is a directory, and a directory reads
   as bland because nothing on it has a shape. Grouping them earned /
   paid / owned does two jobs: it gives the eye something to hold, and
   it makes the argument the intro is already making — these are not
   eight products, they are three families that have to be planned
   together. The icon tile carries the scale contrast; the covers line
   carries the substance, lifted from each service page rather than
   written fresh, so the index cannot drift from the pages. */
.svc-fam{border-top:1px solid var(--hair);padding-top:clamp(24px,3vw,34px);
     margin-top:clamp(28px,3.6vw,44px)}
.svc-fam:first-child{margin-top:0}
@media(min-width:900px){
  .svc-fam{display:grid;grid-template-columns:minmax(0,272px) minmax(0,1fr);
       gap:clamp(28px,4vw,64px);align-items:start}
  /* the family header holds its position while its rows scroll past —
     the one place on this page where stickiness earns itself */
  .fam-head{position:sticky;top:clamp(88px,11vh,104px)}
}
.fam-lbl{display:flex;align-items:center;gap:9px;font-family:ui-monospace,'SFMono-Regular',Menlo,monospace;
     font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
     color:var(--ink-3);margin-bottom:12px}
.fam-lbl::before{content:"";width:20px;height:2px;background:var(--plum);flex:none}
.fam-head h2{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.03em;line-height:1.13;font-size:clamp(20px,2.3vw,26px);
     color:var(--ink);margin:0 0 10px}
.fam-head p{font-size:14.5px;line-height:1.6;color:var(--ink-2);max-width:36ch;margin:0}

.svc-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:0 clamp(14px,1.8vw,20px);
     align-items:start;padding:clamp(15px,1.8vw,19px) 6px;border-bottom:1px solid var(--hair);
     color:inherit;position:relative;
     transition:background .16s var(--ease),padding-left .16s var(--ease)}
.fam-rows > .svc-row:first-child{border-top:1px solid var(--hair)}
@media(min-width:900px){.fam-rows > .svc-row:first-child{border-top:0;padding-top:0}}
.svc-row:hover,.svc-row:focus-visible{background:var(--paper-2);padding-left:14px}

/* the tile is the only thing on the row with a filled ground, which is
   what stops eight rows reading as one grey block */
/* The tiles are the one place plum owns a region on these two pages.
   In LIGHT that works as a solid fill: --plum-s against --paper is
   13.1:1 and the eight tiles read as one set. In DARK --plum-s stays a
   dark surface and the ground is darker still, so the same fill is
   1.14:1 against the card and the tile simply disappears. Dark gets its
   own composition — the lifted surface plus a light hairline for the
   edge, with the glyph in --plum, which inverts to rose. This is the
   "two themes, authored independently" rule doing actual work. */
.svc-row .s-ic{display:grid;place-items:center;width:42px;height:42px;flex:none;
     border:1.5px solid var(--plum-s);border-radius:11px;background:var(--plum-s);
     /* explicit placement: auto-placement fills ACROSS the columns, so the
        promise and covers lines land in column 3 instead of stacking. */
     color:var(--on-plum);grid-column:1;grid-row:1/span 3;
     transition:border-color .16s var(--ease),background .16s var(--ease),color .16s var(--ease)}
.svc-row .s-ic svg{width:21px;height:21px}
/* Dark keeps the plum fill -- dropping it to a neutral surface left the
   page with no colour at all -- and takes its edge from --plum, which
   inverts to rose. A hairline was tried first and came in at 2.69:1,
   under the 3:1 non-text floor. */
:root[data-theme="dark"] .svc-row .s-ic{border-color:var(--plum)}
.svc-row:hover .s-ic,.svc-row:focus-visible .s-ic{background:var(--citron);border-color:var(--citron);
     color:var(--on-citron)}
.svc-row .s-n{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.025em;font-size:clamp(17px,1.8vw,19.5px);line-height:1.2;color:var(--ink);
     grid-column:2;grid-row:1}
.svc-row .s-p{font-size:14.5px;color:var(--ink-2);line-height:1.5;margin-top:3px;
     grid-column:2;grid-row:2}
/* the covers line is deliberately quiet — it rewards a second look and
   must never compete with the name */
.svc-row .s-c{font-size:13px;line-height:1.55;color:var(--ink-3);margin-top:7px;
     grid-column:2;grid-row:3}
.svc-row .s-c span{white-space:nowrap}
.svc-row .s-c span+span::before{content:"·";margin:0 7px;color:var(--hair-2)}
.svc-row i{font-style:normal;color:var(--plum);font-size:17px;line-height:1;align-self:center;
     grid-column:3;grid-row:1/span 3;transition:transform .2s var(--ease)}
.svc-row:hover i,.svc-row:focus-visible i{transform:translateX(4px)}
@media(max-width:560px){
  .svc-row{grid-template-columns:auto minmax(0,1fr)}
  .svc-row i{display:none}
  .svc-row .s-c span{white-space:normal}
}

/* ── related reading: the service-to-article half of the interlink ──
   Same card vocabulary as the Learning Hub so the visitor recognises
   where they're being sent before they read the label. */
.rel-read{margin-top:clamp(34px,4.2vw,52px);padding-top:clamp(26px,3vw,36px);
     border-top:1px solid var(--hair)}
.rel-read h2{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.03em;font-size:clamp(19px,2.2vw,24px);margin-bottom:6px}
.rel-lede{font-size:15px;color:var(--ink-2);max-width:60ch;margin-bottom:clamp(18px,2.2vw,26px)}
.rel-lede a{color:var(--plum);font-weight:700}
.rel-grid{display:grid;gap:14px}
@media(min-width:680px){.rel-grid{grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}}
.rel-card{display:flex;flex-direction:column;border:1px solid var(--hair-2);border-radius:4px;
     background:var(--card);overflow:hidden;color:inherit;
     transition:transform .2s var(--ease),border-color .2s var(--ease)}
.rel-card:hover,.rel-card:focus-visible{transform:translateY(-3px);border-color:var(--plum)}
.rel-card img{display:block;width:100%;aspect-ratio:640/300;object-fit:contain;color:var(--plum);
     background:var(--paper-2);border-bottom:1px solid var(--hair-2)}
.rel-card .in{padding:14px 16px 17px;display:flex;flex-direction:column;gap:7px}
.rel-card .k{font-family:ui-monospace,Menlo,monospace;font-size:11px;letter-spacing:.14em;
     text-transform:uppercase;color:var(--ink-3)}
.rel-card .t{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.025em;font-size:16px;line-height:1.25;color:var(--ink)}
.rel-card .t i{font-style:normal;color:var(--plum);display:inline-block;
     transition:transform .22s var(--ease)}
.rel-card:hover .t i,.rel-card:focus-visible .t i{transform:translateX(4px)}
/* the article CTA now offers two doors: the service, then the call */
.hub-cta .btn + .btn{margin-left:10px}
@media(max-width:560px){.hub-cta .btn{display:flex;justify-content:center;width:100%}
  .hub-cta .btn + .btn{margin:10px 0 0}}

/* ── SMART SOLUTIONS: one searchable grid, no separate featured slot ──
   Redesigned 19 August, twice. First pass grouped by category into six
   bento modules; that read as a spreadsheet and left uneven column
   lengths. Second pass replaced it with this command bar. The Marketing
   Plan Self-Assessment briefly had its own hero panel above the grid —
   flagged as wrong on sight: it is one of the tools, and pulling it out
   made it unsearchable and untagged like every other one. It is now the
   first, wider card in the grid itself (`.tc-wide`), not a separate
   section. ------------------------------------------------------------- */

/* the command bar: a live search that narrows all twenty tools as you
   type, plus category pills. Search is also the one interaction that's
   actually earned here: twenty tools is enough that finding one by name
   beats scrolling past the other nineteen. */
.tools-bar{display:flex;align-items:center;gap:10px;
     background:var(--card);border:2px solid var(--plum);border-radius:100px;
     box-shadow:0 4px 0 var(--ink);padding:8px 8px 8px 22px;
     margin-top:clamp(28px,3.4vw,44px)}
.tools-bar svg{flex:none;width:19px;height:19px;color:var(--ink-3)}
.tools-bar input{flex:1;min-width:0;border:0;background:transparent;outline:0;
     font:600 15.5px 'Public Sans',sans-serif;color:var(--ink)}
.tools-bar input::placeholder{color:var(--ink-3);font-weight:400}
.tools-count{flex:none;font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     font-size:13px;background:var(--plum-s);color:var(--on-plum);border-radius:100px;
     padding:8px 16px;white-space:nowrap}

.tools-pills{display:flex;flex-wrap:wrap;gap:8px;margin:16px 0 8px}
.tp{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:700;font-size:13.5px;
     border:1.5px solid var(--hair);border-radius:100px;padding:8px 16px;background:var(--card);
     color:var(--ink-2);cursor:pointer;transition:border-color .14s var(--ease),background .14s var(--ease),color .14s var(--ease)}
.tp:hover{border-color:var(--plum)}
.tp.on{background:var(--plum-s);border-color:var(--plum-s);color:var(--on-plum)}
.tp:focus-visible{outline:3px solid var(--plum);outline-offset:3px}

/* uniform grid, not masonry — every card the same height per row, so
   twenty results (or four, once filtered) never leave a ragged edge */
.tools-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;
     margin-top:clamp(20px,2.6vw,32px)}
@media(max-width:900px){.tools-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:640px){.tools-grid{grid-template-columns:1fr}}

.tc{display:flex;flex-direction:column;background:var(--card);border:2px solid var(--plum);
     border-radius:14px;box-shadow:0 4px 0 var(--ink);padding:22px;
     text-decoration:none;color:inherit;
     transition:transform .14s var(--ease),box-shadow .14s var(--ease)}
.tc:hover,.tc:focus-visible{transform:translateY(-3px);box-shadow:0 7px 0 var(--ink)}
.tc.hide{display:none}
.tc-top{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px}
.tc-ic{display:grid;place-items:center;width:38px;height:38px;flex:none;
     border:1.5px solid var(--plum-s);border-radius:10px;background:var(--plum-s);color:var(--on-plum)}
:root[data-theme="dark"] .tc-ic{border-color:var(--plum)}
.tc-ic svg{width:19px;height:19px}
/* tier badge — sits above the existing category label, same right-aligned
   column. Carries information the card title and category don't (how much
   prior context the tool assumes), which is the bar for keeping it. */
.tc-side{display:flex;flex-direction:column;align-items:flex-end;gap:5px}
.tc-tier{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:700;font-size:10px;
     letter-spacing:.05em;text-transform:uppercase;background:var(--plum-s);color:var(--on-plum);
     border-radius:100px;padding:3px 10px;white-space:nowrap}
:root[data-theme="dark"] .tc-tier{border:1px solid var(--plum)}
.tc-cat{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:700;font-size:11px;
     letter-spacing:.03em;color:var(--ink-3);text-align:right;line-height:1.3}
.tc h3{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.02em;font-size:16.5px;color:var(--ink);margin:0 0 6px}
.tc p{margin:0;color:var(--ink-2);font-size:14px;line-height:1.55;flex:1}

/* the one assessment that covers all eight services — still the same
   card component, just two columns wide where the grid allows it, so it
   reads as the broadest option rather than a special one */
@media(min-width:640px){.tc-wide{grid-column:span 2}}
.tc-wide p{max-width:62ch}

.tools-empty{display:none;text-align:center;padding:60px 20px;color:var(--ink-3);font-size:15px}
.tools-empty.show{display:block}

/* the one authored moment on this page: bar, pills and grid rise
   together on load — CSS-only, so it never depends on the script
   arriving. The search bar stays fully readable and usable either way. */
.tools-bar,.tools-pills,.tools-grid{animation:tools-rise .6s var(--ease) both}
.tools-pills{animation-delay:.05s}
.tools-grid{animation-delay:.09s}
@keyframes tools-rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){
  .tools-bar,.tools-pills,.tools-grid{animation:none}
}

/* ── SERVICES DROPDOWN ───────────────────────────────────────────────
   The link still navigates; a separate caret opens the panel. Two
   controls, two jobs — a nav item that only opens a menu strands anyone
   who wanted the index page itself. The caret only exists when the
   script does, so with JS off the link behaves exactly as before. */
.nav-svc{position:relative;display:inline-flex;align-items:center}
.nav-caret{display:none;align-items:center;justify-content:center;width:26px;height:38px;
     margin-left:-6px;padding:0;background:none;border:0;cursor:pointer;color:var(--ink-3);
     border-radius:var(--r);transition:color .2s var(--ease),background .2s var(--ease)}
.js .nav-caret{display:inline-flex}
.nav-caret svg{width:11px;height:auto;transition:transform .22s var(--ease)}
.nav-caret:hover,.nav-caret:focus-visible{color:var(--ink);background:var(--paper-2)}
.nav-caret[aria-expanded="true"]{color:var(--plum)}
.nav-caret[aria-expanded="true"] svg{transform:rotate(180deg)}

.nav-menu[hidden]{display:none}
.nav-menu{position:absolute;top:calc(100% + 12px);left:-12px;z-index:41;
     width:min(680px,calc(100vw - 32px));padding:20px 20px 14px;
     background:var(--card);border:1.5px solid var(--hair-2);border-radius:14px;
     box-shadow:0 14px 40px -12px rgba(39,16,32,.28);
     display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px 22px}
.nm-h{grid-column:auto;font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
     color:var(--ink-3);margin:0 0 8px;padding:0 8px}
.nav-menu .nm-col{display:flex;flex-direction:column;gap:2px}
.nav-menu .nm-col a{display:block;height:auto;padding:9px 8px;border-radius:8px;
     white-space:normal;transition:background .16s var(--ease)}
.nav-menu .nm-col a b{display:block;font-size:14px;font-weight:700;letter-spacing:-.015em;color:var(--ink)}
.nav-menu .nm-col a span{display:block;font-size:12.5px;line-height:1.4;color:var(--ink-2);margin-top:1px}
.nav-menu .nm-col a:hover,.nav-menu .nm-col a:focus-visible{background:var(--paper-2)}
.nav-menu .nm-col a:hover b,.nav-menu .nm-col a:focus-visible b{color:var(--plum)}
.nm-all{grid-column:1/-1;display:flex!important;align-items:center;gap:8px;
     margin-top:10px;padding:11px 8px;border-top:1px solid var(--hair);
     /* 44px is the floor for a thumb. This row measured 37px on the phone
        because its padding was 12/2 around a 23px line. */
     font-size:13.5px;font-weight:700;color:var(--plum);min-height:44px}
.nm-all i{font-style:normal;transition:transform .2s var(--ease)}
.nm-all:hover i,.nm-all:focus-visible i{transform:translateX(4px)}

/* Inside the burger the panel is not a floating layer — it expands in
   place, or it would cover the rest of the menu on a phone. */
@media(max-width:1019px){
  .nav-svc{display:flex;flex-wrap:wrap;width:100%}
  .nav-svc > a{flex:1}
  .nav-caret{width:44px;height:50px;margin-left:0}
  .nav-menu{position:static;width:100%;grid-template-columns:1fr;gap:2px;
       margin:2px 0 10px;padding:12px 8px;box-shadow:none;background:var(--paper-2);
       border-color:var(--hair)}
  .nm-h{margin-top:8px}
}
/* ── FAQ ──────────────────────────────────────────────────────────
   Same two-column shape as the services index: the section heading
   holds its place while the list runs past it, so a forty-item list
   never loses the reader. No open/close height animation — <details>
   does not transition reliably from its closed state without script,
   and a reveal on every one of forty rows is noise, not polish. The
   marker animates; the content simply arrives. */
.fq-set{border-top:1px solid var(--hair);padding-top:clamp(22px,2.6vw,32px)}
@media(min-width:900px){
  .fq-set{display:grid;grid-template-columns:minmax(0,290px) minmax(0,1fr);
       gap:clamp(28px,4vw,64px);align-items:start}
  .fq-head{position:sticky;top:clamp(88px,11vh,104px)}
}
.fq-head h2{font-size:clamp(23px,2.5vw,31px);line-height:1.1;letter-spacing:-.032em;margin:0}
.fq-head p{margin:12px 0 0;font-size:15px;line-height:1.55;color:var(--ink-2);max-width:38ch}
.fq-list{min-width:0;margin-top:clamp(18px,2vw,0px)}
@media(min-width:900px){.fq-list{margin-top:0}}

.fq{border-bottom:1px solid var(--hair)}
.fq:first-child{border-top:1px solid var(--hair)}
.fq > summary{display:flex;align-items:flex-start;justify-content:space-between;gap:18px;
     padding:15px 2px;min-height:56px;cursor:pointer;list-style:none;
     font-family:'Bricolage Grotesque','Public Sans',sans-serif;
     font-size:16.5px;font-weight:700;letter-spacing:-.015em;line-height:1.36;
     color:var(--ink);transition:color .16s var(--ease)}
.fq > summary::-webkit-details-marker{display:none}
.fq > summary::marker{content:""}
.fq > summary:hover{color:var(--plum)}
.fq > summary:focus-visible{outline:3px solid var(--plum);outline-offset:2px;border-radius:4px}
.fq-q{min-width:0}
/* A drawn plus, not a glyph. The vertical stroke rotates flat onto the
   horizontal one, so open reads as a minus without swapping characters. */
.fq-m{position:relative;flex:none;width:19px;height:19px;margin-top:3px;color:var(--plum)}
.fq-m::before,.fq-m::after{content:"";position:absolute;left:50%;top:50%;
     width:13px;height:1.9px;border-radius:2px;background:currentColor;
     transform:translate(-50%,-50%);transition:transform .24s var(--ease)}
.fq-m::after{transform:translate(-50%,-50%) rotate(90deg)}
.fq[open] .fq-m::after{transform:translate(-50%,-50%) rotate(0deg)}
.fq-a{padding:0 40px 20px 2px}
.fq-a p{margin:0;font-size:15.5px;line-height:1.62;color:var(--ink-2);max-width:68ch}
@media(max-width:560px){
  .fq > summary{font-size:15.5px;gap:12px}
  .fq-a{padding-right:12px}
}

/* The quiet door to the FAQ, under the hero's two buttons. Deliberately
   a link and not a third pill: it must not compete with the action. */
.ask{display:inline-flex;align-items:center;gap:8px;min-height:44px;margin-top:14px;
     font-size:14.5px;font-weight:600;color:var(--ink-2);
     text-decoration:underline;text-underline-offset:4px;
     text-decoration-color:var(--hair-2);transition:color .18s var(--ease)}
.ask:hover,.ask:focus-visible{color:var(--ink);text-decoration-color:var(--plum)}
.ask i{font-style:normal;transition:transform .18s var(--ease)}
.ask:hover i,.ask:focus-visible i{transform:translateX(3px)}

/* ── Lead form ────────────────────────────────────────────────────
   A native <dialog>: the browser supplies the focus trap, Esc, inert
   background and top-layer painting, none of which is worth hand-
   rolling. Markup is injected by site.js so it lives in one place
   rather than being pasted into every page and drifting.
   Without script the triggers keep their href and the visitor lands
   on the closing band, so nothing depends on JS to be reachable. */
/* margin:auto is what centres a modal dialog — the UA stylesheet sets it
   and the reset on line 109 (*{margin:0}) was overwriting it, because an
   author rule beats the UA sheet whatever its specificity. The form was
   opening pinned to the top-left corner. */
.lead{margin:auto;padding:0;border:0;background:transparent;
     max-width:min(640px,calc(100vw - 24px));width:100%}
.lead::backdrop{background:rgba(16,5,12,.62)}
@supports (backdrop-filter:blur(2px)){.lead::backdrop{backdrop-filter:blur(3px)}}
/* The panel scrolls, but the heading and the close button stay put: an
   eight-field form is taller than a laptop viewport, and a close button
   that scrolls away is the thing that makes a modal feel like a trap. */
.lead-in{background:var(--card);border:2px solid var(--plum);border-radius:14px;
     box-shadow:0 4px 0 var(--ink);max-height:min(90vh,880px);overflow:auto;
     overscroll-behavior:contain;padding:0}
.lead-in:focus{outline:none}
.lead-top{position:sticky;top:0;z-index:1;background:var(--card);
     padding:clamp(18px,3vw,26px) clamp(18px,3vw,28px) 14px;
     border-radius:12px 12px 0 0}
.lead-f,.lead-ok{padding:0 clamp(18px,3vw,28px) clamp(20px,3vw,28px)}
.js .lead[open] .lead-in{animation:lead-in .26s var(--ease) both}
@keyframes lead-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

.lead-top{display:flex;align-items:flex-start;justify-content:space-between;gap:18px}
.lead-top h2{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.03em;font-size:clamp(21px,2.7vw,27px);line-height:1.12;margin:0}
.lead-top p{margin:9px 0 0;font-size:15px;line-height:1.55;color:var(--ink-2);max-width:48ch}
.lead-x{flex:none;width:44px;height:44px;display:grid;place-items:center;border-radius:var(--r);
     background:none;border:1.5px solid var(--hair-2);color:var(--ink);cursor:pointer;
     transition:border-color .18s var(--ease),background .18s var(--ease)}
.lead-x:hover,.lead-x:focus-visible{border-color:var(--plum);background:var(--paper-2)}
.lead-x svg{width:17px;height:17px}

.lead-f{display:grid;gap:13px 16px}
@media(min-width:620px){.lead-f{grid-template-columns:1fr 1fr}.lead-w{grid-column:1/-1}}
.fld{display:flex;flex-direction:column;gap:6px;min-width:0}
.fld label{font-size:13.5px;font-weight:700;letter-spacing:-.005em;color:var(--ink)}
.fld .opt{font-weight:400;color:var(--ink-3)}
.fld input,.fld select,.fld textarea{width:100%;font:inherit;font-size:15px;color:var(--ink);
     background:var(--paper);border:1.5px solid var(--hair-2);border-radius:var(--r);
     padding:12px 13px;min-height:48px;
     transition:border-color .16s var(--ease),box-shadow .16s var(--ease)}
.fld textarea{min-height:104px;resize:vertical;line-height:1.55}
.fld select{appearance:none;cursor:pointer;
     background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23746070' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 2l5 4 5-4'/%3E%3C/svg%3E");
     background-repeat:no-repeat;background-position:right 13px center;background-size:12px;padding-right:36px}
:root[data-theme="dark"] .fld select{
     background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23a397a1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 2l5 4 5-4'/%3E%3C/svg%3E")}
.fld input:focus-visible,.fld select:focus-visible,.fld textarea:focus-visible{
     outline:3px solid var(--plum);outline-offset:2px;border-color:var(--plum)}
/* Errors are named on the field, not collected in a summary the eye
   has to travel back to. --fault is the semantic token; this is the
   one thing on the site that legitimately uses it. */
.fld[data-bad="true"] input,.fld[data-bad="true"] select,.fld[data-bad="true"] textarea{border-color:var(--fault)}
.fld .err{display:none;font-size:13px;font-weight:600;color:var(--fault)}
.fld[data-bad="true"] .err{display:block}

.lead-go{grid-column:1/-1;display:flex;flex-wrap:wrap;align-items:center;gap:14px;margin-top:4px}
.lead-note{font-size:13px;line-height:1.5;color:var(--ink-3);max-width:44ch}
.lead-ok{display:none;text-align:left}
.lead[data-sent="true"] .lead-f{display:none}
.lead[data-sent="true"] .lead-ok{display:block}
.lead-ok h3{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.03em;font-size:22px;margin:22px 0 0}
.lead-ok p{margin:10px 0 0;color:var(--ink-2);font-size:15.5px;line-height:1.6;max-width:52ch}

/* ── Lead form: send details, or book a time ──────────────────────
   Two paths declared before any typing. The picker only renders when
   BOOK_URL is set in site.js — an unconfigured scheduler must not
   appear as a control that goes nowhere. */
.lead-pick{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:4px;
     margin:0 clamp(18px,3vw,28px) 18px;background:var(--paper);
     border:1.5px solid var(--hair-2);border-radius:10px}
.lead-tab{font:inherit;font-size:14px;font-weight:700;letter-spacing:-.01em;
     min-height:42px;padding:0 12px;border:0;border-radius:7px;cursor:pointer;
     background:transparent;color:var(--ink-2);
     transition:background .16s var(--ease),color .16s var(--ease)}
.lead-tab:hover{color:var(--ink)}
.lead-tab:focus-visible{outline:3px solid var(--plum);outline-offset:2px}
.lead-tab[aria-pressed="true"]{background:var(--plum-s);color:var(--on-plum)}
:root[data-theme="dark"] .lead-tab[aria-pressed="true"]{box-shadow:inset 0 0 0 1px var(--plum)}
/* --hair-2 composites to 2.72:1 against --card in dark, under the 3:1 floor
   for a control boundary. The active state is carried by the plum fill, so
   this is polish rather than a violation — but a track you can barely see is
   not a track. 40% lands at 3.43:1. */
:root[data-theme="dark"] .lead-pick{border-color:rgba(245,240,244,.40)}

.lead-book{display:none;padding:0 clamp(18px,3vw,28px) clamp(20px,3vw,28px)}
.lead[data-mode="book"] .lead-book{display:block}
.lead[data-mode="book"] .lead-f{display:none}
.lead-book p{margin:0 0 18px;font-size:15.5px;line-height:1.6;color:var(--ink-2);max-width:52ch}
.lead-book .lead-note{display:block;margin-top:14px}

/* Booking embedded rather than linked out. Google's own snippet paints a
   #039BE5 button and pulls a stylesheet and script from calendar.google.com
   on every page load — for a control most visitors never open. The iframe
   uses the same schedule and is built on first use, so nothing of Google's
   loads until someone actually asks to book. */
.lead[data-mode="book"]{max-width:min(940px,calc(100vw - 24px))}
.lead-embed{width:100%;height:min(640px,68vh);border:1.5px solid var(--hair-2);
     border-radius:10px;background:#fff;display:block}
/* Google's scheduler renders in its own light styling and ignores the page
   theme — nothing can be done about that across an origin. In dark mode it is
   a white panel, so it is given a light inset frame to read as a deliberate
   plate rather than a blown-out rectangle. */
:root[data-theme="dark"] .lead-embed{border-color:rgba(245,240,244,.40);
     box-shadow:0 0 0 6px rgba(245,240,244,.06)}
.lead-book .lead-alt{display:inline-flex;align-items:center;gap:8px;min-height:44px;
     margin-top:12px;font-size:14px;font-weight:600;color:var(--ink-2);
     text-decoration:underline;text-underline-offset:4px;text-decoration-color:var(--hair-2)}
.lead-book .lead-alt:hover,.lead-book .lead-alt:focus-visible{color:var(--ink);text-decoration-color:var(--plum)}
/* Below the embed's usable width the calendar is cramped and the modal is
   nearly full-screen anyway — link out instead. */
@media(max-width:759px){.lead-embed{display:none}}
@media(min-width:760px){.lead-book > .btn{display:none}}

/* ── Trending Now: the news desk ──────────────────────────────────
   The first build put beat, outlet and date on one line, separated only
   by colour. Three different kinds of information — taxonomy,
   attribution, recency — rendered as one grey rule of small caps. With
   ten of twelve items credited to the same outlet it repeated down the
   whole page. Colour alone cannot carry that.

   So each one now gets a different FORM and a different POSITION:

     beat      a section heading. Appears once, above its group, never
               repeated on the items inside it
     outlet    a credit plate at the foot of the item — a distinct
               object, not a line of text, and the click target
     date      inside the plate, subordinate to the outlet, because it
               qualifies the credit rather than standing beside it

   Grouping by beat is not decoration: the beats are our services, and a
   reader who came from the Paid Media page can jump to Paid Media. */

/* The edition summary. Sits between the H2 and the items so a skimmer
   gets the week without scrolling. */
.wk{margin-top:clamp(22px,2.6vw,30px);padding:clamp(22px,2.8vw,32px);
    background:var(--paper-2);border-radius:12px;max-width:72ch}
.wk h3{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
       letter-spacing:-.028em;font-size:clamp(17px,1.9vw,20px);line-height:1.2;color:var(--ink)}
.wk p{margin-top:11px;font-size:clamp(15.5px,1.7vw,17px);line-height:1.62;color:var(--ink-2)}
.wk p b{color:var(--ink);font-weight:700}
.wk .wk-m{margin-top:16px;padding-top:14px;border-top:1px solid var(--hair-2);
          font-size:13px;color:var(--ink-3)}

/* Beat group. The heading is the page's structural spine. */
.beat{margin-top:clamp(38px,4.6vw,62px)}
.beat-h{display:flex;align-items:baseline;gap:11px;
        padding-bottom:11px;border-bottom:2px solid var(--plum);
        font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
        letter-spacing:-.028em;font-size:clamp(19px,2.3vw,25px);line-height:1.16;color:var(--plum)}
.beat-n{font-family:'Public Sans',sans-serif;font-weight:700;font-size:12.5px;
        letter-spacing:.04em;color:var(--ink-3)}

/* The item. No meta row any more — the beat is overhead, the credit is
   underneath, so what is left is just the reading. */
.ni{padding:clamp(20px,2.4vw,28px) 0;border-bottom:1px solid var(--hair-2)}
.ni h4{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
       letter-spacing:-.028em;font-size:clamp(18.5px,2.05vw,22px);line-height:1.18;
       color:var(--ink);max-width:38ch}
.ni p{margin-top:10px;font-size:15px;line-height:1.58;color:var(--ink-2);max-width:66ch}
.ni .take{margin-top:13px;padding:2px 0 2px 15px;border-left:3px solid var(--plum);
          font-size:15px;line-height:1.5;color:var(--ink);max-width:60ch}

/* The credit plate. The page's whole claim is that the reporting is
   someone else's, so the credit is an object you cannot miss rather
   than the faintest text in the item, which is what it was. */
.cred{display:inline-flex;align-items:baseline;flex-wrap:wrap;gap:3px 10px;
      margin-top:15px;padding:9px 15px;min-height:44px;
      background:var(--card);border:1px solid var(--hair-2);border-radius:999px;
      transition:border-color .2s var(--ease),background .2s var(--ease),transform .2s var(--ease)}
.cred:hover,.cred:focus-visible{border-color:var(--plum);background:var(--paper-2);transform:translateY(-1px)}
.cred-o{font-family:'Bricolage Grotesque','Public Sans',sans-serif;
        font-weight:700;font-size:14.5px;color:var(--ink)}
.cred-d{font-size:12.5px;color:var(--ink-3);letter-spacing:.02em}
.cred i{font-style:normal;color:var(--plum);font-weight:700}
.cred:hover .cred-o,.cred:focus-visible .cred-o{color:var(--plum)}

/* No .empty rule here on purpose. One already exists at the 'filed-under
   chips, and the empty state' block above and does the same job. Defining
   it twice at top level is the exact bug the 13 August polish pass removed
   47 declarations of — the later block silently wins. The archive page
   reuses the existing .empty. */

/* Closing line under the homepage FAQ list. Her "Still have a question?"
   reads as a footer, not an intro — it assumes you have already read them. */
.fq-more{margin-top:clamp(20px,2.4vw,28px);font-size:clamp(15px,1.6vw,16.5px);
         line-height:1.6;color:var(--ink-2);max-width:62ch}

/* ── Self-assessment tool ─────────────────────────────────────────────
   One question on screen at a time. The alternative — sixteen questions
   in a long form — reads as work before you have any reason to trust the
   output, and half of them do not apply to a given firm anyway. */
.as-card{margin-top:clamp(24px,3vw,38px);padding:clamp(24px,3.4vw,42px);
         background:var(--card);border:2px solid var(--hair-2);border-radius:14px}
.as-meta{display:flex;flex-wrap:wrap;gap:6px 14px;align-items:baseline;
         font-size:11.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--plum)}
.as-meta .n{color:var(--ink-3);letter-spacing:.04em}
.as-bar{height:3px;border-radius:2px;background:var(--hair-2);margin-top:14px;overflow:hidden}
.as-bar i{display:block;height:100%;width:0;background:var(--plum);
          transition:width .35s var(--ease)}
.as-card h2{margin-top:18px;font-family:'Bricolage Grotesque','Public Sans',sans-serif;
            font-weight:800;letter-spacing:-.03em;font-size:clamp(20px,2.5vw,28px);
            line-height:1.18;color:var(--ink);max-width:30ch}
.as-opts{display:grid;gap:10px;margin-top:clamp(20px,2.6vw,28px)}
.as-opt{text-align:left;padding:15px 18px;min-height:56px;border-radius:10px;
        background:var(--paper);border:2px solid var(--hair-2);cursor:pointer;
        font-family:'Public Sans',system-ui,sans-serif;font-size:16px;color:var(--ink);
        transition:border-color .18s var(--ease),transform .18s var(--ease)}
.as-opt:hover,.as-opt:focus-visible{border-color:var(--plum);transform:translateY(-2px)}
.as-nav{display:flex;gap:12px;margin-top:20px}
.as-nav button{background:none;border:0;cursor:pointer;min-height:44px;
               font-weight:700;font-size:14.5px;color:var(--ink-2)}
.as-nav button:hover:not(:disabled),.as-nav button:focus-visible{color:var(--plum)}
.as-nav button:disabled{opacity:.35;cursor:default}

/* Result. The verdict is one service name, set loud — a number out of a
   hundred would invite argument about the number instead of the finding. */
.as-verdict{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
            letter-spacing:-.032em;font-size:clamp(26px,4vw,44px);line-height:1.06;
            color:var(--plum);max-width:18ch}
.as-diag{margin-top:14px;font-size:clamp(16px,1.8vw,18.5px);line-height:1.6;
         color:var(--ink-2);max-width:60ch}
.as-fixh{margin-top:clamp(24px,3vw,34px);font-size:11.5px;font-weight:700;
         letter-spacing:.15em;text-transform:uppercase;color:var(--ink-3)}
.as-fix{margin-top:12px;display:grid;gap:11px;list-style:none;max-width:62ch}
.as-fix li{position:relative;padding-left:24px;font-size:15.5px;line-height:1.55;color:var(--ink)}
.as-fix li::before{content:"";position:absolute;left:0;top:.62em;width:11px;height:2px;
                   border-radius:1px;background:var(--plum)}

/* The full eight, always shown. Naming one problem without showing the
   working is how a diagnostic turns into a sales pitch. */
.as-all{margin-top:clamp(28px,3.4vw,40px);border-top:1px solid var(--hair-2);
        list-style:none;max-width:62ch}
.as-row{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
        padding:12px 0;border-bottom:1px solid var(--hair-2)}
.as-rn{font-weight:700;font-size:15.5px;color:var(--ink)}
.as-rs{flex:none;font-size:12.5px;font-weight:700;letter-spacing:.04em;
       padding:4px 10px;border-radius:100px;border:1px solid var(--hair-2);color:var(--ink-2)}
.as-rs[data-st="weak"]{color:var(--fault);border-color:var(--fault)}
.as-rs[data-st="unclear"]{color:var(--amber);border-color:var(--amber)}
.as-rs[data-st="ok"]{color:var(--ok);border-color:var(--ok)}
.as-acts{display:flex;flex-wrap:wrap;gap:12px;align-items:center;margin-top:clamp(24px,3vw,34px)}
.as-acts button{background:none;border:0;cursor:pointer;min-height:44px;
                font-weight:700;font-size:14.5px;color:var(--ink-2);text-decoration:underline;
                text-underline-offset:3px}
.as-acts button:hover,.as-acts button:focus-visible{color:var(--plum)}
.as-note{margin-top:18px;font-size:13.5px;line-height:1.55;color:var(--ink-3);max-width:56ch}
@media(min-width:620px){.as-opts{grid-template-columns:repeat(3,1fr)}}

/* ── Calculators (afford-to-pay, ad spend, native budget) ────────────
   Reuses .as-card / .as-verdict / .as-diag / .as-acts / .as-note from
   the self-assessment so a calculator's result panel reads as the same
   component as a diagnostic's — both are "you put numbers or answers
   in, a plain-English read comes out". Only the input grid and the
   output stat are new. */
.cal-grid{display:grid;gap:14px 16px;margin-top:clamp(20px,2.6vw,28px)}
@media(min-width:560px){.cal-grid{grid-template-columns:1fr 1fr}}
.cal-grid .fld input,.cal-grid .fld select{background:var(--card)}
.cal-go{margin-top:clamp(20px,2.6vw,26px)}
.cal-out{margin-top:clamp(24px,3vw,34px);padding-top:clamp(22px,2.8vw,30px);
     border-top:1px solid var(--hair-2)}
.cal-stat{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 14px}
.cal-num{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.03em;font-size:clamp(34px,5.4vw,54px);line-height:1;color:var(--plum)}
.cal-unit{font-size:14.5px;font-weight:700;color:var(--ink-3);letter-spacing:.02em}
.cal-break{margin-top:clamp(24px,3vw,32px)}
.cal-brow{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
     padding:11px 0;border-top:1px solid var(--hair-2);font-size:15px}
.cal-brow:first-of-type{border-top:0}
.cal-brow b{color:var(--ink);font-weight:700}
.cal-brow span{color:var(--ink-3);flex:none}
.cal-brow[data-break="true"] b{color:var(--fault)}
.cal-brow[data-band="good"] b{color:var(--ok)}
.cal-brow[data-band="mid"] b{color:var(--amber)}
.cal-brow[data-band="poor"] b{color:var(--fault)}
.cal-src{margin-top:clamp(20px,2.4vw,26px);font-size:12.5px;line-height:1.6;color:var(--ink-3);max-width:60ch}
.cal-src b{color:var(--ink-2);font-weight:700}
.cal-src ul{margin:8px 0 0;padding:0;list-style:none;display:grid;gap:4px}
.cal-src a{color:var(--ink-3);text-decoration:underline;text-underline-offset:2px}
.cal-src a:hover,.cal-src a:focus-visible{color:var(--plum)}

/* ── Checklists (conversion checklist, pre-launch account check) ─────
   Real checkboxes, not decoration — state lives in the input so it
   survives print, screen readers and keyboard use for free rather than
   needing a bespoke control. Progress is derived, not tracked twice. */
.chk-card{margin-top:clamp(24px,3vw,38px)}
.chk-top{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
     gap:14px 20px;padding-bottom:clamp(16px,2vw,22px);border-bottom:1px solid var(--hair-2)}
.chk-prog{font-size:14px;font-weight:700;color:var(--ink-2)}
.chk-prog b{color:var(--plum)}
.chk-bar{height:3px;border-radius:2px;background:var(--hair-2);margin-top:8px;
     width:min(220px,40vw);overflow:hidden}
.chk-bar i{display:block;height:100%;width:0;background:var(--plum);
     transition:width .3s var(--ease)}
.chk-acts{display:flex;flex-wrap:wrap;gap:10px}
.chk-acts button{font:inherit;font-size:13.5px;font-weight:700;letter-spacing:-.005em;
     min-height:40px;padding:0 16px;border-radius:var(--r);cursor:pointer;
     background:none;border:1.5px solid var(--hair-2);color:var(--ink);
     transition:border-color .16s var(--ease)}
.chk-acts button:hover,.chk-acts button:focus-visible{border-color:var(--plum);color:var(--plum)}
.chk-cat{margin-top:clamp(26px,3.2vw,36px);display:flex;align-items:baseline;
     justify-content:space-between;gap:14px}
.chk-cat h2{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.02em;font-size:clamp(18px,2vw,21px);margin:0}
.chk-cat span{font-size:12.5px;font-weight:700;color:var(--ink-3);letter-spacing:.02em}
.chk-list{list-style:none;margin:12px 0 0;padding:0;display:grid;gap:2px}
.chk-item{display:flex;align-items:flex-start;gap:13px;padding:13px 14px;border-radius:10px;
     transition:background .14s var(--ease)}
.chk-item:hover{background:var(--paper-2)}
.chk-item input[type="checkbox"]{appearance:none;flex:none;width:21px;height:21px;
     margin-top:1px;border-radius:6px;border:1.8px solid var(--hair-2);background:var(--card);
     cursor:pointer;display:grid;place-items:center;transition:border-color .14s var(--ease),background .14s var(--ease)}
.chk-item input[type="checkbox"]:hover{border-color:var(--plum)}
.chk-item input[type="checkbox"]:focus-visible{outline:3px solid var(--plum);outline-offset:2px}
.chk-item input[type="checkbox"]:checked{background:var(--plum);border-color:var(--plum)}
.chk-item input[type="checkbox"]:checked::after{content:"";width:11px;height:7px;
     border-left:2.4px solid var(--on-plum);border-bottom:2.4px solid var(--on-plum);
     transform:rotate(-45deg) translate(1px,-1px)}
.chk-item label{cursor:pointer;font-size:15.5px;line-height:1.5;color:var(--ink)}
.chk-item p{margin:3px 0 0;font-size:13.5px;line-height:1.5;color:var(--ink-3);max-width:56ch}
.chk-item:has(input:checked) label{color:var(--ink-3);text-decoration:line-through;text-decoration-color:var(--hair-2)}
@media print{
  .nav,.marks-bg,.grain,.prog,footer,.totop,.close,.chk-acts,.hero .sub + p,
  .chk-item input[type="checkbox"]{display:none !important}
  .chk-item{page-break-inside:avoid}
  .chk-item::before{content:"\2610";margin-right:6px}
  body{background:#fff;color:#000}
}

/* ── Downloadable template previews (brief, keyword sheet, email pack) ─
   The download is the actual deliverable; the on-page blocks are a
   preview so the page is useful without opening a file, and each block
   can be copied on its own rather than forcing a full download first. */
.dl-card{margin-top:clamp(24px,3vw,38px)}
.dl-block{margin-top:clamp(22px,2.8vw,32px);padding:clamp(18px,2.4vw,26px);
     background:var(--paper-2);border-radius:12px;border-top:1px solid var(--hair-2)}
.dl-block h3{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.02em;font-size:clamp(16.5px,1.9vw,19px);margin:0}
.dl-block > p{margin:8px 0 0;font-size:14.5px;line-height:1.55;color:var(--ink-2);max-width:60ch}
.dl-pre{margin:14px 0 0;padding:14px 16px;background:var(--card);border-radius:8px;
     border:1px solid var(--hair-2);font-family:inherit;font-size:14px;line-height:1.65;
     color:var(--ink);white-space:pre-wrap;max-width:70ch}
.dl-copy{margin-top:12px;font:inherit;font-size:13px;font-weight:700;letter-spacing:-.005em;
     min-height:38px;padding:0 15px;border-radius:var(--r);cursor:pointer;
     background:none;border:1.5px solid var(--hair-2);color:var(--ink);
     transition:border-color .16s var(--ease)}
.dl-copy:hover,.dl-copy:focus-visible{border-color:var(--plum);color:var(--plum)}
.dl-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
     gap:14px 20px;margin-top:clamp(20px,2.6vw,28px)}
.dl-head .btn{flex:none}

/* ── Email gate — the free/custom split on the sales, AM and ops tools ──
   Dashed border reads as "not the default state" without a new colour;
   the tag is the one honest sentence about what unlocking actually does. */
.gate-card{margin-top:clamp(24px,3vw,34px);padding:clamp(20px,2.6vw,30px);
     border:1.5px dashed var(--hair-2);border-radius:12px;background:var(--paper-2)}
.gate-card h3{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.02em;font-size:clamp(17px,2vw,20px);margin:0}
.gate-card > p{margin:8px 0 0;font-size:14.5px;line-height:1.55;color:var(--ink-2);max-width:58ch}
.gate-tag{display:inline-flex;align-items:center;gap:6px;margin-top:10px;font-size:11.5px;
     font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3)}
.gate-card .cal-grid{margin-top:16px;max-width:420px}
.custom-panel{margin-top:clamp(24px,3vw,34px);padding-top:clamp(20px,2.6vw,28px);
     border-top:1.5px solid var(--plum)}
.custom-panel > .tag{display:inline-block;font-size:11px;font-weight:700;letter-spacing:.05em;
     text-transform:uppercase;color:var(--plum);margin-bottom:8px}

/* ── Creative Resizer ─────────────────────────────────────────────── */
.rz-file{display:inline-flex;align-items:center;gap:12px;min-height:48px;padding:0 18px;
     border-radius:var(--r);border:1.5px dashed var(--hair-2);background:var(--paper);
     cursor:pointer;font-size:14.5px;font-weight:700;color:var(--ink);
     transition:border-color .16s var(--ease)}
.rz-file:hover{border-color:var(--plum)}
.rz-file input{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}
.rz-fname{font-size:13.5px;color:var(--ink-3)}
.rz-results{margin-top:18px;display:grid;gap:10px}
.rz-row{display:flex;align-items:center;gap:14px;padding:10px 12px;border-radius:10px;
     border:1px solid var(--hair-2);background:var(--card)}
.rz-thumb{width:64px;height:44px;object-fit:cover;border-radius:6px;background:var(--paper-2);flex:none}
.rz-meta{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}
.rz-meta b{font-size:14.5px;color:var(--ink)}
.rz-meta span{font-size:12.5px;font-weight:600}
.rz-dl{flex:none;font:inherit;font-size:13px;font-weight:700;min-height:38px;padding:0 15px;
     border-radius:var(--r);cursor:pointer;background:none;border:1.5px solid var(--hair-2);
     color:var(--ink);transition:border-color .16s var(--ease)}
.rz-dl:hover,.rz-dl:focus-visible{border-color:var(--plum);color:var(--plum)}
.rz-dl:disabled{opacity:.4;cursor:default}

/* Small reference table — the keyword opportunity sheet's column guide
   and example rows. Scrolls horizontally on narrow screens rather than
   wrapping cells, which is unreadable for a structured sheet. */
.dl-tbl-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;margin-top:16px;
     border:1px solid var(--hair-2);border-radius:10px}
.dl-tbl{width:100%;border-collapse:collapse;font-size:13.5px;min-width:640px}
.dl-tbl th,.dl-tbl td{text-align:left;padding:10px 14px;border-bottom:1px solid var(--hair-2);
     white-space:nowrap}
.dl-tbl th{font-weight:700;color:var(--ink);background:var(--paper-2);letter-spacing:.01em}
.dl-tbl td{color:var(--ink-2)}
.dl-tbl tr:last-child td{border-bottom:0}

/* ── Headline & Ad Copy Generator ─────────────────────────────────── */
/* Platform-target chips — same toggle pattern as .tp (tools-shelf category
   pills) and the aria-pressed convention used by .topic and .lead-tab, so
   this doesn't invent a fourth way to show "on". */
.hg-plats{display:flex;flex-wrap:wrap;gap:10px;margin-top:6px}
.hg-plat{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:700;font-size:14.5px;
     padding:11px 20px;border-radius:100px;border:2px solid var(--hair-2);background:var(--card);
     color:var(--ink);cursor:pointer;transition:border-color .15s,background .15s,color .15s}
.hg-plat:hover{border-color:var(--plum)}
.hg-plat[aria-pressed="true"]{background:var(--plum-s);border-color:var(--plum-s);color:var(--on-plum)}
.hg-plat:focus-visible{outline:3px solid var(--plum);outline-offset:3px}

/* Dual-column output — one column per checked platform. A single checked
   platform gets the full width rather than an empty second column. */
.hg-cols{margin-top:clamp(20px,2.6vw,28px);display:grid;gap:20px}
.hg-cols[data-cols="2"]{grid-template-columns:1fr}
@media(min-width:760px){.hg-cols[data-cols="2"]{grid-template-columns:1fr 1fr}}
.hg-col-h{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
     padding-bottom:10px;border-bottom:2px solid var(--ink)}
.hg-col-h h3{margin:0;font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     font-size:17px;letter-spacing:-.01em;color:var(--ink)}
.hg-col-limit{flex:none;font-size:12px;font-weight:700;color:var(--ink-3);white-space:nowrap}

.hg-list{margin-top:14px;display:grid;gap:10px}
.hg-row{display:flex;flex-direction:column;gap:8px;padding:14px 14px 12px;border-radius:10px;
     border:1px solid var(--hair-2);background:var(--card)}
.hg-row-top{display:flex;align-items:center;justify-content:space-between;gap:10px}
.hg-frame{font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3)}
.hg-ctr{flex:none;font-size:11.5px;font-weight:700;color:var(--plum);white-space:nowrap}
:root[data-theme="dark"] .hg-ctr{color:var(--plum)}
.hg-txt{font-size:15px;line-height:1.45;color:var(--ink);font-weight:600}
.hg-row-bottom{display:flex;align-items:center;justify-content:space-between;gap:10px}
.hg-cnt{flex:none;font-size:12px;font-weight:700;white-space:nowrap}
.hg-copy{flex:none;font:inherit;font-size:12.5px;font-weight:700;letter-spacing:-.005em;
     padding:6px 12px;border-radius:100px;border:1.5px solid var(--hair-2);background:transparent;
     color:var(--ink-2);cursor:pointer;transition:border-color .15s,color .15s}
.hg-copy:hover,.hg-copy:focus-visible{border-color:var(--plum);color:var(--plum)}
.hg-copy[data-copied="true"]{border-color:var(--ok);color:var(--ok)}

.hg-h3{margin-top:22px;margin-bottom:0;font-size:12.5px;font-weight:700;letter-spacing:.04em;
     text-transform:uppercase;color:var(--ink-3)}
.hg-plat-note{margin-top:10px;font-size:13px;color:var(--ink-3)}
.hg-plat-note a{color:inherit}

/* ── Campaign Pacing Tracker (compact multi-stat cards) ───────────── */
.pt-stat{display:flex;flex-direction:column;gap:4px;padding:12px 14px;border-radius:10px;
     border:1px solid var(--hair-2);background:var(--card)}
.pt-num{font-family:'Bricolage Grotesque','Public Sans',sans-serif;font-weight:800;
     letter-spacing:-.01em;font-size:19px;line-height:1.15;color:var(--plum)}
.pt-unit{font-size:12px;font-weight:700;color:var(--ink-3);letter-spacing:.01em}

/* ── Meta Tag & Snippet Previewer ─────────────────────────────────── */
/* The SERP mock intentionally borrows Google's own real-world colours
   rather than the site's plum/citron tokens — the point of a preview is
   to show what a stranger sees on Google, not to brand-wash it. */
.mt-serp{padding:18px 20px;border-radius:8px;border:1px solid var(--hair-2);
     background:#fff;max-width:600px}
:root[data-theme="dark"] .mt-serp{background:#202124;border-color:#3c4043}
.mt-serp-url{font-size:14px;color:#202124;font-family:arial,sans-serif}
:root[data-theme="dark"] .mt-serp-url{color:#bdc1c6}
.mt-serp-title{margin-top:3px;font-size:20px;line-height:1.3;color:#1a0dab;
     font-family:arial,sans-serif;font-weight:400}
:root[data-theme="dark"] .mt-serp-title{color:#8ab4f8}
.mt-serp-desc{margin-top:3px;font-size:14px;line-height:1.57;color:#4d5156;
     font-family:arial,sans-serif;max-width:600px}
:root[data-theme="dark"] .mt-serp-desc{color:#bdc1c6}
.mt-serp-lbl{font-size:11.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
     color:var(--ink-3);margin-bottom:10px}

.mt-card{border-radius:10px;border:1px solid var(--hair-2);overflow:hidden;max-width:500px;background:var(--card)}
.mt-card-img{height:120px;background:linear-gradient(135deg,var(--paper-2),var(--hair-2));
     display:flex;align-items:center;justify-content:center;color:var(--ink-3);font-size:12.5px;font-weight:600}
.mt-card-body{padding:12px 16px}
.mt-card-url{font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.mt-card-title{margin-top:4px;font-size:15.5px;font-weight:700;color:var(--ink);line-height:1.3}
.mt-card-desc{margin-top:4px;font-size:13.5px;color:var(--ink-2);line-height:1.4}

.mt-preview-h3{font-size:12.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
     color:var(--ink-3);margin:26px 0 12px}
.mt-preview-h3:first-child{margin-top:0}

.mt-count{display:block;margin-top:6px;font-size:13px;font-weight:600}
.mt-count.nt-empty{color:var(--ink-3)}
.mt-count.nt-good{color:var(--ok)}
.mt-count.nt-short{color:var(--amber)}
.mt-count.nt-long{color:var(--fault)}

/* ── Schema Markup Validator (lite) ───────────────────────────────── */
.sv-block{margin-top:22px;padding-top:18px;border-top:1px solid var(--hair-2)}
.sv-block:first-child{margin-top:0;padding-top:0;border-top:0}
.sv-block h3{font-size:15.5px;letter-spacing:-.01em;margin-bottom:10px;color:var(--ink)}
.sv-list{list-style:none;display:grid;gap:2px}
.sv-item{display:flex;align-items:flex-start;gap:10px;padding:8px 10px;border-radius:8px;font-size:14px}
.sv-mark{flex:none;width:18px;height:18px;border-radius:50%;display:grid;place-items:center;
     font-size:11px;font-weight:800;margin-top:1px}
.sv-pass .sv-mark{background:var(--ok);color:var(--card)}
.sv-pass{color:var(--ink-2)}
.sv-fail .sv-mark{background:var(--fault);color:var(--card)}
.sv-fail{color:var(--ink)}
.sv-warn .sv-mark{background:var(--amber);color:var(--card)}
.sv-warn{color:var(--ink-2)}
