/* ---- 00-base.css ---- */
/* ==========================================================================================================
   ELLIS STERLING v2, BASE (integrator-owned; section builders list base changes in their notes instead)
   Spec: _plan/HOMEPAGE-SPEC.md section 3. Order of this file:
     1. tokens   2. reset   3. hero 21's shared rules (byte for byte from heroes/p21.html)   4. header and nav
     5. Menu panel and the scroll-up bar   6. skip link and focus   7. grounds   8. type   9. layout primitives
     10. actions (buttons and text links)   11. print
   The page has ONE left edge, the spine: the gutter's inner edge, where the logo's mark and the foot of the A sit.
   Every heading, first line, list, button and link starts there. Second reads sit on the half line (grid column 7).
   ========================================================================================================== */

/* 1. TOKENS. Colours and fonts are pinned by the brief; do not add colours. */
:root{
  /* hero 21's tokens, exactly */
  --green:#133325;--deep:#0D261B;--ink:#071711;
  --bronze:#C38B57;--bronze-dk:#80542E;--bronze-hi:#CE9B69;
  --ivory:#F1ECE2;--ivory-hi:#F8F5EF;
  --on:#EEE8DC;--on2:rgba(238,232,220,.72);--ink2:rgba(7,23,17,.68);
  --serif:"Source Serif 4",Georgia,serif;--sans:"Hanken Grotesk","Helvetica Neue",Arial,sans-serif;
  --out:cubic-bezier(.23,1,.32,1);       /* the only easing: strong ease-out, never ease-in */
  --gut:clamp(20px,5vw,72px);            /* the gutter; its inner edge is the spine (72px at 1568, 64 at 1280) */
  /* The gutter actually used on each side: never inside a notch or rounded corner (viewport-fit=cover, a phone on its
     side). With no inset both equal --gut, so every pixel is where it was. */
  --gut-l:max(var(--gut),env(safe-area-inset-left,0px));
  --gut-r:max(var(--gut),env(safe-area-inset-right,0px));
  /* the page system */
  --col-gap:clamp(16px,2vw,32px);        /* 12-column grid gap */
  --sec:clamp(64px,7.5vw,120px);         /* section padding, top and bottom, every section */
  --gap-head:clamp(28px,3vw,48px);       /* a heading or its lede to the content under it */
  --gap-group:clamp(40px,4.5vw,72px);    /* between groups inside a section, and before a closing link */
  --gap-row:clamp(22px,2.2vw,34px);      /* ledger row padding, top and bottom */
  /* the three type sizes other rules borrow (the firm's portrait finds the h2's cap line; the quotes and the footer
     tagline set at the h3 size; the ledger's text column measures in body text) */
  --fs-h2:clamp(1.625rem,3.7vw,3.625rem);  /* 26 / 47.4 / 58 */
  --fs-h3:clamp(1.375rem,1.9vw,1.875rem);  /* 22 / 24.3 / 30; 19px below 960px (section 8) */
  --fs-body:clamp(1rem,1.3vw,1.15rem);     /* 16 / 16.6 / 18.4, the hero sentence's size */
}

/* 2. RESET. Hero 21's reset first; the body is ink so overscroll never flashes white. */
*,*::before,*::after{box-sizing:border-box}
body{margin:0;font-family:var(--sans);background:var(--ink);color:var(--ink);-webkit-font-smoothing:antialiased}
img{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
::selection{background:rgba(195,139,87,.32);color:inherit}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;-webkit-tap-highlight-color:transparent;scroll-padding-top:80px;caret-color:var(--bronze)}
/* No global smooth scrolling: it would also animate every Tab press. The one jump that glides ("What we do") does it in
   site.js, for a pointer click only and never under reduced motion. */
a,button{touch-action:manipulation}
main:focus{outline:none}
button{font:inherit;color:inherit}
/* Margins come from the spacing tokens, never from browser defaults. Zero specificity, so the type steps in section 8
   (also zero specificity, later in the file) and every section rule win over it. Lists with a class are layout. */
:where(h1,h2,h3,h4,p,figure,blockquote,ul,ol,dl,dd){margin:0}
ul[class],ol[class]{list-style:none;padding:0}
html.menu-open{overflow:hidden}

/* 3. HERO 21'S SHARED RULES, byte for byte from heroes/p21.html. The hero depends on these exact values; change them
   only together with css/01-hero.css. */
.nav{position:absolute;inset:0 0 auto;z-index:5;display:flex;align-items:center;gap:32px;padding:22px var(--gut);font-size:.9375rem}
.nav img{height:34px;width:auto}
.nav .links{margin-left:auto;display:flex;gap:28px;opacity:.8}
.nav .cta{border:1px solid currentColor;padding:10px 16px;font-weight:600;font-size:.875rem}
.sub{font-size:clamp(1rem,1.3vw,1.15rem);line-height:1.6;max-width:46ch;margin:0}
.ctas{display:flex;flex-wrap:wrap;align-items:center;gap:14px 28px}
.btn{display:inline-flex;align-items:center;min-height:50px;padding:0 24px;font-weight:600;font-size:.9375rem;transition:transform .16s ease-out,background-color .2s ease}
.btn:active{transform:scale(.97)}
.lnk{font-weight:600;font-size:.9375rem;display:inline-flex;gap:8px;min-height:44px;align-items:center}
@media (max-width:860px){.nav .links{display:none}.nav .cta{margin-left:auto}}
@media (max-width:560px){.nav{gap:16px;padding-top:18px}.nav img{height:28px}.nav .cta{display:none}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
/* p21's fine-pointer hovers (.btn brightness, .lnk fade to .8) are not carried over: every .btn here is .btn-bronze,
   which sets its own hover, and hero 21 already cancelled the link fade. A text link answers the pointer one way on
   the whole page: its arrow moves 3px (section 10). Control labels are in rem (15px = .9375rem, 14px = .875rem), so a
   reader who raises the browser's font size gets bigger buttons and links too; at the default size nothing moves. */

/* 4. HEADER AND NAV. header.site-head sits before <main> and lands on hero 21's pixels: absolute over the hero,
   transparent, logo at x = gut and y = 27 at 1568. The nav is in the header's flow, so the Menu panel can follow it. */
.site-head{position:absolute;inset:0 0 auto;z-index:50}
.site-head .nav{position:relative;inset:auto;padding-left:var(--gut-l);padding-right:var(--gut-r)}
/* hero 21's nav rules, moved from .h-le .nav with the same values */
.site-head .nav{color:var(--on)}
.site-head .nav .links a{display:inline-flex;align-items:center;min-height:44px}
.site-head .nav img{flex-shrink:0}
/* the nav button follows the shared rule: hidden at 560px and below, where the hero button is the only call */
@media (min-width:561px){.site-head .nav .cta{display:inline-flex;align-items:center;min-height:44px;white-space:nowrap}}
/* the logo link: 8px of extra hit area above and below, cancelled by margins, so the logo stays where it was */
.nav-logo{display:block;flex-shrink:0;padding-block:8px;margin-block:-8px}
/* Menu: hidden above 860px. With JS off it is a link to the footer; site.js swaps in a <button>. */
.nav-menu{display:none}
@media (max-width:860px){
  .nav-menu{display:inline-flex;align-items:center;justify-content:flex-end;min-width:44px;min-height:44px;padding:0;
    border:0;background:none;font-family:inherit;font-weight:600;font-size:.9375rem;line-height:1.2;color:inherit;cursor:pointer}
}
/* at 560px and below the nav holds only the 28px logo; -8px margins keep the 44px target from pushing the logo down */
@media (max-width:560px){.nav-menu{margin-left:auto;margin-block:-8px}}
/* the press dims these (section 10); on fine pointers the block below adds the hover transitions to it */
.site-head .nav .links a,.site-head .nav .cta,.nav-menu,.nav-panel-links a{transition:opacity .1s var(--out)}
@media (hover:hover) and (pointer:fine){
  .site-head .nav .links a,.nav-panel-links a,.nav-menu{text-decoration-line:underline;text-decoration-color:transparent;
    text-decoration-thickness:1px;text-underline-offset:.3em;transition:text-decoration-color .18s ease,opacity .1s var(--out)}
  .site-head .nav .links a:hover,.nav-panel-links a:hover,.nav-menu:hover{text-decoration-color:currentColor}
  .site-head .nav .cta{transition:background-color .18s ease,opacity .1s var(--out)}
  .site-head .nav .cta:hover{background-color:rgba(238,232,220,.1)}
}
/* The current page: the nav's own hover underline, at rest. _plan/sync_chrome.py sets aria-current="page" on the
   page's section link (Insights on every /insights page); the scroll-up bar is the same nav, so it keeps the mark.
   On the homepage no link is current, so nothing changes there. The footer's current link takes its own hover state. */
.site-head .nav .links a[aria-current="page"],.nav-panel-links a[aria-current="page"]{text-decoration-line:underline;
  text-decoration-color:currentColor;text-decoration-thickness:1px;text-underline-offset:.3em}

/* 5. MENU PANEL (860px and below) AND THE SCROLL-UP BAR. Both are driven by site.js; with JS off neither appears. */
.nav-panel{background:var(--deep);color:var(--on);padding:8px var(--gut-r) 24px var(--gut-l);
  opacity:0;transform:translateY(-8px);transition:opacity .15s var(--out),transform .15s var(--out)}
.nav-panel.is-in{opacity:1;transform:none;transition-duration:.2s}
.nav-panel[hidden]{display:none}
.nav-panel-links{margin-bottom:16px}
.nav-panel-links a{display:flex;align-items:center;min-height:48px;font-weight:600;font-size:1.125rem}
.site-head.is-open{background:var(--deep)}
/* The open panel fills the screen under the nav, so the page (and the hero's own button) never shows half-covered
   beneath it; it scrolls itself on a short landscape phone. --menu-y is how far the hero nav had scrolled up. */
.site-head.is-open .nav-panel{height:calc(100vh - 88px + var(--menu-y,0px));overflow-y:auto;overscroll-behavior:contain}
@supports (height:1dvh){.site-head.is-open .nav-panel{height:calc(100dvh - 88px + var(--menu-y,0px))}}
@media (max-width:560px){
  .site-head.is-open .nav-panel{height:calc(100vh - 68px + var(--menu-y,0px))}
  @supports (height:1dvh){.site-head.is-open .nav-panel{height:calc(100dvh - 68px + var(--menu-y,0px))}}
}
.site-head.is-bar.is-open .nav-panel{height:calc(100vh - 64px)}
@supports (height:1dvh){.site-head.is-bar.is-open .nav-panel{height:calc(100dvh - 64px)}}
/* One consultation call in view: from 561 to 860px the hero's nav already shows the outlined button, so the panel
   carries its bronze one only where the nav doesn't (560px and below, and in the bar). */
@media (min-width:561px){.site-head:not(.is-bar) .nav-panel .btn-bronze{display:none}}
@media (min-width:861px){.nav-panel{display:none}}
/* The bar: past scrollY 88, scrolling up brings the same nav back, fixed, 64px tall, with the logo and the links only
   (no call to action on every screen). In over 240ms, out over 200ms. Out of flow in both states, so nothing shifts. */
.site-head.is-bar{position:fixed;background:var(--deep);transform:translateY(-100%);transition:transform .2s var(--out)}
.site-head.is-bar.is-shown{transform:none;transition-duration:.24s}
.site-head.is-bar .nav{height:64px;padding-block:0;border-bottom:1px solid rgba(238,232,220,.12)}
.site-head.is-bar .nav img{height:30px}
.site-head.is-bar .nav .cta{display:none}
.site-head.is-bar .nav-menu{margin-left:auto}
@media (max-width:560px){.site-head.is-bar .nav img{height:28px}}

/* 6. SKIP LINK AND FOCUS */
.skip{position:absolute;left:var(--gut-l);top:12px;z-index:100;display:inline-flex;align-items:center;min-height:44px;padding:0 20px;
  background:var(--bronze);color:var(--ink);font-weight:600;font-size:.9375rem;transform:translateY(-72px)}
.skip:focus{transform:none}
:where(a,button):focus-visible{outline:2px solid var(--focus,var(--bronze-hi));outline-offset:3px}

/* 7. GROUNDS. Each ground means one thing: deep = the firm addressing you (hero, consultation); forest = about you
   (situation, outcomes, clients); ivory = paper you forward (work, engagement, firm, insights); ink = the floor.
   Each restates the text colour and sets the local tokens the type and links use. */
.g-deep,.g-forest,.g-ink{color:var(--on);--fg:var(--on);--fg2:rgba(238,232,220,.72);--rule:rgba(238,232,220,.16);--mark:var(--bronze);--focus:var(--bronze-hi)}
.g-deep{background:var(--deep)}
.g-forest{background:var(--green)}
.g-ink{background:var(--ink)}
.g-ivory{background:var(--ivory);color:var(--ink);--fg:var(--ink);--fg2:rgba(7,23,17,.72);--rule:rgba(7,23,17,.16);--mark:var(--bronze-dk);--focus:var(--bronze-dk)}

/* 8. TYPE. Serif for what you would read out as a heading or a name; Hanken for what explains or operates.
   No uppercase labels or eyebrows. Italic only for the quotes. Sizes in the comments are at 390 / 1280 / 1568. */
.t-h2{font-family:var(--serif);font-weight:300;font-size:var(--fs-h2);line-height:1.1;letter-spacing:-.012em;text-wrap:balance;max-width:16em}  /* 26 / 47.4 / 58, the hero line's size on desktop */
@media (max-width:767px){.t-h2{line-height:1.15}}
.t-h3{font-family:var(--serif);font-weight:400;font-size:var(--fs-h3);line-height:1.2;letter-spacing:-.005em;text-wrap:balance;max-width:24em}  /* 22 / 24.3 / 30 */
.t-statement{font-family:var(--serif);font-weight:300;font-size:clamp(1.375rem,2.2vw,2.125rem);line-height:1.3;letter-spacing:-.008em;max-width:32em;text-wrap:pretty}  /* 22 / 28 / 34; the engagement statement only. 32em sets it as three even lines from 1024px up (30em left "the way." alone on a fourth) */
.t-lede{font-family:var(--sans);font-weight:400;font-size:clamp(1.125rem,1.6vw,1.4375rem);line-height:1.5;max-width:52ch;text-wrap:pretty;color:var(--fg)}  /* 18 / 20.5 / 23 */
.t-body{font-family:var(--sans);font-weight:400;font-size:var(--fs-body);line-height:1.6;max-width:62ch;text-wrap:pretty;color:var(--fg2)}  /* the hero sentence's size */
.t-small{font-family:var(--sans);font-weight:500;font-size:.875rem;line-height:1.5;color:var(--fg2)}  /* captions, notes, legal */
.t-quote{font-family:var(--serif);font-weight:300;font-style:italic;font-size:var(--fs-h3);line-height:1.3;max-width:30em;text-wrap:balance}  /* balanced, so a two-line quote never leaves one word alone */
.t-numeral{font-family:var(--serif);font-weight:300;font-size:clamp(2rem,1.4rem + 1.6vw,2.75rem);line-height:1;color:var(--mark)}  /* Roman I to IV */
.tnum{font-variant-numeric:tabular-nums}
/* The fixed steps between type roles, for the whole page (zero specificity, so a section states a different step only
   where it has a reason): a heading to the text under it 20px; lede to body 16px; paragraph to paragraph 16px;
   h3 to its stacked text 12px. Sections do not restate these. */
:where(.t-h2)+:where(.t-lede,.t-body,.t-statement){margin-top:20px}
:where(.t-lede)+:where(.t-body){margin-top:16px}
:where(.t-body)+:where(.t-body){margin-top:16px}
:where(.t-h3)+:where(.t-body,.t-small){margin-top:12px}
/* Phones and tablets: the h3 drops to 19px, and on phones the h2 takes the hero line's phone size (27.3px at 390), so
   each section title stays clearly above the rows under it (about 1.4 to 1.5 times the h3 from 320 to 959px).
   The quotes and the footer tagline are set at the h3 size, so they follow. */
@media (max-width:959px){:root{--fs-h3:1.1875rem}}
@media (max-width:767px){.t-h2{font-size:clamp(1.5rem,7vw,1.75rem)}}

/* 9. LAYOUT PRIMITIVES. No centred max-width container: line length is limited on the text itself.
   Inside the gutters, 12 columns; content starts on the spine (column 1) or the half line (column 7).
   Below 960px every section is one column on the spine, in DOM order. */
.wrap{padding-left:var(--gut-l);padding-right:var(--gut-r)}
.sec{padding-block:var(--sec)}
.grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--col-gap)}
.at-spine{grid-column:1/7}.at-half{grid-column:7/13}.at-full{grid-column:1/-1}
/* THE LEDGER: the page's one list component (the obstacles, the "Your part" row, the guides). Each row is a .grid
   with a rule on top from the spine to the right gutter, the name on the spine and the text on the half line, first
   baselines aligned. No rule after the last row. */
.ledger{list-style:none;margin:0;padding:0}
.ledger>*{border-top:1px solid var(--rule);padding-block:var(--gap-row);align-items:first baseline}
/* the last row has no rule under it, so its bottom padding would only add to the space after the list */
.ledger>:last-child{padding-bottom:0}
.ledger-name{grid-column:1/7;max-width:18em}
/* Side by side, the text starts level with its name (no stacked step). The body size is set on the column too, so its
   60ch is measured in body text whether the column is the paragraph itself or a div holding paragraphs. */
.ledger-text{grid-column:7/13;max-width:60ch;margin-top:0;font-size:var(--fs-body)}
@media (max-width:959px){.at-spine,.at-half,.ledger-name,.ledger-text{grid-column:1/-1}.ledger-text{margin-top:12px}}

/* 10. ACTIONS. One label for the contact intent: "Arrange a consultation". Bronze fill only in the hero, the
   consultation section and the Menu panel (.btn-bronze, identical to the hero button). Every other action is a
   text link: .lnk with <span aria-hidden="true">→</span>, the arrow in the ground's --mark colour. */
.btn-bronze{background:var(--bronze);color:var(--ink);transition:transform .16s var(--out),background-color .2s ease}
.btn-bronze:active{transform:scale(.97)}
.lnk span{display:inline-block;color:var(--mark);transition:transform .2s var(--out)}
/* The text link that closes a section (the work, the engagement, the firm, Insights): on the spine, --gap-group under
   the last line. A block-level flex box at its own width, so no line-box strut adds height above its 44px target. */
.lnk-end{display:flex;width:fit-content;max-width:100%;margin-top:var(--gap-group)}
@media (hover:hover) and (pointer:fine){
  .btn-bronze:hover{background:var(--bronze-hi)}
  .lnk:hover span{transform:translateX(3px)}
}
/* Press feedback for every input. The browser's tap highlight is off (section 2), so each control answers a press
   itself: the buttons scale (above), a text link's arrow takes its hover step, the nav, Menu and panel links dim. */
.lnk:active span{transform:translateX(3px)}
.site-head .nav .links a:active,.site-head .nav .cta:active,.nav-menu:active,.nav-panel-links a:active{opacity:.72}
@media (prefers-reduced-motion:reduce){.btn:active,.btn-bronze:active,.lnk:active span{transform:none}}
/* Windows high contrast drops button fills; a system-colour border keeps the buttons visible there only */
@media (forced-colors:active){.btn,.btn-bronze{border:1px solid ButtonText}}

/* 11. PRINT. Bank reps, accountants and lawyers print or save the page as PDF, usually without background graphics:
   every ground prints as ink on paper, and the controls that only work on screen are left out. The hero word's own
   print rule is in 01-hero.css. */
@media print{
  body{background:none}
  .g-deep,.g-forest,.g-ink,.g-ivory{background:none;color:#071711;--fg:#071711;--fg2:rgba(7,23,17,.72);--rule:rgba(7,23,17,.24);--mark:#80542E}
  .site-head,.skip,.ctas,.btn,.lnk-end{display:none}
  h2,h3{break-after:avoid}
  .ledger>*,.wk-step,.oc-path,.cl-quote,.fi-portrait{break-inside:avoid}
}

/* ---- 01-hero.css ---- */
/* HERO (.s-le). Ported from heroes/parts/h21.html ("Letter", the owner's pick) with only these changes: .h-le became
   .s-le; the nav moved out to header.site-head (its rules are in 00-base.css as .site-head .nav, same values); the plate
   is the mirrored-padding copy so the photo can drift; a forced-colors rule; no press scale under reduced motion; the
   ground, the button and the link use the page's shared classes (.g-deep, .btn-bronze, .lnk), at the same values.
   Hero 21's own notes follow, unchanged.

   21. Letter. Hero 3 rearranged as a letter. The word hangs under the nav and runs from margin to margin. The line,
   the sentence and the button hang beneath it on one left edge: the same x as the logo and the foot of the A.
   Why: in hero 3 the sentence starts above the line it explains (in a column on the right), so after the headline the
   eye has to climb back up and to the right. Here each part hangs below the one before it on the logo's edge, so the
   word, the line, the sentence and the button read in order. What this fixes is the order, not the distance: the
   button sits lower on the screen than in hero 3. The width hero 3's right column used to take goes to the word.
   This is the control of 21 to 24: the same word geometry, with the stack hung at the gutter.
   Short wide screens (laptops under about 660 to 950px tall, depending on width): stacked, the word would have to
   shrink and would stop short of the margin, lining up with nothing. There the button moves to the end of the
   sentence's last line, where the reading lands, and the word keeps the full measure.
   Still: no motion, no script. The space under "ess" is the word's tail and stays empty.
   Plate: skyline-dusk-warm.jpg, hero 16's method, geometry in em so the crop does not move when the web font swaps in
   (sky in the apex of the A, the horizon through the lowercase, the Empire State in the first s). The plate sits
   .08em down (it was .13em) so the dark foreground roof leaves the A's right foot, just above where "the" begins:
   inside the glyphs against #0D261B, 1st percentile 3.1:1 (was 2.3), 5th 3.8 (was 3.4), median 6.1 (was 5.8).

   THE DRIFT (added for the homepage, at the owner's request: the photo inside "Access" moves a little with the
   cursor). The letters are an opening in the green and the city lies far behind them: when the pointer moves, the
   photo slides a little the same way, like a far view through a window as you lean; it settles back when the
   pointer leaves. Only the photo moves (background-position); the letters, the line, the sentence, the
   buttons and the nav never move. site.js writes --le-dx and --le-dy on .le-word, smoothed on requestAnimationFrame,
   only on (hover:hover) and (pointer:fine), never under reduced motion; without them the word shows the rest crop.
   Range (owner's choice 2026-10-15, double the first range): -.055em to +.055em across, 0 to +.05em down (the photo
   never rises above rest, where the dark roofs would re-enter the letter feet). The strength lives in site.js (MULT). The plate is skyline-dusk-warm-drift.jpg: the same photo with 40 mirrored pixels each
   side (1880x1195), so the original 1800px still spans 2.47em and the rest frame is hero 21's, pixel for pixel. The
   drift is a separate background-position longhand after the shorthand: a bad value can only reset the position,
   never drop the image (which, with a transparent fill, would blank the word). */
@font-face{font-family:"le-fb";src:local("Georgia");size-adjust:92.9%;ascent-override:112%;descent-override:36.6%;line-gap-override:0%}
.s-le{
  /* The vertical budget is in px, vh and vw, never rem, so text zoom grows the sentence without shrinking the word. */
  --le-pt:clamp(88px,11.5vh,120px);              /* the word's line-box top: the A's apex sits 55 to 90px under the nav */
  --le-gap:clamp(28px,3.4vh,40px);               /* the line to the sentence */
  --le-sub:calc(3.2 * clamp(16px,1.3vw,18.4px)); /* the sentence: two lines at 1.6 */
  --le-tail:98px;                                /* 24 to the button, the 50px button, 24 at the bottom */
  --le-k:.893;                                   /* the word's line box .78, the line .108 and its margin .005, in F */
  /* F, the word's size. 2.44 is the ink width of the word "Access" in em, so F fills the measure exactly; it is tied
     to this word. F never grows so tall that the button leaves the first screen. */
  --le-fw:calc((100vw - var(--gut-l) - var(--gut-r)) / 2.44);
  --le-fh:calc((100vh - var(--le-pt) - var(--le-gap) - var(--le-sub) - var(--le-tail)) / var(--le-k));
  --le-f:min(var(--le-fw),max(var(--le-fh),96px));
  /* the deep ground and its text colour come from .g-deep on the section, as on every section */
  position:relative;min-height:100vh;
  overflow-x:clip;container-type:inline-size;
  display:grid;grid-template-columns:minmax(0,1fr);align-content:start;justify-items:start;
  /* top-hung: the leftover height falls to the bottom, never above the word */
  padding:var(--le-pt) var(--gut) 24px;
  /* the gutters stay clear of a notch (base, --gut-l and --gut-r); 100cqi then measures between them, so the word refits */
  padding-left:var(--gut-l);padding-right:var(--gut-r)}
/* inside the section, 100cqi is the measure between the gutters */
@supports (width:1cqi) and (height:1svh){
  .s-le{min-height:100svh;--le-pt:clamp(88px,11.5svh,120px);--le-gap:clamp(28px,3.4svh,40px);--le-fw:calc(100cqi / 2.44);
    --le-fh:calc((100svh - var(--le-pt) - var(--le-gap) - var(--le-sub) - var(--le-tail)) / var(--le-k))}
}
.s-le .le-h1{margin:0;font-weight:inherit;justify-self:stretch;min-width:0}
.s-le .le-word{display:block;width:max-content;
  font-family:"Source Serif 4","le-fb",Georgia,serif;font-weight:500;font-variation-settings:"opsz" 60;
  font-size:var(--le-f);line-height:.78;letter-spacing:-.045em;white-space:nowrap;
  /* the A's ink foot on the gutter; padding-right lets the clip reach the end of the last s */
  margin:0 -.03em 0 -.012em;padding-right:.03em;color:var(--on)}
@supports ((background-clip:text) or (-webkit-background-clip:text)){
  /* The shorthand carries the image, the bronze-hi under it, the size and the rest position (the 40px pad moved out
     to the left, so the original pixels sit where hero 21 has them). The drift is the longhand after it. */
  .s-le .le-word{
    background:var(--bronze-hi) url(../img/skyline-dusk-warm-drift.jpg) calc(2.47em * -40 / 1800) -.08em / calc(2.47em * 1880 / 1800) auto no-repeat;
    background-position:calc(2.47em * -40 / 1800 + var(--le-dx, 0em)) calc(-.08em + var(--le-dy, 0em));
    -webkit-background-clip:text;background-clip:text;color:transparent;-webkit-text-fill-color:transparent}
}
/* Phones get the same plate at 1128px wide (60 percent, the mirrored pad scaled with it): the word spans about 370 CSS
   px there, so 1128 covers a 3x screen at half the bytes. Same proportions, so the em geometry and the crop are
   unchanged. Inside the @supports, so a browser without text clipping never paints the photo as a box. */
@media (max-width:700px){
  @supports ((background-clip:text) or (-webkit-background-clip:text)){
    .s-le .le-word{background-image:url(../img/skyline-dusk-warm-drift-1128.jpg)}
  }
}
/* Windows high contrast: the photo fill would vanish, so the word is plain text there. */
@media (forced-colors:active){
  .s-le .le-word{background:none;color:CanvasText;-webkit-text-fill-color:CanvasText}
}
/* The line is a tenth of the word, so the promise keeps one proportion at every desktop size and reads as the
   second half of one sentence, not a caption. Its gap is about .45 of its own size: on desktop the word's line box
   already holds .04 of the word under the baseline, so the margin is almost nothing; on phones it makes up the rest. */
.s-le .le-rest{display:block;margin-top:max(0px,calc(.45em - .04 * var(--le-f)));
  font-family:var(--serif);font-weight:300;font-size:max(1.7rem,calc(var(--le-f) * .1));line-height:1.08;letter-spacing:-.012em;color:var(--on)}
/* a wider break between the headline and the sentence than inside either group; the button follows its sentence */
.s-le .sub{margin-top:var(--le-gap);max-width:62ch;color:var(--on2);text-wrap:pretty}
/* The button is .btn.btn-bronze and the link .lnk, both from base with the same values hero 21 had (bronze, ink text,
   the press scale, bronze-hi on hover; the bronze arrow that moves 3px; the bronze-hi focus ring from .g-deep). */
.s-le .ctas{margin-top:24px}
/* Short wide screens. Each clause is "this wide and shorter than the stacked version needs at the top of the band",
   so the word always reaches the right margin. The sentence keeps the gutter; the button row moves to the end of
   the sentence and shares its last baseline, so the stack loses the button's own row (74px less, 13px of the
   button hangs below the sentence's last line). */
@media (min-width:1100px) and (max-height:661px),(min-width:1200px) and (max-height:689px),
       (min-width:1280px) and (max-height:721px),(min-width:1366px) and (max-height:748px),
       (min-width:1440px) and (max-height:785px),(min-width:1536px) and (max-height:812px),
       (min-width:1600px) and (max-height:845px),(min-width:1680px) and (max-height:866px),
       (min-width:1728px) and (max-height:897px),(min-width:1800px) and (max-height:949px),
       (min-width:1920px) and (max-height:1004px),(min-width:2048px) and (max-height:1105px),
       (min-width:2304px) and (max-height:1201px){
  .s-le{--le-tail:33px;padding-bottom:20px;grid-template-columns:auto minmax(0,1fr);column-gap:clamp(40px,3.6vw,64px)}
  .s-le .le-h1{grid-column:1/-1}
  .s-le .sub{align-self:last baseline}
  .s-le .ctas{margin-top:0;align-self:last baseline;flex-wrap:nowrap}
}
/* Portrait screens and phones: the word is fitted to the width, so a full-height section would leave a band of empty
   green under the button. The section ends after its content and the next section follows. */
@media (max-width:860px),(orientation:portrait){
  .s-le{min-height:0;padding-bottom:56px}
}
@media (max-width:700px){
  .s-le{--le-pt:104px}
  .s-le .le-rest{font-size:clamp(1.5rem,7vw,1.9rem);text-wrap:balance}
}
/* a phone on its side: the line drops to 1.3rem so the word stays clearly the image, and the budget counts it */
@media (max-height:500px) and (orientation:landscape) and (max-width:1099px){
  .s-le{--le-pt:88px;--le-k:.78;--le-tail:126px}
  .s-le .le-rest{font-size:1.3rem}
}
/* Print: browsers drop background images by default, which would leave "Access" blank. On paper the word is ink, and
   the hero's light text turns dark like every other ground (base section 11). */
@media print{
  .s-le{min-height:0;padding-bottom:24px}
  .s-le .le-word{background:none;color:#071711;-webkit-text-fill-color:#071711}
  .s-le .le-rest,.s-le .sub{color:#071711}
}

/* ---- 02-situation.css ---- */
/* SITUATION (.s-si). Where founders abroad usually get stuck: three obstacles, in the order the steps below answer
   them (the company's tax number, the bank account, the cards). Forest, one step up from the hero's deep, so the
   hero ends on a visible edge. Built from the base ledger: read down the spine, the three statements are the
   summary; each detail sits on the half line beside its statement, first baselines aligned, so neither half of the
   green is left empty. No image, no motion. The h2 to lede step, the ledger and its spacing all come from base. */
.s-si .si-rows{margin-top:var(--gap-head)}

/* ---- 03-work.css ---- */
/* THE WORK (.s-wk). Spec section 6. The first paper ground: what the firm does, in the order the US system needs it.
   Steps I to III answer the three situation rows above in the same order; IV is the payoff.
   Why two by two: this is the page's main explanation, so it reads at the page's body size and measure (about 60
   characters a line), like every other paragraph. Four columns squeezed it to 30 to 39 characters at 16px, the
   densest text on the page. In pairs the steps still run the way you read, left to right and then down (I and II,
   then III and IV), each pair on the spine and the half line, and the Roman numerals carry the order. The situation
   above is a ledger, so a second ledger here would repeat it.
   Below 960px they stack on the spine in DOM order. The ol (role="list", so Safari keeps it a list) gives screen
   readers the count and the order; the numerals are aria-hidden. No motion here except the shared link arrow.
   The h2 to lede and h3 to text steps come from base; the rule to the first line is --gap-row, as in every ruled row
   on the page. */
.s-wk .wk-steps{margin-top:var(--gap-head);align-items:start}

/* one step: the rule, the numeral, the title, the explanation at body size */
.s-wk .wk-step{grid-column:1/-1;border-top:1px solid var(--rule);padding-top:var(--gap-row)}
.s-wk .wk-num{display:block}
.s-wk .wk-name{margin-top:8px}
.s-wk .wk-text{font-size:var(--fs-body);line-height:1.6;max-width:60ch;font-variant-numeric:tabular-nums}  /* figures in text, spec 3.2 */

/* phone and tablet (below 960px): one column on the spine */
.s-wk .wk-step+.wk-step{margin-top:40px}

/* 960px and up: I and II, then III and IV, on the spine and the half line; each step opens with its own rule */
@media (min-width:960px){
  .s-wk .wk-steps{row-gap:var(--gap-group)}
  .s-wk .wk-step+.wk-step{margin-top:0}
  .s-wk .wk-step:nth-child(odd){grid-column:1/7}
  .s-wk .wk-step:nth-child(even){grid-column:7/13}
  .s-wk .wk-name{margin-top:12px}
}

/* ---- 04-outcomes.css ---- */
/* TWO OUTCOMES (.s-oc). Spec section 7. Forest: a part about you, after the ivory steps.
   The same spending goes two ways, so the fork is two paths side by side, each opening with its own rule, the column
   gap between them: one sum, two paths. The home path sits on the spine and is quiet (one line, heading and text in
   the second text colour); the US path sits on the half line and is heavier because it says more and is brighter,
   never because anything in it is bigger. The figure stays in a body-size sentence, and its conditions sit directly
   under it in the same column, so the caveat can't be read apart from the number. No image, no motion, standard
   section padding: a content peak, not a display moment. Below 960px the paths stack, home first, so the larger
   outcome lands last. The type steps come from base; the rule to the first line is --gap-row, as in every ruled row. */
.s-oc .oc-fork{margin-top:var(--gap-head);align-items:start;row-gap:32px}
.s-oc .oc-path{border-top:1px solid var(--rule);padding-top:var(--gap-row)}
.s-oc .oc-path .t-body{max-width:60ch}
/* the quieter outcome: the whole path in the second text colour */
.s-oc .oc-home .t-h3{color:var(--fg2)}
/* the figure reads in the full text colour; the caveat under it stays in --fg2 at the same size, 16px under it (base) */
.s-oc .oc-figure{color:var(--fg);font-variant-numeric:tabular-nums}

/* ---- 05-engagement.css ---- */
/* THE ENGAGEMENT (.s-en, ivory ground). The offer, said once: the firm's part as one statement, then the terms as two
   ledger rows (the plan, your part), then one text link to /services. Laid out like the hero: statement, detail,
   action, all hung on the spine.
   Ivory because this is the paper a founder forwards to an accountant or a partner, and because a dark ground here
   would make outcomes, engagement and clients one long dark run.
   Two rows because these are the deal terms: when the written plan comes and that nothing starts before you approve
   it, then what you do. Each label sits on the spine with its text on the half line, like every ledger row on the
   page, so the left column carries two labels at row rhythm instead of one stranded one. The terms are read in the
   main text colour, not the supporting grey, because they are the substance of the offer.
   Below 960px the base turns each row into one column on the spine.
   No box, no ivory-hi card, no bullets or icons, no button. The only motion is the link arrow (base).
   The h2 to statement step, the statement's 32em measure, the ledger and the closing link all come from base. */

/* Below 960px the column, not the measure, sets the line length, and on tablets (768px, for one) the copy can leave
   a word alone on a fourth line. Balanced, the lines come out even. (Chrome balances up to six lines, so on phones,
   at seven lines and more, it wraps as normal.) */
@media (max-width:959px){.s-en .en-statement{text-wrap:balance}}

/* the statement to the rows: --gap-head */
.s-en .en-part{margin-top:var(--gap-head)}
/* the terms in the main text colour */
.s-en .ledger-text{color:var(--fg)}

/* ---- 06-clients.css ---- */
/* CLIENTS TODAY (.s-cl). Forest, because it is about you: who the clients are, where they are from, what two of them
   said, and who the firm can't take on. Three rows, read top to bottom on the one left edge.
   Row 1: what you read first on the spine (the client group), what you read second on the half line (the places).
     The spine column holds groups (.cl-groups > .cl-group), so another group can be added under the first later
     without touching the grid.
   Row 2: the two quotes side by side, the first on the spine and the second on the half line, then the note.
   Row 3: the not-a-fit sentence on the spine.
   Rows 2 and 3 each carry their own space, rule and padding, so deleting the whole quote block (div.cl-quotes)
   leaves row 3 correctly spaced under row 1 with nothing else to change. No motion, no imagery. */

/* Row 1. The steps inside the group (h3 to text 12px, paragraph to paragraph 16px) come from base. */
.s-cl .cl-who{margin-top:var(--gap-head);align-items:start}
.s-cl .cl-group .t-body{max-width:52ch}
.s-cl .cl-group+.cl-group{margin-top:var(--gap-group)}
/* The places: one list at the body size (.t-body) in the main text colour. Only countries confirmed as where clients
   are from are listed; four today, so one column. From five names the list sets itself in two CSS columns (the
   :has rule), so adding a confirmed country back is an edit to the HTML only. Each name carries 3px above and below
   (6px between names), padding rather than margin so both columns start at the same height. The column gap is the
   grid's, so a second column starts on grid column 10. */
.s-cl .cl-places{margin-top:9px;max-width:none;column-count:1;column-gap:var(--col-gap);line-height:1.5;color:var(--fg)}
.s-cl .cl-places:has(li:nth-child(5)){column-count:2}
.s-cl .cl-places li{padding-block:3px;break-inside:avoid}

/* Rows 2 and 3: each opens with the same space, a rule from the spine to the right gutter, and padding. */
.s-cl .cl-quotes,
.s-cl .cl-nofit{margin-top:var(--gap-group);border-top:1px solid var(--rule);padding-top:var(--gap-row)}

/* Row 2: the quotes. No marks, cards or borders beyond the text's own typographic quotes, which hang outside the
   left edge so the letters line up with the spine and the half line. */
.s-cl .cl-quotes{align-items:start}
@supports not (hanging-punctuation:first){.s-cl .cl-quote blockquote{text-indent:-.4em}}
@supports (hanging-punctuation:first){.s-cl .cl-quote blockquote{hanging-punctuation:first}}
.s-cl .cl-quote figcaption{margin-top:12px}
.s-cl .cl-note{grid-column:1/-1;margin-top:16px}

/* Row 3: the line length stays at 62ch while the rule runs the full measure, so the measure comes from padding. */
.s-cl .cl-nofit{max-width:none;padding-right:max(0px,calc(100% - 62ch))}

/* Below 960px: one column on the spine, in DOM order. */
@media (max-width:959px){
  .s-cl .cl-where{margin-top:32px}
  /* one column: the list keeps to the same 52ch measure as the text above it, so a second column stays close */
  .s-cl .cl-places{column-gap:32px;max-width:52ch}
  .s-cl .cl-quote+.cl-quote{margin-top:24px}
}
@media (max-width:359px){.s-cl .cl-places:has(li:nth-child(5)){column-count:1}}

/* ---- 07-firm.css ---- */
/* THE FIRM (.s-fi, ivory). Trust: who the firm works with, four rules it keeps, and the one face it shows.
   Ivory because Teo's portrait has a pale grey studio background that sits quietly on paper and would glare as a
   light box on green. The firm's words come first, on the spine; the person you would deal with is read second, on
   the half line.
   Desktop (960px and up): the text in columns 1 to 6, then the closing link under it; the portrait fills columns 7 to
   12, the full half, so no ivory is left open beside it. Its height comes from the words: its top on the cap line of
   "The firm", its caption on the same baseline as "About the firm". Width from the column and height from the text,
   so it can never tower over the words or leave a strip of ivory beside or under itself, at any width or after any
   copy edit; the photo is cropped to fit (about 6:5 at 1568, 3:2 at 1920), framed on her face.
   Phone and tablet (below 960px): one column in DOM order, the words, then the portrait at the full measure (4:5 on
   phones, 3:2 from 600px), then the closing link, so the section ends on its link as every other section does.
   No motion beyond the link arrow (base). */
.s-fi .grid{align-items:start}
.s-fi .fi-text{grid-row:1}
/* h2 to lede 20px and rule to rule 16px come from base, as in every section. The four rules: one hairline above the
   list (it separates who the firm is from what it keeps to), placed like every ruled row on the page (--gap-head
   under the lede, --gap-row under the rule); no bullets or ticks; each rule a full sentence in the main text colour */
.s-fi .fi-rules{margin-top:var(--gap-head);padding-top:var(--gap-row);border-top:1px solid var(--rule)}
.s-fi .fi-rules>li{color:var(--fg)}

/* the tint holds the photo's place while it loads (it is lazy); the photo covers it completely once in.
   40% down keeps her eyes about two fifths from the top of a landscape crop and leaves the lit cornice above out */
.s-fi .fi-portrait img{width:100%;max-width:none;object-fit:cover;object-position:50% 40%;background-color:var(--rule)}
.s-fi .fi-portrait figcaption{font-family:var(--sans);font-weight:600;font-size:.9375rem;color:var(--fg)}
@media (min-width:960px){
  /* The figure spans the text's row and the link's row and adds no height of its own (both children are absolute).
     .226em of the h2 is where Source Serif 4's cap line sits in a 1.1 line box (ascent 1.04, descent .34, cap .674). */
  .s-fi .fi-portrait{grid-row:1/3;grid-column:7/13;align-self:stretch;position:relative;margin-top:calc(var(--fs-h2) * .226)}
  /* 44px at the bottom is the caption's row, the same 44px box as the link, so the two share a baseline; the caption
     text then sits 12px under the photo */
  .s-fi .fi-portrait img{position:absolute;top:0;left:0;height:calc(100% - 44px);aspect-ratio:auto}
  .s-fi .fi-portrait figcaption{position:absolute;left:0;bottom:0;display:flex;align-items:center;min-height:44px}
  .s-fi .fi-end{grid-row:2;grid-column:1/7}
}
@media (max-width:959px){
  .s-fi .fi-portrait{grid-column:1/-1;margin-top:40px}
  .s-fi .fi-portrait img{height:auto;aspect-ratio:4/5}
  .s-fi .fi-portrait figcaption{margin-top:12px;line-height:1.4}
  .s-fi .fi-end{grid-column:1/-1}
}
@media (min-width:600px) and (max-width:959px){.s-fi .fi-portrait img{aspect-ratio:3/2}}

/* ---- 08-insights.css ---- */
/* INSIGHTS (.s-in, ivory). Competence: the firm's own writing, four guides a founder, their accountant or a bank rep
   can go deeper with. Same paper as the firm above it, because it is the firm's writing too; one measure-wide rule
   marks the turn, halfway between the firm's last line and this heading. No image: below the hero the page has one
   photo, Teo's.
   Built from the base ledger, like the situation rows: read down the spine, the four titles are the reading list, the
   flagship first, so the order says where to begin; each summary sits on the half line beside its title, first
   baselines aligned, so the paper is used across the measure. Each row is one link: the title's link stretches over
   the row, so the whole row is the target and the focus ring stays on the title.
   At rest each title ends in the bronze arrow every other link on the page carries, so the rows read as links on
   touch screens too, where there is no hover. The arrow is plain inline text glued to the last word by a no-break
   space: an inline-block arrow could wrap onto a line of its own. So it does not slide on hover; the title's
   underline is the hover and press state.
   Motion: the title underline on hover (fine pointers) and press, and the closing link's arrow. */

/* the turn from the firm: no top padding, a rule across the measure, then the usual section padding above the h2.
   The 2px overlap (with 2px of padding putting everything back where it was) paints this ivory over the firm's: the
   boundary falls on a fractional y, and at 125 to 175% display scaling (and when zoomed out) the ink body showed
   through it as a full-bleed hairline lying on top of the measure-wide rule. */
.s-in{padding-top:2px;margin-top:-2px}
.s-in .wrap::before{content:"";display:block;border-top:1px solid var(--rule);margin-bottom:var(--sec)}

/* the heading's group (h2, 20px, lede) comes from base; then --gap-head to the rows */
.s-in .in-list{margin-top:var(--gap-head)}

/* a row: the base ledger's rule and padding; the title in ink, not underlined at rest. The underline sits on the
   title's own span, so it never runs under the space and the arrow. */
.s-in .in-row{position:relative}
.s-in .in-t{text-decoration-line:underline;text-decoration-color:transparent;text-decoration-thickness:1px;
  text-underline-offset:.2em}
/* the arrow: the page's link arrow (Hanken, the ground's --mark), at the title's size */
.s-in .in-go{font-family:var(--sans);font-weight:400;font-size:.8em;color:var(--mark)}
/* the whole row is the target: the link's box stretches over the li, rule to rule */
.s-in .in-link::after{content:"";position:absolute;inset:0}
/* touch has no hover, so a press shows the same underline the mouse gets, for as long as the finger is down */
.s-in .in-link:active .in-t{text-decoration-color:var(--mark)}

/* The ledger's baseline alignment, its last row and the closing link (.lnk-end) come from base. */

@media (hover:hover) and (pointer:fine){
  .s-in .in-t{transition:text-decoration-color .16s var(--out)}
  .s-in .in-link:hover .in-t{text-decoration-color:var(--mark)}
}

/* ---- 09-consultation.css ---- */
/* CONSULTATION (.s-co, deep ground). Decision. The page ends where it began: on the hero's deep green, in the
   hero's order of a line, a sentence and a button, all hung on the spine. One call to action and nothing else, so
   the last thing the reader carries is one next step. The open green to the right is the end of the letter, as in
   the hero; the section is only its content plus the standard padding, so it never turns into an empty green screen.
   No image: the hero's word is the page's one display moment and this does not repeat it.
   Motion: the button's press and fine-pointer hover only, both from the base (.btn-bronze). */

/* The line to the sentence: the one place a heading is followed by more than base's 20px. This is the hero's stack
   again, and the hero puts a wider break between its line and its sentence than inside either one. */
.s-co .t-lede{margin-top:var(--gap-head)}

/* The button 24px under its sentence, as in the hero. A block-level flex box at its own width, so no line-box strut
   adds height above or below it and the section ends exactly at the button plus --sec. */
.s-co .btn-bronze{display:flex;width:fit-content;max-width:100%;margin-top:24px}

/* On the narrowest phones the measure is barely wider than the button: there it takes the full measure, so it
   reads as one deliberate bar rather than a box that almost fits. */
@media (max-width:359px){
  .s-co .btn-bronze{width:100%;justify-content:center}
}

/* ---- 99-foot.css ---- */
/* FOOTER (.site-foot, ink ground). The page settles: one step darker than the deep consultation section above, so
   the letter ends and the reference matter begins. Every route is here, Client login included, with the legal line.
   No address, phone, email, social icons, newsletter, rules, middots or list headings.
   Desktop: the logo and tagline on the spine (columns 1 to 6), the two link lists on the half line (7 to 9 and 10 to
   12), then the legal paragraph and the last line on the spine. Phone: one column on the spine, the lists side by
   side from 360px. The horizontal logo is used because the stacked lockup is centred on its mark. */
.site-foot{padding-top:clamp(56px,6vw,96px);padding-bottom:calc(40px + env(safe-area-inset-bottom))}
.site-foot .foot-brand{grid-column:1/7}
/* 36px logo; 4px of extra hit area above and below, cancelled by margins */
.site-foot .foot-logo{display:block;width:fit-content;padding-block:4px;margin-block:-4px}
.site-foot .foot-logo img{height:36px;width:auto}
.site-foot .foot-tagline{margin-top:24px;font-family:var(--serif);font-weight:300;font-size:var(--fs-h3);
  line-height:1.2;letter-spacing:-.005em;max-width:20em;text-wrap:balance;color:var(--fg)}
/* six inner columns with the page's gap line up exactly with grid columns 7 to 12; -4px puts the first link's
   centre level with the logo's centre */
.site-foot .foot-nav{grid-column:7/13;display:grid;grid-template-columns:repeat(6,minmax(0,1fr));column-gap:var(--col-gap);
  align-content:start;margin-top:-4px}
.site-foot .foot-list:first-child{grid-column:1/4}
.site-foot .foot-list:last-child{grid-column:4/7}
.site-foot .foot-list a{display:inline-flex;align-items:center;min-height:44px;font-weight:500;font-size:.9375rem;line-height:1.3;
  color:var(--fg2);text-decoration-line:underline;text-decoration-color:transparent;text-decoration-thickness:1px;
  text-underline-offset:.2em;transition:color .18s ease,text-decoration-color .18s ease,opacity .1s var(--out)}
.site-foot .foot-legal{grid-column:1/-1;margin-top:clamp(48px,5vw,80px)}
.site-foot .foot-legal-text{max-width:90ch}
/* "© 2026 Ellis Sterling", Privacy and Terms, 24px apart. The links keep a 44px target; negative margins stop that
   target from opening the gap above the line. */
.site-foot .foot-last{margin-top:16px;display:flex;flex-wrap:wrap;align-items:center;column-gap:24px}
.site-foot .foot-last a{display:inline-flex;align-items:center;min-height:44px;margin-block:-11px;
  text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.2em;transition:color .18s ease,opacity .1s var(--out)}
/* the current page (aria-current from _plan/sync_chrome.py): the link's hover state at rest */
.site-foot .foot-list a[aria-current="page"]{color:var(--fg);text-decoration-color:currentColor}
/* the press dims a link on every input (the browser's tap highlight is off) */
.site-foot .foot-list a:active,.site-foot .foot-last a:active{opacity:.72}
@media (hover:hover) and (pointer:fine){
  .site-foot .foot-list a:hover{color:var(--fg);text-decoration-color:currentColor}
  .site-foot .foot-last a:hover{color:var(--fg)}
}
@media (max-width:959px){
  .site-foot .foot-brand,.site-foot .foot-nav,.site-foot .foot-legal{grid-column:1/-1}
  .site-foot .foot-tagline{max-width:none}
  .site-foot .foot-nav{margin-top:32px;grid-template-columns:repeat(2,minmax(0,1fr))}
  .site-foot .foot-list:first-child{grid-column:1}
  .site-foot .foot-list:last-child{grid-column:2}
  .site-foot .foot-legal{margin-top:40px}
}
@media (max-width:359px){
  .site-foot .foot-nav{grid-template-columns:minmax(0,1fr)}
  .site-foot .foot-list:last-child{grid-column:1}
}

/* ---- Body type: Source Sans 3 (owner's choice, 2026-10-15) ---- */
/* Hanken Grotesk overpowered the light Source Serif headings: measured, the line under each h2 carried 37 to 49 percent
   more ink than the heading. Source Sans 3 is drawn as Source Serif's companion (matching x-height and cap height,
   humanist shapes), and set lighter it sits under the headings: lede Light 300 at its size, body 370, controls 600.
   Source Serif 4 is unchanged. Everything is scoped to html:not([data-type="old"]) only so ?type=old (a review aid in
   site.js, delete before launch) can show the old Hanken page for comparison; when the aid goes, drop the scope. The
   :root --sans above still names Hanken only as that review fallback. */
html:not([data-type="old"]){--sans:"Source Sans 3","Helvetica Neue",Arial,sans-serif}
html:not([data-type="old"]) .t-lede{font-weight:300}
html:not([data-type="old"]) :is(.t-body,.s-le .sub){font-weight:370}
html:not([data-type="old"]) :is(.btn,.lnk,.nav-menu,.nav-panel-links a,.skip){font-weight:600;letter-spacing:.01em}
html:not([data-type="old"]) .site-head .nav .cta{font-weight:600;letter-spacing:.01em}
html:not([data-type="old"]) .site-head .nav .links{font-weight:400;letter-spacing:.01em}
html:not([data-type="old"]) .t-small{font-weight:400;letter-spacing:.01em}
html:not([data-type="old"]) .site-foot .foot-list a{font-weight:500;letter-spacing:.01em}
html:not([data-type="old"]) .s-fi .fi-portrait figcaption{font-weight:600;letter-spacing:.01em}
