/* ============================================================================
   Kent Applied Design System: ka.css (v8, 2026-10-05)
   The one stylesheet for everything branded Kent Applied. Pages link it
   directly (/design/ka.css?v=<hash>, stamped by ops/build_site.py).
   Order: tokens, base, layout, header and menu, buttons and links, hero,
   cards, components, CTA band, footer, forms, motion, utilities.
   Motion: CSS owns hover, press, focus and page transitions (translate, scale,
   color, shadow); ka-motion.js (GSAP) owns entrances (transform, opacity,
   clip-path). The two never animate the same property on the same element.
   Rules and usage: site/DESIGN.md and the living guide at /design/.
   Change tokens here, never in a page.
   ========================================================================== */

/* ---------- 1. Tokens ---------- */
:root{
  /* color (contrast on white / on --bg) */
  --bg:#f7f9fc; --surface:#fff;
  --ink:#0a1528;                 /* headings, dark band */
  --body:#41506a;                /* body text 8.1 / 7.7 */
  --mut:#5b6a84;                 /* secondary text 5.5 / 5.2 */
  --line:#e3e9f2; --line-2:#cfdcf3;
  --blue:#1d4ed8;                /* links, labels, prices 6.7 / 6.4 */
  --blue2:#2563eb;               /* focus rings, selected data, borders */
  --sky:#38bdf8;                 /* fills and dots only, never text (2.1:1) */
  --tint:#f2f7ff; --tint-2:#e6efff; --tint-line:#d6e4ff;
  --grad:linear-gradient(135deg,#2563eb,#38bdf8);      /* brand: logo tile, data marks */
  --grad-btn:linear-gradient(135deg,#1d4ed8,#2f6be4);  /* primary button: white text 6.7 to 4.8 */
  --grad-text:linear-gradient(100deg,#2563eb 15%,#0891d1);  /* the one hero word: 4.9 to 3.3, large text */
  --warm:#c2410c;                /* data only: values above a target (5.2 on white) */
  --error:var(--warm);           /* form errors: invalid field borders, the error box's edge */
  --data-dim:#b9c6dc;            /* data only: unselected points */
  /* data palette (v9, 2026-10-08): every chart, research story and fact card draws from these, in
     this order for ordered categories (strongest first). Contrast on white: d1 10.4, d2 6.7, d3 5.1
     (white value labels inside a d3 segment pass AA; it was #0284c7 at 4.1 until 9 Oct); d4 is the
     brand sky, 2.1, so it only ever fills marks whose value is also written as text. */
  --d1:#1e3a8a; --d2:#1d4ed8; --d3:#0373b0; --d4:#38bdf8;
  --grid:#e6ecf5;                /* chart gridlines */
  --axis:#c9d3e3;                /* chart axes and baselines */
  --band:#0a1528; --band-text:#e8eefc; --band-mut:#a9b8d2; --band-link:#7dd3fc;
  --focus:#2563eb;
  /* shape and depth */
  --r:18px; --r-sm:12px; --r-lg:22px;
  --sh:0 1px 2px rgb(10 21 40/.04),0 12px 32px rgb(10 21 40/.06);
  --sh-hover:0 18px 40px rgb(29 78 216/.12);
  --sh-edge:0 10px 18px -14px rgb(10 21 40/.3);   /* under a sticky bar's hairline (the /news/ day bar) */
  --sh-drop:0 14px 24px -14px rgb(10 21 40/.22);  /* a panel that opens down over the page (the /news/ strip) */
  --sh-mark:0 2px 8px rgb(29 78 216/.4);          /* lift under a selected data mark (the /insights/ index dot) */
  /* type */
  --disp:'Space Grotesk','Space Grotesk Fallback',ui-sans-serif,sans-serif;
  --sans:'Inter','Inter Fallback',ui-sans-serif,system-ui,sans-serif;
  --fs-xs:12.5px;                      /* kickers, labels, table heads */
  --fs-sm:14px;                        /* captions, meta, secondary card text */
  --fs-ui:15.5px;                      /* card text, nav, buttons, FAQ answers */
  --fs-base:16.5px;                    /* body */
  --fs-lg:18px;                        /* ledes, row names */
  --fs-xl:21px;                        /* card titles (h3) */
  --fs-2xl:clamp(23px,2.4vw,27px);     /* sub-sections, figure titles, article h2 */
  --fs-3xl:clamp(30px,3.8vw,42px);     /* section h2, band h2 */
  --fs-4xl:clamp(36px,5vw,60px);       /* page h1, homepage hero */
  --measure:68ch;
  /* space */
  --gutter:24px;
  --hdr-h:72px;                        /* fixed header row (68px on phones) */
  --sec:clamp(72px,10vw,128px);
  /* motion */
  --ease-out:cubic-bezier(.23,1,.32,1);   /* arrivals */
  --ease-in:cubic-bezier(.7,0,.84,0);     /* departures */
  --ease-io:cubic-bezier(.65,0,.35,1);    /* between two known places */
  --ease-ui:cubic-bezier(.2,0,0,1);       /* hover, press, focus */
  --dur-press:120ms; --dur-hover:180ms; --dur-ui:240ms; --dur-enter:520ms; --dur-sig:760ms;
  --rise:14px; --step:60ms;
  --chev:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 14'%3E%3Cpath d='M1.3 1.3 6.7 7l-5.4 5.7' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --check:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8.5 6.5 12 13 4.5' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --lock:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Crect x='3.5' y='8.5' width='13' height='9' rx='2' fill='none' stroke='%23000' stroke-width='1.7'/%3E%3Cpath d='M6.5 8.5V6a3.5 3.5 0 0 1 7 0v2.5' fill='none' stroke='%23000' stroke-width='1.7'/%3E%3C/svg%3E");
  --dl:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 2v8.5M4.5 7 8 10.5 11.5 7M3 13.5h10' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* Metric-matched fallbacks. While the web fonts load (display=swap), text sets in Arial scaled to the
   same average width and line metrics as Inter and Space Grotesk at each weight, so nothing re-wraps
   or shifts when the real fonts arrive (CLS). Measured 2026-10-06 with fontTools from the Google Fonts
   files (Inter v20, Space Grotesk v22) against Arial-metric Liberation Sans, weighted by site copy. */
@font-face{font-family:"Inter Fallback";src:local("Arial"),local("ArialMT"),local("Liberation Sans"),local("Helvetica");font-weight:400;size-adjust:107.14%;ascent-override:90.42%;descent-override:22.51%;line-gap-override:0%}
@font-face{font-family:"Inter Fallback";src:local("Arial"),local("ArialMT"),local("Liberation Sans"),local("Helvetica");font-weight:500;size-adjust:108.25%;ascent-override:89.49%;descent-override:22.28%;line-gap-override:0%}
@font-face{font-family:"Inter Fallback";src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("Helvetica Bold");font-weight:600;size-adjust:101.67%;ascent-override:95.28%;descent-override:23.72%;line-gap-override:0%}
@font-face{font-family:"Inter Fallback";src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("Helvetica Bold");font-weight:700;size-adjust:102.69%;ascent-override:94.34%;descent-override:23.49%;line-gap-override:0%}
@font-face{font-family:"Space Grotesk Fallback";src:local("Arial"),local("ArialMT"),local("Liberation Sans"),local("Helvetica");font-weight:500;size-adjust:108.44%;ascent-override:90.74%;descent-override:26.93%;line-gap-override:0%}
@font-face{font-family:"Space Grotesk Fallback";src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("Helvetica Bold");font-weight:600;size-adjust:101.34%;ascent-override:97.1%;descent-override:28.81%;line-gap-override:0%}
@font-face{font-family:"Space Grotesk Fallback";src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("Helvetica Bold");font-weight:700;size-adjust:101.37%;ascent-override:97.07%;descent-override:28.81%;line-gap-override:0%}

/* ---------- 2. Base ---------- */
*,*::before,*::after{box-sizing:border-box}
*{margin:0}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;scroll-padding-top:calc(var(--hdr-h) + 16px)}
@media (max-width:760px){:root{--hdr-h:68px}}
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}
body{font-family:var(--sans);font-size:var(--fs-base);line-height:1.7;color:var(--body);background:var(--bg);-webkit-font-smoothing:antialiased;overflow-x:clip}
[hidden]{display:none!important}
img,video,canvas{max-width:100%}
img{height:auto}
/* 1.08 clipped descenders (p, y, g); 1.16 leaves room for them and for gradient text. */
h1,h2,h3,h4,.disp{font-family:var(--disp);color:var(--ink);line-height:1.16;letter-spacing:-.02em;text-wrap:balance}
p,li,dd,figcaption,blockquote{text-wrap:pretty}
p{max-width:var(--measure)}
/* links: blue, a quiet underline in running text; components override color and decoration */
:where(a){color:var(--blue);text-decoration-thickness:1px;text-underline-offset:.2em}
:where(a:hover){color:var(--ink)}
/* in running text the resting underline is a 35% hairline; on hover a full one sweeps in from the left */
@supports (color:color-mix(in srgb,red,blue)){
  :where(main p:not([class]),main :is(.lede,.sub,.alt,.muted,.note,.who-text,.datafig-cap),main li,main dd,main td,main blockquote) a:where(:not([class])){
    text-decoration:none;padding-bottom:.08em;
    background:linear-gradient(currentColor,currentColor) 0 100%/0 1px no-repeat,linear-gradient(color-mix(in srgb,currentColor 35%,transparent),color-mix(in srgb,currentColor 35%,transparent)) 0 100%/100% 1px no-repeat;
    transition:background-size var(--dur-ui) var(--ease-out),color var(--dur-hover) var(--ease-ui)}
  :where(main p:not([class]),main :is(.lede,.sub,.alt,.muted,.note,.who-text,.datafig-cap),main li,main dd,main td,main blockquote) a:where(:not([class])):hover{background-size:100% 1px,100% 1px}
}
/* one focus ring for everything interactive; dark surfaces swap --focus */
:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
main{display:block}
main:focus{outline:none}
code{font:.9em ui-monospace,SFMono-Regular,Menlo,monospace}
.skip{position:fixed;left:12px;top:12px;z-index:200;padding:12px 18px;border-radius:10px;background:var(--ink);color:#fff;font:600 var(--fs-sm)/1 var(--sans);text-decoration:none;transform:translateY(-180%);transition:transform var(--dur-ui) var(--ease-out)}
.skip:focus{transform:none;color:#fff}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ---------- 3. Layout and text helpers ---------- */
.wrap{max-width:1120px;margin:0 auto;padding:0 var(--gutter)}
section{padding:var(--sec) 0;position:relative}
.sec-flush{padding-top:0}
.sec-tight{padding-top:clamp(24px,4vw,48px)}
/* html scroll-padding keeps focused and linked targets clear of the fixed header; anchored blocks add 8px */
section[id],[id].case,[id].post,.fee-group[id],.datafig[id]{scroll-margin-top:8px}
.kicker{font:700 var(--fs-xs)/1.25 var(--sans);text-transform:uppercase;letter-spacing:.14em;color:var(--blue);margin-bottom:18px}
/* kicker links (breadcrumbs, "Blog" on posts): a faint underline says they are links, and an invisible
   44px-tall hit area makes them easy to tap one-handed without moving the line */
.kicker a{display:inline-block;padding-block:14px;margin-block:-14px;color:inherit;text-decoration:underline 1px rgb(29 78 216/.35);text-underline-offset:.32em;transition:text-decoration-color var(--dur-hover) var(--ease-ui)}
.kicker a:hover{text-decoration-color:currentColor}
.h2{font-size:var(--fs-3xl);margin-bottom:16px}
.lede{max-width:60ch;font-size:var(--fs-lg);color:var(--body)}
.muted{color:var(--mut)}
.tnum,.price,.num,.pnum,.svc-p,.px,.fee-price,.fee-dur,.tier-price,.way-p,table.data{font-variant-numeric:tabular-nums}
.free{color:var(--blue)}
/* gradient text: one word on the whole site, inside the homepage hero headline. Anywhere
   else .grad-text renders as plain heading ink. */
.grad-text{color:inherit}
.hero .hline .grad-text{background:var(--grad-text);-webkit-background-clip:text;background-clip:text;color:transparent;padding-right:.04em}
/* the one text-link style for "See more" links: blue, semibold, arrow, underline on hover */
a.more{display:inline-flex;align-items:center;gap:6px;min-height:40px;font-weight:600;color:var(--blue);text-decoration:none}
a.more::after{content:"\2192";content:"\2192" / "";display:inline-block;transition:transform var(--dur-hover) var(--ease-ui)}
a.more:hover{color:var(--blue);text-decoration:underline}
@media (hover:hover) and (pointer:fine){a.more:hover::after{transform:translateX(3px)}}

/* ---------- 4. Header, nav, phone menu sheet ---------- */
#hdr{position:fixed;inset:0 0 auto;z-index:50;border-bottom:1px solid transparent;transition:background-color .2s,border-color .2s,box-shadow .2s;view-transition-name:ka-header}
/* a programmatic jump (skip link, a filter, a Home key) paints the backdrop at once (ka-motion.js) */
#hdr.snap{transition:none}
#hdr.scrolled,html:not(.js) #hdr{background:rgb(255 255 255/.94);-webkit-backdrop-filter:saturate(1.6) blur(12px);backdrop-filter:saturate(1.6) blur(12px);border-bottom-color:var(--line);box-shadow:0 4px 24px rgb(10 21 40/.05)}
.hdr-row{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:var(--hdr-h)}
.logo{display:inline-flex;align-items:center;gap:9px;min-height:44px;font-family:var(--disp);font-weight:700;font-size:20px;color:var(--ink);text-decoration:none;letter-spacing:-.02em;white-space:nowrap}
.logo:hover{color:var(--ink)}
.logo b{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.logo-mark{flex:none;width:26px;height:26px;border-radius:6px;box-shadow:0 2px 6px rgb(37 99 235/.25)}
/* the lockup: the name over its descriptor, as in the email signature (Tyler, 2026-10-13). One line on
   desktop; two lines on phones and small tablets. At 360 to 379px the descriptor drops its tracking and the
   header gaps tighten so it fits beside Book a call (at 359px and below that button is hidden) */
.logo{gap:10px}
.logo-mark{width:30px;height:30px}
.logo-txt{display:flex;flex-direction:column;gap:3px;line-height:1}
.logo-tag{font:700 9.5px/1.2 var(--sans);letter-spacing:.07em;text-transform:uppercase;color:var(--blue);white-space:nowrap}
.nav-right .btn.small{white-space:nowrap}
@media (min-width:761px) and (max-width:959px){#hdr .lt-2{display:block}}
@media (max-width:520px){
  .hdr-row{gap:12px}
  #hdr .logo,.sheet-top .logo{gap:8px}
  #hdr .logo-mark,.sheet-top .logo-mark{width:28px;height:28px}
  #hdr .logo-tag,.sheet-top .logo-tag{font-size:8.5px;letter-spacing:.035em}
  #hdr .lt-2,.sheet-top .lt-2{display:block}
}
@media (min-width:360px) and (max-width:379px){#hdr .logo-tag,.sheet-top .logo-tag{letter-spacing:0}#hdr .hdr-row{gap:8px}#hdr .nav-right{gap:6px}#hdr .nav-right .btn.small{padding-left:12px;padding-right:12px}}
/* the footer lockup takes two lines where its column is narrower than the one-line descriptor */
@media (max-width:359px),(min-width:861px) and (max-width:1069px){.foot-brand .lt-2{display:block}}
/* small tablets (761 to 819px): the wider lockup plus touch-size menu chevrons would push Book a call into the
   right margin, so the nav links and the row gap tighten a little */
@media (min-width:761px) and (max-width:819px){#hdr .hdr-row{gap:12px}#hdr .nav-top{padding-inline:9px}#hdr .nav-item[data-dd] .nav-top{padding-right:3px}#hdr .nav-top::after{left:9px;right:9px}#hdr .nav-item[data-dd] .nav-top::after{right:3px}}
/* top nav: Services (menu) · Work · Insights (menu) · About. Each menu item is a link to its section
   page plus a chevron button that opens its menu (disclosure pattern, ka-motion.js). Without JS the
   chevrons are gone and the labels are plain links; until ka-motion wires them (html.ka-nav) they keep
   their space but stay hidden, so nothing shifts. */
.navlinks{position:relative;display:flex;align-items:center}
.nav-list{display:flex;align-items:center;gap:2px;list-style:none;padding:0}
.nav-item{display:flex;align-items:center}
.nav-top{position:relative;display:inline-flex;align-items:center;min-height:40px;padding:0 12px;border-radius:10px;color:var(--body);font:500 var(--fs-ui)/1 var(--sans);text-decoration:none;transition:color var(--dur-hover) var(--ease-ui)}
.nav-top:hover,.nav-item.is-open .nav-top{color:var(--ink)}
.nav-top[aria-current]{color:var(--ink);font-weight:600}
.nav-top::after{content:"";position:absolute;left:12px;right:12px;bottom:3px;height:2px;border-radius:2px;background:var(--grad);scale:0 1;opacity:.5;transition:scale var(--dur-ui) var(--ease-out),opacity var(--dur-ui) var(--ease-ui)}
.nav-top:hover::after{scale:1 1}
.nav-top[aria-current]::after{scale:1 1;opacity:1}
.nav-item[data-dd] .nav-top{padding-right:3px}
.nav-item[data-dd] .nav-top::after{right:3px}
.nav-chev{display:inline-grid;place-items:center;width:26px;height:40px;margin-right:4px;padding:0;border:0;border-radius:8px;background:none;color:var(--mut);cursor:pointer;-webkit-tap-highlight-color:transparent;transition:color var(--dur-hover) var(--ease-ui),background-color var(--dur-hover) var(--ease-ui)}
.nav-chev svg{display:block;width:11px;height:8px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:rotate var(--dur-ui) var(--ease-out)}
.nav-item:hover .nav-chev,.nav-chev[aria-expanded=true]{color:var(--ink)}
.nav-chev:hover{background:var(--tint)}
.nav-chev[aria-expanded=true] svg{rotate:180deg}
.nav-chev:focus-visible{outline-offset:-2px}
@media (pointer:coarse){.nav-chev{width:40px;margin-left:2px}}
html:not(.js) .nav-chev{display:none}
html:not(.js) .nav-item[data-dd] .nav-top{padding-right:12px}
html:not(.js) .nav-item[data-dd] .nav-top::after{right:12px}
html.js:not(.ka-nav) .nav-chev{visibility:hidden}
/* one indicator glides under the item in play (hovered, focused, open, or the current section);
   it replaces the per-link markers once ka-motion has placed it */
.nav-ind{position:absolute;left:0;bottom:3px;width:100px;height:2px;border-radius:2px;background:var(--grad);transform-origin:0 50%;opacity:0;pointer-events:none}
.navlinks.has-ind .nav-top::after{display:none}
/* menus: each panel sits under the header, placed by ka-motion.js (left, and --caret for the pointer).
   One shared surface (.nav-pop) draws the card behind whichever panel is open, so moving from one
   menu to the other glides the card to its new size and place while the contents cross-fade. The
   panel's top padding bridges the gap from the label, so the pointer never falls out on the way. */
.nav-dd{position:absolute;z-index:2;top:100%;left:0;width:var(--dd-w);padding-top:calc((var(--hdr-h) - 40px) / 2 + 8px)}
.dd-services{--dd-w:min(736px,calc(100vw - 32px))}
.dd-insights{--dd-w:min(640px,calc(100vw - 32px))}
.dd-card{position:relative;max-height:calc(100vh - var(--hdr-h) - 24px);overflow:auto;overscroll-behavior:contain;padding:12px;border-radius:var(--r-lg)}
/* too tall for a short window: the card scrolls, and soft shadows at its edges say there is more (ka-motion.js adds .dd-scroll) */
.dd-card.dd-scroll{background:linear-gradient(var(--surface) 30%,rgb(255 255 255/0)) center top/100% 36px no-repeat local,linear-gradient(rgb(255 255 255/0),var(--surface) 70%) center bottom/100% 36px no-repeat local,radial-gradient(farthest-side at 50% 0,rgb(10 21 40/.14),transparent) center top/100% 12px no-repeat scroll,radial-gradient(farthest-side at 50% 100%,rgb(10 21 40/.14),transparent) center bottom/100% 12px no-repeat scroll}
@media (max-height:640px){.dd-services .dd-d{display:none}.dd-services .dd-i{padding-block:10px}}
.nav-pop{position:absolute;z-index:1;left:0;top:0;width:0;height:0;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface);box-shadow:0 28px 64px rgb(10 21 40/.14),0 6px 18px rgb(10 21 40/.06);pointer-events:none}
.nav-caret{position:absolute;top:-7px;left:0;width:14px;height:14px;margin-left:-7px}
.nav-caret::before{content:"";position:absolute;inset:0;border-radius:3px 0 0 0;background:var(--surface);box-shadow:-1px -1px 0 var(--line);rotate:45deg}
#hdr.dd-open{background:rgb(255 255 255/.97);border-bottom-color:var(--line);box-shadow:0 4px 24px rgb(10 21 40/.05)}
.dd-i{position:relative;display:flex;align-items:flex-start;gap:14px;padding:12px 14px;border-radius:14px;color:inherit;text-decoration:none;transition:background-color var(--dur-hover) var(--ease-ui)}
.dd-i:hover{color:inherit;background:var(--tint)}
.dd-i:active{background:var(--tint-2)}
.dd-i:focus-visible{outline-offset:-2px}
.dd-i[aria-current] .dd-n{color:var(--blue)}
.dd-t{display:grid;gap:3px;min-width:0}
.dd-n{font:600 16px/1.25 var(--disp);letter-spacing:-.01em;color:var(--ink);transition:color var(--dur-hover) var(--ease-ui)}
.dd-d{font-size:13.5px;line-height:1.45;color:var(--body)}
.dd-m{margin-top:2px;font:600 12.5px/1.3 var(--sans);color:var(--blue);font-variant-numeric:tabular-nums}
.dd-i .svc-glyph{width:40px;height:40px;border-radius:12px}
.dd-i .svc-glyph svg{width:24px;height:24px;stroke-width:3}
.dd-i:hover .svc-glyph::before{opacity:1}
.dd-i:hover .svc-glyph{color:var(--surface)}
.dd-i:hover .svc-glyph .g-dot{fill:var(--surface)}
.dd-grid{display:grid;grid-template-columns:1fr 1fr;gap:2px;list-style:none;padding:0}
/* an odd last group (seven groups since the AI tools) takes the whole row */
.dd-grid>li:last-child:nth-child(odd){grid-column:1/-1}
.dd-foot{display:flex;align-items:center;gap:12px;margin-top:8px;padding-top:10px;border-top:1px solid var(--line)}
/* the quiz tile closes the grid: a dashed tile until it is hovered */
.dd-quiz .svc-glyph,.sheet-quiz .svc-glyph{background:var(--surface);box-shadow:inset 0 0 0 1.5px var(--tint-line)}
.dd-quiz .dd-m{color:var(--blue)}
.dd-hi{flex:1;align-items:center;background:var(--tint);box-shadow:inset 0 0 0 1px var(--tint-line)}
.dd-hi:hover{background:var(--tint-2)}
.dd-badge{flex:none;padding:6px 10px;border-radius:999px;background:var(--grad-btn);color:#fff;font:700 12px/1 var(--sans);letter-spacing:.04em;box-shadow:0 4px 12px rgb(29 78 216/.22)}
.dd-all{flex:none;align-items:center;gap:8px;min-height:48px;font:600 var(--fs-ui)/1.2 var(--sans);color:var(--blue)}
.dd-all::after{content:"\2192";content:"\2192" / "";transition:translate var(--dur-hover) var(--ease-ui)}
.dd-all:hover{color:var(--blue)}
.dd-all[aria-current]{color:var(--ink)}
.dd-all:hover::after{translate:3px 0}
.dd-foot .dd-all:only-child{margin-left:auto}
.dd-more{margin-left:auto;display:flex;flex-direction:column;align-items:flex-end}
.dd-help{display:flex;gap:16px;margin:0}
.dd-help a{display:inline-flex;align-items:center;min-height:30px;font:500 var(--fs-sm)/1.2 var(--sans);color:var(--body);text-decoration:none}
.dd-help a:hover{color:var(--blue);text-decoration:underline}
.dd-help a[aria-current]{color:var(--blue)}
.sheet-help{display:flex;gap:8px;margin:8px 0 0}
.sheet-help a{flex:1;display:flex;align-items:center;justify-content:center;min-height:44px;padding:0 10px;border-radius:12px;box-shadow:inset 0 0 0 1px var(--line);font:600 var(--fs-sm)/1.2 var(--sans);color:var(--blue);text-decoration:none;text-align:center;-webkit-tap-highlight-color:transparent}
.sheet-help a:active{background:var(--tint)}
.dd-hub{margin-top:auto;align-items:center;box-shadow:inset 0 0 0 1px var(--line)}
.dd-hub .dd-n{color:var(--blue)}
.dd-hub::after{content:"\2192";content:"\2192" / "";margin-left:auto;color:var(--blue);font-weight:600;transition:translate var(--dur-hover) var(--ease-ui)}
.dd-hub:hover::after{translate:3px 0}
.dd-hub[aria-current] .dd-n{color:var(--ink)}
.dd-ins{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:2px}
.dd-col{display:flex;flex-direction:column;gap:2px}
.dd-sub{list-style:none;padding:0 0 4px;margin:0 0 0 30px;border-left:1px solid var(--line)}
.dd-feat{align-items:center;gap:12px;padding:9px 12px 9px 14px;margin-left:8px}
.dd-feat .dd-n{font-size:14.5px}
.dd-feat .dd-d{font-size:13px}
.dd-mini{flex:none;width:56px;height:32px;border-radius:8px;background:var(--bg);box-shadow:inset 0 0 0 1px var(--line);overflow:visible}
.dd-mini path,.dd-mini circle{transition:translate var(--dur-ui) var(--ease-out),scale var(--dur-ui) var(--ease-out)}
.dd-mini .m-tgt{fill:none;stroke:var(--ink);stroke-width:1;stroke-dasharray:2 2;opacity:.5}
.dd-mini .m-dim{fill:none;stroke:var(--data-dim);stroke-width:4;stroke-linecap:round}
.dd-mini .m-sel{fill:none;stroke:var(--blue2);stroke-width:5.5;stroke-linecap:round}
.dd-mini .m-ax{fill:none;stroke:var(--line-2);stroke-width:1.2}
/* the evidence map's verdicts, as in the story: Adopt --d1, Pilot --d2, Watch --d3, Hold --d4 */
.dd-mini .m-a{fill:var(--d1)}
.dd-mini .m-p{fill:var(--d2)}
.dd-mini .m-w{fill:var(--d3)}
.dd-mini .m-h{fill:var(--d4)}
.dd-mini .m-lab{fill:none;stroke:var(--line-2);stroke-width:2;stroke-linecap:round}
.dd-mini circle{transform-box:fill-box;transform-origin:center}
@media (hover:hover) and (pointer:fine){
  .dd-feat:hover .m-team .m-sel{translate:-5px 0}
  .dd-feat:hover .m-test .m-dim{stroke:var(--sky)}
  .dd-feat:hover circle{scale:1.18}
}
.nav-right{display:flex;align-items:center;gap:10px}
.nav-right .btn[aria-current]{background:var(--tint);color:var(--blue);box-shadow:inset 0 0 0 1.5px var(--tint-line)}
.menu-btn{display:none;position:relative;flex:none;width:44px;height:44px;padding:0;border:1px solid var(--line);border-radius:12px;background:var(--surface);box-shadow:var(--sh);color:var(--ink);cursor:pointer;-webkit-tap-highlight-color:transparent}
.menu-ico{position:absolute;left:13px;right:13px;top:50%;height:10px;margin-top:-5px}
.menu-ico span{position:absolute;left:0;right:0;height:2px;border-radius:2px;background:currentColor}
.menu-ico span:first-child{top:0}
.menu-ico span:last-child{bottom:0}
.menu-btn.is-close .menu-ico span:first-child{transform:translateY(4px) rotate(45deg)}
.menu-btn.is-close .menu-ico span:last-child{transform:translateY(-4px) rotate(-45deg)}
.menu-btn:active{background:var(--tint)}
@media (max-width:760px){
  .navlinks{display:none}
  .menu-btn{display:block}
  .nav-right .btn.small{min-height:44px;padding:0 14px}
}
@media (max-width:359px){.nav-right .btn.small{display:none}}
html:not(.js) .menu-btn{display:none}
html.js:not(.ka-sheet) #hdr .menu-btn{visibility:hidden}
/* phone menu: a full-height sheet with its own top row, so the close button sits where the menu button
   was. The four top-level destinations come first as rows of one style (Services, Work, Insights,
   About, each with a short descriptor); Services opens onto its group tiles and the free TEAM report,
   Insights onto Research, Blog and News. Book a call stays pinned in a bar at the bottom. */
.sheet{position:fixed;inset:0;z-index:100;background:var(--bg);overflow-y:auto;overscroll-behavior:contain;opacity:0;translate:0 -8px;transition:opacity 150ms var(--ease-in),translate 150ms var(--ease-in)}
.sheet:not([hidden]){display:flex;flex-direction:column}
.sheet>.wrap,.sheet-cta>.wrap{width:100%}
.sheet.open{opacity:1;translate:none;transition:opacity 220ms var(--ease-out),translate 220ms var(--ease-out)}
html.menu-open{overflow:hidden}
/* the top row (logo and close button) sticks while the sheet scrolls, so the close button is always in
   reach; its hairline fades in once the list moves under it (scroll-driven, see section 13) */
.sheet-top{position:sticky;top:0;z-index:2;flex:none;display:flex;align-items:center;justify-content:space-between;min-height:var(--hdr-h);background:rgb(247 249 252/.92);-webkit-backdrop-filter:saturate(1.6) blur(12px);backdrop-filter:saturate(1.6) blur(12px);box-shadow:0 1px 0 var(--line)}
.sheet-top .menu-btn{display:block}
.sheet-body{flex:1 0 auto;padding-top:2px;padding-bottom:8px}
.sheet-main{list-style:none;padding:0;margin:0}
.sheet-main>li{border-bottom:1px solid var(--line)}
.sheet-grp{padding-bottom:12px}
.sheet-row{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:54px;color:var(--ink);text-decoration:none;-webkit-tap-highlight-color:transparent}
.sr-n{font:600 23px/1.1 var(--disp);letter-spacing:-.02em}
.sr-d{display:inline-flex;align-items:center;gap:10px;font-size:13.5px;line-height:1.3;color:var(--mut);text-align:right}
.sr-d::after{content:"";flex:none;width:7px;height:12px;background:var(--blue);opacity:.65;-webkit-mask:var(--chev) center/contain no-repeat;mask:var(--chev) center/contain no-repeat}
.sheet-row[aria-current] .sr-n{color:var(--blue)}
.sheet-cats{display:grid;grid-template-columns:1fr 1fr;gap:8px;list-style:none;padding:0;margin:2px 0 0}
.sheet-cats>li:last-child:nth-child(odd){grid-column:1/-1}
.sheet-cat{display:flex;align-items:center;gap:10px;height:100%;min-height:52px;padding:7px 10px;border:1px solid var(--line);border-radius:14px;background:var(--surface);color:inherit;text-decoration:none;-webkit-tap-highlight-color:transparent}
.sheet-cat[aria-current]{border-color:var(--tint-line);background:var(--tint)}
.sheet-cat[aria-current] .sc-n{color:var(--blue)}
.sheet-cat .svc-glyph{width:34px;height:34px;border-radius:10px}
.sheet-cat .svc-glyph svg{width:21px;height:21px;stroke-width:3.2}
.sc-t{display:grid;gap:2px;min-width:0}
.sc-n{font:600 14.5px/1.2 var(--disp);letter-spacing:-.01em;color:var(--ink)}
.sc-m{font-size:12.5px;line-height:1.3;color:var(--mut)}
.sheet-hi{display:flex;align-items:center;gap:12px;min-height:52px;margin-top:8px;padding:7px 12px;border-radius:14px;background:var(--tint);box-shadow:inset 0 0 0 1px var(--tint-line);color:inherit;text-decoration:none;-webkit-tap-highlight-color:transparent}
.sheet-hi[aria-current] .sc-n{color:var(--blue)}
.sheet-quiz{border-style:dashed;border-color:var(--line-2)}
.sheet-quiz .sc-m{font-weight:600;color:var(--blue)}
.sheet-ins{list-style:none;padding:0 0 0 16px;margin:0 0 0 2px;border-left:2px solid var(--tint-line)}
.sheet-in{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:44px;color:var(--ink);text-decoration:none;-webkit-tap-highlight-color:transparent}
.sheet-ins li+li .sheet-in{border-top:1px solid var(--line)}
.si-n{font:600 17px/1.2 var(--disp);letter-spacing:-.01em}
.si-d{font-size:13.5px;line-height:1.3;color:var(--mut);text-align:right}
.sheet-in[aria-current] .si-n{color:var(--blue)}
.si-all .si-n{color:var(--blue)}
.si-all[aria-current] .si-n{color:var(--ink)}
:is(.sheet-row,.sheet-in,.sheet-cat):active{background-color:var(--tint)}
.sheet-hi:active{background-color:var(--tint-2)}
.sheet-mail{display:flex;align-items:center;justify-content:center;min-height:48px;margin-top:4px;font-size:var(--fs-ui)}
.sheet-cta{position:sticky;bottom:0;z-index:1;flex:none;margin-top:auto;padding:12px 0 calc(12px + env(safe-area-inset-bottom));border-top:1px solid var(--line);background:rgb(247 249 252/.92);-webkit-backdrop-filter:saturate(1.6) blur(12px);backdrop-filter:saturate(1.6) blur(12px)}
.sheet .btn{width:100%}
@media (min-width:761px){.sheet{display:none!important}}
/* reading progress: blog posts only (the header partial adds it there); CSS scroll timeline, no JS */
.read-progress{position:fixed;inset:0 0 auto;height:2px;background:var(--grad);transform-origin:0 50%;transform:scaleX(0);z-index:60;pointer-events:none}
@supports not (animation-timeline:scroll()){.read-progress{display:none}}
#progress{display:none}

/* ---------- 5. Buttons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:48px;padding:0 24px;border:0;border-radius:12px;background:var(--grad-btn);color:#fff;font:600 var(--fs-ui)/1.2 var(--sans);text-align:center;text-decoration:none;cursor:pointer;box-shadow:0 8px 22px rgb(29 78 216/.24);transition:box-shadow var(--dur-hover) var(--ease-ui),translate var(--dur-press) var(--ease-ui),scale var(--dur-press) var(--ease-ui),background-position var(--dur-ui) var(--ease-ui);background-size:140% 100%;background-position:0 0;-webkit-tap-highlight-color:transparent}
.btn:hover{color:#fff;box-shadow:0 14px 32px rgb(29 78 216/.36);background-position:100% 0}
.btn:active{translate:0 1px;scale:.985;box-shadow:0 4px 12px rgb(29 78 216/.28)}
.btn.small{min-height:40px;padding:0 16px;font-size:var(--fs-sm);box-shadow:0 6px 16px rgb(29 78 216/.2)}
.btn.ghost{background:var(--surface);color:var(--blue);box-shadow:inset 0 0 0 1.5px var(--line),var(--sh)}
.btn.ghost:active{box-shadow:inset 0 0 0 1.5px var(--blue2),var(--sh)}
.btn.ghost:hover{color:var(--blue);box-shadow:inset 0 0 0 1.5px var(--blue2),var(--sh-hover)}
.btn.block{display:flex;width:100%}
.btn[disabled],.btn[aria-disabled=true]{opacity:.6;cursor:default}
.btn .arr{display:inline-block;transition:transform var(--dur-hover) var(--ease-ui)}
@media (hover:hover) and (pointer:fine){.btn:hover .arr{transform:translateX(3px)}}
.cta-row{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
@media (max-width:480px){.hero .cta-row .btn{flex:1 1 100%}}
/* the quiet written-proposal line under a hero's booking button (offer pages): text, never a second button */
.cta-alt{margin:14px 0 0;font-size:var(--fs-sm);color:var(--mut)}
.cta-alt a{font-weight:600}

/* ---------- 6. Hero ---------- */
.hero{min-height:92svh;display:flex;align-items:center;padding:140px 0 90px;overflow:clip;position:relative}
.hero>.wrap{width:100%;position:relative}
.hero.page{min-height:auto;padding:148px 0 56px}
.hero h1{font-size:var(--fs-4xl);font-weight:700;letter-spacing:-.035em;line-height:1.14;max-width:20ch;margin-bottom:22px}
.hero .sub{font-size:var(--fs-lg);max-width:58ch;margin-bottom:32px}
.hero.page .sub{margin-bottom:28px}
.hline{display:block}
/* atmosphere: a static soft wash (no blur filter, no motion). .orbs in older markup renders the same wash. */
.wash::before,.orbs{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(560px 460px at calc(100% - 120px) 110px,rgb(191 217 255/.6),rgb(219 234 254/.28) 45%,transparent 72%),radial-gradient(480px 400px at 60px calc(100% - 20px),rgb(186 230 253/.42),transparent 70%)}
.wash{position:relative}
/* the lower glow sits on the hero's bottom edge; fade the wash out above it so no hero ends in a hard line */
.hero.wash::before{-webkit-mask-image:linear-gradient(#000 calc(100% - 200px),transparent);mask-image:linear-gradient(#000 calc(100% - 200px),transparent)}
.hero.page.wash::before{-webkit-mask-image:linear-gradient(#000 calc(100% - 160px),transparent);mask-image:linear-gradient(#000 calc(100% - 160px),transparent)}
.orb{display:none}
.gridbg{position:absolute;inset:0;background:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px);background-size:56px 56px;-webkit-mask-image:radial-gradient(ellipse 78% 62% at 50% 36%,#000 25%,transparent 72%);mask-image:radial-gradient(ellipse 78% 62% at 50% 36%,#000 25%,transparent 72%);opacity:.55;pointer-events:none}
.badge{display:inline-flex;align-items:center;gap:9px;background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:8px 16px;font:600 13px/1.35 var(--sans);color:var(--body);box-shadow:var(--sh);margin-bottom:26px}
.badge .dot{flex:none;width:8px;height:8px;border-radius:50%;background:var(--grad);box-shadow:0 0 0 4px rgb(56 189 248/.18)}
.badge a{color:var(--blue);font-weight:700}
.marquee{display:none}
@media (max-width:640px){.hero{padding:116px 0 60px;min-height:auto}.hero.page{padding:116px 0 40px}}
@media (max-width:760px){.badge{align-items:flex-start;border-radius:16px;padding:9px 14px}.badge .dot{margin-top:5px}}

/* homepage hero grid with the "Ways to start" card */
.hero-grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);gap:56px;align-items:center}
.hero-grid h1{max-width:15ch}
.proofline{display:flex;flex-wrap:wrap;gap:8px 18px;margin-top:28px;font:600 13px/1.3 var(--sans);color:var(--mut)}
.proofline span{display:inline-flex;align-items:center;gap:8px}
.proofline span::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--grad)}
.start-card{padding:22px;border-radius:var(--r-lg)}
.start-card .kicker{margin-bottom:12px}
.start-item{position:relative;display:grid;grid-template-columns:1fr auto;gap:4px 14px;padding:16px 14px;margin:0 -6px;border-radius:14px;color:inherit;text-decoration:none;transition:background-color var(--dur-hover) var(--ease-ui);-webkit-tap-highlight-color:transparent}
.start-item+.start-item::before{content:"";position:absolute;left:14px;right:14px;top:0;height:1px;background:var(--line)}
.start-item:hover{background:var(--tint);color:inherit}
.start-item:active{background:var(--tint-2)}
.start-item b{font:700 16.5px/1.25 var(--disp);color:var(--ink);letter-spacing:-.01em}
.start-item .px{font:700 13px/1.25 var(--sans);color:var(--blue);text-align:right;white-space:nowrap}
.start-item p{grid-column:1/-1;font-size:var(--fs-sm);line-height:1.5;color:var(--body);margin:0}
.start-card .all{display:inline-block;margin-top:10px;font:600 var(--fs-sm) var(--sans);color:var(--blue);text-decoration:none}
@media (max-width:960px){.hero-grid{grid-template-columns:1fr;gap:36px}.hero-grid h1{max-width:18ch}}
@media (max-width:760px){.start-card{padding:16px}.proofline{font-size:12.5px}}

/* ---------- 7. Cards ---------- */
/* static cards never move; only link cards (a.card) respond to the pointer */
.card{position:relative;background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh)}
a.card{display:block;color:inherit;text-decoration:none;transition:translate var(--dur-ui) var(--ease-out),box-shadow var(--dur-ui) var(--ease-ui),border-color var(--dur-hover) var(--ease-ui),background-color var(--dur-press) var(--ease-ui);-webkit-tap-highlight-color:transparent}
a.card:hover{color:inherit}
/* spotlight: a soft light that follows the mouse inside link cards (ka-motion.js sets --mx/--my) */
a.card::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:radial-gradient(340px circle at var(--mx,50%) var(--my,0%),rgb(56 189 248/.10),rgb(37 99 235/.04) 40%,transparent 70%);opacity:0;transition:opacity var(--dur-ui) var(--ease-ui)}
@media (hover:hover) and (pointer:fine){a.card:hover{translate:0 -3px;box-shadow:var(--sh-hover);border-color:var(--line-2)}a.card:hover::after{opacity:1}}
a.card:active{translate:none;background:var(--tint)}
.card.pad{padding:28px}
.form-card{padding:clamp(20px,3vw,32px)}

/* stats */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:16px;margin-top:44px}
.stat{padding:28px}
.stat .num{font:700 44px/1.1 var(--disp);letter-spacing:-.03em;color:var(--blue)}
.stat b{display:block;color:var(--ink);font-size:var(--fs-ui);margin:10px 0 6px;font-weight:600}
.stat p{font-size:var(--fs-sm);color:var(--mut);line-height:1.6}
@media (max-width:640px){.stat .num{font-size:38px}}
.proof{background:var(--tint);border:1px solid var(--tint-line);border-radius:14px;padding:18px}
.proof .pnum{font:700 30px/1.15 var(--disp);letter-spacing:-.02em;color:var(--blue)}
.proof p{font-size:13px;color:var(--mut);line-height:1.5;margin-top:4px}

/* zipper (two staggered columns, static) */
.zipper{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:44px;align-items:start}
.zipper .col{display:grid;gap:18px}
.zipper .col.right{margin-top:56px}
@media (max-width:700px){.zipper{grid-template-columns:1fr}.zipper .col.right{margin-top:0}}

/* principal (who does the work, full version) */
.principal{border-radius:var(--r-lg);padding:clamp(26px,4.5vw,52px);display:grid;grid-template-columns:auto minmax(0,1fr);gap:28px 36px;align-items:start}
.lead-mark{position:relative;overflow:hidden;width:76px;height:76px;border-radius:20px;background:var(--grad-btn);color:#fff;display:flex;align-items:center;justify-content:center;font:700 26px var(--disp);letter-spacing:-.02em;box-shadow:0 10px 24px rgb(29 78 216/.26);flex-shrink:0}
.lead-mark img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.principal .lead-mark{width:88px;height:88px;font-size:30px;border-radius:24px}
.principal h2{margin-bottom:14px}
.principal p{font-size:var(--fs-base);max-width:64ch}
.principal p+p{margin-top:12px}
.principal .tiles{grid-column:1/-1;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
.principal .acts{grid-column:1/-1;display:flex;gap:12px;flex-wrap:wrap}
@media (max-width:760px){
  .principal{grid-template-columns:1fr}
  .principal .lead-mark{width:64px;height:64px;font-size:22px;border-radius:18px}
  .principal .tiles{grid-template-columns:1fr;gap:8px}
  .principal .tiles .proof{display:flex;align-items:center;gap:14px;padding:12px 14px}
  .principal .tiles .pnum{min-width:62px;font-size:26px}
  .principal .tiles .proof p{margin:0}
}

/* offers (legacy cards; new price layouts use .tiers) */
.offers{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));gap:18px;margin-top:48px}
.offer{padding:34px 30px;display:flex;flex-direction:column}
.offer.sig{border:1.5px solid var(--blue2)}
.offer h3{font-size:22px;margin-bottom:4px}
.offer .tag{position:absolute;top:0;left:26px;transform:translateY(-50%);background:var(--grad-btn);color:#fff;font:700 var(--fs-xs)/1 var(--sans);letter-spacing:.08em;text-transform:uppercase;padding:7px 13px;border-radius:999px;z-index:1}
.offer .price{font:700 var(--fs-ui)/1.4 var(--sans);color:var(--blue);margin-bottom:14px}
.offer p{color:var(--body);font-size:var(--fs-ui);flex:1}
.offer .fit{margin-top:18px;padding-top:16px;border-top:1px solid var(--line);font-size:13px;color:var(--mut)}
.offer .fit b{color:var(--body)}

/* work */
.workgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr));gap:18px;margin-top:48px}
.work{padding:30px 28px;display:flex;flex-direction:column;color:var(--body)}
.work .wk-kicker{font:700 var(--fs-xs)/1.25 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--blue);margin-bottom:12px}
.work h3{font-size:var(--fs-xl);margin-bottom:8px}
.work p{font-size:14.5px;color:var(--mut);flex:1}
.work .go{margin-top:16px;font:600 var(--fs-sm) var(--sans);color:var(--blue);display:inline-flex;align-items:center;gap:6px}
.case{border-radius:var(--r-lg);padding:clamp(28px,4.5vw,52px);margin-bottom:26px}
.case .meta{display:flex;gap:10px;flex-wrap:wrap;margin:14px 0 20px}
.pill{font:600 12px/1 var(--sans);color:var(--blue);background:var(--tint);border:1px solid var(--tint-line);border-radius:999px;padding:7px 13px}
.case h2{font-size:var(--fs-2xl)}
.case p{margin-bottom:14px;font-size:var(--fs-base)}
.case .case-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin:22px 0 6px}
.case h4{font:700 13px/1.3 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--blue);margin:22px 0 8px}

/* the link under a grid of cards ("See the portfolio") */
.grid-cta{margin-top:40px}
@media (max-width:700px){.grid-cta{margin-top:34px}}

/* deck (data-deck): a row of cards that keeps its own grid on wide screens and becomes a sideways swipe
   on phones, one card at 86% with the next peeking, snapping card by card. ka-motion.js adds position dots
   (.deck-dots) when the row overflows; without JS it is a plain horizontal scroller. Cards end at their
   content (no stretching to the tallest). Used by the homepage services overview, Portfolio cards and Facts */
[data-deck]{position:relative}
@media (max-width:760px){
  html [data-deck]{display:flex;align-items:flex-start;gap:12px;overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x mandatory;scroll-padding-inline:var(--gutter);margin-inline:calc(-1 * var(--gutter));padding:6px var(--gutter) 14px;scrollbar-width:none}
  html [data-deck]::-webkit-scrollbar{display:none}
  html [data-deck]::after{content:"";flex:0 0 1px}
  html [data-deck]>*{flex:0 0 min(86%,360px);min-width:0;scroll-snap-align:start}
}
.deck-dots{display:flex;justify-content:center;gap:2px;margin-top:2px}
.deck-dots[hidden]{display:none}
.deck-dots button{display:grid;place-items:center;width:28px;height:28px;padding:0;border:0;background:none;cursor:pointer;-webkit-tap-highlight-color:transparent}
.deck-dots button::before{content:"";width:7px;height:7px;border-radius:4px;background:var(--line-2);transition:width var(--dur-ui) var(--ease-out),background-color var(--dur-ui) var(--ease-ui)}
.deck-dots button.is-on::before{width:22px;background:var(--blue2)}

.article{max-width:760px;margin:0 auto;padding:0 var(--gutter)}
.article-hero{padding:148px 0 40px}
.article-hero h1{font-size:clamp(32px,4.6vw,52px);max-width:24ch;margin:14px 0 18px}
.article-hero .meta{font:500 var(--fs-sm) var(--sans);color:var(--mut)}
.article p{margin-bottom:18px;font-size:17px}
.article h2{font-size:var(--fs-2xl);margin:38px 0 14px}
.article h3{font-size:20px;margin:28px 0 10px}
.article ul,.article ol{margin:0 0 18px 22px}
.article li{margin-bottom:8px;font-size:var(--fs-base)}
.article blockquote{border-left:3px solid var(--sky);padding:4px 0 4px 20px;color:var(--mut);font-style:italic;margin-bottom:18px}
.article .figure{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:22px 24px;margin:22px 0;box-shadow:var(--sh)}
.article .figure .big{font:700 34px/1.2 var(--disp);color:var(--blue)}
.article .figure p{margin:4px 0 0;font-size:var(--fs-sm);color:var(--mut)}
.article .src{font-size:13px;color:var(--mut);border-top:1px solid var(--line);padding-top:16px;margin-top:34px}
@media (max-width:640px){.article-hero{padding:116px 0 30px}}

/* method */
.split{display:grid;grid-template-columns:1fr 1fr;gap:64px;align-items:start}
@media (max-width:860px){.split{grid-template-columns:1fr;gap:36px}}
.principles{display:grid;gap:10px}
.pr{display:flex;gap:18px;background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:20px 22px;box-shadow:var(--sh)}
.pr .n{font:700 15px/1.6 var(--disp);color:var(--blue)}
.pr b{color:var(--ink);display:block;margin-bottom:3px;font-size:var(--fs-ui)}
.pr p{font-size:14.5px;color:var(--mut);line-height:1.6}
.bigquote{font:500 clamp(24px,3vw,34px)/1.4 var(--disp);letter-spacing:-.02em;color:var(--ink);position:sticky;top:120px}
@media (max-width:860px){.bigquote{position:static}}

/* about */
.about-card{border-radius:var(--r-lg);padding:clamp(30px,5vw,56px);display:grid;grid-template-columns:1.4fr 1fr;gap:48px}
@media (max-width:860px){.about-card{grid-template-columns:1fr;gap:28px}}
.about-card p{margin-bottom:14px;font-size:var(--fs-base)}
.about-facts{display:grid;gap:12px;align-content:start}
.fact{border-left:3px solid var(--blue2);padding:2px 0 2px 16px;font-size:14.5px;color:var(--mut)}
.fact b{color:var(--ink);display:block;font-size:15px}
.note{max-width:820px;margin:56px auto 0;background:var(--tint);border:1px solid var(--tint-line);border-radius:var(--r);padding:22px 26px;font-size:14.5px;color:var(--body)}
.note b{color:var(--ink)}
.pubs-list{margin-top:36px;display:grid;gap:10px}
.pub{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:16px 20px;font-size:14.5px;color:var(--body)}
.pub b{color:var(--ink)}
.pub .pv{font:600 12.5px var(--sans);color:var(--blue);margin-top:4px;display:block}
.pub a{color:var(--blue);text-decoration:none}
.pub a:hover{text-decoration:underline}

/* steps (numbered sequences) */
.steps{display:grid;gap:14px;margin-top:40px;position:relative}
.step{display:grid;grid-template-columns:56px minmax(0,1fr);gap:18px;padding:24px 26px 24px 22px;align-items:start}
.step .sn{width:44px;height:44px;border-radius:12px;background:var(--grad-btn);color:#fff;display:flex;align-items:center;justify-content:center;font:700 16px var(--disp);box-shadow:0 8px 20px rgb(29 78 216/.22)}
.step h3{font-size:var(--fs-xl);margin-bottom:6px}
.step .when{font:700 var(--fs-xs)/1.3 var(--sans);color:var(--blue);text-transform:uppercase;letter-spacing:.1em;margin-bottom:8px}
.step p{font-size:var(--fs-ui);color:var(--body)}
.step ul{margin:10px 0 0 18px;font-size:14.5px;color:var(--mut)}
.step li{margin-bottom:4px}
.twocol{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:44px}
@media (max-width:760px){.twocol{grid-template-columns:1fr}.step{grid-template-columns:44px minmax(0,1fr);gap:14px;padding:20px 18px}}
.twocol .card{padding:28px}
.twocol h3{font-size:19px;margin-bottom:12px}
.twocol ul{margin-left:18px;font-size:15px}
.twocol li{margin-bottom:8px}

/* checklists: payment terms, inclusions, tier contents */
.checks,ul.terms{list-style:none;padding:0}
.checks{display:grid;gap:8px}
.checks li,ul.terms li{position:relative;padding-left:26px}
.checks li{font-size:var(--fs-ui)}
.checks li::before,ul.terms li::before{content:"";position:absolute;left:0;top:.3em;width:16px;height:16px;background:var(--blue);-webkit-mask:var(--check) center/contain no-repeat;mask:var(--check) center/contain no-repeat}
ul.terms{margin:24px 0 0;display:flex;flex-wrap:wrap;gap:10px 28px}
ul.terms li{font:500 var(--fs-sm)/1.5 var(--sans);color:var(--ink)}

/* ---------- 8. Components (v8) ---------- */

/* 8a. Fee schedule: grouped service rows; the whole row is one link */
.fees{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--sh);padding:6px clamp(14px,2.4vw,28px) clamp(14px,2.4vw,28px)}
.fee-h{display:flex;align-items:baseline;gap:10px;font:700 var(--fs-xs)/1.25 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--blue);padding:24px 0 10px;border-bottom:1px solid var(--line-2);margin:0}
.fee-h .cnt{font-weight:500;letter-spacing:0;text-transform:none;color:var(--mut)}
.fee-list{list-style:none;padding:0;margin:0 -12px}
.fee{position:relative;isolation:isolate;display:grid;grid-template-columns:minmax(0,15rem) minmax(0,1fr) 8.5rem 7.5rem 8px;grid-template-areas:"name line dur price chev";column-gap:20px;align-items:baseline;padding:16px 12px;border-radius:12px;color:inherit;text-decoration:none;background:linear-gradient(90deg,var(--tint-2),var(--tint) 60%) no-repeat 0 0/0% 100%;transition:background-size var(--dur-ui) var(--ease-out),background-color var(--dur-press) var(--ease-ui);-webkit-tap-highlight-color:transparent}
.fee:hover{color:inherit}
.fee-list li+li .fee::before{content:"";position:absolute;left:12px;right:12px;top:0;height:1px;background:var(--line);transition:opacity var(--dur-hover) var(--ease-ui)}
.fee-name{grid-area:name;font:600 var(--fs-lg)/1.3 var(--disp);letter-spacing:-.01em;color:var(--ink);transition:color var(--dur-hover) var(--ease-ui),translate var(--dur-ui) var(--ease-out)}
.fee-line{grid-area:line;font-size:var(--fs-ui);line-height:1.5;color:var(--body)}
.fee-dur{grid-area:dur;font-size:var(--fs-sm);color:var(--mut)}
.fee-price{grid-area:price;text-align:right;font:700 var(--fs-ui)/1.3 var(--sans);color:var(--ink);white-space:nowrap}
.fee-price .from{font-weight:500;font-size:var(--fs-sm);color:var(--mut);margin-right:4px}
.fee-price .mo,.way-p .mo{display:block;margin-top:3px;font:500 var(--fs-sm)/1.3 var(--sans);color:var(--mut)}
.fee-price.free{color:var(--blue)}
.fee::after{content:"";grid-area:chev;align-self:center;width:8px;height:14px;background:var(--mut);-webkit-mask:var(--chev) center/contain no-repeat;mask:var(--chev) center/contain no-repeat;transition:transform var(--dur-hover) var(--ease-ui),background-color var(--dur-hover) var(--ease-ui)}
@media (hover:hover) and (pointer:fine){
  .fee:hover{background-size:100% 100%}
  .fee:hover .fee-name{color:var(--blue);translate:4px 0}
  .fee:hover::after{transform:translateX(4px);background:var(--blue)}
  .fee-list li:hover .fee::before,.fee-list li:hover+li .fee::before{opacity:0}
}
.fee:active{background-color:var(--tint-2);background-size:100% 100%;transition-duration:var(--dur-press)}
.fee:active::after{transform:translateX(5px);background:var(--blue)}
.fee:focus-visible{outline-offset:-2px;background-size:100% 100%}
.fee-list li:focus-within .fee::before,.fee-list li:focus-within+li .fee::before{opacity:0}
@media (max-width:960px){
  .fee{grid-template-columns:minmax(0,1fr) 7.5rem 7rem 8px;grid-template-areas:"name dur price chev" "line line line chev";row-gap:4px}
}
@media (max-width:600px){
  .fee-list{margin:0 -8px}
  .fee{grid-template-columns:minmax(0,1fr) auto 8px;grid-template-areas:"name name chev" "line line chev" "dur price chev";column-gap:14px;row-gap:3px;padding:14px 8px}
  .fee-list li+li .fee::before{left:8px;right:8px}
  .fee-name{font-size:17px}
  .fee-line{font-size:var(--fs-sm)}
  .fee-dur{font-size:13px;align-self:baseline}
  .fee::after{background:var(--blue);opacity:.7}
}
.fee-custom{margin-top:18px;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px 32px;align-items:end;padding:24px clamp(18px,2.4vw,28px);background:var(--tint);border:1px solid var(--tint-line);border-radius:var(--r)}
.fee-custom h3{grid-column:1/-1;font-size:var(--fs-xl)}
.fee-custom p{font-size:var(--fs-ui);max-width:60ch}
@media (max-width:600px){.fee-custom{grid-template-columns:1fr;gap:8px}.fee-custom .btn{width:100%;margin-top:8px}}

/* 8b. Ways to start rows (homepage card, phone menu) */
.ways{list-style:none;padding:0;background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh);overflow:hidden}
.way{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto 8px;column-gap:14px;align-items:center;min-height:64px;padding:12px 16px;color:inherit;text-decoration:none;background:linear-gradient(90deg,var(--tint-2),var(--tint) 60%) no-repeat 0 0/0% 100%;transition:background-size var(--dur-ui) var(--ease-out),background-color var(--dur-press) var(--ease-ui);-webkit-tap-highlight-color:transparent}
.way:hover{color:inherit;background-size:100% 100%}
.way:active{background-color:var(--tint-2);background-size:100% 100%}
.ways li+li .way{border-top:1px solid var(--line)}
.way-n{display:block;font:600 16.5px/1.25 var(--disp);color:var(--ink);letter-spacing:-.01em}
.way-m{display:block;font-size:13.5px;line-height:1.4;color:var(--mut);margin-top:2px}
.way-p{font:700 var(--fs-ui)/1 var(--sans);color:var(--blue);white-space:nowrap}
.way-p .from{font-weight:500;font-size:var(--fs-sm);color:var(--mut);margin-right:4px}
.way::after{content:"";width:8px;height:14px;background:var(--blue);opacity:.7;-webkit-mask:var(--chev) center/contain no-repeat;mask:var(--chev) center/contain no-repeat;transition:translate var(--dur-ui) var(--ease-out),opacity var(--dur-hover) var(--ease-ui)}
@media (hover:hover) and (pointer:fine){.way:hover::after{translate:4px 0;opacity:1}}
.way:focus-visible{outline-offset:-3px}

/* 8c. Data figure: label, title, chart, caption with caveats, source, CSV, table */
.datafig{margin:0;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--sh);padding:clamp(18px,3vw,32px)}
.datafig-label{font:700 var(--fs-xs)/1.25 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--blue);margin-bottom:8px}
.datafig-title{font-size:var(--fs-2xl);max-width:34ch;margin-bottom:6px}
.datafig-sub{font-size:var(--fs-ui);color:var(--body);max-width:62ch}
.datafig-body{position:relative;margin-top:20px}
.datafig-body svg{display:block;width:100%;height:auto;overflow:visible}
.datafig-cap{margin-top:18px;padding-top:14px;border-top:1px solid var(--line);font-size:var(--fs-sm);line-height:1.6;color:var(--body)}
.datafig-cap>*+*{margin-top:8px}
.datafig-cap b{color:var(--ink)}
.datafig-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:4px 20px;margin-top:10px;font-size:13px;color:var(--mut)}
.datafig-src{max-width:none;font-size:13px;color:var(--mut)}
.datafig-src a{color:var(--mut)}
.datafig-dl{display:inline-flex;align-items:center;gap:7px;min-height:44px;font:600 var(--fs-sm) var(--sans);color:var(--blue);text-decoration:none}
.datafig-dl::before{content:"";width:15px;height:15px;background:currentColor;-webkit-mask:var(--dl) center/contain no-repeat;mask:var(--dl) center/contain no-repeat}
.datafig-dl:hover{color:var(--blue);text-decoration:underline}
.datafig{transition:box-shadow var(--dur-ui) var(--ease-ui),border-color var(--dur-ui) var(--ease-ui)}
@media (hover:hover) and (pointer:fine){
  .datafig:has(>a.more):hover{box-shadow:var(--sh-hover);border-color:var(--line-2)}
  .datafig:has(>a.more):hover>a.more::after{transform:translateX(3px)}
}
.datafig-table{margin-top:4px;border-top:1px solid var(--line)}
.datafig-table>summary{display:flex;align-items:center;gap:8px;min-height:44px;list-style:none;cursor:pointer;font:600 var(--fs-sm) var(--sans);color:var(--blue)}
.datafig-table>summary::-webkit-details-marker{display:none}
.datafig-table>summary::before{content:"";width:8px;height:14px;background:currentColor;-webkit-mask:var(--chev) center/contain no-repeat;mask:var(--chev) center/contain no-repeat;transition:transform var(--dur-ui) var(--ease-ui)}
.datafig-table[open]>summary::before{transform:rotate(90deg)}
.table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;max-height:420px;overflow-y:auto;border:1px solid var(--line);border-radius:12px;margin:4px 0 8px}
table.data{width:100%;border-collapse:collapse;font-size:var(--fs-sm);line-height:1.45}
table.data caption{text-align:left;padding:10px 12px;font-size:13px;color:var(--mut)}
table.data th{position:sticky;top:0;background:var(--surface);text-align:left;font:700 12px/1.3 var(--sans);letter-spacing:.06em;text-transform:uppercase;color:var(--mut);padding:10px 12px;border-bottom:1px solid var(--line-2);white-space:nowrap}
table.data td{padding:9px 12px;border-bottom:1px solid var(--line);color:var(--body);vertical-align:top}
table.data tr:last-child td{border-bottom:0}
table.data .num,table.data th.num{text-align:right}
/* a row's own header (th scope="row"): the row's name, in ink, wrapping, never the column heads' small caps */
table.data tbody th{position:static;padding:9px 12px;border-bottom:1px solid var(--line);background:none;font:600 var(--fs-sm)/1.45 var(--sans);letter-spacing:0;text-transform:none;color:var(--ink);white-space:normal;vertical-align:top}
table.data tr:last-child th{border-bottom:0}
@media (hover:hover){table.data tbody tr:hover>*{background:var(--tint)}}
/* article tables (post_parts.article_tables): the tables in a post's or report's text. A framed card with a tinted
   header band, zebra rows, the first column wrapping in ink, numbers right-aligned in tabular figures. On phones a
   table of up to three text columns becomes one card per row (.art-stack); a wider one scrolls inside its frame,
   with a line under it saying so (.art-scroll) */
.art-table{margin:10px 0 30px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);box-shadow:var(--sh);overflow:hidden}
.art-table table.data{font-size:15px;line-height:1.5}
.art-table thead th{position:static;padding:12px 16px;background:var(--tint);border-bottom:1px solid var(--tint-line);font:700 var(--fs-xs)/1.3 var(--sans);letter-spacing:.08em;color:var(--blue)}
.art-table tbody th,.art-table td{padding:13px 16px;font-size:15px}
.art-table tbody th{min-width:9em;width:30%}
.art-table tbody tr:nth-child(even)>*{background:color-mix(in srgb,var(--tint) 55%,var(--surface))}
@media (hover:hover){.art-table tbody tr:hover>*{background:var(--tint)}}
.art-table caption:not(.sr-only){caption-side:top;padding:12px 16px;border-bottom:1px solid var(--line);text-align:left;font:600 var(--fs-sm)/1.4 var(--sans);color:var(--ink)}
.art-table:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
.art-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.art-scroll table.data{min-width:560px}
.art-scroll th,.art-scroll td.num{white-space:nowrap}
.art-table+.art-hint{display:none}
@media (max-width:600px){
  .art-table+.art-hint{display:block;margin:-22px 0 28px;font-size:13px;color:var(--mut)}
  .art-stack thead{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
  .art-table.art-stack :is(table,tbody,tr,th,td){display:block;width:auto;min-width:0}
  .art-table.art-stack tbody tr{padding:14px 16px;border-bottom:1px solid var(--line)}
  .art-table.art-stack tbody tr:nth-child(even){background:color-mix(in srgb,var(--tint) 55%,var(--surface))}
  .art-table.art-stack tbody tr:last-child{border-bottom:0}
  .art-table.art-stack tbody tr>*{padding:0;border:0;background:none}
  .art-table.art-stack tbody th{margin-bottom:4px;font-size:var(--fs-ui)}
  .art-stack td+td{margin-top:8px}
  .art-stack:not(.art-2) td[data-label]::before{content:attr(data-label);display:block;margin-bottom:2px;font:700 11.5px/1.3 var(--sans);letter-spacing:.08em;text-transform:uppercase;color:var(--mut)}
}
/* data marks: brand blue for the selected item, warm only for values above a target */
.mark-sel{fill:var(--blue2);color:var(--blue2)}
.mark-dim{fill:var(--data-dim);color:var(--data-dim)}
.mark-warm{fill:var(--warm);color:var(--warm)}

/* ---- Charts and fact cards (ka-charts.js) ---- (start)
   The script draws the marks in the data tokens (it reads them from :root) and sets every SVG
   label's size itself (13px labels and values, 12px ticks), so its measurements match what
   renders. This block styles the text, legend, tooltip, brand row and the HTML chart types.
   Usage: site/DESIGN.md "Charts and fact cards". */
.kc{position:relative}
.kc-plot{position:relative;border-radius:6px;-webkit-tap-highlight-color:transparent}
.kc-plot[tabindex]:focus-visible{outline-offset:6px}
.kc .kc-svg{display:block;width:100%;height:auto;overflow:visible}
.kc text{font-family:var(--sans);fill:var(--body)}
.kc .kc-l,.kc .kc-v{fill:var(--ink)}
.kc .kc-v.kc-q{fill:var(--body)}
.kc .kc-x{fill:var(--mut)}
.kc :is(.kc-v,.kc-x,.kc-in,.kc-n),.kc-tr b,.kc-cn,.kf-num,.kf-bv{font-variant-numeric:tabular-nums}
.kc .kc-n{font-family:var(--disp);fill:var(--ink);letter-spacing:-.03em}
.kc .kc-in{fill:var(--surface);transition:fill var(--dur-hover) var(--ease-ui)}
.kc .kc-in.kc-dk,.kc-hov .kc-in:not(.kc-on){fill:var(--ink)} /* ink on a light or dimmed fill */
.kc .kc-h{paint-order:stroke;stroke:var(--surface);stroke-width:4px;stroke-linejoin:round}
.kc-m{transition:opacity var(--dur-hover) var(--ease-ui)}
.kc-hov .kc-m:not(.kc-on){opacity:.4}
.kc-key{display:flex;flex-wrap:wrap;gap:6px 18px;margin:0 0 14px;font-size:13px;line-height:1.4;color:var(--body)}
.kc-ki{display:inline-flex;align-items:center;gap:7px}
.kc-sw{flex:none;width:12px;height:12px;border-radius:3px}
.kc-sw-l{width:16px;height:3px;border-radius:2px}
.kc-sw-d{width:10px;height:10px;border-radius:50%}
/* a drawn key mark (ka-charts-more.js mkey: bullet, slope, area) keeps its own size; .datafig-body svg would stretch it */
.kc-ki>svg{flex:none;width:auto;height:auto}
/* charts v2 (ka-charts-more.js): the key for a sequential scale, low value, ramp, high value */
.kc-ramp{gap:8px}
.kc-rbar{flex:none;width:96px;height:10px;border-radius:3px}
.kc-rl{color:var(--mut)}
.kc-rv{font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.kc .kc-at{fill:var(--mut);font-weight:600}
/* tooltip: the value leads, the name follows */
.kc-tip{position:absolute;left:0;top:0;z-index:5;max-width:min(260px,100%);padding:8px 12px;border:1px solid var(--line);border-radius:10px;background:var(--surface);box-shadow:0 8px 24px rgb(10 21 40/.12);font-size:13px;line-height:1.4;color:var(--body);pointer-events:none;opacity:0;transition:opacity 120ms var(--ease-ui)}
.kc-tip.on{opacity:1}
.kc-tip p{max-width:none}
.kc-th{font-weight:600;color:var(--ink);margin-bottom:2px}
.kc-tr{display:flex;align-items:baseline;gap:7px}
.kc-tr b{font-weight:700;color:var(--ink)}
.kc-tk{flex:none;align-self:center;width:12px;height:3px;border-radius:2px}
.kc-tn{margin-top:3px;font-size:12.5px;color:var(--mut)}
/* brand row: the watermark inside every chart and fact card (survives screenshots, PNGs and embeds) */
.kc-brand{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:6px 16px;margin-top:18px;padding-top:12px;border-top:1px solid var(--line);font-size:12px;line-height:1.45;color:var(--mut)}
.kc-by{display:inline-flex;align-items:center;gap:7px;font:700 13px/1 var(--disp);letter-spacing:-.02em;color:var(--ink);white-space:nowrap}
.kc-by b{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.kc-k{display:block;flex:none;width:18px;height:18px;border-radius:4px;background:var(--grad)}
:is(.kc,.kf) .kc-k svg{display:block;width:100%;height:100%;fill:none;stroke:#fff;stroke-width:12;stroke-linecap:round;stroke-linejoin:round}
.kc-meta{display:flex;flex-wrap:wrap;gap:2px 14px}
.kc-url{color:var(--mut);text-decoration:none}
a.kc-url:hover{color:var(--blue);text-decoration:underline}
/* compare: two or three big numbers, bars on one scale */
.kc-cmp{display:grid;grid-template-columns:repeat(var(--n,2),minmax(0,1fr));gap:22px 32px}
.kc-cmp.kc-stack{grid-template-columns:minmax(0,1fr)}
.kc-cn{font:600 clamp(34px,4.6vw,48px)/1.05 var(--disp);letter-spacing:-.03em;color:var(--ink)}
.kc-cl{margin:6px 0 12px;font-size:var(--fs-sm);line-height:1.45;color:var(--body)}
.kc .kc-cb{display:block;width:100%;height:10px;overflow:visible}
/* steps: a process as a connected sequence; a row when each step gets 170px, else a list */
.kc-steps{list-style:none;margin:0;padding:0;display:grid}
.kc-st{position:relative;display:grid;grid-template-columns:32px minmax(0,1fr);align-content:start;column-gap:14px;padding-bottom:22px}
.kc-st:last-child{padding-bottom:0}
.kc-sn{display:grid;place-items:center;width:32px;height:32px;border-radius:50%;background:var(--grad-btn);color:#fff;font:700 14px/1 var(--disp)}
.kc-sl{position:absolute;left:15px;top:38px;bottom:6px;width:2px;border-radius:1px;background:var(--axis)}
.kc-stt{margin-top:5px;font:600 var(--fs-ui)/1.35 var(--sans);color:var(--ink)}
.kc-stx{margin-top:4px;font-size:var(--fs-sm);line-height:1.55;color:var(--body)}
.kc-row{grid-template-columns:repeat(var(--n),minmax(0,1fr));column-gap:20px}
.kc-row .kc-st{grid-template-columns:minmax(0,1fr);padding-bottom:0}
.kc-row .kc-sl{left:42px;right:-14px;top:15px;bottom:auto;width:auto;height:2px}
.kc-row .kc-sb{margin-top:12px}
/* steps forms (ka-charts-more.js, spec.form): path, stairs, cards, checklist, cycle, qa. Tokens only, so a page
   theme reaches them; text in the text tokens, white only on the blue tiles and stops */
.kc-f :is(ol,ul){list-style:none;margin:0;padding:0}
.kc-f .kc-stt{margin-top:0}
.kc-f .kc-ic{display:block;width:22px;height:22px}
.kc-pw{position:relative}
.kc-prd{position:absolute;top:20px;bottom:20px;left:19px;width:3px;border-radius:2px;background:var(--axis);overflow:hidden}
.kc-pw.kc-two .kc-prd{left:calc(50% - 1.5px)}
.kc-prf{position:absolute;inset:0;background:linear-gradient(180deg,var(--d2),var(--d4))}
.kc-path{display:grid;row-gap:14px}
.kc-pi{position:relative;display:grid;grid-template-columns:40px minmax(0,1fr);column-gap:14px;align-items:start}
.kc-pn{position:relative;z-index:1;display:grid;place-items:center;width:40px;height:40px;border-radius:50%;background:var(--grad-btn);color:#fff;font:700 15px/1 var(--disp);box-shadow:0 0 0 5px var(--surface),var(--sh-mark)}
.kc-pn .kc-ic{width:20px;height:20px}
.kc-pc{position:relative;padding:12px 16px 14px;border:1px solid var(--tint-line);border-radius:var(--r-sm);background:var(--tint)}
.kc-pc::before{content:"";position:absolute;top:19px;left:-15px;width:14px;height:2px;background:var(--tint-line)}
.kc-two .kc-path{row-gap:0}
.kc-two .kc-pi{grid-template-columns:minmax(0,1fr) 40px minmax(0,1fr);column-gap:18px}
.kc-two .kc-pi+.kc-pi{margin-top:-22px}
.kc-two .kc-pn{grid-column:2;grid-row:1}
.kc-two .kc-pi .kc-pc{grid-row:1}
.kc-two .kc-l .kc-pc{grid-column:1}
.kc-two .kc-r .kc-pc{grid-column:3}
.kc-two .kc-l .kc-pc::before{left:auto;right:-19px;width:18px}
.kc-two .kc-r .kc-pc::before{left:-19px;width:18px}
.kc-stairs{display:grid;row-gap:var(--bg)}
.kc-sti{display:grid;grid-template-columns:calc(var(--bn) * var(--bw) + (var(--bn) - 1) * var(--bg)) minmax(0,1fr);column-gap:16px}
.kc-blk{display:flex;gap:var(--bg)}
.kc-bk{flex:none;width:var(--bw);min-height:44px;border-radius:5px;background:var(--tint-2);box-shadow:inset 0 0 0 1px var(--tint-line)}
.kc-bk-on{display:flex;justify-content:center;padding-top:10px;background:var(--grad-btn);box-shadow:none}
.kc-bkn{color:#fff;font:700 13px/1 var(--disp)}
.kc-bkn .kc-ic{width:16px;height:16px}
.kc-sti .kc-fb{padding:9px 0 14px;border-bottom:1px solid var(--line)}
.kc-sti:last-child .kc-fb{border-bottom:0;padding-bottom:4px}
.kc-cards{display:grid;grid-template-columns:repeat(var(--cols,1),minmax(0,1fr));gap:14px}
.kc-cd{position:relative;padding:18px 18px 20px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);box-shadow:var(--sh)}
.kc-cd::before{content:"";position:absolute;left:18px;right:18px;top:-1px;height:3px;border-radius:0 0 3px 3px;background:var(--grad)}
.kc-cd.kc-wide{grid-column:1/-1}
.kc-cdt{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:14px}
.kc-ct{flex:none;display:grid;place-items:center;width:42px;height:42px;border-radius:12px;background:var(--grad-btn);color:#fff;font:700 16px/1 var(--disp)}
.kc-cdn{font:600 40px/.9 var(--disp);letter-spacing:-.04em;color:var(--tint-line);font-variant-numeric:tabular-nums}
.kc-cdn.kc-real{color:var(--blue)}
.kc-ckp{border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);box-shadow:var(--sh);overflow:hidden}
.kc-ckh{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:baseline;gap:4px 12px;padding:12px 18px;background:var(--tint);border-bottom:1px solid var(--tint-line)}
.kc-ckl{font:600 var(--fs-sm)/1.35 var(--sans);color:var(--ink)}
.kc-ckc{font:700 var(--fs-xs)/1.3 var(--sans);letter-spacing:.08em;text-transform:uppercase;color:var(--blue);white-space:nowrap}
.kc-f .kc-ck{padding:2px 18px}
.kc-cki{display:grid;grid-template-columns:26px minmax(0,1fr);column-gap:14px;padding:14px 0;border-bottom:1px solid var(--line)}
.kc-cki:last-child{border-bottom:0}
.kc-cb2{display:block;width:26px;height:26px;overflow:visible}
.kc-cbr{fill:var(--tint-2);stroke:var(--blue2);stroke-width:2}
.kc-cbt{fill:none;stroke:var(--blue);stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}
.kc-s-open .kc-cbr{fill:none;stroke:var(--axis)}
.kc-cki .kc-stt{margin-top:2px}
.kc-cks{margin-bottom:3px;font:700 11.5px/1.2 var(--sans);letter-spacing:.08em;text-transform:uppercase;color:var(--mut)}
.kc-cyw{display:grid;row-gap:22px}
.kc-cyw.kc-two{grid-template-columns:auto minmax(0,1fr);column-gap:32px;align-items:center}
.kc-cyr{position:relative;margin:0 auto}
.kc-cyr svg{display:block;overflow:visible}
.kc-cya,.kc-cyh{fill:none;stroke:var(--d4);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
.kc-cyn{color:#fff}
.kc-cyn circle{fill:var(--blue2);stroke:var(--surface);stroke-width:4}
.kc .kc-cyn text{fill:#fff;font:700 14px var(--disp)}
.kc-cym{position:absolute;left:50%;top:50%;translate:-50% -50%;display:flex;flex-direction:column;align-items:center;gap:6px;width:max-content;max-width:var(--cym,160px);text-align:center}
.kc-cym p{font:600 var(--fs-sm)/1.4 var(--sans);color:var(--ink)}
.kc-f .kc-cyi2{width:20px;height:20px;color:var(--blue)}
.kc-cyl{display:grid;row-gap:12px}
.kc-cyi{display:grid;grid-template-columns:28px minmax(0,1fr);column-gap:12px}
.kc-cyb{display:grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--blue2);color:#fff;font:700 13px/1 var(--disp)}
.kc-f .kc-cyb .kc-ic{width:16px;height:16px}
.kc-cyi .kc-stt{margin-top:4px}
.kc-qh{display:grid;grid-template-columns:minmax(0,.9fr) 40px minmax(0,1.5fr);margin-bottom:12px}
.kc-qh p,.kc-qk{font:700 var(--fs-xs)/1.3 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--blue)}
.kc-qhr{grid-column:3}
.kc-qb{min-width:0}
.kc-qk{margin-bottom:4px}
.kc-qa{display:grid;row-gap:12px}
.kc-qi{display:grid;grid-template-columns:minmax(0,1fr)}
.kc-two .kc-qi{grid-template-columns:minmax(0,.9fr) 40px minmax(0,1.5fr);row-gap:0}
.kc-qq{display:flex;gap:10px;align-items:flex-start;padding:12px 14px;border:1px solid var(--tint-line);border-radius:var(--r-sm);background:var(--tint)}
.kc-qn{flex:none;display:grid;place-items:center;width:24px;height:24px;margin-top:-1px;border-radius:50%;background:var(--blue2);color:#fff;font:700 12px/1 var(--disp)}
.kc-f .kc-qn .kc-ic{width:15px;height:15px}
.kc-qc{position:relative;display:block;align-self:center;height:2px;margin:0 6px 0 2px;border-radius:1px;background:var(--d4)}
.kc-qc::after{content:"";position:absolute;right:0;top:-4px;width:8px;height:8px;border-top:2px solid var(--d4);border-right:2px solid var(--d4);border-radius:1px;transform:rotate(45deg)}
.kc-qw:not(.kc-two) .kc-qc{width:2px;height:18px;margin:4px 0 6px 25px}
.kc-qw:not(.kc-two) .kc-qc::after{right:auto;left:-4px;top:auto;bottom:0;transform:rotate(135deg)}
.kc-qr{padding:12px 16px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);box-shadow:var(--sh)}
.kc-qr .kc-stx{margin-top:0}
/* interactive: the figure's image and a link to the live version */
.kc-int{display:block;overflow:hidden;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--tint);text-decoration:none}
.kc-int img{display:block;width:100%;height:auto}
.kc-thumb .kc-int img{aspect-ratio:16/9;object-fit:cover;object-position:50% 0}
.kc-go{display:flex;align-items:center;gap:8px;min-height:44px;padding:10px 14px;border-top:1px solid var(--line);background:var(--surface);font:600 var(--fs-sm)/1.3 var(--sans);color:var(--blue);transition:color var(--dur-hover) var(--ease-ui)}
.kc-go .arr{transition:translate var(--dur-ui) var(--ease-out)}
.kc-int:hover .kc-go{color:var(--ink)}
.kc-int:hover .kc-go .arr{translate:3px 0}
/* no-JS: the figure's PNG (the script swaps it for the live chart) */
[data-chart]>img,[data-chart]>noscript>img{display:block;width:100%;height:auto;border-radius:var(--r-sm)}
/* the chart's height, held until ka-charts.js has drawn it, so nothing below moves: build_charts.py
   measures each spec and writes --kch (a phone column, 304px) and --kchw (from 606px, where the
   chart switches to its wide layout) on the host; ka-charts.js adds .kc-drawn to the host at the chart's first paint */
html.js [data-chart][style*="--kch"]:not(.kc-drawn){min-height:var(--kch)}
@media (min-width:606px){html.js [data-chart][style*="--kchw"]:not(.kc-drawn){min-height:var(--kchw)}}
/* fact cards (KA.facts): the host gives the frame (.card, .datafig) */
.kf{display:flex;flex-direction:column;align-items:flex-start}
.kf-top{display:flex;align-items:center;justify-content:space-between;gap:20px;width:100%}
.kf-num{max-width:none;font:600 clamp(56px,9vw,92px)/.95 var(--disp);letter-spacing:-.04em;color:var(--ink)}
.kf-unit{margin-top:10px;font-size:var(--fs-ui);line-height:1.4;color:var(--body)}
.kf-ring{flex:none;display:block;width:clamp(84px,14vw,124px);height:auto}
.kf-rule{display:block;width:min(100%,220px);height:3px;margin:22px 0 18px;border-radius:2px;background:var(--grad)}
.kf-bars{display:grid;gap:12px;width:100%;max-width:520px;margin-bottom:18px}
.kf-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:5px 12px;font-size:var(--fs-sm);line-height:1.4;color:var(--body)}
.kf-bv{font-weight:600;color:var(--ink)}
.kf .kf-bar{grid-column:1/-1;display:block;width:100%;height:8px;overflow:visible}
.kf-stmt{max-width:46ch;font-size:var(--fs-lg);font-weight:500;line-height:1.5;color:var(--ink)}
.kf-ctx{max-width:60ch;margin-top:10px;font-size:var(--fs-ui);line-height:1.6;color:var(--body)}
.kf-src{max-width:62ch;margin-top:14px;font-size:13px;line-height:1.5;color:var(--mut)}
.kf-src a{color:var(--mut)}
.kf .kc-brand{align-self:stretch}
.kf-card .kf-num{font-size:46px}
.kf-card .kf-unit{margin-top:6px;font-size:var(--fs-sm)}
.kf-card .kf-ring{width:60px}
.kf-card .kf-rule{width:96px;margin:14px 0 12px}
.kf-card .kf-bars{gap:8px;margin-bottom:12px}
.kf-card .kf-stmt{font-size:var(--fs-ui);line-height:1.5}
.kf-card .kf-src{margin-top:8px}
.kf-card .kc-brand{margin-top:14px}
/* ---- Charts and fact cards (ka-charts.js) ---- (end) */

/* ---- Share (ka-share.js) ---- (start)
   The share row under charts, facts, articles and research, and its menu. From 761px the menu is a
   popover anchored to its button: it turns opaque in 140ms and settles from the button over 500ms,
   as the header menus do. Below that it is a bottom sheet that rises like the phone menu's Book bar
   (460ms) while the page dims. Its rows arrive in reading order. CSS transitions only (translate,
   scale, opacity, colors); GSAP never touches these elements. Usage: site/DESIGN.md "Share". */
.ka-share{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
html.js .ka-share:empty{min-height:40px}
/* a chart or fact row narrower than 520px (the chart page's 320px aside, a phone): the buttons share
   each line in equal widths. A chart's Download PNG takes a line of its own under Embed, Cite and
   Share, so the row reads as one block and never as a button that wrapped; a fact's three fill one
   line when they fit. A wider row keeps each button at its own width. */
.ka-share[data-share-kind=chart],.ka-share[data-share-kind=fact]{container:ksh/inline-size}
@container ksh (max-width:519px){
  .ka-share .ksh-b{flex:1 1 0;justify-content:center;gap:6px;padding:0 10px;white-space:nowrap}
  .ka-share[data-share-kind=chart]>a.ksh-b{flex-basis:100%}
}
.ksh-ico{flex:none;width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.ksh-i-more{stroke-width:3.4}
.ksh-b{display:inline-flex;align-items:center;gap:8px;min-height:40px;padding:0 14px 0 12px;border:0;border-radius:10px;background:var(--surface);box-shadow:inset 0 0 0 1px var(--line-2);color:var(--ink);font:600 var(--fs-sm)/1.2 var(--sans);text-decoration:none;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--dur-hover) var(--ease-ui),box-shadow var(--dur-hover) var(--ease-ui),translate var(--dur-press) var(--ease-ui)}
.ksh-b .ksh-ico{color:var(--blue)}
.ksh-b:hover,.ksh-b[aria-expanded=true]{color:var(--ink);background:var(--tint);box-shadow:inset 0 0 0 1px var(--tint-line)}
.ksh-b:active{translate:0 1px;background:var(--tint-2)}
/* the menu: one dialog element, .ksh-pop or .ksh-sheet by viewport width when it opens */
.ksh-panel{position:fixed;z-index:60;display:flex;flex-direction:column;background:var(--surface);color:var(--body);font-size:var(--fs-sm);line-height:1.5}
.ksh-panel:focus{outline:none}
.ksh-sc{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:12px}
.ksh-pop{width:min(360px,calc(100vw - 24px));border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:0 28px 64px rgb(10 21 40/.14),0 6px 18px rgb(10 21 40/.06);transform-origin:var(--cx) 0;opacity:0;scale:.95;translate:0 -10px;transition:opacity 180ms var(--ease-in),scale 180ms var(--ease-in),translate 180ms var(--ease-in)}
.ksh-pop.ksh-up{transform-origin:var(--cx) 100%;translate:0 10px}
.ksh-pop.open{opacity:1;scale:none;translate:none;transition:opacity 140ms var(--ease-out),scale 500ms var(--ease-out),translate 500ms var(--ease-out)}
.ksh-caret{position:absolute;top:-7px;left:var(--cx);width:14px;height:14px;margin-left:-7px;pointer-events:none}
.ksh-caret::before{content:"";position:absolute;inset:0;border-radius:3px 0 0 0;background:var(--surface);box-shadow:-1px -1px 0 var(--line);rotate:45deg}
.ksh-up .ksh-caret{top:auto;bottom:-7px;rotate:180deg}
.ksh-sheet{left:0;right:0;bottom:0;z-index:110;max-height:calc(100vh - 40px);max-height:calc(100dvh - 40px);border-radius:var(--r-lg) var(--r-lg) 0 0;box-shadow:0 -16px 48px rgb(10 21 40/.18);padding-bottom:env(safe-area-inset-bottom);translate:0 100%;transition:translate 200ms var(--ease-in)}
.ksh-sheet.open{translate:none;transition:translate 460ms var(--ease-out)}
.ksh-sheet::before{content:"";flex:none;width:36px;height:4px;margin:8px auto 0;border-radius:2px;background:var(--line-2)}
.ksh-sheet .ksh-caret{display:none}
.ksh-sheet .ksh-sc{padding:8px 16px 16px}
.ksh-scrim{position:fixed;inset:0;z-index:109;background:rgb(10 21 40/.4);opacity:0;transition:opacity 200ms var(--ease-in)}
.ksh-scrim.open{opacity:1;transition:opacity 220ms var(--ease-out)}
html.ksh-lock{overflow:hidden}
/* contents: a title row, the link with its copy button, the networks as tiles, then rows */
.ksh-top{display:flex;align-items:center;gap:4px;margin:-4px -4px 10px}
.ksh-h{flex:1;min-width:0;padding-left:6px;font:600 16px/1.25 var(--disp);letter-spacing:-.01em;color:var(--ink)}
.ksh-back+.ksh-h{padding-left:0}
.ksh-ib{position:relative;flex:none;width:36px;height:36px;padding:0;border:0;border-radius:10px;background:none;color:var(--mut);cursor:pointer;transition:background-color var(--dur-hover) var(--ease-ui),color var(--dur-hover) var(--ease-ui)}
.ksh-ib:hover{background:var(--tint);color:var(--ink)}
.ksh-ib:focus-visible{outline-offset:-2px}
.ksh-ib::before,.ksh-x::after{content:"";position:absolute;left:50%;top:50%;width:15px;height:1.8px;margin:-.9px 0 0 -7.5px;border-radius:1px;background:currentColor;rotate:45deg}
.ksh-x::after{rotate:-45deg}
.ksh-back::before{width:8px;height:14px;margin:-7px 0 0 -5px;border-radius:0;-webkit-mask:var(--chev) center/contain no-repeat;mask:var(--chev) center/contain no-repeat;rotate:180deg}
.ksh-link{display:flex;align-items:center;gap:8px;padding:5px 5px 5px 12px;border-radius:12px;background:var(--bg);box-shadow:inset 0 0 0 1px var(--line)}
.ksh-url{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--body)}
.ksh-copy{flex:none;display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:36px;padding:0 12px;border:0;border-radius:9px;background:var(--tint);box-shadow:inset 0 0 0 1px var(--tint-line);color:var(--blue);font:600 var(--fs-sm)/1 var(--sans);white-space:nowrap;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--dur-hover) var(--ease-ui),color var(--dur-hover) var(--ease-ui),translate var(--dur-press) var(--ease-ui)}
.ksh-copy:hover{background:var(--tint-2);color:var(--blue)}
.ksh-copy:active{translate:0 1px}
.ksh-copy.is-done{background:var(--blue);box-shadow:none;color:#fff}
.ksh-copy.is-done::before{content:"";width:14px;height:14px;background:currentColor;-webkit-mask:var(--check) center/contain no-repeat;mask:var(--check) center/contain no-repeat}
.ksh-soc{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:4px;list-style:none;padding:0;margin:12px 0 0}
.ksh-t{display:flex;flex-direction:column;align-items:center;gap:6px;width:100%;padding:8px 2px;border:0;border-radius:12px;background:none;color:var(--ink);font:500 13px/1.2 var(--sans);text-decoration:none;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--dur-hover) var(--ease-ui)}
.ksh-t .ksh-ico{box-sizing:content-box;width:20px;height:20px;padding:10px;border-radius:12px;background:var(--tint);color:var(--blue);transition:background-color var(--dur-hover) var(--ease-ui),color var(--dur-hover) var(--ease-ui)}
.ksh-t:hover{color:var(--ink);background:var(--bg)}
.ksh-t:hover .ksh-ico{background:var(--grad-btn);color:#fff}
.ksh-t:active .ksh-ico{background:var(--tint-2);color:var(--blue)}
.ksh-rows{list-style:none;padding:8px 0 0;margin:10px 0 0;border-top:1px solid var(--line)}
.ksh-r{display:flex;align-items:center;gap:12px;width:100%;min-height:40px;padding:0 10px;border:0;border-radius:10px;background:none;color:var(--ink);font:500 var(--fs-ui)/1.3 var(--sans);text-align:left;text-decoration:none;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--dur-hover) var(--ease-ui)}
.ksh-r .ksh-ico{color:var(--blue)}
.ksh-r[data-go]::after{content:"";flex:none;width:7px;height:12px;margin-left:auto;background:var(--mut);-webkit-mask:var(--chev) center/contain no-repeat;mask:var(--chev) center/contain no-repeat;transition:translate var(--dur-hover) var(--ease-ui)}
.ksh-r:hover{color:var(--ink);background:var(--tint)}
.ksh-r:hover::after{translate:3px 0}
.ksh-r:active{background:var(--tint-2)}
.ksh-t:focus-visible,.ksh-r:focus-visible{outline-offset:-2px}
.ksh-note{color:var(--body)}
.ksh-code{display:block;width:100%;margin-top:10px;padding:10px 12px;border:1px solid var(--line-2);border-radius:10px;background:var(--bg);color:var(--ink);font:12.5px/1.55 ui-monospace,SFMono-Regular,Menlo,monospace;resize:vertical;word-break:break-all}
.ksh-code+.ksh-copy,.ksh-cite .ksh-copy{margin-top:8px}
.ksh-lic{margin-top:12px;padding-top:10px;border-top:1px solid var(--line);font-size:13px;color:var(--mut)}
.ksh-cite+.ksh-cite{margin-top:14px}
.ksh-k{margin-bottom:6px;font:700 var(--fs-xs)/1.25 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--blue)}
.ksh-ct{max-width:none;padding:10px 12px;border-radius:10px;background:var(--bg);box-shadow:inset 0 0 0 1px var(--line);color:var(--ink);overflow-wrap:anywhere}
.ksh-tmp{position:fixed;top:0;left:0;width:1px;height:1px;opacity:0}
/* phones: 44px targets; on iOS Safari (the browser that zooms into small text fields) the code is 16px */
@media (max-width:760px){.ksh-b{min-height:44px}html.js .ka-share:empty{min-height:44px}}
.ksh-sheet .ksh-ib,.ksh-sheet .ksh-copy{min-width:44px;min-height:44px}
.ksh-sheet .ksh-r{min-height:48px}
.ksh-sheet .ksh-h{font-size:17px}
@supports (-webkit-touch-callout:none){.ksh-code{font-size:16px}}
/* motion: rows rise in reading order on open; another view slides in from the side it comes from
   while the panel glides to its height (ka-share.js sets the height); reduced motion: all at once */
.ksh-s{transition:opacity 300ms var(--ease-out) calc(40ms + var(--i) * 28ms),translate 520ms var(--ease-out) calc(40ms + var(--i) * 28ms)}
/* closing: the contents stay put while the panel leaves, and reset once it is hidden */
.ksh-panel:not(.open) .ksh-s{opacity:0;translate:0 12px;transition:opacity 0s 300ms,translate 0s 300ms}
@keyframes ksh-fw{from{opacity:0;translate:24px 0}}
@keyframes ksh-bk{from{opacity:0;translate:-24px 0}}
.ksh-fw{animation:ksh-fw 420ms var(--ease-out)}
.ksh-bk{animation:ksh-bk 420ms var(--ease-out)}
.ksh-panel.open.ksh-glide{transition:height 360ms var(--ease-io),translate 460ms var(--ease-out),scale 500ms var(--ease-out),opacity 140ms var(--ease-out)}
@media print{.ka-share,.ksh-panel,.ksh-scrim{display:none!important}}
/* ---- Share (ka-share.js) ---- (end) */

/* 8d. FAQ accordion (one component everywhere) */
.faq{margin-top:32px;display:grid;gap:10px;max-width:820px}
.faq-group+.faq-group{margin-top:40px}
.faq-group>h2,.faq-group>h3{font-size:var(--fs-xl);margin-bottom:12px}
.faq details{background:var(--surface);border:1px solid var(--line);border-radius:14px;box-shadow:var(--sh);transition:border-color var(--dur-hover) var(--ease-ui)}
.faq details[open]{border-color:var(--line-2)}
.faq summary{display:flex;justify-content:space-between;align-items:center;gap:16px;min-height:56px;padding:14px 20px;border-radius:14px;list-style:none;cursor:pointer;font:600 var(--fs-base)/1.4 var(--sans);color:var(--ink);transition:color var(--dur-hover) var(--ease-ui);-webkit-tap-highlight-color:transparent}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";flex:none;width:14px;height:14px;background:linear-gradient(currentColor,currentColor) center/14px 2px no-repeat,linear-gradient(currentColor,currentColor) center/2px 14px no-repeat;color:var(--blue);transition:transform var(--dur-ui) var(--ease-ui)}
.faq details[open]>summary::after{transform:rotate(45deg)}
.faq summary:hover{color:var(--blue)}
.faq summary:active{background:var(--tint)}
.faq summary:focus-visible{outline-offset:-2px}
.faq details>:not(summary){margin:0 20px;font-size:var(--fs-ui);color:var(--body);max-width:68ch}
.faq details>:not(summary)+:not(summary){margin-top:10px}
.faq details>:last-child:not(summary){margin-bottom:20px}
.faq-a>*+*{margin-top:10px}

/* 8e. Tiers: price options side by side, price as the headline */
.tiers{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:16px;margin-top:32px;align-items:stretch}
.tier{position:relative;display:flex;flex-direction:column;padding:26px 24px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh)}
.tier.rec{border:1.5px solid var(--blue2)}
.tier-tag{position:absolute;top:0;left:22px;transform:translateY(-50%);background:var(--grad-btn);color:#fff;font:700 11.5px/1 var(--sans);letter-spacing:.08em;text-transform:uppercase;padding:7px 12px;border-radius:999px}
.tier-name{font:600 var(--fs-xl)/1.25 var(--disp);color:var(--ink);letter-spacing:-.01em}
.tier-price{font:700 var(--fs-3xl)/1.1 var(--disp);color:var(--ink);letter-spacing:-.025em;margin-top:12px}
.tier-price small{font:500 var(--fs-sm) var(--sans);letter-spacing:0;color:var(--mut);margin-left:4px}
.tier-dur{font-size:var(--fs-sm);color:var(--mut);margin-top:4px}
.tier-desc{font-size:var(--fs-ui);margin-top:14px}
.tier .checks{margin-top:16px;flex:1;align-content:start}
.tier .btn{margin-top:22px;align-self:flex-start}

/* 8f. Data-handling box */
.data-box{background:var(--tint);border:1px solid var(--tint-line);border-radius:var(--r);padding:clamp(20px,3vw,28px)}
.data-box h2,.data-box h3{display:flex;align-items:center;gap:10px;font-size:var(--fs-xl);margin-bottom:12px}
.data-box h2::before,.data-box h3::before{content:"";flex:none;width:20px;height:20px;background:var(--blue);-webkit-mask:var(--lock) center/contain no-repeat;mask:var(--lock) center/contain no-repeat}
.data-box dl>div{display:grid;grid-template-columns:10rem minmax(0,1fr);gap:4px 20px;padding:12px 0;border-top:1px solid var(--tint-line)}
.data-box dt{font:600 var(--fs-sm)/1.55 var(--sans);color:var(--ink)}
.data-box dd{margin:0;font-size:var(--fs-ui);line-height:1.55;color:var(--body)}
.data-box p{font-size:var(--fs-ui)}
@media (max-width:600px){.data-box dl>div{grid-template-columns:1fr}}

/* 8g. Who does the work (compact): 64px photo, one line, a link */
.who{display:flex;align-items:center;gap:16px;max-width:720px;padding:16px 20px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh)}
.who-photo{flex:none;width:64px;height:64px;border-radius:50%;object-fit:cover;background:var(--tint)}
.who-text{flex:1;min-width:0;margin:0;font-size:var(--fs-ui);line-height:1.5;color:var(--body)}
.who-text b{color:var(--ink)}
.who-text a.more{display:flex;width:max-content;min-height:36px}

/* 8h. Group glyph: a 48-unit line drawing in a tint tile, one per service group (GROUP_INFO in
   ops/build_offer_pages.py). .g-dot is a sky fill, .g-dash a dashed reference line. Solid strokes carry
   pathLength="1" so they can be drawn in. */
.svc-glyph{position:relative;isolation:isolate;flex:none;display:grid;place-items:center;width:48px;height:48px;border-radius:14px;background:var(--tint);box-shadow:inset 0 0 0 1px var(--tint-line);color:var(--blue2)}
.svc-glyph::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;background:var(--grad-btn);opacity:0;transition:opacity var(--dur-ui) var(--ease-ui)}
.svc-glyph svg{display:block;width:30px;height:30px;overflow:visible;fill:none;stroke:currentColor;stroke-width:2.7;stroke-linecap:round;stroke-linejoin:round;transition:color var(--dur-ui) var(--ease-ui)}
.svc-glyph .g-dot{fill:var(--sky);stroke:none;transition:fill var(--dur-ui) var(--ease-ui)}
.svc-glyph .g-dash{stroke-width:2;stroke-dasharray:2.5 4.5;opacity:.55}

/* 8i. Offer card: the hero visual on every offer page from 961px (hidden on narrower screens, where the
   hero's first sentence already gives the price and duration). The group glyph draws in, the price
   and duration, then every service's starting price as ticks on one log scale with this offer
   marked: the strip wipes in left to right and the mark grows (ka-motion, data-build in a data-hero
   block). Generated by build_offer_pages.py (offer_card); hand-built offer pages carry it between
   <!-- ka:offer-card --> markers. */
.offer-card{padding:24px 26px 18px;background:rgb(255 255 255/.86);-webkit-backdrop-filter:blur(10px) saturate(1.3);backdrop-filter:blur(10px) saturate(1.3);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--sh)}
@media (max-width:960px){.hero .offer-card{display:none}}
@media (min-width:961px){.hero-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,22rem);gap:64px;align-items:center}}
.oc-top{display:flex;align-items:center;gap:14px}
.offer-card .svc-glyph{width:56px;height:56px;border-radius:16px}
.offer-card .svc-glyph svg{width:34px;height:34px}
.oc-g{display:inline-flex;align-items:center;min-height:44px;font:600 var(--fs-sm)/1.3 var(--sans);color:var(--blue);text-decoration:none}
.oc-g:hover{color:var(--blue);text-decoration:underline;text-underline-offset:.25em}
.oc-price{margin-top:18px;font:700 clamp(34px,3.2vw,44px)/1.05 var(--disp);letter-spacing:-.03em;color:var(--ink);font-variant-numeric:tabular-nums;max-width:none}
.oc-price .from{margin-right:6px;font:500 var(--fs-ui)/1 var(--sans);letter-spacing:0;color:var(--mut)}
.oc-price .per{font:500 var(--fs-ui)/1 var(--sans);letter-spacing:0;color:var(--mut)}
.oc-mo{margin-top:6px;font:600 var(--fs-ui)/1.3 var(--sans);color:var(--ink);font-variant-numeric:tabular-nums}
.oc-dur{margin-top:6px;font-size:var(--fs-ui);color:var(--body)}
.oc-strip{margin-top:20px;padding-top:16px;border-top:1px solid var(--line)}
.oc-label{margin-bottom:10px;font:700 var(--fs-xs)/1.25 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--mut)}
.oc-track{position:relative;height:24px;margin:0 6px}
.oc-track::before{content:"";position:absolute;left:0;right:0;top:50%;height:1px;background:var(--line-2)}
.oc-ticks,.oc-ticks>span{position:absolute;inset:0}
.oc-ticks i{position:absolute;top:50%;left:var(--a);width:2px;height:12px;margin:-6px 0 0 -1px;border-radius:1px;background:var(--data-dim)}
.oc-m{position:absolute;top:50%;left:var(--a);background:var(--blue2);box-shadow:0 0 0 3px var(--surface)}
.oc-bar{width:calc(var(--b) - var(--a));height:8px;margin-top:-4px;border-radius:4px}
.oc-dot{width:12px;height:12px;margin:-6px 0 0 -6px;border-radius:50%}
.oc-axis{position:relative;height:18px;margin:6px 6px 0;max-width:none;font-size:11.5px;color:var(--mut);font-variant-numeric:tabular-nums}
.oc-axis span{position:absolute;left:var(--a);translate:-50% 0;white-space:nowrap}
.oc-axis span:first-child{translate:-30% 0}
.oc-axis span:last-child{translate:-80% 0}
.offer-card a.more{margin-top:6px;font-size:var(--fs-sm)}

/* 8j. Insights sections (/research/, /blog/, /news/, /charts/, /facts/): the kicker is a breadcrumb back to /insights/,
   and the five sections follow it as tabs, the current one raised, so they hold one place on every page. */
.crumbs{color:var(--mut)}
.crumbs a{color:var(--blue)}
.crumbs .sep{margin:0 .55em;color:var(--mut);font-weight:500}
/* the tabs sit in one slot on every section page: under the breadcrumb, above the title */
.ins-tabs{display:inline-flex;flex-wrap:wrap;gap:4px;margin:0 0 clamp(26px,3vw,36px);padding:4px;border-radius:14px;background:var(--tint-2);box-shadow:inset 0 0 0 1px var(--tint-line)}
.ins-tabs a{display:inline-flex;align-items:center;min-height:40px;padding:0 18px;border-radius:10px;color:var(--body);font:600 var(--fs-ui)/1 var(--sans);text-decoration:none;transition:color var(--dur-hover) var(--ease-ui),background-color var(--dur-hover) var(--ease-ui),box-shadow var(--dur-ui) var(--ease-ui)}
.ins-tabs a:hover{color:var(--ink);background:rgb(255 255 255/.6)}
.ins-tabs a[aria-current]{color:var(--blue);background:var(--surface);box-shadow:0 1px 2px rgb(10 21 40/.06),0 4px 14px rgb(29 78 216/.12)}
.ins-tabs a:focus-visible{outline-offset:-2px}
/* phones: the five tabs stay one row on every Insights page. They share the width while they fit
   (all five do at 390px) and the row scrolls sideways inside itself when they don't, so the page
   keeps its width; pages/charts.js brings the current tab into view on the Charts and Facts pages. */
@media (max-width:600px){
  .ins-tabs{display:flex;flex-wrap:nowrap;gap:2px;max-width:100%;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none}
  .ins-tabs::-webkit-scrollbar{display:none}
  .ins-tabs a{flex:1 0 auto;justify-content:center;min-height:44px;padding:0 10px;font-size:var(--fs-sm)}
}

/* ---------- 9. Dark CTA band (one per page, at the end) ---------- */
.band,.end-cta{position:relative;isolation:isolate;overflow:clip;background:var(--band);color:var(--band-text);border-radius:28px;--focus:#93c5fd}
.band::before,.end-cta::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;background:radial-gradient(480px 380px at 0 0,rgb(37 99 235/.34),transparent 70%),radial-gradient(440px 360px at 100% 100%,rgb(3 105 161/.3),transparent 70%)}
.band{width:min(1072px,100% - 2*var(--gutter));margin-inline:auto}
.wrap .band{width:auto}
.band .inner{max-width:780px;margin:0 auto;padding:clamp(56px,8vw,100px) clamp(20px,4vw,32px);text-align:center}
.band h2,.band h3,.end-cta h2,.end-cta h3{color:#fff}
.band h2{font-size:var(--fs-3xl);letter-spacing:-.03em;margin-bottom:16px}
.band.compact h2,.band.compact h3{font-size:var(--fs-xl);letter-spacing:-.02em;margin:0 0 8px}
.band.compact p{font-size:var(--fs-ui);margin:0 0 18px}
.band .lede{color:var(--band-mut);margin:0 auto 30px}
.band p{color:var(--band-mut)}
.band .kicker,.end-cta .kicker{color:var(--band-link)}
.band a:not(.btn),.end-cta a:not(.btn){color:var(--band-link)}
.band a:not(.btn):hover,.end-cta a:not(.btn):hover{color:#fff}
.band .alt{margin:18px auto 0;font-size:var(--fs-sm)}
/* under the band's one button: "Rather write it down? Get a written proposal" (stamped by build_site.py) */
.band-prop{margin:16px auto 0;font-size:var(--fs-sm);color:var(--band-mut)}
.band-prop a{font-weight:600}
.band.compact .band-prop{margin:12px 0 0}
.band-prop+.alt{margin-top:6px}
.band-acts{display:flex;flex-wrap:wrap;gap:12px 22px;justify-content:center;align-items:center}
.band .btn.ghost,.end-cta .btn.ghost{background:transparent;color:#fff;box-shadow:inset 0 0 0 1.5px rgb(255 255 255/.32)}
/* compact: inside a content column (articles, the end of a form page) */
.band.compact,.end-cta{width:auto;margin:40px 0 0;border-radius:20px;text-align:left}
.band.compact .inner{max-width:none;padding:26px 24px;text-align:left}
.band.compact .band-acts{justify-content:flex-start}
.end-cta{padding:26px 24px;box-shadow:0 18px 40px rgb(10 21 40/.16)}
.end-cta h2,.end-cta h3{font-size:var(--fs-xl);margin:0 0 8px}
.end-cta p{color:var(--band-mut);font-size:var(--fs-ui);margin:0 0 18px}
.end-cta .row{display:flex;flex-wrap:wrap;gap:12px 18px;align-items:center}
.end-cta .alt{font-weight:600;font-size:var(--fs-ui);text-decoration:none}
.end-cta .alt:hover{text-decoration:underline}
@media (max-width:640px){.band{border-radius:22px}}

/* ---------- 10. Footer ---------- */
main>section:last-child{padding-bottom:clamp(56px,7vw,96px)}
main>:last-child:not(section){margin-bottom:clamp(56px,7vw,96px)}
.site-foot{border-top:1px solid var(--line);background:var(--surface);padding:52px 0 calc(28px + env(safe-area-inset-bottom));font-size:var(--fs-sm);color:var(--body)}
.foot-grid{display:grid;grid-template-columns:minmax(0,1.4fr) repeat(3,minmax(0,1fr));gap:36px 32px}
.foot-brand .logo{font-size:19px}
.foot-tag{margin-top:10px;font-size:var(--fs-ui);line-height:1.5;color:var(--ink);max-width:28ch}
.foot-brand address{margin-top:16px;font-style:normal;line-height:1.6;color:var(--mut)}
.foot-contact{list-style:none;padding:0;margin-top:10px}
.foot-contact a{display:inline-flex;align-items:center;min-height:32px}
.foot-acts{margin-top:14px}
.foot-h{font:700 var(--fs-xs)/1.25 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--ink);margin:4px 0 10px}
.foot-col ul{list-style:none;padding:0}
.foot-col a{display:inline-flex;align-items:center;min-height:34px;color:var(--body);text-decoration:underline 1px transparent;text-underline-offset:.55em;transition:color var(--dur-hover) var(--ease-ui),text-decoration-color var(--dur-ui) var(--ease-ui),text-underline-offset var(--dur-ui) var(--ease-out)}
.foot-col a:hover{color:var(--blue);text-decoration-color:currentColor;text-underline-offset:.22em}
.foot-col a[aria-current]{color:var(--ink);font-weight:600}
.foot-base{display:flex;flex-wrap:wrap;justify-content:space-between;gap:6px 24px;margin-top:44px;padding-top:18px;border-top:1px solid var(--line);color:var(--mut);font-size:13px}
@media (max-width:860px){.foot-grid{grid-template-columns:1fr 1fr}.foot-brand{grid-column:1/-1}}
@media (max-width:600px){.foot-col a,.foot-contact a{min-height:44px}.foot-grid{gap:28px 20px}}
/* legacy footer pieces (pages not yet restamped) */
.foot-mark{display:none}
.foot-row{display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;font-size:13.5px;color:var(--mut);border-top:1px solid var(--line);padding-top:26px}
.foot-row a{color:var(--mut);text-decoration:none}

/* ---------- 11. Forms ---------- */
.form{display:grid;gap:12px}
.form label,.label{display:block;font:600 12px var(--sans);letter-spacing:.08em;text-transform:uppercase;color:var(--mut);margin-bottom:5px}
.form input,.form select,.form textarea,.input{width:100%;font:inherit;font-size:16px;padding:12px 13px;border:1px solid var(--line-2);border-radius:12px;background:var(--surface);color:var(--ink);transition:border-color var(--dur-hover) var(--ease-ui)}
.form input:focus,.form select:focus,.form textarea:focus,.input:focus{border-color:var(--blue2)}
.form input:focus-visible,.form select:focus-visible,.form textarea:focus-visible,.input:focus-visible{outline:2px solid var(--focus);outline-offset:1px}
.form textarea{min-height:110px;resize:vertical}
.form .two{display:grid;grid-template-columns:1fr;gap:12px}
@media (min-width:560px){.form .two{grid-template-columns:1fr 1fr}}
.opts{display:flex;flex-wrap:wrap;gap:8px}
.form label.opt,.opt{display:inline-flex;align-items:center;gap:8px;min-height:40px;white-space:nowrap;flex:0 0 auto;margin:0;border:1px solid var(--line-2);border-radius:999px;padding:8px 14px;font:500 var(--fs-sm) var(--sans);text-transform:none;letter-spacing:0;color:var(--ink);background:var(--surface);cursor:pointer;transition:border-color var(--dur-hover),background-color var(--dur-hover)}
.opt input{margin:0;accent-color:var(--blue2)}
.opt:has(input:checked){border-color:var(--blue);background:var(--tint)}
.opt:has(input:focus-visible){outline:2px solid var(--focus);outline-offset:2px}
.hp{position:absolute;left:-9999px;opacity:0;height:0;width:0}
.ok{background:#ecfdf5;border:1px solid #a7f3d0;color:#065f46;border-radius:14px;padding:16px 18px;font-size:15px}
.note-muted{font-size:13px;color:var(--mut)}
.chip{display:inline-block;font:600 12px var(--sans);padding:4px 10px;border-radius:999px;background:var(--tint);color:var(--blue);border:1px solid var(--tint-line)}
.chip.ok{background:#dcfce7;color:#166534;border-color:#bbf7d0;padding:4px 10px;font-size:12px;border-radius:999px}
.chip.warn{background:#fef3c7;color:#92400e;border-color:#fde68a}
.chip.mut{background:var(--bg);color:var(--mut);border-color:var(--line)}
.bookgrid{display:grid;grid-template-columns:1fr;gap:22px;margin-top:8px}
@media (min-width:960px){.bookgrid{grid-template-columns:1.1fr .9fr;align-items:start}}
.bookgrid .card{padding:22px 20px}
@media (min-width:960px){.bookgrid .card{padding:30px 28px}}
.bookgrid h3{font-size:19px;margin:0 0 8px}
.why li{margin-bottom:8px}

/* ---------- 12. Homepage services (v20 rows; the homepage moves to .fees) ---------- */
.svc-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px;margin-top:8px;align-items:start}
.svc-group{padding:22px 22px 10px;border-radius:20px}
.svc-group h3{font:700 var(--fs-xs)/1.25 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--blue);margin:0 0 6px}
.svc{display:grid;grid-template-columns:1fr auto;gap:2px 14px;padding:14px 0;border-top:1px solid var(--line);text-decoration:none;color:inherit}
.svc:hover{color:inherit}
.svc-group h3+.svc{border-top:0}
.svc-n{font:700 16.5px/1.3 var(--disp);color:var(--ink)}
.svc-p{font:600 13px/1.3 var(--sans);color:var(--blue);text-align:right;white-space:nowrap}
.svc-l{grid-column:1/-1;font-size:14.5px;line-height:1.5;color:var(--body)}
.svc:hover .svc-n{color:var(--blue)}
@media (max-width:860px){.svc-grid{grid-template-columns:1fr}}

/* /news/ */
.news-wrap{max-width:760px}
.nday{margin:0 0 34px}
.nday h2{font:700 13px/1.2 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--blue);margin:0 0 6px;padding-bottom:10px;border-bottom:1px solid var(--line)}
.nitem{padding:18px 0;border-bottom:1px solid var(--line)}
.nitem .nt{font:700 19px/1.3 var(--disp);color:var(--ink);letter-spacing:-.01em;text-decoration:none}
.nitem .nt:hover{color:var(--blue);text-decoration:underline;text-decoration-thickness:1px}
.nitem .ns{font:600 12.5px var(--sans);color:var(--mut);margin:6px 0 8px}
.nitem p{font-size:var(--fs-ui);margin:0 0 6px;max-width:64ch}
.nitem .nw{color:var(--ink)}
.nitem .nw b{color:var(--blue);font-weight:700}
.nfoot{font-size:13px;color:var(--mut);margin-top:10px}

/* ---------- 13. Motion ----------
   Language: content ARRIVES (rises from below; type rises through line masks), data ASSEMBLES
   (builds along its own axis; numbers count to their true value), the interface RESPONDS (under
   250ms). Ambient motion lives only in generative fields, slow, paused offscreen.
   Split of duties: ka-motion.js (GSAP) animates transform, opacity and clip-path on entrances and
   clears them when done; CSS here animates translate, scale, colors and shadows on hover and press.
   Nothing below hides content unless html.js-motion is set, and that class only exists when the
   motion layer is about to run (set in <head>, dropped by a failsafe if it never starts). */

/* 13a. Gate: the title intro's pieces wait, invisible but in place, for ka-motion.js. It writes
   their from-states inline and then adds html.ka-ready. Opacity only: find-in-page, focus and
   crawlers still see the text. */
html.js-motion:not(.ka-ready) main h1:not([data-motion=off] h1),
html.js-motion:not(.ka-ready) main h1:not([data-motion=off] h1)+*,
html.js-motion:not(.ka-ready) main h1:not([data-motion=off] h1)+*+*,
html.js-motion:not(.ka-ready) main h1:not([data-motion=off] h1)+*+*+*,
html.js-motion:not(.ka-ready) main :is(.kicker,.badge):has(+h1:not([data-motion=off] h1)),
html.js-motion:not(.ka-ready) main [data-hero]:not([data-motion=off] *),
html.js-motion.ka-first:not(.ka-ready) [data-intro] .ka-field{opacity:0}
/* parked while GSAP moves it, so no CSS transition can race a tween */
.ka-tw{transition:none!important}
/* split text: line masks get room for descenders and overhangs; while the homepage headline is
   split, the gradient word carries its own gradient */
.ka-line-mask{padding:0 .1em .16em;margin:0 -.1em -.16em}
.ka-split .grad-text{background:none!important;color:inherit!important}
.ka-split .grad-text .ka-word,.ka-split .ka-word:has(>.grad-text){background:var(--grad-text);-webkit-background-clip:text;background-clip:text;color:transparent}
.ka-split .ka-word .grad-text{color:transparent!important}
/* one pass of light across the gradient word after the homepage intro */
.grad-text.ka-sheen{position:relative}
.grad-text.ka-sheen::after{content:attr(data-sheen);position:absolute;inset:0;padding-right:inherit;pointer-events:none;background:linear-gradient(100deg,transparent 35%,rgb(255 255 255/.85) 50%,transparent 65%) no-repeat;background-size:260% 100%;background-position:120% 0;-webkit-background-clip:text;background-clip:text;color:transparent;animation:ka-sheen 1.3s var(--ease-io) .1s both}
@keyframes ka-sheen{to{background-position:-60% 0}}

/* 13b. Generative fields (ka-field.js): decorative canvas layers */
.ka-field{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden;contain:strict}
.ka-field canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.hero>.ka-field~.wrap,.hero>.ka-field~*:not(.gridbg,.ka-pause){position:relative;z-index:1}
/* the hero field thins out behind the headline column so the text keeps its contrast, and fades out
   above the hero's bottom edge so the points never stop on a line */
.hero>.ka-field{-webkit-mask-image:linear-gradient(90deg,rgb(0 0 0/.72) 0,rgb(0 0 0/.66) 36%,#000 58%),linear-gradient(#000 calc(100% - 110px),transparent);-webkit-mask-composite:source-in;mask-image:linear-gradient(90deg,rgb(0 0 0/.72) 0,rgb(0 0 0/.66) 36%,#000 58%),linear-gradient(#000 calc(100% - 110px),transparent);mask-composite:intersect}
@media (max-width:960px){.hero>.ka-field{bottom:auto;height:min(100%,720px);-webkit-mask-image:linear-gradient(180deg,#000 0,rgb(0 0 0/.55) 30%,rgb(0 0 0/.3) 60%,transparent 100%);-webkit-mask-composite:source-over;mask-image:linear-gradient(180deg,#000 0,rgb(0 0 0/.55) 30%,rgb(0 0 0/.3) 60%,transparent 100%);mask-composite:add}}
/* surfaces that sit on a field are frosted on desktop, so the stream shows through softly */
@media (min-width:961px){.hero>.ka-field~.wrap :is(.ways,.card){background:rgb(255 255 255/.74);-webkit-backdrop-filter:blur(12px) saturate(1.4);backdrop-filter:blur(12px) saturate(1.4)}}
/* dark band: the network sits under the content and stays quiet behind the centered text */
.band>.ka-field{z-index:-1;-webkit-mask-image:radial-gradient(ellipse 58% 64% at 50% 50%,rgb(0 0 0/.18),#000 92%);mask-image:radial-gradient(ellipse 58% 64% at 50% 50%,rgb(0 0 0/.18),#000 92%)}
/* pause toggle for anything that moves on its own (ka-field.js adds it; WCAG 2.2.2). It sits in the
   zone's lower right corner, on the content grid's edge in a hero */
.ka-pause{position:absolute;z-index:3;right:16px;bottom:16px;display:grid;place-items:center;width:32px;height:32px;padding:0;border:1px solid var(--line);border-radius:50%;background:rgb(255 255 255/.72);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:var(--mut);cursor:pointer;opacity:.85;transition:color var(--dur-hover) var(--ease-ui),opacity var(--dur-hover) var(--ease-ui),border-color var(--dur-hover) var(--ease-ui);-webkit-tap-highlight-color:transparent}
.ka-pause:hover{color:var(--ink);opacity:1;border-color:var(--line-2)}
.ka-pause:active{scale:.94}
.ka-pause svg{display:block;width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.ka-pause .i-play{display:none;fill:currentColor;stroke-width:1.2}
.ka-pause[aria-pressed=true] .i-pause{display:none}
.ka-pause[aria-pressed=true] .i-play{display:block}
.hero>.ka-pause{right:max(var(--gutter),calc((100% - 1120px) / 2 + var(--gutter)));bottom:20px}
.band>.ka-pause{right:18px;bottom:18px;border-color:rgb(255 255 255/.2);background:rgb(10 21 40/.35);color:var(--band-mut)}
.band>.ka-pause:hover{color:#fff;border-color:rgb(255 255 255/.4)}
.ka-video>.ka-pause{right:12px;bottom:12px}

/* 13c. Video loop slot: poster first, video only near the viewport, field if it can't play */
.ka-video{position:relative;overflow:clip;isolation:isolate;border-radius:var(--r);background:var(--tint);aspect-ratio:var(--ratio,16/9);box-shadow:var(--sh)}
.ka-video video{display:block;width:100%;height:100%;object-fit:cover}
.ka-video>.ka-field{display:none}
.ka-video.is-fallback>.ka-field{display:block}
.ka-video.is-fallback video{opacity:0}

/* 13d. Media hover: the image eases in a little and the caption rises (mouse only; phones
   always show the caption) */
.ka-media{position:relative;overflow:clip;isolation:isolate;border-radius:var(--r);background:var(--tint)}
.ka-media img,.ka-media video{display:block;width:100%;height:100%;object-fit:cover;transition:scale 900ms var(--ease-out)}
.ka-media-cap{position:absolute;inset:auto 0 0;margin:0;max-width:none;padding:28px 16px 12px;background:linear-gradient(transparent,rgb(10 21 40/.74));color:#fff;font-size:var(--fs-sm);line-height:1.45;transition:translate var(--dur-ui) var(--ease-out),opacity var(--dur-ui) var(--ease-ui)}
@media (hover:hover) and (pointer:fine){
  .ka-media-cap{translate:0 35%;opacity:0}
  :is(a,.ka-media):hover>.ka-media img,:is(a,.ka-media):hover>.ka-media video,a:hover .ka-media img{scale:1.04}
  .ka-media:hover>.ka-media-cap,a:hover .ka-media-cap,.ka-media:focus-within>.ka-media-cap{translate:none;opacity:1}
}

/* 13e. Keyframes (CSS fallbacks and small pieces that need no script) */
@keyframes ka-rise{from{opacity:0;translate:0 var(--rise)}}
@keyframes ka-drop{from{opacity:0;translate:0 -4px}}
@keyframes ka-draw{from{stroke-dashoffset:1.02}}
@keyframes ka-grow{to{transform:scaleX(1)}}
@keyframes ka-vt-out{to{opacity:0;translate:0 -8px}}
@keyframes ka-vt-in{from{opacity:0;translate:0 14px}}
@keyframes ka-fade-in{from{opacity:0}}
@media (prefers-reduced-motion:no-preference){
  /* fallback entrances when GSAP did not load (ka-motion.js adds .rv-in on arrival) */
  .rv-in{animation:ka-rise var(--dur-enter) var(--ease-out) backwards;animation-delay:calc(var(--i,0) * var(--step))}
  [data-rv-i="1"]{--i:1}[data-rv-i="2"]{--i:2}[data-rv-i="3"]{--i:3}[data-rv-i="4"]{--i:4}
  /* the logo K draws itself on the first page of a visit */
  html:not(.ka-seen) #hdr .logo-mark [pathLength]{stroke-dasharray:1 2;animation:ka-draw 700ms var(--ease-io) 150ms backwards}
  /* FAQ answers settle in when opened; Chromium also animates the height */
  .faq details[open]>:not(summary){animation:ka-drop var(--dur-ui) var(--ease-out) backwards}
  @supports (interpolate-size:allow-keywords){
    .faq details{interpolate-size:allow-keywords}
    .faq details::details-content{block-size:0;overflow-y:clip;transition:block-size var(--dur-ui) var(--ease-io),content-visibility var(--dur-ui) allow-discrete}
    .faq details[open]::details-content{block-size:auto}
  }
  /* menu icon morph, and the phone menu's contents arrive in order */
  .menu-ico span{transition:transform var(--dur-ui) var(--ease-io)}
  .sheet-main>li,.sheet-cats>li,.sheet-hi,.sheet-ins>li,.sheet-mail{transition:opacity 260ms var(--ease-out),translate 420ms var(--ease-out)}
  .sheet:not(.open) :is(.sheet-main>li,.sheet-cats>li,.sheet-hi,.sheet-ins>li,.sheet-mail){opacity:0;translate:0 12px;transition-duration:120ms}
  .sheet.open .sheet-main>li:nth-child(2){transition-delay:110ms}
  .sheet.open .sheet-main>li:nth-child(3){transition-delay:150ms}
  .sheet.open .sheet-main>li:nth-child(4){transition-delay:300ms}
  .sheet.open .sheet-mail{transition-delay:330ms}
  /* the tiles and rows inside a group follow their row in reading order */
  .sheet.open .sheet-cats>li:nth-child(1){transition-delay:40ms}.sheet.open .sheet-cats>li:nth-child(2){transition-delay:62ms}
  .sheet.open .sheet-cats>li:nth-child(3){transition-delay:84ms}.sheet.open .sheet-cats>li:nth-child(4){transition-delay:106ms}
  .sheet.open .sheet-cats>li:nth-child(5){transition-delay:128ms}.sheet.open .sheet-cats>li:nth-child(6){transition-delay:150ms}
  .sheet.open .sheet-cats>li:nth-child(7){transition-delay:172ms}.sheet.open .sheet-cats>li:nth-child(8){transition-delay:194ms}
  .sheet.open .sheet-hi{transition-delay:212ms}
  .sheet.open .sheet-ins>li:nth-child(1){transition-delay:180ms}.sheet.open .sheet-ins>li:nth-child(2){transition-delay:200ms}
  .sheet.open .sheet-ins>li:nth-child(3){transition-delay:220ms}.sheet.open .sheet-ins>li:nth-child(4){transition-delay:240ms}
  .sheet.open .sheet-ins>li:nth-child(5){transition-delay:260ms}.sheet.open .sheet-ins>li:nth-child(6){transition-delay:280ms}
  .sheet-cta{transition:translate 460ms var(--ease-out) 90ms}
  .sheet:not(.open) .sheet-cta{translate:0 100%;transition-duration:120ms;transition-delay:0s}
  /* reading progress on posts */
  @supports (animation-timeline:scroll()){.read-progress{animation:ka-grow linear both;animation-timeline:scroll(root)}}
  /* the phone menu's sticky top row: no hairline at the top of the list, full hairline after 24px of
     scroll (without scroll timelines or with reduced motion the hairline simply stays) */
  @supports (animation-timeline:scroll()){
    .sheet-top{animation:ka-sheet-edge linear both;animation-timeline:scroll(nearest block);animation-range:0 24px}
    @keyframes ka-sheet-edge{from{box-shadow:0 1px 0 transparent}to{box-shadow:0 1px 0 var(--line)}}
  }
  /* browsers without cross-document view transitions: a short fade on internal navigation */
  html.ka-pt main{animation:ka-fade-in 320ms var(--ease-out) both}
}
/* cross-document page transitions: the page lifts out, then the next one rises in, header held still.
   The new page waits for the old one to finish (delay = the old one's duration), so two pages never
   show at once. */
@view-transition{navigation:auto}
::view-transition-old(root){animation:120ms var(--ease-in) both ka-vt-out}
::view-transition-new(root){animation:380ms var(--ease-out) 120ms both ka-vt-in}
::view-transition-group(ka-header),::view-transition-new(ka-header){animation:none}
::view-transition-old(ka-header){display:none}
@media (prefers-reduced-motion:reduce){
  @view-transition{navigation:none}
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms!important;animation-delay:0s!important;animation-iteration-count:1!important;transition-duration:.01ms!important;transition-delay:0s!important}
}

/* ---------- 14. Print ---------- */
@media print{
  #hdr,.sheet,.nav-dd,.skip,.read-progress,.site-foot .foot-acts,.ka-field,.ka-pause,.ka-dock{display:none!important}
  body{background:#fff}
  .hero{min-height:auto;padding:24px 0}
}

   main, so this pill shows on the preview and can never reach production pages. */
html:has(meta[name="ka-build"][content="stage"]) body::after{content:"Staging";position:fixed;left:12px;bottom:12px;z-index:2147483647;font:600 11px/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;padding:7px 10px;border-radius:999px;background:#b45309;color:#fff;pointer-events:none;box-shadow:0 2px 8px rgb(0 0 0/.18)}
html:has(meta[name="ka-build"][content="stage"]) .ka-dock{bottom:calc(var(--dk) + 40px + env(safe-area-inset-bottom))}

/* ---- External links (.ext) ---- (start)
   A link that leaves kentapplied.com: a small north-east arrow follows the text, raised like a
   superscript, in the link blue; the markup carries visually hidden text "(opens in a new tab)".
   Generated titles wrap their last word with the arrow in .ext-nw, so the arrow never wraps onto a
   line by itself. With a mouse the arrow nudges up and right on hover. Links keep target="_blank"
   rel="noopener" (link rule). Markup:
   <a class="ext" href="https://…" target="_blank" rel="noopener">Title of the <span class="ext-nw">story</span><span class="sr-only"> (opens in a new tab)</span></a> */
:root{--ext:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.6 9.4 9.2 2.8M4.2 2.6h5.2v5.2' fill='none' stroke='%23000' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}
.ext::after,.ext .ext-nw::after{content:"";display:inline-block;width:.54em;height:.54em;margin-left:.2em;vertical-align:.32em;background:var(--blue);-webkit-mask:var(--ext) center/contain no-repeat;mask:var(--ext) center/contain no-repeat;transition:translate var(--dur-ui) var(--ease-out)}
.ext:has(.ext-nw)::after{content:none}
.ext-nw{white-space:nowrap}
.band .ext::after,.band .ext .ext-nw::after{background:currentColor}
@media (hover:hover) and (pointer:fine){.ext:hover::after,.ext:hover .ext-nw::after{translate:.12em -.12em}}
@media (forced-colors:active){.ext::after,.ext .ext-nw::after{background:LinkText}}
/* ---- External links (.ext) ---- (end) */

/* ---- Page dock (.ka-dock) ---- (start)
   Back and Top in one small bar at the bottom left (DESIGN.md "Page dock"). Stamped after the footer
   by ops/build_site.py with the page's parent list; ka-motion.js adds .on when the visitor scrolls back
   up more than a screen down the page, and removes it on the way down, near the top, once the footer
   is on screen, while a text field has focus and while a figure (.datafig) is under it. Keyboard focus inside it shows it wherever the page
   is. It rises 10px as it arrives and drops away when it goes; reduced motion makes both instant.
   <nav class="ka-dock" aria-label="Back and top" data-dock hidden>
     <a class="ka-dock-back" href="/services/" aria-label="Back to All services"><svg class="ka-dock-i">…</svg><span class="ka-dock-l">All services</span></a>
     <button class="ka-dock-top" type="button" aria-label="Back to top"><svg class="ka-dock-i">…</svg></button>
   </nav> */
.ka-dock{--dk:16px;position:fixed;z-index:45;left:max(var(--dk),env(safe-area-inset-left));bottom:calc(var(--dk) + env(safe-area-inset-bottom));display:flex;align-items:stretch;height:46px;border:1px solid var(--line-2);border-radius:999px;background:color-mix(in srgb,var(--surface) 92%,transparent);-webkit-backdrop-filter:saturate(1.6) blur(12px);backdrop-filter:saturate(1.6) blur(12px);box-shadow:var(--sh);opacity:0;translate:0 10px;pointer-events:none;transition:opacity 140ms var(--ease-in),translate 140ms var(--ease-in)}
@media (min-width:761px){.ka-dock{--dk:24px}}
.ka-dock.on{opacity:1;translate:none;pointer-events:auto;transition:opacity 220ms var(--ease-out),translate 360ms var(--ease-out)}
/* its own rule: a browser without :has() drops only this one */
.ka-dock:has(:focus-visible){opacity:1;translate:none;pointer-events:auto}
.ka-dock>a,.ka-dock>button{position:relative;display:flex;align-items:center;justify-content:center;gap:8px;min-width:44px;margin:0;padding:0 18px 0 14px;border:0;border-radius:999px;background:none;color:var(--blue);font:600 var(--fs-ui)/1 var(--sans);text-decoration:none;white-space:nowrap;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--dur-hover) var(--ease-ui),color var(--dur-hover) var(--ease-ui)}
.ka-dock>.ka-dock-top{width:44px;padding:0}
/* a hairline between the two halves, only when both show */
.ka-dock-back:not([hidden])+.ka-dock-top::before{content:"";position:absolute;left:-1px;top:12px;bottom:12px;width:1px;background:var(--line-2)}
.ka-dock-i{flex:none;width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;transition:translate var(--dur-ui) var(--ease-out)}
.ka-dock>a:active,.ka-dock>button:active{background:var(--tint-2)}
/* the ring sits inside each half, so it never crosses the bar's edge or the hairline */
.ka-dock>a:focus-visible,.ka-dock>button:focus-visible{outline-offset:-2px}
@media (hover:hover) and (pointer:fine){
  .ka-dock>a:hover,.ka-dock>button:hover{background:var(--tint);color:var(--ink)}
  .ka-dock-back:hover .ka-dock-i{translate:-3px 0}
  .ka-dock-top:hover .ka-dock-i{translate:0 -2px}
}
/* ---- Page dock (.ka-dock) ---- (end) */
