@charset "utf-8";
/* ═══════════════════════════════════════════════════════════════════════
   HASHIR SARWAR — EDITORIAL BRUTALIST
   Static HTML + CSS + vanilla JS. No frameworks, no build step, no images.

   MOTION LANGUAGE — everything obeys this sentence:
   "Everything moves like a printing press: mass-driven and mechanical.
    Type arrives from behind a hard edge rather than fading in, hairlines
    DRAW rather than appear, and colour SNAPS rather than crossfades.
    Nothing bounces, blurs, or eases back."

   COLOUR LAW — --signal is a FILL, a RULE, or a MARK. It is `color` only
   at >=24px (or >=18.66px bold). Below that use --signal-ink. NEVER light
   text on a --signal fill, in either theme (3.30:1 / 3.07:1 = FAIL).
   The page is MONOCHROME AT REST: Services, Clients and Stack carry zero
   signal until the pointer or keyboard focus enters them.

   THE THREE-VOICE LAW
   1. Archivo is never used below 22px.
   2. Archivo is uppercase-only (a lowercase glyph is not in the subset and
      falls back to Arial Black mid-string).
   3. Space Mono is uppercase-only and never sets a sentence.
   ═══════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────── 1. TOKENS ───────────── */
:root{
  color-scheme: light;

  --paper:      #FAF8F5;
  --ink:        #111110;
  --ink-2:      #4A4741;
  --ink-3:      #6B6760;

  --signal:     #FF2E88;
  --signal-ink: #AB0044;

  --ground:     var(--paper);
  --focus-ring: var(--signal);
  --focus-halo: var(--paper);
  --select-bg:  var(--signal);
  --select-fg:  var(--ink);

  --rule-1: 1px;
  --rule-2: 2px;
  --rule-3: 8px;
  --rule-c: var(--ink);

  --radius: 0;

  --gutter:   1rem;
  --margin:   1.25rem;
  --nav-h:    3.25rem;
  --band-h:   3.25rem;
  --chrome-h: var(--nav-h);
  --page-max: 1760px;

  --s-1:.25rem; --s-2:.5rem;  --s-3:.75rem; --s-4:1rem;
  --s-5:1.5rem; --s-6:2rem;   --s-7:3rem;   --s-8:4rem;
  --s-10:8rem;  --s-11:12rem;
  --sec-top: clamp(3rem, 6vw, 6.5rem);
  --sec-bot: clamp(4rem, 8vw, 9rem);

  --f-display:"Archivo","Archivo Fallback","Arial Black",Arial,sans-serif;
  --f-sans:"Instrument Sans","Instrument Fallback",-apple-system,"Segoe UI",Arial,sans-serif;
  --f-mono:"Space Mono","Space Fallback",ui-monospace,"SF Mono",Menlo,monospace;

  /* fluid 360 -> 1600, frozen above 1600 */
  --t-display-1: clamp(3.72rem, -0.61rem + 19.35vw, 26.9rem);
  --t-display-2: clamp(2.75rem, 1.15rem + 7.10vw, 8.25rem);
  --t-display-3: clamp(2.125rem, 1.22rem + 4.03vw, 5.25rem);
  --t-display-4: clamp(2.5rem, 1.48rem + 4.52vw, 6rem);
  --t-display-5: calc(var(--t-display-1) * .5175);
  --t-heading-1: clamp(1.5rem, 1.21rem + 1.29vw, 2.5rem);
  --t-heading-2: clamp(1.375rem, 1.16rem + .97vw, 2.125rem);
  --t-lead:      clamp(1.125rem, .94rem + .81vw, 1.75rem);
  --t-body:      clamp(1rem, .95rem + .20vw, 1.156rem);
  --t-body-s:    clamp(.906rem, .88rem + .12vw, 1rem);
  --t-nav:       clamp(.813rem, .78rem + .16vw, .938rem);
  --t-tag:       clamp(.719rem, .69rem + .12vw, .813rem);
  --t-label:     clamp(.688rem, .66rem + .12vw, .781rem);
  --t-caption:   clamp(.75rem, .72rem + .12vw, .844rem);

  /* manual optical sizing — neither family ships an opsz axis */
  --tr-mega:-.035em; --tr-xl:-.030em; --tr-l:-.022em; --tr-m:-.015em;
  --tr-s:-.010em;    --tr-text:-.006em; --tr-flat:0em;
  --tr-caps:.06em;   --tr-mono:.14em;

  --lh-wordmark:.80; --lh-display:.88; --lh-heading:1.04;
  --lh-lead:1.32;    --lh-body:1.52;

  --measure-lead:26ch;

  /* geometry eases; colour does not */
  --e-in:  cubic-bezier(.16,1,.30,1);
  --e-out: cubic-bezier(.55,0,1,.45);
  --e-flat: linear;

  --d-1:90ms; --d-2:180ms; --d-3:280ms; --d-4:480ms; --d-5:720ms; --d-6:900ms;
  --travel:.9em;

  --z-sticky:30; --z-measure:40; --z-modal:50; --z-skip:60;
}

/* a true ground flip, in BOTH themes */
/* --signal-ink must be remapped alongside the ground: it is tuned against the
   BACKGROUND it sits on, not against the theme. Without it, the Fiverr link
   inside this ink block used the light-ground value and hovered at 2.53:1. */
.invert{
  --ground:#111110; --paper:#111110;
  --ink:#F2F0EA; --ink-2:#A9A59D; --ink-3:#8A867E;
  --rule-c:#F2F0EA; --focus-halo:#111110; --select-fg:#111110;
  --signal-ink:#FF5CA0;
  background:#111110; color:#F2F0EA;
}

@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    color-scheme: dark;
    --paper:#0C0C0B; --ink:#F2F0EA; --ink-2:#A9A59D; --ink-3:#8A867E;
    --signal-ink:#FF5CA0; --select-fg:#0C0C0B;
  }
  :root:not([data-theme="light"]) .invert{
    --ground:#F2F0EA; --paper:#F2F0EA;
    --ink:#0C0C0B; --ink-2:#4A4741; --ink-3:#6B6760;
    --rule-c:#0C0C0B; --focus-halo:#F2F0EA;
    /* --select-fg contrasts against --select-bg (the signal fill), NOT against
       this block's paper. #F2F0EA on #FF2E88 is 3.07:1 — the exact light-on-
       signal pairing the colour law at the top of this file forbids. */
    --select-fg:#0C0C0B;
    --signal-ink:#AB0044;
    background:#F2F0EA; color:#0C0C0B;
  }
}
:root[data-theme="dark"]{
  color-scheme: dark;
  --paper:#0C0C0B; --ink:#F2F0EA; --ink-2:#A9A59D; --ink-3:#8A867E;
  --signal-ink:#FF5CA0; --select-fg:#0C0C0B;
}
:root[data-theme="dark"] .invert{
  --ground:#F2F0EA; --paper:#F2F0EA;
  --ink:#0C0C0B; --ink-2:#4A4741; --ink-3:#6B6760;
  --rule-c:#0C0C0B; --focus-halo:#F2F0EA;
  --select-fg:#0C0C0B;          /* see the note in the media-query twin above */
  --signal-ink:#AB0044;
  background:#F2F0EA; color:#0C0C0B;
}
:root[data-theme="light"]{
  color-scheme: light;
  --paper:#FAF8F5; --ink:#111110; --ink-2:#4A4741; --ink-3:#6B6760;
  --signal-ink:#AB0044; --select-fg:#111110;
}

@media (min-width:600px) { :root{ --gutter:1.25rem; --margin:1.75rem; } }
@media (min-width:1024px){ :root{ --gutter:1.5rem;  --margin:2.5rem;  } }
@media (min-width:1440px){ :root{ --margin:4rem; } }
@media (min-width:1920px){ :root{ --gutter:1.75rem; --margin:5rem; --rule-2:3px; --rule-3:12px; } }
@media (min-width:2200px){ :root{ --margin:6rem; --page-max:2040px; } }

/* ─────────────────────────────────────────────── 2. RESET ────────────── */
*,*::before,*::after{ box-sizing:border-box; }
html{
  font-size:100%; -webkit-text-size-adjust:100%;
  scroll-padding-block-start: calc(var(--chrome-h) + 1rem);
}
html,body{ overflow-x:clip; }         /* clip, NOT hidden — hidden breaks sticky */
body{ margin:0; background:var(--paper); color:var(--ink); }
img,svg{ max-inline-size:100%; }
::selection{ background:var(--select-bg); color:var(--select-fg); }
:where(h1,h2,h3,h4,p,ul,ol,dl,dd,figure,blockquote){ margin:0; }
:where(ul,ol){ padding:0; list-style:none; }
*{ hyphens:manual; }
button{ font:inherit; color:inherit; background:none; border:0; padding:0; cursor:pointer; }

/* metric-matched fallbacks — kills CLS with no build step */
@font-face{ font-family:"Archivo Fallback";
  src:local("Arial Black"),local("Impact"),local("Arial");
  size-adjust:92%; ascent-override:92%; descent-override:22%; line-gap-override:0%; }
@font-face{ font-family:"Instrument Fallback";
  src:local("Helvetica Neue"),local("Arial");
  size-adjust:97%; ascent-override:96%; descent-override:24%; line-gap-override:0%; }
@font-face{ font-family:"Space Fallback";
  src:local("Menlo"),local("Consolas"),local("Courier New");
  size-adjust:92%; ascent-override:100%; descent-override:26%; line-gap-override:0%; }

@property --wght{ syntax:'<number>'; inherits:true; initial-value:800; }

/* ─────────────────────────────────────────────── 3. TYPE ─────────────── */
body{
  font-family:var(--f-sans);
  font-size:var(--t-body);
  font-weight:400;
  line-height:var(--lh-body);
  letter-spacing:var(--tr-text);
  font-synthesis:none;
  font-kerning:normal;
  font-variant-ligatures:common-ligatures contextual;
}
p{ text-wrap:pretty; hanging-punctuation:first allow-end last; }

.label{
  font-family:var(--f-mono); font-size:var(--t-label); line-height:1;
  letter-spacing:var(--tr-mono); text-transform:uppercase; color:var(--ink-3);
  margin-inline-end:calc(-1 * var(--tr-mono));
}

/* tracked uppercase display: ligatures OFF, kerning ON */
.wordmark__line,.slug__title,.slug__num,.row__title,.stack__name,.client__name,
.client__mark,.contact__h,.mail__addr,.nav a,.label,.chip,.footer-wm__line{
  font-variant-ligatures:none; font-feature-settings:"kern" 1;
}
.stat__fig,.slug__num,.row__idx,.chip,.colophon__legal{
  font-variant-numeric:tabular-nums lining-nums;
}
.wordmark__line,.slug__title,.row__title,.client__name,
.contact__h,.stat__fig,.footer-wm__line{
  hyphens:none; overflow-wrap:normal; word-break:normal;
}
/* NOT hyphens:none — these carry authored &shy; break points (WOO|COMMERCE,
   JAVA|SCRIPT) and hyphens:none makes the browser ignore a soft hyphen. */
.stack__name{ hyphens:manual; overflow-wrap:break-word; }
@media (max-width:480px){
  .row__desc,.contact__deck,.section__intro{ hyphens:auto; hyphenate-limit-chars:9 4 4; }
}

/* cap-height alignment against a rule */
.trim-cap{ text-box:trim-both cap alphabetic; line-height:1; }
@supports not (text-box: trim-both cap alphabetic){
  .trim-cap{ line-height:.73; margin-block-start:-.135em; margin-block-end:-.09em; }
}

/* optical flush-left — applied to the element carrying the display size */
[data-optical="A"]{ margin-inline-start:-.030em }
[data-optical="W"],[data-optical="V"]{ margin-inline-start:-.022em }
[data-optical="T"]{ margin-inline-start:-.026em }
[data-optical="Y"]{ margin-inline-start:-.024em }
[data-optical="O"],[data-optical="C"]{ margin-inline-start:-.012em }
[data-optical="S"]{ margin-inline-start:-.008em }
[data-optical="J"]{ margin-inline-start:-.010em }

.vh{
  position:absolute; inline-size:1px; block-size:1px; overflow:hidden;
  clip-path:inset(50%); white-space:nowrap; border:0; padding:0; margin:-1px;
}
.nowrap{ white-space:nowrap; }

/* ─────────────────────────────────────────────── 4. GRID ─────────────── */
/* The [c] line name is what makes column addressing work through subgrid.
   Named-line-plus-index into a repeat() is NOT addressable without it. */
/* The outer bleed tracks are a FIXED --margin below 1024px, not minmax(x,1fr).
   As 1fr they were co-equal with the content columns and took an identical
   share of free space, so at 390px every track — margins included — resolved
   to 51.7px and the page shipped a timid, shrunken layout with a margin a
   full column wide. From 1024px up the content tracks are capped px values,
   so 1fr there correctly absorbs only the leftover. */
.shell{
  display:grid;
  column-gap:var(--gutter);
  grid-template-columns:
    [bleed-start] var(--margin)
    [content-start] repeat(4,[c] minmax(0,1fr))
    [content-end] var(--margin) [bleed-end];
}
.shell > *{ grid-column:content; }
.shell > .bleed{ grid-column:bleed; }

@media (min-width:600px){ .shell{ grid-template-columns:
  [bleed-start] var(--margin) [content-start] repeat(6,[c] minmax(0,1fr))
  [content-end] var(--margin) [bleed-end]; } }
@media (min-width:1024px){ .shell{ grid-template-columns:
  [bleed-start] minmax(2.5rem,1fr) [content-start] repeat(12,[c] minmax(0,124.667px))
  [content-end] minmax(2.5rem,1fr) [bleed-end]; } }
@media (min-width:1440px){ .shell{ grid-template-columns:
  [bleed-start] minmax(4rem,1fr) [content-start] repeat(12,[c] minmax(0,124.667px))
  [content-end] minmax(4rem,1fr) [bleed-end]; } }
@media (min-width:1920px){ .shell{ grid-template-columns:
  [bleed-start] minmax(5rem,1fr) [content-start] repeat(12,[c] minmax(0,121px))
  [content-end] minmax(5rem,1fr) [bleed-end]; } }
@media (min-width:2200px){ .shell{ grid-template-columns:
  [bleed-start] minmax(6rem,1fr) [content-start] repeat(12,[c] minmax(0,144.334px))
  [content-end] minmax(6rem,1fr) [bleed-end]; } }

/* Subgrid is the only mechanism that inherits tracks, LINES and GAPS together.
   Each consumer (.ledger, .row, .clients, .client, .contact) declares it
   directly and carries its own @supports fallback. */

/* ── the rule language: three weights, ink only, never an <hr> ────────── */
.section{
  border-block-start:var(--rule-2) solid var(--rule-c);
  padding-block-end:var(--sec-bot);
  position:relative;
}
.section--act{ border-block-start-width:var(--rule-3); }

section[id]{ scroll-margin-block-start:calc(var(--chrome-h) + 1rem); }

/* ─────────────────────────────────────── 5. FOCUS + SKIP ─────────────── */
:focus-visible{
  outline:2px solid var(--focus-ring);
  outline-offset:2px;
  box-shadow:0 0 0 4px var(--focus-halo);
}
:focus:not(:focus-visible){ outline:none; }
.mail:focus-visible{ --focus-ring:var(--ink); }
#main:focus{ outline:none; }

.skip{
  position:fixed; inset-block-start:.5rem; inset-inline-start:.5rem;
  z-index:var(--z-skip); transform:translateY(-250%);
  background:var(--ink); color:var(--paper); padding:.75rem 1rem;
  font-family:var(--f-mono); font-size:var(--t-label);
  letter-spacing:var(--tr-mono); text-transform:uppercase; text-decoration:none;
}
.skip:focus{ transform:none; }

/* ─────────────────────────────────────────────── 6. NAV ──────────────── */
.nav{
  position:sticky; inset-block-start:0; z-index:var(--z-sticky);
  block-size:var(--nav-h); background:var(--paper);
  border-block-end:var(--rule-1) solid var(--rule-c);
  align-items:center;
}
.nav__mark{
  grid-column:c 1 / span 2; color:var(--ink);
  display:inline-flex; align-items:center; block-size:var(--nav-h);
}
.nav__mark svg{ display:block; }
.nav__links{
  grid-column:span 6 / content-end; justify-self:end;
  display:none; gap:var(--s-5);
}
@media (min-width:900px){ .nav__links{ display:flex; } }
.nav a{
  font-family:var(--f-mono); font-size:var(--t-nav); line-height:1;
  letter-spacing:var(--tr-mono); text-transform:uppercase;
  text-decoration:none; color:var(--ink);
  display:flex; align-items:center; block-size:var(--nav-h);
  padding-inline:.25rem; position:relative;
}
.nav a .n{ color:var(--ink-3); margin-inline-end:.5em; }
.nav__links a::after{
  content:""; position:absolute; inset-inline:0; inset-block-end:12px;
  block-size:2px; background:var(--signal);
  transform:scaleX(0); transform-origin:left center;
}
.nav__menu{
  grid-column:span 2 / content-end; justify-self:end;
  font-family:var(--f-mono); font-size:var(--t-nav); line-height:1;
  letter-spacing:var(--tr-mono); text-transform:uppercase;
  block-size:var(--nav-h); padding-inline:.25rem;
}
@media (min-width:900px){ .nav__menu{ display:none; } }

/* mobile index — a real <dialog>: focus trap, Escape, inert page, backdrop */
.menu{
  max-inline-size:none; max-block-size:none; inline-size:100%; block-size:100%;
  border:0; padding:0; margin:0;
}
.menu::backdrop{ background:rgba(0,0,0,.6); }
.menu__bar{
  display:flex; align-items:center; justify-content:space-between;
  block-size:var(--nav-h); padding-inline:var(--margin);
  border-block-end:var(--rule-1) solid var(--rule-c);
}
.menu__close{
  font-family:var(--f-mono); font-size:var(--t-nav); line-height:1;
  letter-spacing:var(--tr-mono); text-transform:uppercase;
  padding:.75rem .25rem;
}
.menu nav{ display:flex; flex-direction:column; }
.menu nav a{
  font-family:var(--f-display); font-size:clamp(2rem,11vw,3rem);
  font-variation-settings:"wght" 800,"wdth" 95;
  line-height:1; letter-spacing:var(--tr-l); text-transform:uppercase;
  text-decoration:none; color:var(--ink);
  display:flex; align-items:baseline; gap:.5em;
  padding:1.15rem var(--margin);
  border-block-end:var(--rule-1) solid var(--rule-c);
  block-size:auto;
}
.menu nav a .n{
  font-family:var(--f-mono); font-size:var(--t-label);
  letter-spacing:var(--tr-mono); color:var(--ink-3); margin:0;
}

/* ─────────────────────────────────────────────── 7. HERO ─────────────── */
.hero{
  position:relative; min-block-size:84svh;
  align-content:start; padding-block-end:var(--s-8);
}
@media (max-height:520px){ .hero{ min-block-size:auto; } }

.hero__slug{
  display:flex; align-items:center; justify-content:space-between;
  flex-wrap:wrap; gap:var(--s-3);
  padding-block:var(--s-5) var(--s-4);
}
.hero__rule{ border-block-start:var(--rule-1) solid var(--rule-c); transform-origin:left center; }

.status{
  display:inline-flex; align-items:center; gap:.6em;
  border:var(--rule-1) solid var(--rule-c); border-radius:var(--radius);
  padding:.45rem .7rem;
  font-family:var(--f-mono); font-size:var(--t-label); line-height:1;
  letter-spacing:var(--tr-mono); text-transform:uppercase; color:var(--ink);
}
/* an 8px SQUARE, not a circle. It does not pulse — refusing that is the point. */
.status::before{ content:""; inline-size:8px; block-size:8px; background:var(--signal); flex:none; }

.wordmark{ margin-block:clamp(2.5rem,5vw,5rem) 0; position:relative; }
.wordmark__line{
  display:block;
  inline-size:fit-content;      /* without this the fitter measures the CONTAINER
                                   every iteration and converges to wdth 62 */
  font-family:var(--f-display);
  font-size:var(--wm-size, var(--t-display-1));
  /* the var() fallback is load-bearing: --wght exists only via @property, and
     in an engine without it an unresolvable var() invalidates the WHOLE
     declaration — losing the fitted wdth too, not just the weight. */
  font-variation-settings:"wght" var(--wght,800),"wdth" var(--wdth,100);
  line-height:var(--lh-wordmark);
  letter-spacing:var(--tr-mega);
  text-transform:uppercase; white-space:nowrap;
  color:var(--ink);
}
.wordmark__line[data-fit]:nth-of-type(1){ --wdth:114.5; }  /* static pre-fit: ships correct */
.wordmark .r-mask:nth-of-type(2) .wordmark__line{ --wdth:100; }

.hero__deck{
  grid-column:content;
  font-size:var(--t-lead); line-height:var(--lh-lead); letter-spacing:var(--tr-s);
  max-inline-size:var(--measure-lead);
  margin-block-start:clamp(2.5rem,5vw,4.5rem);
  /* the mask's overflow:hidden would otherwise clip the signal underline
     sitting .14em below the last line */
  padding-block-end:.35em; margin-block-end:-.35em;
}
.ul{ position:relative; white-space:nowrap; }
.ul::after{
  content:""; position:absolute; inset-inline:0; inset-block-end:-.14em;
  block-size:2px; background:var(--signal);
  transform:scaleX(0); transform-origin:left center;
}
html:not(.js) .ul::after,
html[data-motion="off"] .ul::after,
html.is-ready .ul::after{ transform:scaleX(1); }

.hero__cta{
  grid-column:content; display:flex; flex-wrap:wrap; gap:var(--s-3);
  margin-block-start:var(--s-6);
}
.hero__cta > .r-mask{ display:block; }
@media (max-width:599px){
  .hero__cta{ flex-direction:column; align-items:stretch; }
  .hero__cta .btn{ inline-size:100%; }
}

@media (min-width:600px){
  .hero__deck{ grid-column:c 1 / span 5; }
}
@media (min-width:1024px){
  .hero__deck{ grid-column:c 1 / span 6; margin-block-start:clamp(2.5rem,5vw,4.5rem); }
  .hero__cta{
    grid-column:c 8 / content-end; justify-self:end;
    flex-direction:column; align-items:stretch;
    margin-block-start:clamp(2.5rem,5vw,4.5rem);
  }
  .hero__cta .btn{ justify-content:space-between; }
}

/* Registration marks — they live in the OUTER margins, like trim marks on a
   printed sheet. grid-column:bleed is load-bearing: an absolutely positioned
   grid item is contained by its GRID AREA, so without this they resolve
   against the content column and strike straight through the slug text. */
.reg{
  grid-column:bleed;
  position:absolute; inline-size:12px; block-size:12px; color:var(--ink-3);
  background:
    linear-gradient(currentColor,currentColor) 50% 0   /1px 4px no-repeat,
    linear-gradient(currentColor,currentColor) 50% 100%/1px 4px no-repeat,
    linear-gradient(currentColor,currentColor) 0   50% /4px 1px no-repeat,
    linear-gradient(currentColor,currentColor) 100% 50%/4px 1px no-repeat;
}
.reg--tl{ inset-block-start:var(--s-6); inset-inline-start:var(--margin); }
.reg--tr{ inset-block-start:var(--s-6); inset-inline-end:var(--margin); }
.reg--bl{ inset-block-end:var(--s-6);   inset-inline-start:var(--margin); }
.reg--br{ inset-block-end:var(--s-6);   inset-inline-end:var(--margin); }
@media (max-width:599px){ .reg{ display:none; } }

/* ─────────────────────────────────────────── 8. BUTTONS ──────────────── */
/* The surface is a pseudo-element, not the button's own background.
   `isolation:isolate` is mandatory (without it z-index:-1 escapes to an
   ancestor stacking context and the slab can vanish) — but inside that
   context a negative-z child paints ABOVE the element's own background,
   so a background on .btn itself would be covered by the slab and the
   ink-coloured label would sit on ink. Two layers fixes it deterministically:
   slab at -2, surface at -1, label on top. */
.btn{
  display:inline-flex; align-items:center; justify-content:space-between;
  gap:var(--s-5); min-block-size:52px; padding:1.05em 1.4em;
  font-family:var(--f-sans); font-weight:600; font-size:var(--t-nav);
  letter-spacing:.04em; text-transform:uppercase; text-decoration:none;
  border-radius:var(--radius); border:2px solid var(--ink);
  background:transparent;
  isolation:isolate;
  position:relative;
}
.btn::before{ content:""; position:absolute; inset:0; z-index:-1; }   /* surface */
.btn::after{                                                          /* slab    */
  content:""; position:absolute; inset:-2px; z-index:-2;
  background:var(--ink); transform:translate(6px,6px);
}
.btn--primary  { color:var(--ground); }
.btn--primary::before  { background:var(--ink); }
.btn--secondary{ color:var(--ink); }
.btn--secondary::before{ background:var(--ground); }

/* ─────────────────────────────────────────── 9. STATS ────────────────── */
.stats-sec{ border-block-start:var(--rule-2) solid var(--rule-c); }
.stats{
  display:grid; grid-template-columns:1fr;
  min-block-size:clamp(7rem,12vw,11rem);
}
.stats__cell{
  display:flex; align-items:baseline; justify-content:space-between; gap:var(--s-4);
  padding:var(--s-5) var(--margin);
  border-block-start:var(--rule-1) solid var(--rule-c);
  min-block-size:4.5rem;
}
.stats__cell:first-child{ border-block-start:0; }
@media (min-width:700px){
  .stats{ grid-template-columns:5fr 4fr 3fr; }     /* B2 — ignores the 12 columns */
  .stats__cell{
    flex-direction:column; align-items:flex-start; justify-content:flex-end;
    gap:var(--s-2);
    padding:var(--s-6) var(--s-5) var(--s-6) var(--margin);
    border-block-start:0;
    border-inline-start:var(--rule-1) solid var(--rule-c);
  }
  .stats__cell:first-child{ border-inline-start:0; }
}
.stat__fig{
  font-family:var(--f-display); font-size:var(--t-display-4);
  font-variation-settings:"wght" 800,"wdth" 118;
  line-height:.86; letter-spacing:-.03em; text-transform:uppercase;
  color:var(--ink); display:block;
}
/* ∞ is an x-height glyph among cap-height siblings, and heavy weights close
   its counters — so it is lighter, larger, and optically nudged up. */
.stat__fig--inf{
  font-variation-settings:"wght" 600,"wdth" 100;
  font-size:calc(var(--t-display-4) * 1.14); letter-spacing:0;
}
/* the optical nudge uses `top`, NOT transform — the child also carries the
   rise animation, whose `both` fill mode would overwrite a transform here */
.stat__fig--inf > *{ position:relative; inset-block-start:-.055em; }

/* ────────────────────────────────────── 10. SECTION OPENER ───────────── */
.slug{
  grid-column:content;
  display:grid; grid-template-columns:auto 1fr auto;
  align-items:baseline; row-gap:.75rem;
  column-gap:clamp(.75rem,1.6vw,1.25rem);
  padding-block:clamp(2rem,4vw,3.5rem) 0;
}
.slug__num{
  grid-column:1; grid-row:1;
  font-family:var(--f-display); font-size:var(--t-heading-1);
  font-variation-settings:"wght" 900,"wdth" 125;
  letter-spacing:-.02em; text-transform:uppercase; color:var(--ink);
}
/* nth-child, NOT :first-of-type/:last-of-type — those count every <span>
   sibling, so the "first"/"last" span are the number and the meta, and the
   rules match nothing. The component contract is a fixed five children. */
.slug__rule{ border-block-start:var(--rule-1) solid var(--rule-c); align-self:center; min-inline-size:1.5rem; }
.slug > .slug__rule:nth-child(2){ grid-column:2; grid-row:1; }
.slug > .slug__rule:nth-child(4){ display:none; }
.slug__meta{
  grid-column:3; grid-row:1;
  font-family:var(--f-mono); font-size:var(--t-label); line-height:1;
  letter-spacing:var(--tr-mono); text-transform:uppercase; color:var(--ink-3);
}
.slug__title{
  grid-column:1 / -1; grid-row:2;
  font-family:var(--f-display); font-size:var(--t-display-3);
  font-variation-settings:"wght" 800,"wdth" 92;
  line-height:var(--lh-display); letter-spacing:var(--tr-l);
  text-transform:uppercase; color:var(--ink);
}
@media (max-width:400px){ .slug__meta{ display:none; } }
@media (min-width:700px){
  .slug{ grid-template-columns:auto 1fr auto 1fr auto; row-gap:0; }
  .slug__num{ grid-column:1; grid-row:1; }
  .slug > .slug__rule:nth-child(2){ grid-column:2; grid-row:1; }
  .slug__title{ grid-column:3; grid-row:1; }
  .slug > .slug__rule:nth-child(4){ display:block; grid-column:4; grid-row:1; }
  .slug__meta{ grid-column:5; grid-row:1; }
}

.section__intro{
  grid-column:content;
  font-size:var(--t-lead); line-height:var(--lh-lead); letter-spacing:var(--tr-s);
  color:var(--ink-2);
  max-inline-size:34ch;
  padding-block:var(--s-5) var(--sec-top);
}
@media (min-width:600px){ .section__intro{ grid-column:c 1 / span 5; } }
@media (min-width:1024px){ .section__intro{ grid-column:c 1 / span 6; } }

/* ─────────────────────────────────────── 11. SERVICES LEDGER ─────────── */
.ledger{ display:grid; grid-template-columns:subgrid; border-block-start:var(--rule-1) solid var(--rule-c); }
@supports not (grid-template-columns: subgrid){ .ledger{ display:block; } }

.row{
  grid-column:bleed; display:grid; grid-template-columns:subgrid;
  align-items:start; position:relative;
  row-gap:var(--s-3);
  padding-block:clamp(1.75rem,3vw,2.75rem);
  border-block-end:var(--rule-1) solid var(--rule-c);
}
@supports not (grid-template-columns: subgrid){
  .row{ display:block; padding-inline:var(--margin); }
}
.row__idx{
  grid-column:c 1; grid-row:1;
  font-family:var(--f-mono); font-size:var(--t-label); line-height:1;
  letter-spacing:var(--tr-mono); text-transform:uppercase; color:var(--ink-3);
}
.row__cat{
  grid-column:c 2 / content-end; grid-row:1;
  display:flex; align-items:center; justify-content:space-between; gap:var(--s-3);
  font-family:var(--f-mono); font-size:var(--t-label); line-height:1.5;
  letter-spacing:var(--tr-mono); text-transform:uppercase; color:var(--ink-3);
}
.row__title{
  grid-column:content; grid-row:2;
  font-family:var(--f-display); font-size:var(--t-heading-1);
  font-variation-settings:"wght" var(--rw,700),"wdth" 88;
  line-height:var(--lh-heading); letter-spacing:var(--tr-m);
  text-transform:uppercase; color:var(--ink);
}
.row__body{ grid-column:content; grid-row:3; }
.row__desc{ font-size:var(--t-body-s); line-height:1.46; color:var(--ink-2); max-inline-size:52ch; }

@media (min-width:1024px){
  .row{ row-gap:0; }
  .row__idx  { grid-column:c 1 / span 1; grid-row:1; }
  .row__cat  { grid-column:c 2 / span 3; grid-row:1; padding-inline-end:var(--s-4); }
  .row__title{ grid-column:c 5 / span 4; grid-row:1;
               border-inline-start:var(--rule-1) solid var(--rule-c);
               padding-inline-start:var(--s-4); }
  .row__body { grid-column:c 9 / content-end; grid-row:1;
               border-inline-start:var(--rule-1) solid var(--rule-c);
               padding-inline-start:var(--s-4); }
  /* the two vertical spines run the full height of every row, so across six
     contiguous rows they read as two continuous lines down the section */
  .row__title,.row__body{ align-self:stretch; }
}

/* the acid spine PRE-LIGHTS only — it never reveals content, so touch and
   keyboard users lose nothing */
.row::before{
  content:""; position:absolute; inset-block:0; inset-inline-start:0;
  inline-size:6px; background:var(--signal);
  transform:scaleY(0); transform-origin:50% 100%;
}
.chip-row{
  display:flex; flex-wrap:wrap; gap:var(--s-2);
  border-block-start:var(--rule-1) solid var(--rule-c);
  padding-block-start:var(--s-4); margin-block-start:var(--s-4);
}
.chip{
  display:inline-block;
  font-family:var(--f-mono); font-size:var(--t-tag); line-height:1;
  letter-spacing:var(--tr-caps); text-transform:uppercase; color:var(--ink);
  padding:.5em .72em .46em;
  padding-inline-end:calc(.72em - var(--tr-caps));  /* SUBTRACT the trailing track */
  border:var(--rule-1) solid var(--rule-c); border-radius:var(--radius);
  white-space:nowrap;
}

/* the registration cross — one device, four contexts, pure CSS.
   Four 4px arms around a 4px void: a TARGET, not a plus. */
.mark{
  display:inline-block; inline-size:12px; block-size:12px; flex:none;
  background:
    linear-gradient(currentColor,currentColor) 50% 0   /1px 4px no-repeat,
    linear-gradient(currentColor,currentColor) 50% 100%/1px 4px no-repeat,
    linear-gradient(currentColor,currentColor) 0   50% /4px 1px no-repeat,
    linear-gradient(currentColor,currentColor) 100% 50%/4px 1px no-repeat;
}

/* ─────────────────────────────────────────── 12. CLIENTS ─────────────── */
.clients{
  display:grid; grid-template-columns:subgrid;
  overflow:clip;                      /* B3 clips at the BLEED edge */
  border-block-start:var(--rule-1) solid var(--rule-c);
}
@supports not (grid-template-columns: subgrid){ .clients{ display:block; } }
/* overflow:clip has no partial degradation — the declaration is simply dropped,
   and with it 52px of horizontal overflow appears and the footer wordmark stops
   being cut by the document edge. */
@supports not (overflow: clip){
  .clients,.footer-wm{ overflow:hidden; }
}

.client{
  grid-column:bleed; display:grid; grid-template-columns:subgrid;
  align-items:center; row-gap:var(--s-5);
  padding-block:var(--s-8);
}
@supports not (grid-template-columns: subgrid){
  .client{ display:block; padding-inline:var(--margin); }
}
.client + .client{ border-block-start:var(--rule-1) solid var(--rule-c); }

.client__mark{
  grid-column:content; grid-row:1;
  font-family:var(--f-display); font-size:clamp(9rem,26vw,26rem);
  font-variation-settings:"wght" 800,"wdth" 100;
  line-height:.78; letter-spacing:-.04em; text-transform:uppercase;
  color:var(--ink); user-select:none; display:block;
}
.client__meta{ grid-column:content; grid-row:2; }
.client__name{
  font-family:var(--f-display); font-size:var(--t-display-3);
  font-variation-settings:"wght" 800,"wdth" 95;
  line-height:var(--lh-display); letter-spacing:var(--tr-l);
  text-transform:uppercase; color:var(--ink);
  margin-block:var(--s-3) var(--s-5);
}
.scope__row{
  display:grid; grid-template-columns:1fr; gap:var(--s-1);
  border-block-start:var(--rule-1) solid var(--rule-c);
  padding-block:.875rem;
}
.scope__row dd{ font-size:var(--t-body-s); line-height:1.4; letter-spacing:var(--tr-flat); font-weight:500; }
.scope__row dd span{ display:flex; align-items:center; gap:.6em; }
.scope__row dd .mark{ color:var(--ink-3); }
@media (min-width:600px){
  .scope__row{ grid-template-columns:10rem 1fr; gap:var(--s-4); align-items:baseline; }
}
@media (min-width:1024px){
  .client{ min-block-size:72svh; row-gap:0; }
  .client__mark{
    grid-column:bleed-start / span 6; grid-row:1;
    margin-inline-start:-.14em; font-size:clamp(14rem,26vw,26rem);
  }
  .client__meta{ grid-column:c 7 / content-end; grid-row:1; }
  .client--flip .client__mark{
    grid-column:span 6 / bleed-end; justify-self:end;
    margin-inline-start:0; margin-inline-end:-.14em;
  }
  /* Measured: Archivo's I and M carry the SAME .0749em sidebearing, but the M's
     ink is 838 units wide and the I's stem only 180. So -.14em (roughly 2x the
     sidebearing) crops the M pleasingly and amputates 36% of the I.
     Pulling the I out by exactly its own sidebearing lands the stem ON the
     viewport edge — it still reads as bleeding off, but nothing is sliced. */
  .client--flip .client__mark[data-optical="I"]{ margin-inline-end:-.075em; }
  .client--flip .client__meta{ grid-column:c 1 / span 6; }
}

/* ─────────────────────────────────────────── 13. STACK ───────────────── */
/* gap:1px + ink container + paper cells = perfect never-doubled hairlines,
   no border-collapse maths, no :nth-child exceptions */
.stack{
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--rule-1); background:var(--rule-c);
  border-block:var(--rule-1) solid var(--rule-c);
}
@media (min-width:900px){ .stack{ grid-template-columns:repeat(4,minmax(0,1fr)); } }
@media (min-width:2200px){
  .stack{ max-inline-size:var(--page-max); margin-inline:auto;
          border-inline:var(--rule-1) solid var(--rule-c); }
}
.stack__cell{
  background:var(--ground);
  /* inline-size:100% is load-bearing. With only aspect-ratio + max-block-size
     the cap resolves the BLOCK axis first and the ratio then shrinks the
     inline axis — cells stop filling their tracks and the 1px gaps render as
     140px slabs of container background. A definite width fixes the axis
     order: width from the track, height from the ratio, then capped. */
  inline-size:100%; aspect-ratio:5/4;
  max-block-size:clamp(8.5rem,16vw,13rem);
  display:flex; flex-direction:column; justify-content:space-between;
  padding:clamp(1rem,2vw,1.75rem);
}
.stack__head{ display:flex; justify-content:space-between; gap:.5rem; }
.stack__name{
  font-family:var(--f-display); font-size:var(--t-heading-2);
  font-variation-settings:"wght" 700,"wdth" 84;
  line-height:.95; letter-spacing:var(--tr-m);
  text-transform:uppercase; color:var(--ink);
}

/* ─────────────────────────────────────────── 14. CONTACT ─────────────── */
/* CONTACT is the only section without an intro, so its slug title sits
   directly above the display headline. Raising only the clamp FLOOR separates
   them at narrow widths; the 3vw term overtakes 2rem at 1067px, so every
   viewport above that renders identically to before. */
.contact{ grid-column:content; padding-block:clamp(2rem,3vw,3rem) 0; }
.contact__h{
  font-family:var(--f-display); font-size:var(--t-display-2);
  font-variation-settings:"wght" 800,"wdth" 96;
  line-height:.86; letter-spacing:var(--tr-xl);
  text-transform:uppercase; color:var(--ink);
}
.contact__deck{
  font-size:var(--t-lead); line-height:var(--lh-lead); letter-spacing:var(--tr-s);
  color:var(--ink-2); max-inline-size:38ch;
  margin-block-start:var(--s-6);
}
@media (min-width:1024px){
  .contact{ display:grid; grid-template-columns:subgrid; grid-column:content; align-items:start; }
  .contact__h{ grid-column:c 1 / span 7; grid-row:1; }
  .contact__deck{ grid-column:c 9 / content-end; grid-row:1; margin-block-start:.6em; }
  .contact .mail{ grid-column:c 1 / span 10; grid-row:2; }
  .contact__note{ grid-column:c 1 / span 7; grid-row:3; }
}
/* .contact is the last subgrid consumer in the file; without this it keeps
   display:grid, the `c` names resolve against implicit lines, and the heading
   and deck collide on row 1. Source order matters: @supports adds no
   specificity, so this must come after the block above. */
@supports not (grid-template-columns: subgrid){
  @media (min-width:1024px){
    .contact{ display:block; }
    .contact__h,.contact__deck,.contact .mail,.contact__note{ grid-column:auto; grid-row:auto; }
    .contact__deck{ margin-block-start:var(--s-6); }
  }
}

/* THE one filled --signal block in the entire document. #111110 on #FF2E88
   = 5.40:1, legal at any size, in both themes. Never light text on signal. */
.mail{
  display:flex; align-items:baseline; flex-wrap:wrap; gap:var(--s-3) var(--s-5);
  background:var(--signal); color:#111110; text-decoration:none;
  padding:clamp(1.25rem,2.5vw,2rem) clamp(1.25rem,2.5vw,2rem);
  margin-block-start:clamp(3rem,6vw,5rem);
  position:relative;
}
.mail__label{ color:#111110; flex-basis:100%; }
/* The address only fits on one line above ~1580px. word-break:break-word made
   arbitrary mid-word breaking the FIRST resort, orphaning a single letter M on
   line two of the one accent slab on the page. min() scales it to fit instead,
   and break-word is demoted to a last resort behind normal break opportunities. */
.mail__addr{
  font-family:var(--f-display); font-size:min(var(--t-display-3), 4.8vw);
  font-variation-settings:"wght" 800,"wdth" 88;
  line-height:.92; letter-spacing:var(--tr-l);
  text-transform:uppercase;
  /* 4.8vw is measured, not guessed: it is the largest factor at which the
     22-character address still sets on ONE line inside the slab at every
     width 320-2560. Above that it orphaned a single letter M onto line two
     of the one accent block on the page.
     min-inline-size:0 + overflow-wrap:anywhere are the hard safety net —
     this is a flex item, whose default min-width:auto floors it at its
     min-content width, and plain `overflow-wrap:break-word` does NOT reduce
     min-content. Without both, the address overflowed the slab instead of
     ever wrapping. */
  min-inline-size:0; overflow-wrap:anywhere; word-break:normal; hyphens:none;
}
.mail__mark{ position:absolute; inset-block-start:1.25rem; inset-inline-end:1.25rem; color:#111110; }
.contact__note{
  font-size:var(--t-body-s); line-height:1.5; color:var(--ink-2);
  margin-block-start:var(--s-6);
}

/* display:inline, NOT inline-flex — this link also appears mid-sentence in
   the contact note, and a flex box there swallows the space after it. */
.link-ext{
  font-family:var(--f-mono); font-size:var(--t-caption); line-height:1;
  letter-spacing:var(--tr-mono); text-transform:uppercase;
  text-decoration:none; color:var(--ink);
  border-block-end:var(--rule-1) solid var(--rule-c);
  padding-block-end:.28em;
  display:inline; white-space:nowrap;
}
.link-ext::after{
  content:""; display:inline-block;
  inline-size:.42em; block-size:.42em;
  margin-inline:.55em .18em;   /* trailing margin: this link also sits mid-sentence */
  border-block-start:1px solid currentColor; border-inline-end:1px solid currentColor;
  transform:translateY(-.12em) rotate(-45deg);
}

/* ─────────────────────────────────────────── 15. FOOTER ──────────────── */
footer{ border-block-start:var(--rule-1) solid var(--rule-c); }
.colophon{
  grid-column:content; display:grid; grid-template-columns:1fr;
  align-items:center;
}
.colophon > *{
  min-block-size:var(--band-h); display:flex; align-items:center;
  gap:var(--s-5); flex-wrap:wrap;
}
.colophon__legal{
  font-size:var(--t-caption); line-height:1.4; letter-spacing:var(--tr-flat);
  color:var(--ink-3);
}
.colophon__social{ gap:var(--s-5); }
.colophon__social a{ padding-block:.75rem; }
.colophon__toggles{ gap:var(--s-6); }
@media (min-width:900px){
  .colophon{ grid-template-columns:5fr 4fr 5fr; }
  .colophon__social{ justify-content:center; }
  .colophon__toggles{ justify-content:flex-end; }
}

.toggle{
  display:inline-flex; align-items:center; gap:.55em;
  font-family:var(--f-mono); font-size:var(--t-caption); line-height:1;
  letter-spacing:var(--tr-mono); text-transform:uppercase;
  padding-block:.75rem;
}
.toggle__key{ color:var(--ink-3); }
.toggle__sep{ color:var(--ink-3); }
.toggle__opt{ color:var(--ink-3); position:relative; padding-block-end:.3em; }
.toggle__opt[data-active]{ color:var(--ink); }
.toggle__opt[data-active]::after{
  content:""; position:absolute; inset-inline:0; inset-block-end:0;
  block-size:2px; background:var(--signal);
}

/* B4 — the wordmark cut through by the document's bottom edge.
   em/cap resolve against the CONTAINER, which carries the display size. */
.footer-wm{
  border-block-start:var(--rule-3) solid var(--rule-c);
  font-size:var(--t-display-5);
  padding-inline:var(--margin);
  block-size:.62cap; overflow:clip;
}
@supports not (block-size: 1cap){ .footer-wm{ block-size:.45em; } }
.footer-wm__line{
  display:block; inline-size:fit-content;
  font-family:var(--f-display);
  font-variation-settings:"wght" 800,"wdth" var(--wdth,100);
  font-size:1em; letter-spacing:-.04em; text-transform:uppercase;
  white-space:nowrap; color:var(--ink);
  line-height:1; text-box:trim-both cap alphabetic;
}
@supports not (text-box: trim-both cap alphabetic){
  .footer-wm__line{ margin-block-start:-.26em; }
}

/* ────────────────────────────────── 16. THE MEASURE (signature 2) ────── */
[data-measure]{ position:relative; }
.cx,.cy{
  position:absolute; pointer-events:none; z-index:var(--z-measure);
  background:var(--rule-c); will-change:transform;
}
.cx{ inset-inline:0; inset-block-start:0; block-size:1px; }
.cy{ inset-block:0; inset-inline-start:0; inline-size:1px; }
.cread{
  position:absolute; pointer-events:none; z-index:var(--z-measure);
  inset-block-start:0; inset-inline-start:0;
  font-family:var(--f-mono); font-size:11px; line-height:1;
  letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink); background:var(--ground);
  border:1px solid var(--rule-c); padding:.4em .5em;
  white-space:nowrap;
}
.cx[hidden],.cy[hidden],.cread[hidden]{ display:none; }

/* ══════════════════════════════════════════ 17. MOTION ════════════════
   EVERY animation and transition in this build lives inside
   html[data-motion="on"]. There is no `* { animation:none !important }`
   panic block, because every element's final state IS its default state:
   the reduced-motion build is simply the page at t=∞.
   ═════════════════════════════════════════════════════════════════════ */

.r-mask{ overflow:hidden; display:block; }
.r-mask > *{ display:block; }
/* interactive elements need a PADDED mask or the overflow box clips the
   focus ring (2px offset + 4px halo) and the button's 6px slab */
.r-mask--pad{ padding:12px; margin:-12px; }
/* .btn declares its own layout mode; the mask reset above has equal
   specificity and comes later, so it was silently making every hero CTA
   display:block — killing align-items, justify-content and gap on it. */
.r-mask > .btn{ display:flex; }
/* the fitted wordmark's ink now lands on the mask's clip boundary */
.wordmark .r-mask{ padding-inline-start:4px; margin-inline-start:-4px; }

html[data-motion="on"]{ scroll-behavior:smooth; }

/* Animations are APPLIED by .is-ready rather than paused until it. A paused
   animation with fill-mode:both parks the element at its `from` state — so a
   failed main.js would leave the hero permanently blank. This way the absence
   of an animation is simply the finished page, which is the whole principle:
   the reduced-motion build is the page at t=∞. */
html[data-motion="on"].is-ready .anim{
  animation-duration:var(--dur,480ms);
  animation-timing-function:var(--e-in);
  animation-fill-mode:both;
  animation-delay:calc(var(--t,0ms) + (var(--i,0) * var(--stagger,40ms)));
}
html[data-motion="on"].is-ready .rise{ animation-name:rise; }
html[data-motion="on"].is-ready .draw-x{ animation-name:drawX; animation-duration:var(--dur,720ms); }
html[data-motion="on"].is-ready .pop{ animation-name:pop; animation-duration:var(--dur,240ms); }
html[data-motion="on"].is-ready .status--in{ animation-name:drawX; animation-duration:var(--dur,320ms); transform-origin:left center; }

@keyframes rise { from{ transform:translateY(var(--travel)); } to{ transform:none; } }
@keyframes drawX{ from{ transform:scaleX(0); }               to{ transform:scaleX(1); } }
@keyframes pop  { from{ transform:scale(.4); }               to{ transform:none; } }

/* the ink-up: the press registering. wdth holds its fitted value, so the two
   lines are slightly narrow and ragged for half a second and then CONVERGE
   to flush as the ink comes up. Zero layout shift below it. */
html[data-motion="on"].is-ready .wordmark{ animation:ink var(--d-6) var(--e-in) both; }
@keyframes ink{ from{ --wght:300; } to{ --wght:800; } }

html[data-motion="on"] .ul::after{
  transition:transform var(--d-4) var(--e-in) 700ms;
}

/* scroll reveals — one-shot, never re-animating on scroll back up.
   .failsafe is set by a 2.5s watchdog in the inline head gate: if main.js
   never runs, nothing on this page can stay hidden. */
/* NOTE: the .in rule must carry the SAME selector prefix as the hiding rule.
   A shorter prefix loses on specificity and the element never reveals. */
html.js[data-motion="on"]:not(.failsafe) [data-reveal]{ opacity:0; }
html.js[data-motion="on"]:not(.failsafe) [data-reveal].in{
  opacity:1;
  animation:rise var(--d-4) var(--e-in) both;
}
html:not([data-motion="on"]) [data-reveal],
html.failsafe [data-reveal],
html:not(.js) [data-reveal]{ opacity:1; }

/* ── hover + focus. Every :hover has a matching :focus-visible. ───────── */
html[data-motion="on"] .nav__links a::after,
html[data-motion="on"] .row::before{
  transition:transform var(--d-2) var(--e-out);
}
.nav__links a[aria-current="true"]::after,
.nav__links a:hover::after,
.nav__links a:focus-visible::after{
  transform:scaleX(1);
}
html[data-motion="on"] .nav__links a:hover::after,
html[data-motion="on"] .nav__links a:focus-visible::after,
html[data-motion="on"] .nav__links a[aria-current="true"]::after{
  transform-origin:left center;
  transition-duration:var(--d-2);
  transition-timing-function:var(--e-in);
}

/* The .btn carries `.anim .rise`, and a finished animation with fill-mode:both
   keeps writing transform from the ANIMATION ORIGIN, which outranks every
   author-normal declaration. So the button must move with `translate`, not
   `transform`, or its hover/focus/active states are simply dead.
   RULE: any element carrying .anim that also needs an interaction transform
   must use translate/rotate/scale (or top/left) — never transform.
   The ::after slab has no animation, so transform on it is fine. */
html[data-motion="on"] .btn,
html[data-motion="on"] .btn::after{
  transition:transform var(--d-3) var(--e-in),
             translate var(--d-3) var(--e-in),
             background-color var(--d-1) var(--e-flat),
             color var(--d-1) var(--e-flat);
}
@media (hover:hover) and (pointer:fine){
  .btn:hover{ translate:2px 2px; }
  .btn:hover::after{ transform:translate(4px,4px); }
}
.btn:focus-visible{ translate:2px 2px; }
.btn:focus-visible::after{ transform:translate(4px,4px); }
.btn:active{ translate:6px 6px; }
.btn:active::after{ transform:translate(0,0); }
html[data-motion="on"] .btn:active,
html[data-motion="on"] .btn:active::after{ transition-duration:var(--d-1); }

html[data-motion="on"] .row__title{
  transition:font-variation-settings var(--d-3) var(--e-in);
}
html[data-motion="on"] .mark{
  transition:transform var(--d-3) var(--e-in), color var(--d-1) var(--e-flat);
}
@media (hover:hover) and (pointer:fine){
  .row:hover::before{ transform:scaleY(1); transform-origin:50% 0; }
  .row:hover{ --rw:900; }
  .row:hover .row__mark{ transform:rotate(45deg); color:var(--signal); }
}
.row:focus-within::before{ transform:scaleY(1); transform-origin:50% 0; }
.row:focus-within{ --rw:900; }

.mail:hover .mail__mark,
.mail:focus-visible .mail__mark{ transform:rotate(45deg); }

html[data-motion="on"] .link-ext{
  transition:color var(--d-1) var(--e-flat), border-color var(--d-1) var(--e-flat);
}
/* hover changes TWO things so the affordance never depends on colour alone */
.link-ext:hover,.link-ext:focus-visible{
  color:var(--signal-ink);
  border-block-end-width:2px;
  border-block-end-color:var(--signal);
}
html[data-motion="on"] .toggle__opt{ transition:color var(--d-1) var(--e-flat); }

/* Reduced motion: the slab is static at 6px, hover swaps colour only.
   The surface swap MUST target ::before, not .btn. A `background` on .btn is
   permanently occluded by ::before (see the two-layer note above), so setting
   it here while `color` still applies produced a 1:1-contrast button — an
   invisible label on hover AND on focus-visible. This branch also matches
   when JS is disabled (no data-motion attribute at all), so the bug hit every
   no-JS visitor regardless of their motion preference. */
html:not([data-motion="on"]) .btn:hover,
html:not([data-motion="on"]) .btn:focus-visible{ translate:none; }
html:not([data-motion="on"]) .btn:hover::after,
html:not([data-motion="on"]) .btn:focus-visible::after{ transform:translate(6px,6px); }
html:not([data-motion="on"]) .btn--primary:hover::before,
html:not([data-motion="on"]) .btn--primary:focus-visible::before{ background:var(--signal); }
html:not([data-motion="on"]) .btn--primary:hover,
html:not([data-motion="on"]) .btn--primary:focus-visible{ color:#111110; border-color:var(--signal); }
html:not([data-motion="on"]) .btn--secondary:hover::before,
html:not([data-motion="on"]) .btn--secondary:focus-visible::before{ background:var(--ink); }
html:not([data-motion="on"]) .btn--secondary:hover,
html:not([data-motion="on"]) .btn--secondary:focus-visible{ color:var(--ground); }
html:not([data-motion="on"]) .row:hover::before,
html:not([data-motion="on"]) .row:focus-within::before{ transform:scaleY(1); }
