/* ═══════════════════════════════════════════════════════════════════════════
   ZACARIAS MEDIA — v11 · stylesheet
   Extracted from the page in v11 so the site can be more than one page and
   the second one costs a cache hit rather than another download. The only
   script still inline is the theme and language boot, which has to run
   before the first paint.
   ═══════════════════════════════════════════════════════════════════════════ */

@font-face{font-family:"Space Grotesk";font-weight:400 700;font-display:swap;src:url("fonts/space-grotesk.woff2") format("woff2")}
@font-face{font-family:"IBM Plex Sans";font-weight:300 600;font-display:swap;src:url("fonts/ibm-plex-sans.woff2") format("woff2")}
@font-face{font-family:"IBM Plex Mono";font-weight:400;font-display:swap;src:url("fonts/ibm-plex-mono-400.woff2") format("woff2")}
@font-face{font-family:"IBM Plex Mono";font-weight:500;font-display:swap;src:url("fonts/ibm-plex-mono-500.woff2") format("woff2")}
/* ═══════════════════════════════════════════════════════════════════════════
   ZACARIAS MEDIA — v11
   Design tokens. One source of truth. Every custom property used anywhere in
   this file is defined here, in all three theme states.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  /* ── brand accents: the five mediums ───────────────────────────────────── */
  --d1:#5570f3; --d2:#eb745a; --d3:#f5d654; --d4:#c96ad8; --d5:#72c5a2;

  /* ── the sixth colour ────────────────────────────────────────────────────
     The house orange, one value in both themes so it reads as the one constant
     next to the five mediums. It lives here rather than in a theme block
     because it does not change between them; only --accent-text does, and that
     one is set per theme below.
       --accent      fills, rules, dots, marks, selection — shape, not text
       --accent-ink  what sits on top of an --accent fill */
  --accent:#FF9900;
  --accent-ink:#1a1a1a;    /* 9.0:1 on the accent fill */

  /* ── type ──────────────────────────────────────────────────────────────── */
  --sans:"IBM Plex Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --display:"Space Grotesk","IBM Plex Sans",-apple-system,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

  /* Fluid scale. Each step is a clamp so there is never a breakpoint jump. */
  --fs-mono:11px;
  --fs-xs:clamp(.78rem,.75rem + .18vw,.86rem);
  --fs-sm:clamp(.86rem,.83rem + .2vw,.95rem);
  --fs-md:clamp(.95rem,.9rem + .3vw,1.08rem);
  --fs-lg:clamp(1.05rem,.98rem + .45vw,1.28rem);
  --fs-h3:clamp(1.05rem,.95rem + .6vw,1.35rem);
  --fs-h2:clamp(1.75rem,1.3rem + 2.2vw,3.1rem);
  --fs-h1:clamp(2.15rem,1.5rem + 3.3vw,4.4rem);
  --fs-hero:clamp(2.4rem,1.5rem + 4.2vw,5.2rem);

  /* ── space & shape ─────────────────────────────────────────────────────── */
  --edge:clamp(20px,5vw,80px);
  --hdr:56px;
  --hdr-tall:clamp(74px,9vh,104px);  /* the masthead, before any scroll */
  --maxw:1400px;
  /* Three steps and a pill. --r-lg is the one radius every surface takes, at
     any size: the reel, the form, a portfolio card, the five's stage, a project
     video, a pull quote. There used to be a fourth step above it that only the
     reel and the form used, which is what made those two read as rounder than
     the page they sit in. Anything smaller than a surface (a chip, an input, a
     swatch, a 2px rail) is not on this scale; it is round in proportion to
     itself, which is why those keep their own values. */
  --r-sm:8px; --r-md:12px; --r-lg:18px; --r-pill:999px;

  /* ── motion ────────────────────────────────────────────────────────────── */
  --ease:cubic-bezier(.16,1,.3,1);          /* long, settling */
  --ease-io:cubic-bezier(.65,0,.35,1);      /* symmetric */
  --spring:cubic-bezier(.34,1.4,.5,1);      /* small overshoot, macOS-ish */
  --t-fast:.18s; --t-med:.34s; --t-slow:.62s;
}

/* ── light ──────────────────────────────────────────────────────────────── */
/* v10: the ground is neutral now, not cream. Every grey below is a true grey,
   so nothing casts a warm tint against an almost white page.
   v11: light is no longer the base state. It is reached only by an explicit
   choice, so it is written against the attribute alone — see the dark block
   below, which is what a bare :root now resolves to. */
:root[data-theme="light"]{
  color-scheme:light;
  --bg:#fafafa;            /* page */
  --bg-raise:#ffffff;      /* cards that sit above the page */
  --bg-sunk:#f0f0f0;       /* wells, image placeholders */
  --bg-blur:rgba(250,250,250,.72); /* translucent chrome */
  --fg:#1f1f1f;            /* primary ink, 15.8:1 on --bg */
  --fg-2:#525252;          /* body copy, 7.5:1 */
  --fg-3:#666666;          /* meta, captions — 5.5:1 on --bg, so it still passes at 11px */
  --line:rgba(0,0,0,.13);
  --line-soft:rgba(0,0,0,.07);
  --chip:rgba(0,0,0,.05);
  /* The lip of a well. --line is ink on paper and paper on ink, which is right
     for a rule between things but wrong for the edge of a recess: on the dark
     theme it lights the edge of a box that is darker than the page it sits in,
     so the player read as a grey stroke drawn round a black rectangle. A
     recess is edged by a shadow, so this darkens in both themes and only the
     amount changes. */
  --well-edge:rgba(0,0,0,.13);
  /* At luminance .440 the house orange is loud on ink (9.1:1 on the dark
     ground) and quiet on paper (2.1:1 on --bg). So the token splits by job
     rather than by theme: --accent is shape and lives on :root, and this is
     the same colour where it has to be read as small type, darkened on a
     light ground to clear 4.5:1. */
  --accent-text:#9E5E00;   /* 5.0:1 on --bg, 5.2:1 on --bg-raise */
  --focus:#3f6be0;
  --shadow-1:0 1px 2px rgba(0,0,0,.05), 0 4px 14px rgba(0,0,0,.05);
  --shadow-2:0 2px 6px rgba(0,0,0,.07), 0 18px 44px rgba(0,0,0,.11);
  /* The canvas well. v10 lights it: it is the same raised white as a card,
     so the wash over it lands as a clean tint of the medium's colour rather
     than a muddied one, and the solid is drawn in the light tuned accents that
     :root already hands out — which is what they were mixed for. */
  --stage:#ffffff;
  --stage-ink:#5f5f5f;     /* the counter in its corner, 5.4:1 on the washed well */
  --logo-invert:1;         /* client artwork is white; invert on paper */
  /* the five, tuned for a light ground */
  --a1:#4a63e0; --a2:#cf5740; --a3:#9d7f10; --a4:#a94cba; --a5:#2f8a66;
}

/* ── dark ───────────────────────────────────────────────────────────────────
   v11: the default, and not conditional on anything. A bare :root carries the
   ink palette, so the site is dark before the attribute is read, before script
   runs, and whatever the operating system is set to. The light block above is
   more specific, so an explicit choice still wins. */
:root,
:root[data-theme="dark"]{
  color-scheme:dark;
  --bg:#191816;
  --bg-raise:#232220;
  --bg-sunk:#121211;
  --bg-blur:rgba(25,24,22,.72);
  --fg:#f2eee4;
  --fg-2:#b4b0a7;
  --fg-3:#8d8981;
  --line:rgba(242,238,228,.15);
  --line-soft:rgba(242,238,228,.08);
  --chip:rgba(242,238,228,.07);
  --well-edge:rgba(0,0,0,.55);
  --focus:#7f9dff;
  --shadow-1:0 1px 2px rgba(0,0,0,.4), 0 4px 14px rgba(0,0,0,.3);
  --shadow-2:0 2px 6px rgba(0,0,0,.45), 0 18px 44px rgba(0,0,0,.45);
  --stage:#0e0e0d;
  --stage-ink:#8d8d8d;
  --logo-invert:0;
  --accent-text:#FF9900;   /* 9.1:1 on --bg, so no darkening is needed here */
  --a1:#5570f3; --a2:#eb745a; --a3:#f5d654; --a4:#c96ad8; --a5:#72c5a2;
}

/* Ink polarity, available to any element. A section uses it to set its own
   ground; the fixed chrome adopts it while such a section is behind it, which
   is what a native title bar does over a surface of its own.

   v10: in the light theme this is no longer an inversion. Perception OS used
   to punch a black hole through a light page; it now keeps the light palette
   and separates itself the way every other well on the page does, by sitting
   one step below the page rather than by flipping polarity. The wireframes
   pick up --a1..--a5 from this block, so they restate themselves in the
   light-ground versions of the five with nothing else to change. In the dark
   theme the inversion is intact: the section still goes a step darker than
   the page, which is the same gesture read the other way round. */
.invert,
.hdr[data-invert="true"],
.rail[data-invert="true"]{
  color-scheme:dark;
  --bg:#141412; --bg-raise:#1e1d1b; --bg-sunk:#0c0c0b; --bg-blur:rgba(20,20,18,.72);
  --fg:#f2eee4; --fg-2:#b4b0a7; --fg-3:#8d8981;
  --line:rgba(242,238,228,.15); --line-soft:rgba(242,238,228,.08); --chip:rgba(242,238,228,.07); --focus:#7f9dff;
  --stage:#0a0a09; --stage-ink:#8d8d8d; --logo-invert:0; --accent-text:#FF9900;
  --a1:#5570f3; --a2:#eb745a; --a3:#f5d654; --a4:#c96ad8; --a5:#72c5a2;
}
:root[data-theme="light"] .invert,
:root[data-theme="light"] .hdr[data-invert="true"],
:root[data-theme="light"] .rail[data-invert="true"]{
  color-scheme:light;
  --bg:#f2f2f2; --bg-raise:#fafafa; --bg-sunk:#e8e8e8; --bg-blur:rgba(242,242,242,.72);
  --fg:#1f1f1f; --fg-2:#525252; --fg-3:#616161;
  --line:rgba(0,0,0,.13); --line-soft:rgba(0,0,0,.07); --chip:rgba(0,0,0,.05); --focus:#3f6be0;
  --stage:#ffffff; --stage-ink:#5f5f5f; --logo-invert:1; --accent-text:#9E5E00;
  --a1:#4a63e0; --a2:#cf5740; --a3:#9d7f10; --a4:#a94cba; --a5:#2f8a66;
}
.invert{background:var(--bg); color:var(--fg)}


/* ═══ RESET & BASE ════════════════════════════════════════════════════════ */
*,*::before,*::after{box-sizing:border-box}
html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-padding-top:0;
}
body{
  margin:0;
  background:var(--bg);
  color:var(--fg);
  font-family:var(--sans);
  font-size:var(--fs-md);
  font-weight:300;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
  overscroll-behavior-y:none;
  transition:background-color var(--t-med) var(--ease-io), color var(--t-med) var(--ease-io);
}
/* Locks page scroll while a modal owns the screen, without the layout shift
   that removing the scrollbar normally causes. */
body.is-locked{overflow:hidden}

img,svg,canvas,video,iframe{display:block;max-width:100%}
/* The UA rule for [hidden] is display:none at user-agent origin, so any author
   display beats it: .pcard{display:flex} left trimmed cards flagged hidden and
   still painted. Author origin plus !important settles it once for every
   element on the page rather than per component. */
[hidden]{display:none !important}
img{height:auto}
a{color:inherit;text-decoration:none;-webkit-tap-highlight-color:transparent}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;-webkit-tap-highlight-color:transparent}
ol,ul{margin:0;padding:0;list-style:none}
h1,h2,h3,h4,p,dl,dd,figure,blockquote{margin:0}
/* Browsers give <fieldset> a groove border, side margins and a min-width of
   min-content. All three fight flex layout, so all three go. */
fieldset{border:0;margin:0;padding:0;min-inline-size:0}
legend{padding:0;display:block}
input,textarea,select{font:inherit;color:inherit}
::selection{background:var(--accent);color:var(--accent-ink)}

/* One focus ring for the whole site: visible on every surface, never on a
   plain mouse click. */
:focus{outline:none}
:focus-visible{
  outline:2px solid var(--focus);
  outline-offset:3px;
  border-radius:var(--r-sm);
}

.skip{
  position:fixed;left:-9999px;top:0;z-index:400;
  background:var(--fg);color:var(--bg);padding:12px 18px;border-radius:0 0 var(--r-md) 0;
}
.skip:focus-visible{left:0;top:0;outline-offset:-4px}

/* ═══ TYPE PRIMITIVES ═════════════════════════════════════════════════════ */
.mono{
  font-family:var(--mono);font-size:var(--fs-mono);font-weight:500;
  letter-spacing:.16em;text-transform:uppercase;line-height:1.4;
  font-variant-numeric:tabular-nums;
}
.eyebrow{
  display:flex;align-items:center;gap:11px;color:var(--fg-3);
  margin:0 0 clamp(14px,2.2vh,24px);
}
.eyebrow s{width:26px;height:1px;background:currentColor;opacity:.55;text-decoration:none;flex:none}
.h1,.h2,.h3{font-family:var(--display);font-weight:700;letter-spacing:-.034em;text-wrap:balance}
/* ── widows and orphans ───────────────────────────────────────────────────
   balance on anything headline shaped, so a two line title never drops one
   word onto a line of its own; pretty on running copy, which lets the engine
   pull a word back rather than leave a short last line. Both fall back to
   normal wrapping where unsupported, so nothing depends on them. */
.dx__q,.dimb__name,.pcard-title,.pclient,.step h3,.why h3,.os__k,.foot__tag,
.eyebrow,.deliv__l,.conv__legend,h3,figcaption{text-wrap:balance}
.dimb__d,.step p,.why p,.pdesc,.os__s,.dx__hint,.reel__cap,.hero__meta,
.who__lede,.who__sub,.ai__lede,.foot__place,.tag,p.lede{text-wrap:pretty}
/* Nothing on this page wants a hyphenated break. */
body{hyphens:none;-webkit-hyphens:none}
.h1{font-size:var(--fs-h1);line-height:1.02;max-width:19ch}
.h2{font-size:var(--fs-h2);line-height:1.05;max-width:20ch;letter-spacing:-.03em}
.h3{font-size:var(--fs-h3);line-height:1.2;font-weight:600;letter-spacing:-.02em}
.hero-h{font-family:var(--display);font-weight:700;font-size:var(--fs-hero);line-height:1;
  letter-spacing:-.04em;margin:0;max-width:16ch;text-wrap:balance}
.dim{color:var(--fg-3)}
.lede{
  font-size:var(--fs-lg);font-weight:300;line-height:1.5;color:var(--fg-2);
  max-width:50ch;margin:clamp(14px,2vh,22px) 0 0;text-wrap:pretty;
}
.body-sm{font-size:var(--fs-sm);line-height:1.5;color:var(--fg-2)}

/* ═══ LAYOUT ══════════════════════════════════════════════════════════════ */
.wrap{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:var(--edge)}

/* A section is at least one viewport, centred, and snaps. Sections taller than
   the viewport opt out of snapping via .sect--tall so they never trap anyone. */
.sect{
  position:relative;
  min-height:100svh;
  display:flex;flex-direction:column;justify-content:center;
  padding-block:calc(var(--hdr) + clamp(28px,6vh,72px)) clamp(40px,8vh,96px);
  scroll-snap-align:start;
  scroll-snap-stop:normal;
}
.sect--tall{min-height:0;scroll-snap-align:none;justify-content:flex-start}
.sect--flush{padding-block:0}

/* Proximity, never mandatory: the browser eases to a section when you land
   near one and stays out of the way everywhere else. Disabled outright when
   a section is taller than the viewport, and under reduced motion. */
@media (min-height:620px) and (pointer:fine){
  html{scroll-snap-type:y proximity}
}
html.no-snap{scroll-snap-type:none}

/* Content lifts in as it arrives. One class, one observer.
   The hidden starting state is gated behind html.js, which the inline head
   script sets: if scripting is off or the bundle fails to parse, every .rv
   element is simply visible rather than invisible forever. */
.rv{transition:opacity .8s var(--ease), transform .8s var(--ease)}
.js .rv{opacity:0;transform:translateY(22px)}
.js .rv.in{opacity:1;transform:none}
.rv-1{transition-delay:.06s}.rv-2{transition-delay:.12s}.rv-3{transition-delay:.18s}
.rv-4{transition-delay:.24s}.rv-5{transition-delay:.3s}.rv-6{transition-delay:.36s}

/* ═══ TITLE SWEEP ═════════════════════════════════════════════════════════
   A title arrives dim and lights along its own reading line as the page
   moves, so the eye is walked through it rather than handed all of it at
   once. It is a mask, not a colour: a mask touches alpha only, so the two
   tone headings keep the exact relationship between their bright half and
   their .dim half, and nothing here has to know what either colour is.

   No element is rewritten to do this. The copy inside a [data-t] heading has
   to stay byte for byte what the dictionary holds, or the language switch
   would have nothing to match and the markup would drift from the deck, so
   the sweep is one custom property on the outside of the text instead of a
   span around every word.

   The axis leans slightly up, not down: at 80deg a point low in the box sits
   earlier along the gradient than one high in it, which is what puts a second
   line after the first rather than under it.

   --lit runs 0 to 1 and is set by the one scroll frame. It rests at 1, so
   with no script, no mask support or reduced motion the title is simply and
   fully painted. */
@supports ((mask-image:linear-gradient(#000,#000)) or (-webkit-mask-image:linear-gradient(#000,#000))){
  @media (prefers-reduced-motion:no-preference){
    .js .lit{
      --lit:1;
      --lit-edge:calc(var(--lit) * 132% - 16%);
      --lit-mask:linear-gradient(80deg,
        rgba(0,0,0,1) 0,
        rgba(0,0,0,1) var(--lit-edge),
        rgba(0,0,0,.26) calc(var(--lit-edge) + 17%),
        rgba(0,0,0,.26) 100%);
      -webkit-mask-image:var(--lit-mask);
              mask-image:var(--lit-mask);
    }
    /* Once it has finished it stays finished: the mask comes off altogether,
       which also takes the element back out of its own compositing layer. */
    .js .lit[data-lit="done"]{-webkit-mask-image:none;mask-image:none}
  }
}

/* ═══ REDUCED MOTION ══════════════════════════════════════════════════════
   Not just animation-duration: transitions, snapping and the pinned scroll
   sequences all stand down, and revealed content starts visible. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;scroll-snap-type:none}
  *,*::before,*::after{
    animation-duration:.001ms!important;
    animation-iteration-count:1!important;
    transition-duration:.001ms!important;
    scroll-behavior:auto!important;
  }
  .rv{opacity:1;transform:none}
}


/* ═══ HEADER ══════════════════════════════════════════════════════════════
   A macOS-style translucent bar: it lets the page tint through, keeps a
   hairline edge, and gains that edge only once you have scrolled past the
   top so the hero meets the screen cleanly. */
.hdr{
  position:fixed;inset:0 0 auto;z-index:150;height:var(--hdr-tall);
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding-inline:var(--edge);
  color:var(--fg);
  background:var(--bg-blur);
  -webkit-backdrop-filter:saturate(180%) blur(20px);
  backdrop-filter:saturate(180%) blur(20px);
  border-bottom:1px solid transparent;
  transition:border-color var(--t-med) var(--ease-io),
  background-color var(--t-med) var(--ease-io),
  height var(--t-slow) var(--ease);
}
/* No backdrop-filter (Firefox without the flag, older engines): fall back to
   an opaque bar rather than unreadable text over moving content. */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .hdr{background:var(--bg)}
}
.hdr[data-scrolled="true"]{border-bottom-color:var(--line);height:var(--hdr)}
/* At rest the header is a masthead: the complete wordmark across a full width
   band, ruled top and bottom. Scrolling collapses it to the compact bar and
   crossfades the wordmark into the Z. --hdr stays the scrolled height because
   every anchor offset on the page is measured against it, and by the time an
   anchor matters the bar is already collapsed. */
.hdr::before{content:"";position:absolute;inset:0 0 auto;height:1px;
  background:var(--line);opacity:0;transition:opacity var(--t-med) var(--ease-io)}
.hdr[data-scrolled="false"]::before{opacity:1}
/* The wordmark and the Z are one object in two states, so they are laid out
   as one: a single grid cell both of them occupy, left aligned and centred on
   the same line. That shared cell is the whole trick — the marks cross fade in
   place, over the same anchor, and the box keeps one size through the swap so
   nothing downstream of it moves either.

   Their sizes are locked to each other rather than clamped apart. The two files
   are the same artwork: the Z is 66.6 x 82.8 of the wordmark's 583 x 163.6 box,
   so a Z drawn at 82.8/583 of the wordmark's width is the wordmark's own Z, at
   the wordmark's own scale, at every viewport, with nothing to keep in sync by
   hand. One clamp therefore sizes the whole masthead. Its floor is set from the
   other end: 148px is the wordmark width whose Z lands on 21px, the smallest
   the mark reads as a logo rather than as a letter. */
.hdr__logo{position:relative;display:grid;place-items:center;flex:none;
  border-radius:var(--r-sm);isolation:isolate;
  --logo-w:clamp(118px,12vw,157px);
  --logo-z:calc(var(--logo-w) * 0.142);    /* 82.8 / 583, the Z's height */
  width:var(--logo-w);
}
/* The wordmark and the Z are one object in two states, so they are laid out as
   one: a single grid cell that both of them occupy, each centred in it. The
   swap therefore turns about a shared centre point rather than about an edge,
   and the box holds one size through it, so nothing downstream of the logo
   moves either.

   Their sizes stay locked to each other. The two files are the same artwork:
   the Z is 66.6 x 82.8 of the wordmark's 583 x 163.6 box, so a Z drawn at
   82.8/583 of the wordmark's width is the wordmark's own Z, at the wordmark's
   own scale, at every viewport, with nothing to keep in sync by hand. One
   clamp therefore sizes the whole masthead. */
.hdr__logo > *{grid-area:1/1;transition:opacity var(--t-med) var(--ease-io),
  transform var(--t-slow) var(--ease)}
.hdr__word{width:var(--logo-w);height:auto;
  filter:invert(calc(1 - var(--logo-invert)));transform-origin:center}
.hdr__z{display:block;transform-origin:center}
.zmark{width:auto;height:var(--logo-z);display:block;color:var(--fg)}
/* scrolled: wordmark shrinks away, Z steps up */
.hdr[data-scrolled="true"] .hdr__word{opacity:0;transform:scale(.62)}
.hdr[data-scrolled="true"] .hdr__z{opacity:1;transform:scale(1)}
.hdr[data-scrolled="false"] .hdr__word{opacity:1;transform:scale(1)}
.hdr[data-scrolled="false"] .hdr__z{opacity:0;transform:scale(1.5)}
@media (prefers-reduced-motion:reduce){
  .hdr,.hdr__logo > *{transition:none}
}
.hdr__mid{display:flex;align-items:center;gap:clamp(14px,1.8vw,30px);margin-inline:auto}
.hdr__link{
  font-size:var(--fs-xs);font-weight:400;color:var(--fg-2);white-space:nowrap;
  padding:6px 2px;border-radius:var(--r-sm);position:relative;
  transition:color var(--t-fast) var(--ease-io);
}
.hdr__link::after{
  content:"";position:absolute;left:0;right:0;bottom:2px;height:1px;
  background:currentColor;transform:scaleX(0);transform-origin:left center;
  transition:transform var(--t-med) var(--ease);
}
.hdr__link:hover{color:var(--fg)}
.hdr__link:hover::after{transform:scaleX(1)}
.hdr__link[aria-current="true"]{color:var(--fg)}
.hdr__link[aria-current="true"]::after{transform:scaleX(1);background:var(--accent)}
.hdr__r{display:flex;align-items:center;gap:clamp(8px,1vw,14px);flex:none}

/* ── segmented control ──────────────────────────────────────────────────── */
.seg{
  display:flex;align-items:center;position:relative;
  padding:2px;border-radius:var(--r-pill);
  background:var(--chip);border:1px solid var(--line-soft);
}
.seg button{
  position:relative;z-index:1;
  font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;white-space:nowrap;
  padding:5px 11px;border-radius:var(--r-pill);
  /* secondary rather than tertiary ink: at 10px uppercase on the chip fill,
     --fg-3 measured 4.25:1, just under AA. */
  color:var(--fg-2);
  transition:color var(--t-med) var(--ease-io);
}
.seg button:hover{color:var(--fg)}
.seg button[aria-pressed="true"]{color:var(--fg)}
/* The knob is one element that slides, the way a real segmented control does,
   instead of a background appearing under each button in turn. */
.seg__knob{
  position:absolute;z-index:0;top:2px;bottom:2px;left:0;
  border-radius:var(--r-pill);background:var(--bg-raise);
  box-shadow:var(--shadow-1);
  transition:transform var(--t-med) var(--spring), width var(--t-med) var(--spring);
  pointer-events:none;
}
.seg[data-ready="false"] .seg__knob{opacity:0}

/* ── primary button ─────────────────────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;gap:9px;
  padding:9px 14px 9px 17px;border-radius:var(--r-pill);
  background:var(--fg);color:var(--bg);
  font-size:var(--fs-xs);font-weight:500;white-space:nowrap;
  transition:transform var(--t-med) var(--spring), box-shadow var(--t-med) var(--ease-io), opacity var(--t-fast);
}
.btn:hover{transform:translateY(-2px);box-shadow:var(--shadow-2)}
.btn:active{transform:translateY(0) scale(.98)}
.btn i{
  width:19px;height:19px;border-radius:50%;background:var(--accent);
  display:grid;place-items:center;color:var(--accent-ink);font-style:normal;font-size:10px;flex:none;
  transition:transform var(--t-med) var(--spring);
}
.btn:hover i{transform:translate(1px,-1px)}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.45;pointer-events:none}
.btn--ghost{background:transparent;color:var(--fg);border:1px solid var(--line);padding:8px 16px}
.btn--ghost:hover{border-color:var(--fg);box-shadow:none}

.link{
  display:inline-flex;align-items:center;gap:8px;font-size:var(--fs-sm);
  color:var(--fg-2);border-bottom:1px solid var(--line);padding-bottom:3px;
  transition:color var(--t-fast), border-color var(--t-fast);
}
.link:hover{color:var(--fg);border-color:currentColor}

/* ── responsive chrome ──────────────────────────────────────────────────── */
/* Below the label breakpoint the appearance control keeps all three states
   as glyphs rather than disappearing, so a phone can still override the OS. */
.seg__ico{display:none;font-size:12px;line-height:1;letter-spacing:0}
@media (max-width:1080px){ .hdr__mid{display:none} }
@media (max-width:860px){
  .seg--theme .seg__word{display:none}
  .seg--theme .seg__ico{display:block}
  .seg--theme button{padding:5px 9px}
}
@media (max-width:560px){
  .seg button{padding:5px 8px;font-size:9px;letter-spacing:.06em}
  .seg--theme button{padding:5px 7px}
  .hdr .btn span{display:none}
  .hdr .btn{padding:9px 11px}
  .hdr{gap:10px}
  .hdr__r{gap:7px}
}
@media (max-width:360px){ .seg--lang{display:none} }

/* ═══ SECTION RAIL ════════════════════════════════════════════════════════
   The dot rail is a real <nav> of links, so it works without JS, reads as
   navigation to a screen reader, and shows where you are. */
.rail{
  position:fixed;right:max(12px,calc(var(--edge)*.38));top:50%;
  transform:translateY(-50%);z-index:130;
  display:flex;flex-direction:column;gap:11px;
  padding:10px 6px;
}
.rail a{
  display:grid;place-items:center;width:24px;height:12px;border-radius:var(--r-sm);
}
.rail span{
  display:block;width:100%;height:2px;border-radius:2px;background:var(--fg);
  opacity:.24;transform:scaleX(.5);transform-origin:right center;
  transition:opacity var(--t-med) var(--ease), transform var(--t-med) var(--ease);
}
.rail a:hover span{opacity:.6;transform:scaleX(.78)}
.rail a[aria-current="true"] span{opacity:1;transform:scaleX(1);background:var(--accent)}
@media (max-width:900px),(max-height:560px){ .rail{display:none} }

/* ═══ PROGRESS ════════════════════════════════════════════════════════════
   A hairline of read-progress under the header. Cheap, honest, unobtrusive. */
.prog{
  position:fixed;top:var(--hdr);left:0;right:0;height:2px;z-index:149;
  transform-origin:left center;transform:scaleX(0);
  background:linear-gradient(90deg,var(--a1),var(--a2),var(--a3),var(--a4),var(--a5));
  pointer-events:none;
}


/* ═══ HERO ════════════════════════════════════════════════════════════════ */
#top{overflow:hidden}
.hero__fx{position:absolute;inset:0;width:100%;height:100%;z-index:0;pointer-events:none}
.hero__in{position:relative;z-index:1}
.hero__cta{display:flex;align-items:center;gap:clamp(14px,2vw,26px);flex-wrap:wrap;
  margin-top:clamp(22px,3.4vh,38px)}
.hero__meta{
  position:absolute;left:var(--edge);right:var(--edge);bottom:clamp(20px,4vh,34px);z-index:1;
  display:flex;align-items:flex-end;justify-content:space-between;gap:20px;
  color:var(--fg-3);
}
.hero__scroll{display:flex;align-items:center;gap:9px}
.hero__scroll b{
  width:20px;height:32px;border:1px solid var(--line);border-radius:var(--r-pill);
  position:relative;flex:none;
}
.hero__scroll b::after{
  content:"";position:absolute;left:50%;top:7px;width:2px;height:5px;border-radius:2px;
  background:currentColor;margin-left:-1px;animation:wheelHint 2s var(--ease-io) infinite;
}
@keyframes wheelHint{0%,100%{opacity:0;transform:translateY(0)}30%{opacity:.9}70%{opacity:0;transform:translateY(9px)}}
@media (max-height:640px){ .hero__meta{display:none} }
@media (max-width:640px){ .hero__meta .mono:first-child{display:none} }

/* ═══ REEL ════════════════════════════════════════════════════════════════ */
.reel{
  /* The player is capped by the height left over after the heading, the
     caption and the client strip, so the whole section still fits one
     viewport on a laptop instead of pushing the strip below the fold. */
  position:relative;width:100%;margin-inline:auto;
  max-width:min(100%, 1120px, calc((100svh - 430px) * 16 / 9));
  aspect-ratio:16/9;overflow:hidden;
  border-radius:var(--r-lg);
  background:var(--bg-sunk);box-shadow:var(--shadow-2);
  margin-top:clamp(24px,4vh,48px);
}
/* The frame was a real border on a rounded, overflow-hidden box with the player
   laid over it at inset:0. At the corners the square-cornered iframe covered the
   inside of the curve, so the line read as broken exactly where the eye checks
   it. An inset ring paints on top of the player and inherits the radius, so it
   closes all the way round. */
.reel::after{content:"";position:absolute;inset:0;pointer-events:none;
  border-radius:inherit;box-shadow:inset 0 0 0 1px var(--well-edge);z-index:3}
.reel .vid{position:absolute;inset:0;width:100%;height:100%;display:block}
/* Shown until the player upgrades — and left in place if it never does, so the
   frame is never an empty hole. */
.vid__fallback{
  position:absolute;inset:0;display:grid;place-content:center;gap:14px;justify-items:center;
  text-align:center;padding:24px;color:var(--fg-3);background:var(--bg-sunk);
}
.vid__fallback[hidden]{display:none}
.reel__cap{margin:14px 0 0;color:var(--fg-3);text-align:center}

/* ── client marquee ────────────────────────────────────────────────────── */
.strip{margin-top:clamp(26px,4vh,52px)}
.marq{
  overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
}
.marq__t{
  display:flex;align-items:center;width:max-content;
  gap:clamp(36px,5.5vw,80px);padding-left:clamp(36px,5.5vw,80px);
  animation:marq 34s linear infinite;
}
/* One max-height cannot make logos look equal: a wide wordmark and a compact
   badge at the same height read as very different sizes. Each logo carries a
   --k optical factor set on the element, and the box is fixed so the row sits
   on one baseline whatever the aspect ratio. */
.marq img{
  height:calc(clamp(20px,2.2vw,30px) * var(--k,1));
  width:auto;max-width:calc(150px * var(--k,1));object-fit:contain;
  filter:invert(var(--logo-invert));opacity:.55;
  transition:opacity var(--t-med) var(--ease-io);
}
.marq:hover .marq__t,.marq:focus-within .marq__t{animation-play-state:paused}
.marq img:hover{opacity:1}
@keyframes marq{from{transform:translateX(0)}to{transform:translateX(-50%)}}
/* A loop that never stops is exactly what reduced motion is asking about. */
@media (prefers-reduced-motion:reduce){
  .marq__t{animation:none;flex-wrap:wrap;width:auto;justify-content:center;row-gap:22px;padding-left:0}
  .marq{mask-image:none;-webkit-mask-image:none}
}

/* ═══ THE FIVE — pinned scroll sequence ═══════════════════════════════════
   The section is five viewports tall and the stage inside is sticky, so the
   browser's own scrolling drives the sequence. No wheel is intercepted:
   trackpad momentum, the scrollbar, Page Down, find-in-page and mobile
   flick-scroll all keep working. */
.pin{position:relative}
#five.pin{height:500svh}
#os.pin{height:320svh}
.pin__stage{
  position:sticky;top:0;height:100svh;
  display:flex;flex-direction:column;justify-content:center;
  padding-block:calc(var(--hdr) + clamp(20px,4vh,48px)) clamp(28px,5vh,60px);
  overflow:hidden;
}
.five__head{margin-bottom:clamp(18px,3vh,40px)}

/* The five markers sit directly above the stage and share its width, so the
   sequence reads as a progress bar for the thing it is actually driving.
   Equal columns rather than fixed widths: they stay flush with the stage at
   any size, and the whole strip is the same object as the box below it. */
.five__viz{width:100%;max-width:min(100%,42vh);margin-inline:auto;
  display:flex;flex-direction:column;gap:clamp(10px,1.4vh,16px)}
.five__ticks{display:grid;grid-template-columns:repeat(5,1fr);gap:7px;width:100%}
.five__ticks b{
  display:block;height:6px;border-radius:3px;background:var(--line);
  position:relative;overflow:hidden;
}
.five__ticks b i{
  position:absolute;inset:0;background:var(--tc);display:block;
  transform:scaleX(0);transform-origin:left center;
  transition:transform .5s var(--ease);
}
.five__ticks b[data-on="true"] i{transform:scaleX(1)}

.five__body{display:grid;gap:clamp(20px,3.4vw,64px);grid-template-columns:1fr;align-items:center}
@media (min-width:1000px){.five__body{grid-template-columns:1.05fr .95fr}}
.five__col{display:grid}
.dimb{
  grid-area:1/1;opacity:0;pointer-events:none;
  transform:translateY(14px);
  transition:opacity .5s var(--ease), transform .5s var(--ease);
}
.dimb[data-on="true"]{opacity:1;transform:none;pointer-events:auto}
.dimb__n{color:var(--fg-3);margin:0 0 12px}
.dimb__name{
  font-family:var(--display);font-weight:700;letter-spacing:-.038em;line-height:1;margin:0;
  font-size:clamp(2rem,5vw,4.2rem);display:flex;align-items:center;gap:.26em;
}
.dimb__name u{
  width:.22em;height:.22em;border-radius:4px;background:var(--c);
  text-decoration:none;flex:none;
}
.dimb__d{
  font-size:var(--fs-lg);font-weight:300;line-height:1.45;color:var(--fg-2);
  max-width:34ch;margin:clamp(12px,1.8vh,20px) 0 0;
}
.deliv{margin:clamp(16px,2.4vh,26px) 0 0}
.deliv__l{color:var(--fg-3);margin:0 0 11px}
.deliv ul{display:flex;flex-wrap:wrap;gap:7px}
.deliv li{
  font-size:var(--fs-xs);font-weight:400;padding:7px 13px;border-radius:var(--r-pill);
  border:1px solid var(--line);color:var(--fg);
  background:color-mix(in srgb,var(--c) 12%,transparent);
}
@supports not (background:color-mix(in srgb,red 12%,transparent)){.deliv li{background:var(--chip)}}

.five__stage{
  position:relative;aspect-ratio:1;border-radius:var(--r-lg);background:var(--stage);
  overflow:hidden;width:100%;
  border:1px solid var(--line);box-shadow:var(--shadow-2);
}
.five__stage canvas{position:absolute;inset:0;width:100%;height:100%}
.five__wash{position:absolute;inset:0;opacity:.13;background:var(--wc,var(--d1));
  transition:background-color .5s var(--ease-io)}
.five__c{position:absolute;left:15px;bottom:13px;color:var(--stage-ink);z-index:2}
@media (max-width:999px){
  .five__viz{max-width:min(230px,26vh);order:-1}
  .dimb__d{max-width:46ch}
}
@media (max-height:680px) and (max-width:999px){ .five__viz{display:none} }

/* Reduced motion: a scroll sequence is a scroll sequence. Unpin it and show
   all five at once as an ordinary list. */
@media (prefers-reduced-motion:reduce){
  #five.pin,#os.pin{height:auto}
  .pin__stage{position:static;height:auto;min-height:0}
  .five__col{display:block}
  .dimb{opacity:1;transform:none;pointer-events:auto;padding-block:clamp(20px,4vh,40px);
    border-top:1px solid var(--line-soft)}
  .five__viz{display:none}
}

/* ═══ PERCEPTION OS ═══════════════════════════════════════════════════════ */
#os .pin__stage{padding:0;display:block}
.conv{position:absolute;inset:0}
.conv canvas{position:absolute;inset:0;width:100%;height:100%}
.conv__legend{
  position:absolute;top:calc(var(--hdr) + 18px);left:var(--edge);right:var(--edge);
  display:flex;gap:14px;flex-wrap:wrap;color:var(--fg-3);
}
.conv__legend span{display:flex;align-items:center;gap:6px}
.conv__legend i{width:7px;height:7px;border-radius:2px;background:var(--c);flex:none}
@media (max-width:720px){.conv__legend{display:none}}
.conv__copy{
  position:absolute;inset:auto 0 0;padding:22vh var(--edge) clamp(40px,9vh,90px);
  display:grid;pointer-events:none;
  /* var(--bg) here is the section's own inverted ground, so the copy always
     sits on the same ink it is coloured against. */
  background:linear-gradient(to top,var(--bg) 34%,color-mix(in srgb,var(--bg) 60%,transparent) 68%,transparent);
}
@supports not (background:color-mix(in srgb,red 60%,transparent)){
  .conv__copy{background:linear-gradient(to top,var(--bg) 40%,transparent)}
}
.stg{
  grid-area:1/1;opacity:0;margin:0;max-width:30ch;
  font-family:var(--display);font-weight:600;
  font-size:clamp(1.1rem,2vw,1.85rem);line-height:1.2;letter-spacing:-.024em;
  color:var(--fg);
  transform:translateY(12px);
  transition:opacity .5s var(--ease-io), transform .5s var(--ease-io);
}
.stg[data-on="true"]{opacity:1;transform:none}
.stg small{
  display:block;font-family:var(--mono);font-size:var(--fs-mono);font-weight:500;
  letter-spacing:.16em;text-transform:uppercase;color:var(--fg-3);margin-bottom:.9em;
}
.os{
  font-family:var(--display);font-weight:700;letter-spacing:-.032em;line-height:1;
  font-size:clamp(1.9rem,4.6vw,3.8rem);display:flex;align-items:flex-start;gap:.1em;
}
.os sup{font-size:.24em;margin-top:.55em;color:var(--fg-3)}
.os__s{
  margin:.7em 0 0;font-family:var(--sans);font-weight:300;font-size:var(--fs-md);
  line-height:1.5;color:var(--fg-2);max-width:44ch;letter-spacing:0;
}
@media (prefers-reduced-motion:reduce){
  #os .pin__stage{padding-block:calc(var(--hdr) + 6vh) 8vh}
  .conv{position:relative;inset:auto;min-height:0}
  .conv canvas,.conv__legend{display:none}
  .conv__copy{position:relative;inset:auto;padding:0 var(--edge);background:none;display:grid;gap:clamp(28px,5vh,56px)}
  .stg{grid-area:auto;opacity:1;transform:none}
}

/* ═══ PROCESS ═════════════════════════════════════════════════════════════ */
/* The head sets the claim against the qualification, sitting them on the same
   baseline rather than stacking them, which is how the v2 site opened this. */
.proc__head{display:grid;gap:clamp(14px,2vw,44px);align-items:end;
  margin-bottom:clamp(30px,5vh,70px)}
@media (min-width:900px){.proc__head{grid-template-columns:1.15fr .85fr}}
.proc__head .h2{max-width:15ch;margin:0}
.proc__head .lede{max-width:44ch;margin:0}

/* The rail sits outside the copy, and the copy is padded off it, so the line
   is a margin element rather than a divider inside the text block. */
.proc{
  --rail-x:clamp(5px,1.4vw,14px);
  --rail-pad:clamp(34px,6vw,72px);
  position:relative;padding-left:var(--rail-pad);
}
.proc__rail{position:absolute;left:var(--rail-x);top:6px;bottom:6px;width:2px;
  border-radius:2px;background:var(--line)}
/* The fill is the five mediums in one pass, ordered as a spectrum rather than
   in medium order, which is how v2 drew it.

   v2 grew the gradient element's height, which squeezed all five colours into
   whatever was filled so far: the colour at any point slid around as you
   scrolled. Here the element is the full rail and a wipe uncovers it, so the
   gradient is pinned to the track. A given height is always the same colour,
   and the colour arriving at a node is the colour that node lights up in.
   The transition only smooths the frame to frame step, so it still tracks
   scroll rather than running on a clock of its own. */
.proc__rail i{
  position:absolute;inset:0;border-radius:2px;
  background:linear-gradient(180deg,var(--a1),var(--a5),var(--a3),var(--a2),var(--a4));
  clip-path:inset(0 0 100% 0);
  transition:clip-path .12s linear;
}
.steps{list-style:none;margin:0;padding:0}
.step{
  position:relative;
  display:grid;gap:6px clamp(20px,4vw,60px);align-items:baseline;
  padding-block:clamp(18px,3.2vh,34px);
  border-bottom:1px solid var(--line-soft);
}
.step:last-child{border-bottom:0}
@media (min-width:820px){
  .step{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
}
/* Number and title sit on one baseline, which is how v2 set them. */
.step__t{display:flex;align-items:baseline;gap:clamp(11px,1.2vw,16px);min-width:0}
.step__n{
  position:relative;flex:none;
  font-family:var(--mono);font-size:var(--fs-mono);font-weight:500;letter-spacing:.16em;
  color:var(--fg-3);transition:color var(--t-med) var(--ease-io);
}
/* v2 coloured the number itself. That worked because it sat on near black;
   on paper three of the five land between 3.7 and 4.1 to one, which is under
   the bar this file holds all type to. So the colour goes where colour is
   allowed to go on this site, into the marker and the rail, and the number
   says "reached" by moving from tertiary ink to primary instead. Same signal,
   read at 15.8 to one rather than 3.7. */
.step[data-on="true"] .step__n{color:var(--fg)}
/* The node ties the row to the line. Hanging it off the number rather than off
   the row means it centres on that line by itself, at any type size and in
   either language, with nothing to keep in step by hand. */
.step__n::before{
  content:"";position:absolute;z-index:1;
  left:calc(var(--rail-x) - var(--rail-pad) - 6px);
  top:50%;
  width:14px;height:14px;border-radius:50%;box-sizing:border-box;
  background:var(--bg);border:2px solid var(--line);
  transform:translateY(-50%);
  transition:border-color var(--t-med) var(--ease-io),
             background-color var(--t-med) var(--ease-io),
             transform var(--t-med) var(--spring);
}
.step[data-on="true"] .step__n::before{
  background:var(--sc);border-color:var(--sc);transform:translateY(-50%) scale(1.14);
}
.step__h{
  margin:0;font-family:var(--display);font-weight:700;letter-spacing:-.03em;line-height:1.1;
  font-size:clamp(1.5rem,3.4vw,2.6rem);
  transition:color var(--t-med) var(--ease-io);
}
.step p{margin:0;font-size:var(--fs-md);line-height:1.55;color:var(--fg-2);max-width:46ch}
/* Narrow: the description drops under the title and lines up with it rather
   than with the number, so the column edge the eye follows stays put. */
@media (max-width:819px){
  .step{grid-template-columns:1fr}
  .step p{margin-left:calc(var(--fs-mono) * 1.7 + clamp(11px,1.2vw,16px))}
}
/* No scroll to read from: show the line complete and every step lit, so the
   section still says what it says. */
@media (prefers-reduced-motion:reduce){
  .proc__rail i{clip-path:none!important}
  .step__n{color:var(--sc)}
  .step__n::before{background:var(--sc);border-color:var(--sc)}
}

/* ═══ WHY ═════════════════════════════════════════════════════════════════ */
/* ═══ ABOUT ═══════════════════════════════════════════════════════════════
   One section, three panels, one switch between them. */
.abt{
  position:relative;display:flex;align-items:center;flex-wrap:wrap;
  margin-top:clamp(12px,1.8vh,20px);border-bottom:1px solid var(--line-soft);
}
.abt__b{
  position:relative;z-index:1;
  font-family:var(--mono);font-size:var(--fs-xs);font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;white-space:nowrap;
  padding:11px 15px;color:var(--fg-3);
  transition:color var(--t-med) var(--ease-io);
}
.abt__b:first-child{padding-left:0}
.abt__b:hover{color:var(--fg-2)}
.abt__b[aria-selected="true"]{color:var(--fg)}
/* One rule slides under the selected tab, the way the header's segmented
   control moves one knob rather than lighting each cell in turn. */
.abt__ink{
  position:absolute;z-index:0;left:0;bottom:-1px;height:2px;
  background:var(--accent);border-radius:2px;pointer-events:none;
  transition:transform var(--t-med) var(--spring),width var(--t-med) var(--spring);
}
.abt[data-ready="false"] .abt__ink{opacity:0}

.abp{margin-top:clamp(16px,2.4vh,28px)}
.abp__p + .abp__p{margin-top:clamp(26px,4vh,44px)}
/* With script the panels stack in one place and the box is told the height of
   whichever one is showing, so the section is only ever as tall as what is on
   screen and the change of height is part of the same move as the fade.
   Without script they simply follow one another and all three read, which is
   the honest fallback for a switch. Visibility rather than display keeps the
   fade animatable while still taking the hidden panels out of the reading
   order and off the tab ring. */
.js .abp{position:relative;overflow:hidden;transition:height var(--t-slow) var(--ease)}
.js .abp__p{
  position:absolute;inset:0 0 auto 0;margin-top:0;
  opacity:0;visibility:hidden;transform:translateY(12px);pointer-events:none;
  transition:opacity var(--t-med) var(--ease-io),
             transform var(--t-med) var(--ease),
             visibility 0s linear var(--t-med);
}
.js .abp__p[data-on="true"]{
  opacity:1;visibility:visible;transform:none;pointer-events:auto;
  transition:opacity var(--t-med) var(--ease-io),
             transform var(--t-slow) var(--ease),
             visibility 0s;
}

/* ── the six reasons ─────────────────────────────────────────────────────── */
.why{display:grid;gap:clamp(15px,2vw,30px);grid-template-columns:repeat(3,1fr);
  margin-top:clamp(16px,2.4vh,32px)}
.why div{border-top:1px solid var(--line);padding-top:13px;
  display:grid;grid-template-columns:auto 1fr;column-gap:13px;align-content:start}
.why h3{margin:0;grid-column:2;align-self:center}
.why p{margin:7px 0 0;grid-column:2;font-size:var(--fs-sm);line-height:1.5;color:var(--fg-2)}
@media (max-width:900px){.why{grid-template-columns:1fr 1fr}}
/* One column means six rows stacked, and the section still owes the brief a
   single viewport. The rows tighten rather than the section growing a scroll
   of its own; the mark keeps its size, since shrinking that is what would
   actually read as cramped. */
@media (max-width:520px){
  .why{grid-template-columns:1fr;gap:10px}
  .why div{padding-top:10px}
  .why p{margin-top:5px}
  .abt__b{padding:9px 12px}
}

/* ── the marks ────────────────────────────────────────────────────────────
   A mark is two things: the silhouette, and the tile it sits on. Both arrive
   on the reveal the row already runs, a beat behind its words, so the row
   reads first and the mark resolves under it instead of competing with it.
   The tile opens first and the glyph settles into it, which is the whole of
   the effect: two short moves, offset, neither of them large. */
.wic{
  grid-column:1;grid-row:1 / span 2;align-self:start;
  position:relative;display:grid;place-items:center;
  width:34px;height:34px;color:var(--accent-text);
}
.wic::before{
  content:"";position:absolute;inset:0;border-radius:var(--r-md);
  background:color-mix(in srgb,var(--accent) 15%,transparent);
  transform:scale(.55);opacity:0;
  transition:transform .72s var(--spring),opacity .5s var(--ease-io);
  transition-delay:.12s;
}
@supports not (background:color-mix(in srgb,red 15%,transparent)){
  .wic::before{background:var(--chip)}
}
.wic__g{
  position:relative;width:20px;height:20px;display:block;
  opacity:0;transform:scale(.6) rotate(-14deg);
  transition:transform .66s var(--spring),opacity .44s var(--ease-io);
  transition-delay:.2s;
}
.why div.in .wic::before{transform:none;opacity:1}
.why div.in .wic__g{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  .wic::before,.wic__g{opacity:1;transform:none}
}

/* ═══ WHO / AI ════════════════════════════════════════════════════════════ */
.who{font-size:var(--fs-sm);font-weight:300;line-height:1.5;color:var(--fg-3);
  max-width:46ch;margin:clamp(18px,2.6vh,30px) 0 0}


/* ═══ WORK ════════════════════════════════════════════════════════════════
   Two views on one section: a grid of cards, and one project in detail.
   The URL hash is the source of truth, so every project is linkable and the
   back button behaves. */
#work{padding-bottom:clamp(60px,10vh,120px)}
.work__head{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;flex-wrap:wrap}
.pcount{font-size:var(--fs-sm);color:var(--fg-3);margin-top:12px}

.menu-grid{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(30px,3.4vw,52px);
  margin-top:clamp(26px,4vh,48px);
}
@media(max-width:940px){.menu-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:620px){.menu-grid{grid-template-columns:1fr}}

.pcard{
  display:flex;flex-direction:column;border-radius:var(--r-lg);overflow:hidden;
  background:var(--bg-raise);border:1px solid var(--line-soft);
  transition:transform var(--t-med) var(--ease), box-shadow var(--t-med) var(--ease-io),
             border-color var(--t-med) var(--ease-io);
  will-change:transform;
}
.pcard:hover{transform:translateY(-4px);box-shadow:var(--shadow-2);border-color:var(--line)}
.pcard:active{transform:translateY(-1px)}
.pcard-img{aspect-ratio:16/10;overflow:hidden;background:var(--bg-sunk);
  border-bottom:1px solid var(--line-soft)}
.pcard-img img{width:100%;height:100%;object-fit:cover;
  transition:transform .7s var(--ease)}
.pcard:hover .pcard-img img{transform:scale(1.045)}
.pcard-body{padding:20px 20px 22px;display:flex;flex-direction:column;flex:1}
.pcard-client{
  font-family:var(--mono);font-size:10.5px;color:var(--accent-text);font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;margin-bottom:9px;
}
.pcard-title{font-family:var(--display);font-size:var(--fs-h3);font-weight:600;text-wrap:balance;
  letter-spacing:-.022em;line-height:1.25;margin-bottom:10px}
.pcard-tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:auto}
.pcard-go{
  font-size:var(--fs-xs);color:var(--accent-text);font-weight:500;margin-top:18px;
  display:flex;align-items:center;gap:7px;
}
.pcard-go span:last-child{transition:transform var(--t-med) var(--spring)}
.pcard:hover .pcard-go span:last-child{transform:translateX(4px)}

/* ── tags ──────────────────────────────────────────────────────────────── */
.tag{
  font-size:var(--fs-xs);color:var(--fg-2);background:var(--chip);
  padding:5px 12px;border-radius:var(--r-pill);line-height:1.4;
  border:1px solid var(--line-soft);
}
.pcard-tags .tag{font-size:11px;padding:4px 10px}

/* ── detail ────────────────────────────────────────────────────────────── */
.backbar{
  position:sticky;top:var(--hdr);z-index:60;
  display:flex;align-items:center;gap:14px;
  padding:13px 0;margin-bottom:10px;
  background:var(--bg-blur);
  -webkit-backdrop-filter:saturate(180%) blur(20px);
  backdrop-filter:saturate(180%) blur(20px);
  border-bottom:1px solid var(--line-soft);
}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .backbar{background:var(--bg)}
}
.backbar::before{
  /* bleed the bar to the viewport edges without leaving the content column */
  content:"";position:absolute;top:0;bottom:0;left:calc(var(--edge)*-1);right:calc(var(--edge)*-1);
  background:inherit;border-bottom:inherit;z-index:-1;
}
.btn-back{
  display:inline-flex;align-items:center;gap:8px;font-size:var(--fs-sm);color:var(--fg-2);
  padding:6px 12px 6px 10px;border-radius:var(--r-pill);border:1px solid var(--line);
  transition:color var(--t-fast), border-color var(--t-fast), background-color var(--t-fast);
  white-space:nowrap;flex:none;
}
.btn-back:hover{color:var(--fg);border-color:var(--fg);background:var(--chip)}
.backbar-title{font-size:var(--fs-sm);color:var(--fg-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media(max-width:640px){.backbar-title{display:none}}

.proj{padding-top:clamp(24px,4vh,44px)}
.pnum{
  font-family:var(--mono);font-size:var(--fs-mono);color:var(--fg-3);font-weight:500;
  letter-spacing:.14em;font-variant-numeric:tabular-nums;margin-bottom:14px;text-transform:uppercase;
}
.pclient{font-family:var(--display);font-size:var(--fs-sm);color:var(--accent-text);
  font-weight:600;margin-bottom:10px;letter-spacing:.01em}
.proj h3{font-family:var(--display);font-weight:700;letter-spacing:-.03em;line-height:1.1;
  font-size:var(--fs-h2);max-width:24ch;margin:0}
.pdesc{font-size:var(--fs-md);color:var(--fg-2);line-height:1.62;max-width:66ch;margin-top:20px}
.tags{display:flex;flex-wrap:wrap;gap:7px;margin-top:24px}

.cover{
  margin-top:clamp(26px,4vh,44px);border-radius:var(--r-lg);overflow:hidden;
  background:var(--bg-sunk);border:1px solid var(--line-soft);box-shadow:var(--shadow-1);
}
/* The wrapper is the control; it must not disturb the layout the image had. */
.zoom{display:block;width:100%;padding:0;border:0;background:none;cursor:zoom-in;
  border-radius:inherit;overflow:hidden;line-height:0}
.zoom:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
.cover img{width:100%;height:auto;transition:transform .7s var(--ease)}
.cover:hover img,.cover .zoom:focus-visible img{transform:scale(1.012)}
.gal{display:grid;grid-template-columns:repeat(2,1fr);gap:18px;margin-top:18px}
.gal.solo{grid-template-columns:1fr}
@media(max-width:700px){.gal{grid-template-columns:1fr}}
.gal figure{margin:0;display:flex;flex-direction:column;gap:10px}
.gal .zoom{border-radius:var(--r-md);overflow:visible}
.gal img{
  width:100%;height:auto;border-radius:var(--r-md);
  border:1px solid var(--line-soft);background:var(--bg-sunk);
  transition:transform var(--t-med) var(--ease), box-shadow var(--t-med) var(--ease-io);
}
.gal .zoom:hover img,.gal .zoom:focus-visible img{transform:translateY(-3px);box-shadow:var(--shadow-2)}
.gal figcaption,.vwrap figcaption{font-size:var(--fs-xs);color:var(--fg-3);line-height:1.5}

.vwrap{margin-top:clamp(26px,4vh,44px);display:flex;flex-direction:column;gap:12px}
/* Same well as the reel, and it was carrying the same fault twice over: a real
   border and an inset ring, both of them a lightening, around a box that sits
   darker than the page. One ring, darkening, exactly as the reel does it. */
.vwrap .vid{
  display:block;width:100%;aspect-ratio:16/9;border-radius:var(--r-lg);overflow:hidden;
  background:var(--bg-sunk);box-shadow:inset 0 0 0 1px var(--well-edge);position:relative;
}

/* pull quotes and notes */
.note{
  margin-top:clamp(26px,4vh,44px);padding:clamp(20px,2.4vw,30px);
  border-radius:var(--r-lg);background:var(--bg-raise);border:1px solid var(--line-soft);
  max-width:72ch;
}
.note.quote{border-left:3px solid var(--accent)}
.note .nt{
  font-family:var(--mono);font-size:var(--fs-mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--fg-3);margin-bottom:12px;
}
.note p{font-size:var(--fs-md);line-height:1.6;color:var(--fg)}
.note.quote p{font-family:var(--display);font-weight:500;font-size:var(--fs-lg);letter-spacing:-.018em}
.note .aut{margin-top:12px;font-size:var(--fs-sm);color:var(--fg-3)}
.backfoot{margin-top:clamp(30px,5vh,56px);padding-top:clamp(20px,3vh,32px);
  border-top:1px solid var(--line-soft)}

/* ═══ LIGHTBOX ════════════════════════════════════════════════════════════ */
.lb{
  position:fixed;inset:0;z-index:200;background:rgba(13,13,13,.94);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  display:grid;place-items:center;padding:clamp(16px,4vw,48px);
  opacity:0;visibility:hidden;
  transition:opacity var(--t-med) var(--ease-io), visibility 0s linear var(--t-med);
}
.lb.on{opacity:1;visibility:visible;transition-delay:0s}
.lb__fig{margin:0;display:flex;flex-direction:column;align-items:center;gap:18px;max-height:100%}
.lb img{max-width:min(96vw,1500px);max-height:80vh;width:auto;height:auto;
  border-radius:var(--r-md);object-fit:contain;box-shadow:0 30px 90px rgba(0,0,0,.5)}
.lb figcaption{
  color:rgba(251,250,247,.72);font-size:var(--fs-sm);text-align:center;
  max-width:min(680px,88vw);line-height:1.5;
}
.lb__btn{
  position:absolute;background:rgba(250,250,250,.12);color:#fafafa;
  border-radius:50%;width:44px;height:44px;font-size:19px;
  display:grid;place-items:center;
  transition:background-color var(--t-fast), transform var(--t-fast) var(--spring);
}
.lb__btn:hover{background:rgba(250,250,250,.26);transform:scale(1.06)}
.lb__btn:focus-visible{outline-color:#fafafa}
.lb__x{top:clamp(14px,2.4vw,26px);right:clamp(14px,2.4vw,26px)}
.lb__prev{left:clamp(10px,2vw,26px);top:50%;transform:translateY(-50%)}
.lb__next{right:clamp(10px,2vw,26px);top:50%;transform:translateY(-50%)}
.lb__prev:hover,.lb__next:hover{transform:translateY(-50%) scale(1.06)}
.lb__count{position:absolute;top:clamp(14px,2.4vw,26px);left:clamp(14px,2.4vw,26px);
  color:rgba(251,250,247,.6)}


/* ═══ CONTACT ═════════════════════════════════════════════════════════════ */
#contact{padding-bottom:0}
.book{display:grid;gap:clamp(30px,4vw,68px);align-items:start}
@media(min-width:1000px){.book{grid-template-columns:1.02fr .98fr}}

.ans{display:flex;flex-direction:column;gap:10px;margin:clamp(18px,2.4vh,26px) 0 0}
.ans li{position:relative;padding-left:24px;font-size:var(--fs-md);font-weight:300;color:var(--fg-2)}
.ans li::before{content:"";position:absolute;left:0;top:.66em;width:12px;height:1px;background:var(--accent)}

.det{
  display:grid;gap:clamp(14px,2vw,30px);grid-template-columns:repeat(3,1fr);
  margin-top:clamp(16px,2.4vh,38px);padding-top:clamp(12px,1.7vh,22px);
  border-top:1px solid var(--line);
}
.det dt{color:var(--fg-3);margin-bottom:7px}
.det dd{margin:0;font-size:var(--fs-md);font-weight:300}
.det a{border-bottom:1px solid var(--line);transition:border-color var(--t-fast)}
.det a:hover{border-color:currentColor}
@media(max-width:640px){.det{grid-template-columns:1fr;gap:14px}}

/* ── diagnostic ────────────────────────────────────────────────────────── */
.dx{
  border:1px solid var(--line);border-radius:var(--r-lg);
  background:var(--bg-raise);padding:clamp(16px,1.8vw,26px);
  /* The floor stops the card collapsing between the short steps; it is not
     there to hold the tall ones, which have always grown past it. Sized to the
     opening step rather than to a share of the screen, so the closing view is
     as tall as it needs to be and not 70px more. */
  min-height:clamp(360px,46vh,470px);
  display:flex;flex-direction:column;height:auto;
  box-shadow:var(--shadow-1);
}
.dx__bar{display:flex;gap:6px;margin-bottom:clamp(20px,2.6vh,30px)}
.dx__bar i{flex:1;height:2px;background:var(--line);border-radius:2px;
  transition:background-color .45s var(--ease)}
.dx__bar i.on{background:var(--fg)}
.dx__step{display:none;flex-direction:column;gap:clamp(10px,1.3vh,14px);flex:1}
.dx__step.on{display:flex;animation:dxIn .42s var(--ease) both}
@keyframes dxIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.dx__q{font-family:var(--display);font-weight:600;letter-spacing:-.022em;margin:0;
  font-size:clamp(1.15rem,1.7vw,1.5rem);line-height:1.2}
.dx__hint{margin:0;color:var(--fg-3);font-size:var(--fs-xs)}
/* A <legend> is the fieldset's caption, not a flex item, so the column gap
   never applied to it and every question sat flush against its first answer. */
.dx__step > legend.dx__q{margin-bottom:clamp(10px,1.4vh,15px);padding:0;float:none;width:100%}
.dx__opts{display:flex;flex-direction:column;gap:9px;margin:0}
.dx__opt{
  display:flex;align-items:center;gap:12px;padding:13px 16px;cursor:pointer;
  border:1px solid var(--line);border-radius:var(--r-md);
  font-size:var(--fs-sm);font-weight:300;position:relative;
  transition:border-color var(--t-fast), background-color var(--t-fast);
}
.dx__opt:hover{border-color:var(--fg-3);background:var(--chip)}
.dx__opt input{position:absolute;opacity:0;width:0;height:0}
.dx__opt s{
  flex:none;width:16px;height:16px;border:1.5px solid var(--fg-3);border-radius:50%;
  display:block;text-decoration:none;
  transition:border-color var(--t-fast), box-shadow var(--t-fast);
}
.dx__opt.multi s{border-radius:5px}
.dx__opt:has(input:checked){border-color:var(--fg);background:var(--chip)}
.dx__opt:has(input:checked) s{border-color:var(--fg);box-shadow:inset 0 0 0 4px var(--fg)}
.dx__opt:has(input:focus-visible){outline:2px solid var(--focus);outline-offset:2px}
/* :has() is everywhere current, but the state must still be legible without it. */
@supports not selector(:has(*)){
  .dx__opt input:checked ~ s{border-color:var(--fg);box-shadow:inset 0 0 0 4px var(--fg)}
  .dx__opt input:focus-visible ~ s{outline:2px solid var(--focus);outline-offset:2px}
}

/* Eighteen deliverables will not fit as stacked rows, so this step reads as
   grouped chips and scrolls inside the card rather than stretching it. */
.dx__groups{display:flex;flex-direction:column;gap:14px}
.dx__g{display:flex;flex-direction:column;gap:7px}
.dx__gl{margin:0;font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--fg-3)}
.dx__opts--chips{flex-direction:row;flex-wrap:wrap;gap:7px}
.dx__opts--chips .dx__opt{padding:8px 13px;gap:8px;border-radius:var(--r-pill)}
.dx__opts--chips .dx__opt s{width:13px;height:13px;border-width:1.4px;border-radius:4px}
.dx__opts--chips .dx__opt:has(input:checked) s{box-shadow:inset 0 0 0 3px var(--fg)}
@supports not selector(:has(*)){
  .dx__opts--chips .dx__opt input:checked ~ s{box-shadow:inset 0 0 0 3px var(--fg)}
}

.dx__in{display:flex;flex-direction:column;gap:10px}
.dx__in input{
  font-size:var(--fs-sm);font-weight:300;color:var(--fg);background:var(--bg);
  border:1px solid var(--line);border-radius:var(--r-md);padding:13px 16px;width:100%;
  transition:border-color var(--t-fast), box-shadow var(--t-fast);
}
.dx__in input::placeholder{color:var(--fg-3)}
.dx__in input:focus-visible{outline:none;border-color:var(--focus);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--focus) 26%,transparent)}
.dx__in input[aria-invalid="true"]{border-color:var(--d2)}

/* The step shakes once when it is not answered, and says why. */
.dx__step.nudge{animation:dxShake .42s var(--ease-io)}
@keyframes dxShake{0%,100%{transform:translateX(0)}20%{transform:translateX(-7px)}
  40%{transform:translateX(6px)}60%{transform:translateX(-4px)}80%{transform:translateX(2px)}}
.dx__err{margin:0;font-size:var(--fs-xs);color:var(--d2);min-height:1.3em}
.dx__err:empty{min-height:0}
@media (prefers-reduced-motion:reduce){
  .dx__step.on{animation:none}
  .dx__step.nudge{animation:none}
  .dx__bar i{transition:none}
}

.dx__nav{display:flex;align-items:center;gap:16px;margin-top:auto;padding-top:clamp(12px,1.6vh,20px)}
.dx__back{color:var(--fg-3);font-size:var(--fs-sm);padding:6px 4px;border-radius:var(--r-sm);
  transition:color var(--t-fast)}
.dx__back:hover{color:var(--fg)}
.dx__cal{flex:1;display:flex;flex-direction:column;gap:12px;min-height:clamp(400px,48vh,540px)}
.dx__fallback{margin:auto;display:flex;flex-direction:column;align-items:flex-start;gap:14px;
  padding:clamp(18px,2.4vw,28px);border:1px solid var(--line);border-radius:var(--r-md);
  background:var(--bg)}
.dx__fallback p{margin:0;font-size:var(--fs-sm);color:var(--fg-2);max-width:40ch}
.sched__l{margin:0 0 clamp(8px,1.2vh,14px);color:var(--fg-3)}

/* ═══ THE CLOSING SCREEN ══════════════════════════════════════════════════
   Contact and the footer are one screen, not two things that happen to follow
   each other. Scrolled to the end you should see the whole invitation, the
   form, and the footer, with nothing clipped under the fixed bar.

   So the section is at least a screen tall and the footer is pushed to the
   foot of it. The slack lands between the form and the footer rather than
   below the fold, and the section stops growing past a screen the moment its
   content fits inside one. Under that, .book keeps a floor on the gap, so an
   overflowing screen still separates the two blocks. */
/* The bar is measured at --hdr-tall here, not --hdr. Every other section is
   read while scrolling, so the compact bar is what sits over it; this one is
   read at the end of the document, where readScroll deliberately opens the
   masthead again. Padding for the collapsed height is what put the eyebrow and
   the top of the headline underneath it. */
#contact{min-height:100svh;padding-block:calc(var(--hdr-tall) + clamp(8px,1.6vh,22px)) 0}
#contact > .wrap{flex:1;display:flex;flex-direction:column;min-height:0}
#contact > .wrap > .book{margin-bottom:clamp(14px,2.4vh,48px)}
/* The closing headline is sized off the width like every other h1, which on a
   short wide screen is the one place that costs more than it can afford. A
   height cap lets it step down only where the room actually runs out; on a
   tall screen the min never binds and the type is untouched. */
#contact .h1{font-size:min(var(--fs-h1),7.6vh)}
/* A short screen still has to hold the whole closing view, so it gives in the
   gaps of the footer's link lists and the form's rule and fields. Never in the
   type, and never in the height of anything you tap. Scoped by height, so a
   tall screen keeps the roomier setting untouched. */
@media (max-height:820px){
  /* Scoped through #contact so these win over the footer rules further down
     the sheet, which carry the same specificity and would otherwise take it
     on source order alone. */
  #contact .foot__nav{gap:5px}
  #contact .dx__bar{margin-bottom:12px}
  #contact .dx__in{gap:8px}
}
#contact .foot{margin-top:auto}

/* ═══ FOOTER ══════════════════════════════════════════════════════════════ */
.foot{
  margin-top:clamp(48px,8vh,110px);
  border-top:1px solid var(--line);
  color:var(--fg-3);font-size:var(--fs-sm);
}
.foot a{color:var(--fg-3);transition:color var(--t-fast) var(--ease-io)}
.foot a:hover{color:var(--fg)}
.foot__top{
  display:grid;gap:clamp(26px,4vw,64px);
  grid-template-columns:minmax(0,1.6fr) repeat(2,minmax(0,1fr));
  padding:clamp(18px,2.6vh,34px) 0 clamp(16px,2.2vh,28px);
}
@media(max-width:720px){.foot__top{grid-template-columns:1fr 1fr}
  .foot__brand{grid-column:1/-1}}
.foot__brand{display:flex;flex-direction:column;gap:12px;align-items:flex-start}
.foot__z{display:block;color:var(--fg)}
.foot__z .zmark{height:clamp(30px,3.6vw,40px)}
.foot__tag{margin:0;color:var(--fg-2);font-family:var(--display);
  font-size:var(--fs-lg);letter-spacing:-.022em;max-width:22ch;text-wrap:balance}
.foot__nav{display:flex;flex-direction:column;gap:9px;align-items:flex-start}
.foot__h{margin:0 0 4px;font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--accent-text)}
.foot__place{margin:0;color:var(--fg-3)}
/* The base row closes the page on its own now; the oversized sign off
   wordmark that used to sit above it is gone, so this rule carries the rule
   line that used to belong to it. */
.foot__base{
  border-top:1px solid var(--line-soft);
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  /* The parent company line closes the page now, so this row no longer has to
     carry the bottom margin of the whole site. The closing screen is measured
     to one viewport and every pixel here comes out of it. */
  flex-wrap:wrap;padding:clamp(10px,1.5vh,18px) 0 clamp(8px,1.1vh,14px);
  font-size:var(--fs-xs);
}
.foot__made{display:inline-flex;align-items:center;gap:8px}
/* a slow pulse, the only thing on the page that keeps time */
.foot__dot{
  width:6px;height:6px;border-radius:50%;background:var(--accent);flex:none;
  animation:footPulse 3.4s var(--ease-io) infinite;
}
@keyframes footPulse{0%,100%{opacity:.35;transform:scale(.82)}50%{opacity:1;transform:scale(1)}}
.foot__up{display:inline-flex;align-items:center;gap:7px}
.foot__up i{transition:transform var(--t-med) var(--spring);display:inline-block}
.foot__up:hover i{transform:translateY(-3px)}
@media (prefers-reduced-motion:reduce){
  .foot__dot{animation:none;opacity:.8}
  .foot__up i{transition:none}
}
.foot a:hover{color:var(--fg)}

/* ═══ BILINGUAL MARKUP ════════════════════════════════════════════════════
   Long-form project copy carries both languages in the markup. The rule is
   written symmetrically so neither language is the implicit default and
   nothing is ever shown twice. */
.t>[data-l]{display:none}
html[lang="en"] .t>[data-l="en"]{display:inline}
html[lang="es"] .t>[data-l="es"]{display:inline}


/* ═══════════════════════════════════════════════════════════════════════════
   v11 ADDITIONS
   ═══════════════════════════════════════════════════════════════════════════ */

/* ═══ POPUP MENU ═══════════════════════════════════════════════════════════
   The trigger sits in the fixed bar, so it is reachable from any scroll
   position without a second floating object competing with the rail. */
.mbtn{
  display:inline-flex;align-items:center;gap:9px;flex:none;
  padding:7px 13px 7px 11px;border-radius:var(--r-pill);
  border:1px solid var(--line);background:transparent;color:var(--fg);
  font-size:var(--fs-xs);font-weight:500;
  transition:border-color var(--t-fast) var(--ease-io),
             background-color var(--t-fast) var(--ease-io);
}
.mbtn:hover{border-color:var(--fg);background:var(--chip)}
.mbtn__w{white-space:nowrap}
/* Three rules that become two crossed ones. Each bar owns its own transform,
   so the move is one continuous gesture rather than a swap of two icons. */
.mbtn__ico{display:block;position:relative;width:16px;height:12px;flex:none}
.mbtn__ico i{
  position:absolute;left:0;right:0;height:1.5px;border-radius:2px;background:currentColor;
  transition:transform var(--t-med) var(--spring), opacity var(--t-fast) var(--ease-io);
}
.mbtn__ico i:nth-child(1){top:0}
.mbtn__ico i:nth-child(2){top:5.25px}
.mbtn__ico i:nth-child(3){top:10.5px}
.mbtn[aria-expanded="true"] .mbtn__ico i:nth-child(1){transform:translateY(5.25px) rotate(45deg)}
.mbtn[aria-expanded="true"] .mbtn__ico i:nth-child(2){opacity:0;transform:scaleX(.3)}
.mbtn[aria-expanded="true"] .mbtn__ico i:nth-child(3){transform:translateY(-5.25px) rotate(-45deg)}

.mpop{position:fixed;inset:0;z-index:300;display:block}
.mpop[hidden]{display:none !important}
.mpop__scrim{
  position:absolute;inset:0;background:rgba(0,0,0,.5);
  opacity:0;transition:opacity var(--t-med) var(--ease-io);
  -webkit-backdrop-filter:blur(0px);backdrop-filter:blur(0px);
}
.mpop.on .mpop__scrim{
  opacity:1;-webkit-backdrop-filter:blur(14px) saturate(150%);backdrop-filter:blur(14px) saturate(150%);
  transition:opacity var(--t-med) var(--ease-io),
             backdrop-filter var(--t-slow) var(--ease-io),
             -webkit-backdrop-filter var(--t-slow) var(--ease-io);
}
/* The panel opens from the corner the button is in, so the gesture reads as
   the button unfolding rather than as a sheet arriving from nowhere. Small
   move, long ease: subtle is the brief. */
.mpop__panel{
  position:absolute;top:calc(var(--hdr) + 10px);right:var(--edge);
  width:min(760px, calc(100vw - var(--edge) * 2));
  max-height:calc(100svh - var(--hdr) - 26px);overflow:auto;overscroll-behavior:contain;
  padding:clamp(24px,3vw,38px) clamp(22px,3vw,38px) clamp(26px,3.4vw,40px);
  border-radius:var(--r-lg);border:1px solid var(--line);
  background:var(--bg-raise);color:var(--fg);box-shadow:var(--shadow-2);
  transform-origin:100% 0;
  opacity:0;transform:translateY(-10px) scale(.97);
  transition:opacity var(--t-fast) var(--ease-io), transform var(--t-med) var(--ease);
}
.mpop.on .mpop__panel{
  opacity:1;transform:none;
  transition:opacity var(--t-med) var(--ease-io), transform var(--t-slow) var(--spring);
}
.mpop__h{
  font-family:var(--display);font-weight:700;letter-spacing:-.03em;
  font-size:var(--fs-h3);margin:0 44px 4px 0;
}
.mpop__x{
  position:absolute;top:clamp(16px,2vw,24px);right:clamp(16px,2vw,24px);
  width:34px;height:34px;border-radius:50%;display:grid;place-items:center;
  border:1px solid var(--line);color:var(--fg-2);font-size:13px;
  transition:color var(--t-fast),border-color var(--t-fast),transform var(--t-med) var(--spring);
}
.mpop__x:hover{color:var(--fg);border-color:var(--fg);transform:rotate(90deg)}

.mpop__cols{display:grid;grid-template-columns:1fr 1.15fr;gap:clamp(22px,3vw,44px);margin-top:clamp(16px,2vw,24px)}
@media (max-width:720px){.mpop__cols{grid-template-columns:1fr;gap:26px}}
.mpop__l{color:var(--fg-3);margin:0 0 10px}
.mpop__nav{display:flex;flex-direction:column}

/* Every row inside the panel arrives on the same stagger, keyed off --i, so
   the list resolves top to bottom instead of appearing all at once. On close
   the delay is dropped and everything leaves together. */
.mpop__a,.mq,.mpop__pref{
  opacity:0;transform:translateY(9px);
  transition:opacity .3s var(--ease-io), transform .42s var(--ease);
}
.mpop.on .mpop__a,.mpop.on .mq,.mpop.on .mpop__pref{
  opacity:1;transform:none;transition-delay:calc(var(--i,0) * 26ms + 60ms);
}
.mpop__a{
  display:flex;align-items:baseline;gap:12px;
  padding:9px 10px;margin-inline:-10px;border-radius:var(--r-sm);
  font-family:var(--display);font-size:var(--fs-lg);font-weight:600;letter-spacing:-.02em;
  color:var(--fg-2);
  transition:opacity .3s var(--ease-io), transform .42s var(--ease),
             color var(--t-fast) var(--ease-io), background-color var(--t-fast) var(--ease-io);
}
.mpop__a b{color:var(--fg-3);font-weight:500;flex:none;transition:color var(--t-fast)}
.mpop__a:hover{color:var(--fg);background:var(--chip)}
.mpop__a:hover b{color:var(--accent-text)}
.mpop__a[aria-current="true"]{color:var(--fg)}
.mpop__a[aria-current="true"] b{color:var(--accent-text)}

.mpop__quick{display:flex;flex-direction:column;gap:8px}
.mq{
  display:flex;align-items:center;gap:13px;padding:11px 13px;
  border-radius:var(--r-md);border:1px solid var(--line-soft);background:var(--bg);
  transition:opacity .3s var(--ease-io), transform .42s var(--ease),
             border-color var(--t-fast) var(--ease-io), background-color var(--t-fast) var(--ease-io);
}
.mpop.on .mq:hover{border-color:var(--line);background:var(--chip);transform:translateX(3px)}
.mq__ico{
  width:32px;height:32px;flex:none;border-radius:var(--r-sm);display:grid;place-items:center;
  background:var(--chip);color:var(--fg-2);
}
.mq__ico svg{width:17px;height:17px}
.mq--go .mq__ico{background:var(--accent);color:var(--accent-ink)}
.mq__t{display:flex;flex-direction:column;gap:2px;min-width:0}
.mq__t b{font-size:var(--fs-sm);font-weight:500;color:var(--fg)}
.mq__t i{
  font-style:normal;font-size:var(--fs-xs);color:var(--fg-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.mpop__prefs{display:flex;flex-wrap:wrap;gap:10px}
.mpop__prefs .seg--theme .seg__word{display:inline}
.mpop__prefs .seg--theme .seg__ico{display:none}

@media (max-width:560px){
  .mpop__panel{
    top:auto;bottom:0;right:0;left:0;width:auto;
    max-height:88svh;border-radius:var(--r-lg) var(--r-lg) 0 0;
    transform-origin:50% 100%;transform:translateY(18px) scale(1);
  }
  .mpop__a{font-size:var(--fs-md)}
}
@media (prefers-reduced-motion:reduce){
  .mpop__panel,.mpop__scrim,.mpop__a,.mq,.mpop__pref,.mbtn__ico i{transition:none}
  .mpop__a,.mq,.mpop__pref{opacity:1;transform:none}
}

/* The header carries the menu now, so below the tablet break the two
   segmented controls stand down and live inside the panel instead. */
@media (max-width:760px){
  .hdr .seg{display:none}
  .mbtn__w{display:none}
  .mbtn{padding:8px 10px}
}

/* ═══ MANIFESTO ════════════════════════════════════════════════════════════ */
.man__h{max-width:22ch}
.man{display:grid;gap:clamp(14px,2vw,22px);grid-template-columns:repeat(3,1fr);
  margin-top:clamp(20px,3vh,34px)}
@media (max-width:820px){.man{grid-template-columns:1fr;gap:12px}}
.man__i{display:grid;grid-template-columns:auto 1fr;gap:14px;
  border-top:1px solid var(--line);padding-top:14px}
.man__i b{color:var(--accent-text);font-weight:500}
.man__i h3{margin:0}
.man__i p{margin:6px 0 0;font-size:var(--fs-sm);line-height:1.5;color:var(--fg-2)}
.man__q{
  margin:clamp(20px,3vh,32px) 0 0;font-family:var(--display);font-weight:600;
  font-size:var(--fs-h3);letter-spacing:-.02em;color:var(--fg);
  padding-left:16px;border-left:2px solid var(--accent);
}

/* ═══ TEAM ═════════════════════════════════════════════════════════════════
   The reference is a row of dark cards with the portrait in monochrome, the
   name in the display face and the role set in italic under it. Photos are
   dropped into img/team/ — until one is there the tile shows the initials, so
   the card is complete either way. */
.tm__head{text-align:center;margin-bottom:clamp(20px,3vh,34px)}
.tm__h{margin-inline:auto;max-width:none;position:relative;padding-bottom:14px}
.tm__h::after{
  content:"";position:absolute;left:50%;bottom:0;transform:translateX(-50%);
  width:clamp(90px,10vw,130px);height:2px;border-radius:2px;background:var(--accent);
}
.tm__sub{margin:16px 0 0;color:var(--fg-2);font-size:var(--fs-sm)}
.tm{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(14px,1.6vw,24px);align-items:start}
@media (max-width:1000px){.tm{grid-template-columns:repeat(2,1fr)}}
@media (max-width:520px){.tm{grid-template-columns:1fr}}
.tm__c{
  background:var(--bg-raise);border:1px solid var(--line-soft);
  border-radius:var(--r-lg);padding:clamp(16px,1.6vw,22px);
  transition:transform var(--t-med) var(--ease), border-color var(--t-med) var(--ease-io),
             box-shadow var(--t-med) var(--ease-io);
}
.tm__c:hover{transform:translateY(-3px);border-color:var(--line);box-shadow:var(--shadow-1)}
.tm__ph{
  position:relative;display:grid;place-items:center;
  aspect-ratio:1/1;width:100%;overflow:hidden;
  border-radius:var(--r-md);background:var(--bg-sunk);
}
/* The fallback is under the photo, not instead of it: if the file is missing
   the script drops the <img> and the monogram is simply what is left. */
.tm__ph::before{
  content:attr(data-mono);
  font-family:var(--display);font-weight:700;font-size:clamp(28px,3.6vw,42px);
  letter-spacing:-.04em;color:var(--fg-3);opacity:.5;
}
.tm__img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:grayscale(1) contrast(1.04);
  transition:filter var(--t-slow) var(--ease-io), transform .7s var(--ease);
}
.tm__c:hover .tm__img{transform:scale(1.03)}
.tm__n{
  font-family:var(--display);font-weight:700;letter-spacing:-.025em;line-height:1.15;
  font-size:var(--fs-h3);margin:16px 0 0;
}
.tm__r{margin:3px 0 0;font-style:italic;font-family:var(--display);font-weight:400;
  font-size:var(--fs-md);color:var(--fg-2);line-height:1.25}
.tm__d{margin:13px 0 0;font-size:var(--fs-sm);line-height:1.55;color:var(--fg-2)}
.tm__d u{text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:var(--line);color:var(--fg)}
.tm__d em{font-style:italic}
.tm__foot{
  margin:clamp(20px,3vh,30px) 0 0;font-size:var(--fs-sm);color:var(--fg-3);
  max-width:56ch;text-wrap:pretty;
}

/* ═══ AI — HUMAN · AI · HUMAN ══════════════════════════════════════════════
   The diagram is the argument, so it is built out of the page's own parts: a
   rule that runs through all three nodes, a fill the reader drives along it,
   and the middle node marked as the only one that is not a person. */
.hah{
  /* The rail has to start on the first node's marker and stop on the last
     one's, at any width, so the gap is a token the geometry can be written
     against rather than a number buried in the shorthand. With three equal
     columns the last marker sits at 2/3 of the track plus 2/3 of one gap,
     which is what the two calc()s below say and all they say. */
  --hg:clamp(16px,2.2vw,30px);
  --hah-dot:6.5px;                       /* half the marker, its centre line */
  /* How far the reader has driven the fill, and how tall the rail is when it
     stands up in one column. Both are written by the script on every frame;
     they are declared here so the stylesheet still resolves on its own, before
     the script has run or if it never does. */
  --p:0;
  --vlen:0px;
  position:relative;display:grid;grid-template-columns:repeat(3,1fr);
  gap:var(--hg);margin-top:clamp(26px,4vh,46px);
}
.hah::before{
  content:"";position:absolute;top:11px;height:1px;background:var(--line);z-index:0;
  left:var(--hah-dot);
  right:calc(33.333% - var(--hg) * 2 / 3 - var(--hah-dot));
}
/* The fill is the same idea as the method's rail, turned on its side: one
   coloured line uncovered by a wipe the reader drives with the scrollbar, and
   three nodes that light as it reaches them. It replaces the loop that used to
   run here on a clock of its own. The claim is the gesture, so it should be
   made when somebody is actually looking at it, and it should stop where they
   stop rather than keep going without them. */
.hah::after{
  content:"";position:absolute;top:11px;height:1px;z-index:1;
  left:var(--hah-dot);
  right:calc(33.333% - var(--hg) * 2 / 3 - var(--hah-dot));
  background:linear-gradient(90deg,var(--a1),var(--accent),var(--a4));
  clip-path:inset(0 calc((1 - var(--p,0)) * 100%) 0 0);
}
/* One column, so the rail stands up and runs top to bottom instead. It ends on
   the last marker rather than at the foot of the last paragraph, which is what
   --vlen carries: the script measures it, because only the script knows how
   tall three blocks of translated copy turned out. */
@media (max-width:820px){
  .hah{grid-template-columns:1fr;gap:18px}
  .hah::before,.hah::after{
    top:11px;left:6px;right:auto;width:1px;height:var(--vlen,0px);
  }
  .hah::after{
    background:linear-gradient(180deg,var(--a1),var(--accent),var(--a4));
    clip-path:inset(0 0 calc((1 - var(--p,0)) * 100%) 0);
  }
  /* The line is now beside the copy rather than above it, so the copy moves
     off it. Same arrangement the method uses, for the same reason. */
  .hah__n{padding-left:28px}
  .hah__k{left:28px}
}
/* No scroll to read it from: the line is complete and every node is lit. */
@media (prefers-reduced-motion:reduce){
  .hah::after{clip-path:none}
}
.hah__n{position:relative;z-index:2;padding-top:30px}
.hah__n::before{
  content:"";position:absolute;left:0;top:5px;width:13px;height:13px;border-radius:50%;
  background:var(--bg);border:2px solid var(--line);box-sizing:border-box;
  transition:border-color var(--t-med) var(--ease-io),
             background-color var(--t-med) var(--ease-io),
             transform var(--t-med) var(--spring);
}
.hah__n[data-on="true"]::before{border-color:var(--fg);transform:scale(1.12)}
.hah__n[data-kind="ai"][data-on="true"]::before{border-color:var(--accent);background:var(--accent)}
.hah__k{
  position:absolute;left:22px;top:5px;color:var(--fg-3);line-height:13px;
  opacity:.45;transition:opacity var(--t-med) var(--ease-io), color var(--t-med) var(--ease-io);
}
.hah__n[data-on="true"] .hah__k{opacity:1}
.hah__n[data-kind="ai"][data-on="true"] .hah__k{color:var(--accent-text)}
@media (prefers-reduced-motion:reduce){
  .hah__n::before{transition:none;border-color:var(--fg-3)}
  .hah__n[data-kind="ai"]::before{border-color:var(--accent);background:var(--accent)}
  .hah__k{opacity:1;transition:none}
  .hah__n[data-kind="ai"] .hah__k{color:var(--accent-text)}
}
.hah__n h3{margin:0}
.hah__n p{margin:8px 0 0;font-size:var(--fs-sm);line-height:1.5;color:var(--fg-2);max-width:34ch}
.hah__note{
  margin:clamp(20px,3vh,30px) 0 0;color:var(--fg-3);
}

/* ── the model rails ───────────────────────────────────────────────────────
   Two marquees running against each other, on the page's own marquee, so the
   only new thing here is what rides on it. */
.mods{
  margin-top:clamp(26px,4vh,44px);
  border-radius:var(--r-lg);border:1px solid var(--line-soft);background:var(--bg-sunk);
  padding:clamp(18px,2.4vw,28px) 0;
  display:flex;flex-direction:column;gap:clamp(16px,2.2vh,26px);
}
.mods__l{margin:0 0 12px;padding-inline:clamp(18px,2.4vw,28px);color:var(--fg-3)}
.mods__t{gap:clamp(20px,2.8vw,40px);padding-left:clamp(20px,2.8vw,40px);animation-duration:42s}
.mods__t--rev{animation-direction:reverse;animation-duration:48s}
.mchip{
  display:inline-flex;align-items:center;gap:10px;flex:none;
  padding:9px 16px 9px 12px;border-radius:var(--r-pill);
  border:1px solid var(--line-soft);background:var(--bg-raise);
  transition:border-color var(--t-med) var(--ease-io), transform var(--t-med) var(--spring);
}
.mchip b{
  font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:var(--fg-2);white-space:nowrap;
}
.mchip__g{width:20px;height:20px;flex:none;color:var(--mc,var(--accent));opacity:.9}
.mods__m:hover .mchip:hover{border-color:var(--mc,var(--accent));transform:translateY(-2px)}
.mods__m:hover .mchip:hover b{color:var(--fg)}
/* One slow sweep of light across each rail, so the row is alive even when the
   marquee is paused under the pointer. */
.mods__m{position:relative}
.mods__m::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:2;
  background:linear-gradient(100deg,transparent 42%,
    color-mix(in srgb,var(--accent) 12%,transparent) 50%,transparent 58%);
  transform:translateX(-100%);animation:modsSweep 7.5s var(--ease-io) infinite;
}
@supports not (background:color-mix(in srgb,red 12%,transparent)){
  .mods__m::after{display:none}
}
@keyframes modsSweep{0%,55%{transform:translateX(-100%)}100%{transform:translateX(100%)}}
@media (prefers-reduced-motion:reduce){
  .mods__m::after{animation:none;display:none}
  .mods__t{flex-wrap:wrap;justify-content:center;row-gap:12px}
}
.mods__q{
  margin:clamp(26px,4vh,44px) 0 0;padding-left:clamp(16px,2vw,24px);
  border-left:2px solid var(--accent);
}
.mods__q p{
  margin:0;font-family:var(--display);font-weight:600;letter-spacing:-.028em;
  font-size:var(--fs-h2);line-height:1.12;max-width:26ch;text-wrap:balance;
}

/* ═══ FOOTER ═══════════════════════════════════════════════════════════════
   v11 gives the sections list five destinations rather than four, which is one
   row more than the closing screen has to spare at a short viewport. Two
   columns puts them back inside it, and keeps doing so if a sixth is ever
   added. */
.foot__nav--sec{
  display:grid;grid-template-columns:repeat(2,auto);
  column-gap:clamp(14px,2vw,30px);row-gap:9px;
  justify-content:start;align-content:start;
}
.foot__nav--sec .foot__h{grid-column:1 / -1}

/* ═══ WORK — the featured three ════════════════════════════════════════════ */
.menu-grid--feat{grid-template-columns:repeat(3,1fr)}
@media (max-width:940px){.menu-grid--feat{grid-template-columns:1fr}}
.work__more{margin:clamp(22px,3.4vh,38px) 0 0}
.pcount--all{margin-bottom:0}


/* ═══ THE DOOR TO THE ARCHIVE ═══════════════════════════════════════════════
   v11 first shipped this as a text link under the featured three, which read
   as a footnote. It is the second most important thing that section does, so
   it is a panel with a button in it: one accent hairline along the top so the
   eye finds it, and the same pill the rest of the site uses for a decision. */
.xcta{
  position:relative;overflow:hidden;
  margin-top:clamp(26px,4vh,44px);
  display:flex;align-items:center;justify-content:space-between;
  gap:clamp(18px,3vw,44px);flex-wrap:wrap;
  padding:clamp(20px,2.6vw,34px);
  border-radius:var(--r-lg);border:1px solid var(--line);
  background:var(--bg-raise);box-shadow:var(--shadow-1);
  transition:border-color var(--t-med) var(--ease-io), box-shadow var(--t-med) var(--ease-io);
}
.xcta::before{
  content:"";position:absolute;inset:0 0 auto;height:2px;
  background:linear-gradient(90deg,var(--accent),transparent 68%);
}
.xcta:hover{border-color:var(--line);box-shadow:var(--shadow-2)}
.xcta__h{
  margin:0;font-family:var(--display);font-weight:700;letter-spacing:-.028em;
  font-size:var(--fs-h3);line-height:1.16;max-width:26ch;text-wrap:balance;
}
.xcta__s{margin:9px 0 0;font-size:var(--fs-sm);line-height:1.5;color:var(--fg-2);
  max-width:54ch;text-wrap:pretty}
@media (max-width:620px){
  .xcta{flex-direction:column;align-items:flex-start;gap:20px}
  .xcta .btn--lg{width:100%;justify-content:space-between}
}

/* The same pill, sized for a decision rather than for a bar. */
.btn--lg{padding:13px 17px 13px 24px;font-size:var(--fs-sm);gap:12px;flex:none}
.btn--lg i{width:23px;height:23px;font-size:12px}

/* ═══ BREADCRUMB ═══════════════════════════════════════════════════════════
   The portfolio page is a page now, so it says where it sits. */
.crumb{display:flex;align-items:center;gap:10px;color:var(--fg-3);
  margin:0 0 clamp(14px,2.2vh,24px)}
.crumb a{color:var(--fg-3);transition:color var(--t-fast) var(--ease-io)}
.crumb a:hover{color:var(--fg)}
.crumb s{text-decoration:none;opacity:.5}
.crumb span{color:var(--fg-2)}

/* The archive page opens on its heading rather than on a masthead, so it needs
   the room a hero would otherwise have taken. */
[data-page="portfolio"] #portfolio{padding-top:calc(var(--hdr-tall) + clamp(24px,5vh,60px))}
[data-page="portfolio"] .foot{margin-top:clamp(50px,9vh,110px)}

/* ═══ PRICING ══════════════════════════════════════════════════════════════
   The figure is the point of the section, so it is set at heading scale and
   given the accent, and the three cards under it are the terms rather than
   tiers. No plan grid: there is one way to buy this. */
.pr__head{display:grid;gap:14px;max-width:62ch;margin-bottom:clamp(28px,4vh,44px)}
.pr__floor{
  font-family:var(--display);font-weight:700;letter-spacing:-.03em;line-height:1.1;
  font-size:clamp(24px,3.4vw,40px);max-width:20ch;
  margin-bottom:clamp(22px,3vh,34px);
}
.pr__grid{
  display:grid;gap:clamp(14px,1.6vw,20px);
  grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
}
.pr__c{
  position:relative;padding:22px 20px 24px;
  border:1px solid var(--line-soft);border-radius:var(--r-md);background:var(--chip);
}
/* the same hairline of colour the method steps carry, so the two sections
   read as one system rather than two visual languages */
.pr__c::before{
  content:"";position:absolute;left:20px;right:20px;top:0;height:2px;
  border-radius:0 0 2px 2px;background:var(--sc,var(--accent));opacity:.9;
}
.pr__n{margin-bottom:8px}
.pr__c p{color:var(--fg-2);font-size:var(--fs-sm);line-height:1.55}
.pr__note{margin-top:clamp(18px,2.4vh,28px);color:var(--fg-2)}

/* On a phone the three terms stack, and the section is the only one on the
   page whose content then outgrows its own screen: 969px against 812px in
   Spanish, which is the longer of the two. The spacing is what is oversized
   there, not the type, so only the spacing comes down. Nothing is hidden and
   no size is changed, which leaves 38px to spare in Spanish and 91px in
   English on the smallest phone we support. */
@media (max-width:620px){
  #pricing{padding-block:calc(var(--hdr) + 12px) 20px}
  #pricing .eyebrow{margin-bottom:10px}
  #pricing .pr__head{gap:8px;margin-bottom:14px}
  #pricing .pr__floor{margin-bottom:12px}
  #pricing .pr__grid{gap:8px}
  #pricing .pr__c{padding:14px 16px 16px}
  #pricing .pr__c::before{left:16px;right:16px}
  #pricing .pr__note{margin-top:10px}
}

/* ═══ FAQ ══════════════════════════════════════════════════════════════════
   Native details, so it works with no script and reads correctly to assistive
   tech. The marker is drawn rather than borrowed: the default triangle is not
   ours and cannot be styled the same way in every engine. */
.faq{margin-top:clamp(26px,4vh,42px);border-top:1px solid var(--line-soft)}
.faq__i{border-bottom:1px solid var(--line-soft)}
.faq__q{
  display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding:20px 2px;cursor:pointer;list-style:none;
  font-size:var(--fs-md);font-weight:500;color:var(--fg);
  transition:color var(--t-fast);
}
.faq__q::-webkit-details-marker{display:none}
.faq__q:hover{color:var(--fg-2)}
.faq__q i{
  position:relative;flex:none;width:14px;height:14px;
  transition:transform var(--t-med) var(--spring);
}
.faq__q i::before,.faq__q i::after{
  content:"";position:absolute;inset:50% 0 auto;height:1.5px;
  background:currentColor;border-radius:1px;
}
.faq__q i::after{transform:rotate(90deg);transition:opacity var(--t-med) var(--ease-io)}
.faq__i[open] .faq__q i{transform:rotate(180deg)}
.faq__i[open] .faq__q i::after{opacity:0}
.faq__a{padding:0 2px 22px;max-width:72ch}
.faq__a p{color:var(--fg-2);line-height:1.6}
@media (max-width:560px){ .faq__q{font-size:var(--fs-sm);padding:17px 2px} }

/* ═══ SPECIALISTS ══════════════════════════════════════════════════════════
   The bench, sitting under the three staff cards on the same tab. Same
   greyscale and grain as the portraits above it, because one tab should not
   carry two photographic treatments. */
.tal{margin-top:clamp(26px,4vh,42px);padding-top:clamp(22px,3vh,32px);border-top:1px solid var(--line-soft)}
.tal__h{color:var(--fg-3);margin:0 0 6px}
.tal__d{color:var(--fg-2);font-size:var(--fs-sm);max-width:58ch;margin:0 0 18px}
.tal__row{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(8px,1vw,14px)}
.tal__row figure{margin:0;border-radius:var(--r-md);overflow:hidden;background:var(--bg-sunk)}
.tal__row img{
  display:block;width:100%;height:auto;aspect-ratio:3/2;object-fit:cover;
  filter:grayscale(1) contrast(1.04);
  transition:transform .7s var(--ease);
}
.tal__row figure:hover img{transform:scale(1.03)}
@media (max-width:700px){ .tal__row{grid-template-columns:repeat(2,1fr)} }

/* ═══ FOUNDER ══════════════════════════════════════════════════════════════
   Two columns where there is room, and one where there is not. The photo
   column is optional by design: the script drops the <img> if the file is
   missing, and an empty figure collapses to nothing rather than a gap. */
/* The photo column is capped rather than proportional: the source is 660px
   wide, so letting it stretch to a third of a 1400px page would render it
   at 1.4x and look soft. At 340 it lands near 2x, and a modest portrait
   beside a long text block reads better than a large one anyway. */
.fnd{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,340px);gap:clamp(22px,3.5vw,52px);align-items:start}
.fnd__t{min-width:0}
.fnd__b{color:var(--fg-2);font-size:var(--fs-sm);line-height:1.6;max-width:56ch;margin:14px 0 0}
.fnd__l{color:var(--fg-3);margin:clamp(18px,2.6vh,26px) 0 8px}
.fnd__ul{list-style:none;margin:0;padding:0;display:grid;gap:7px}
.fnd__ul li{
  position:relative;padding-left:20px;color:var(--fg);font-size:var(--fs-sm);line-height:1.5;
}
.fnd__ul li::before{
  content:"";position:absolute;left:0;top:.62em;width:7px;height:1px;background:var(--accent);
}
.fnd__s{color:var(--fg-3);font-size:var(--fs-xs);margin:16px 0 0;max-width:52ch}
.fnd__f{margin:0;border-radius:var(--r-md);overflow:hidden;background:var(--bg-sunk)}
/* The script removes the <img> when the file is missing, which leaves the
   figure holding whitespace, so :empty never matches it. :has does, and the
   whole column stands down rather than reserving space for nothing. */
.fnd__f:not(:has(img)){display:none}
.fnd:not(:has(.fnd__img)){grid-template-columns:1fr}
.fnd__img{display:block;width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;filter:grayscale(1) contrast(1.04)}
@media (max-width:820px){
  .fnd{grid-template-columns:1fr}
  .fnd__f{max-width:320px}
}

/* ═══════════════════════════════════════════════════════════════════════════
   v11.2 ADDITIONS
   ═══════════════════════════════════════════════════════════════════════════ */

/* ═══ MOBILE RHYTHM ═══════════════════════════════════════════════════════
   Every .sect is at least one viewport tall and centres its content inside
   that. On a desktop, where a section is nearly full anyway, the leftover is
   breathing room. On a phone it is not: the reel is 375 wide, so the player is
   211 tall, and the section still reserved a whole 812pt screen for roughly
   half that much content. The result was a band of nothing above the heading
   and another below the client strip, on every short section.

   Below the tablet break a section is therefore sized by what is in it, with a
   generous but finite pad. The two sections that are genuinely full screen
   objects keep their height: the hero, which is the first thing anyone sees,
   and the closing screen, which holds the form and the footer. Snapping is
   already off here, so nothing depends on a section being exactly a viewport. */
@media (max-width:720px){
  .sect{
    min-height:0;
    justify-content:flex-start;
    padding-block:calc(var(--hdr) + clamp(26px,4.5vh,44px)) clamp(30px,5vh,52px);
  }
  #top{min-height:100svh;justify-content:center}
  #contact{min-height:100svh}

  /* The player and the client strip sat on desktop margins inside a section
     that no longer has room to spare for them. */
  .reel{margin-top:clamp(18px,2.6vh,28px)}
  .reel__cap{margin-top:11px}
  .strip{margin-top:clamp(20px,3vh,32px)}

  /* The same tightening where a heading, a lede and a grid stack up. */
  .proc__head{margin-bottom:clamp(24px,3.5vh,40px)}
  .foot{margin-top:clamp(32px,5vh,60px)}
  .pr__head{margin-bottom:clamp(14px,2vh,22px)}
}

/* A phone that is short as well as narrow gives a little more, since the pad
   is what is left once the fixed masthead has taken its share. */
@media (max-width:720px) and (max-height:740px){
  .sect{padding-block:calc(var(--hdr) + 22px) 26px}
}

/* ═══ MENU PREFERENCES, MOVED TO THE TOP ══════════════════════════════════
   They used to close the panel, under a column of quick links. Below the
   tablet break the header's own two controls are hidden, which makes this the
   only place a visitor can change language or appearance, so it is the first
   row now rather than the last. Label and controls sit on one line where
   there is width for it, and wrap onto two where there is not. */
.mpop__pref{
  display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;
  gap:10px clamp(14px,2vw,24px);
  margin-top:clamp(14px,1.8vw,20px);padding-bottom:clamp(14px,1.8vw,20px);
  border-bottom:1px solid var(--line-soft);
}
.mpop__pref .mpop__l{margin:0}

/* ═══ FOOTER · SOCIAL AND THE PARENT COMPANY ══════════════════════════════ */
/* One account, one icon. A row of five greyed logos is a link farm; a single
   live destination under the wordmark is a place to go. */
.foot__soc{display:flex;align-items:center;gap:10px;margin-top:2px}
.soc{
  width:38px;height:38px;flex:none;display:grid;place-items:center;
  border-radius:var(--r-pill);border:1px solid var(--line);color:var(--fg-2);
  transition:color var(--t-fast) var(--ease-io),
             border-color var(--t-fast) var(--ease-io),
             background-color var(--t-fast) var(--ease-io),
             transform var(--t-med) var(--spring);
}
.soc svg{width:19px;height:19px;display:block}
.foot .soc:hover{color:var(--fg);border-color:var(--fg);background:var(--chip);transform:translateY(-2px)}
@media (prefers-reduced-motion:reduce){.soc{transition:none}.foot .soc:hover{transform:none}}
/* The parent company, and the last thing on the page. It used to be a 15px
   wordmark tucked into a corner at 72% opacity, which said "footnote" when the
   fact it carries is "this studio has a house behind it". So it is a band now:
   its own rule, its own air, centred, and a real link out to grupozacarias.com.
   Still quieter than anything above it — tertiary ink, small sans, no fill —
   but unmistakably deliberate rather than left over. */
.gzb{
  position:relative;isolation:isolate;
  display:flex;flex-direction:column;align-items:center;
  gap:clamp(17px,2.4vh,26px);text-align:center;
  margin:0;padding:clamp(34px,5vh,64px) 0 clamp(30px,4.2vh,54px);
  border-top:1px solid var(--line);
  color:var(--fg-3);text-decoration:none;
}
/* A wash rather than a fill: it has no edges, so the band can stay inside the
   wrap's measure without a background that stops short of the screen. It is
   off until the pointer arrives, which is what keeps the resting state quiet. */
.gzb::before{
  content:"";position:absolute;z-index:0;left:50%;top:52%;
  width:min(620px,92%);height:min(190px,90%);transform:translate(-50%,-50%);
  background:radial-gradient(ellipse at center,
             rgba(255,153,0,.07),rgba(255,153,0,.025) 45%,transparent 72%);
  opacity:0;pointer-events:none;
  transition:opacity var(--t-slow) var(--ease-io);
}
.gzb:hover::before,.gzb:focus-visible::before{opacity:1}
.gzb > *{position:relative;z-index:1}
/* The two lines of type are the site's sans rather than the mono the rest of
   the footer's meta uses: no uppercase, almost no tracking, nothing to read
   until you look for it. The wordmark between them is the only thing in this
   band allowed to be big. */
.gzb__l{
  font-family:var(--sans);font-size:11px;font-weight:400;letter-spacing:.005em;
  text-transform:none;color:var(--fg-3);opacity:.8;
  transition:color var(--t-med) var(--ease-io),opacity var(--t-med) var(--ease-io);
}
.gzb:hover .gzb__l{color:var(--fg-2);opacity:1}
.gzb__mark{display:block;line-height:0;position:relative}
.gzb__logo{
  display:block;height:clamp(26px,4.4vw,46px);width:auto;
  filter:invert(var(--logo-invert));opacity:.82;
  transition:opacity var(--t-med) var(--ease-io),
             transform var(--t-med) var(--spring);
}
.gzb:hover .gzb__logo,.gzb:focus-visible .gzb__logo{opacity:1;transform:translateY(-1px)}
.gzb__go{
  display:inline-flex;align-items:center;gap:6px;
  font-family:var(--sans);font-size:11px;font-weight:400;letter-spacing:.005em;
  text-transform:none;color:var(--fg-3);
  opacity:.62;transition:opacity var(--t-med) var(--ease-io),color var(--t-med) var(--ease-io);
}
.gzb:hover .gzb__go,.gzb:focus-visible .gzb__go{opacity:1;color:var(--fg-2)}
.gzb__go i{display:inline-block;font-style:normal;
  transition:transform var(--t-med) var(--spring)}
.gzb:hover .gzb__go i,.gzb:focus-visible .gzb__go i{transform:translate(1px,-1px)}
/* The sheen. Masked with the wordmark itself, so the light travels through the
   letterforms and not across a rectangle over them. It is a pure enhancement:
   with no mask support the layer simply never paints, and the logo underneath
   is untouched. Held until the band has been revealed so nothing animates off
   screen, then a slow pass with a long rest between them. */
@supports ((-webkit-mask-image:url("../img/grupozacarias.svg")) or (mask-image:url("../img/grupozacarias.svg"))){
  .gzb__sheen{
    position:absolute;inset:0;pointer-events:none;
    -webkit-mask:url("../img/grupozacarias.svg") center/contain no-repeat;
            mask:url("../img/grupozacarias.svg") center/contain no-repeat;
    background-image:linear-gradient(100deg,
      transparent 38%,var(--accent) 50%,transparent 62%);
    background-size:280% 100%;background-repeat:no-repeat;
    background-position:180% 0;
    opacity:0;
  }
  .gzb.in .gzb__sheen{animation:gzSheen 7.5s var(--ease-io) 1s infinite}
  .gzb:hover .gzb__sheen{animation-duration:3.4s;animation-delay:0s}
}
@keyframes gzSheen{
  0%{background-position:180% 0;opacity:0}
  6%{opacity:.35}
  30%{background-position:-80% 0;opacity:0}
  100%{background-position:-80% 0;opacity:0}
}
@media (max-width:520px){
  .gzb{padding-top:clamp(28px,4.2vh,48px);gap:clamp(15px,2.2vh,22px)}
  .gzb__l,.gzb__go{font-size:10px}
}
@media (prefers-reduced-motion:reduce){
  .gzb::before,.gzb__l,.gzb__logo,.gzb__go,.gzb__go i{transition:none}
  .gzb:hover .gzb__logo,.gzb:focus-visible .gzb__logo{transform:none}
  .gzb:hover .gzb__go i,.gzb:focus-visible .gzb__go i{transform:none}
  .gzb.in .gzb__sheen,.gzb:hover .gzb__sheen{animation:none}
}
