/* =============================================================================
   Meitar Patents — landing page
   Palette + type sampled from Meitar Brand Book 2025:
     Meitar Blue      #172F56      Innovation Blue  #3B4FA3
     Stone Grey       #EBECE6      Clean White      #FFFFFF
     Deep brand navy  #131A44      Accent tint      #ABDBF0
   Typeface: Rubik (Regular 400 / Medium 500), per brand book.
   ========================================================================== */

/* ------------------------------------------------------------- tokens --- */
/* ── brand constants — identical in both themes ───────────────────────── */
:root{
  --navy-800:#131A44;   /* BRAND deep navy — the book's background */
  --navy-700:#172F56;   /* MEITAR BLUE          — book p15         */
  --navy-600:#1E3A69;   /* Meitar Blue, lifted                     */
  --blue-500:#3B50A3;   /* INNOVATION BLUE      — book p15         */
  --blue-400:#5D74D6;
  --blue-300:#8DA0E8;
  --cyan-200:#ACDBEF;   /* accent tint          — book p15         */
  --stone:#EBEBE6;      /* STONE GREY           — book p15         */
  --white:#FFFFFF;

  /* The six secondary tints from the brand book's palette page. The book's
     own instruction is to use them as light touches for variety, not as
     fields of colour — so they appear as the wheel's per-area accents and as
     the index numbers that run down the page, and nowhere as a fill. */
  --tint-sky:   #ACDBEF;
  --tint-lilac: #CAC1E0;
  --tint-green: #D7E8B4;
  --tint-olive: #BAB86B;
  --tint-coral: #EFAE94;
  --tint-sand:  #F1CCA1;
  /* the same five as triplets, for anything that needs to mix them. These are
     BRAND CONSTANTS — the --t1..--t6 slots further down are theme-adjusted so
     they stay legible as ink on each ground, and are a different thing. */
  --tint-sky-rgb:   172,219,239;
  --tint-lilac-rgb: 202,193,224;
  --tint-green-rgb: 215,232,180;
  --tint-coral-rgb: 239,174,148;
  --tint-sand-rgb:  241,204,161;

  --wrap: 1240px;
  --pad: clamp(20px, 5vw, 64px);
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 22px;

  --ease: cubic-bezier(.22,.8,.28,1);
  --ease-out: cubic-bezier(.16,1,.3,1);
  --t-fast: .22s;
  --t: .42s;
  --t-slow: .8s;
  /* the bar settling in is its own pace: slower than anything else on the
     page and on a curve with no overshoot at either end */
  --t-nav: .55s;
  --ease-nav: cubic-bezier(.33,0,.2,1);

  --font: 'Rubik', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif;
}

/* Swapping ground is a big visual move; easing the few properties that carry
   it keeps the switch from reading as a page reload. */
body, .nav, .section, .footer, .domain, .why, .pillars li, .partners, .pcard,
.edge img, .section__bg img{
  transition:background-color .45s var(--ease), color .45s var(--ease),
             border-color .45s var(--ease), filter .45s var(--ease);
}
@media (prefers-reduced-motion: reduce){
  body, .nav, .section, .footer, .domain, .why, .pillars li, .partners, .pcard,
  .edge img, .section__bg img{ transition:none; }
}

/* ── DARK (default) ───────────────────────────────────────────────────────
   The canvas tones are #131A44 held at the same hue and dropped in
   lightness; Meitar Blue is the surface colour, and the accent tint carries
   every interaction. ------------------------------------------------------ */
:root, [data-theme="dark"]{
  color-scheme: dark;

  --canvas:      #0C1330;
  --canvas-soft: #0F1739;
  --canvas-deep: #080D22;

  --surface:      var(--navy-700);   /* cards, panels          */
  --surface-2:    var(--navy-600);   /* raised panel           */
  --surface-soft: var(--canvas-soft);/* quiet cell             */
  --surface-hot:  var(--navy-700);   /* hover fill             */
  --surface-deep: var(--navy-800);

  --ink:        var(--stone);
  --ink-strong: var(--white);
  --ink-dim:    #C2CBDC;
  --ink-faint:  #93A0BC;

  --line:        rgba(171,219,240,.16);
  --line-strong: rgba(171,219,240,.30);
  --grid-line:   rgba(171,219,240,.055);

  --accent:      var(--cyan-200);
  --accent-rgb:  171,219,240;
  --on-accent:   #0C1330;

  --wash-rgb:  23,47,86;             /* section radial washes  */
  --wash-a:    .80;
  --scrim:     rgba(4,7,22,.74);
  /* MEITAR BLUE, and close to solid. It used to be a 72% wash, which over a
     bright cover photograph read as grey rather than as the brand colour. */
  /* MEITAR BLUE, solid, at every scroll position. It floated transparent over
     the cover while the cover was dark; now that every section is light, a
     transparent bar would put white type on a pale photograph. One colour is
     the only state that works on a light page. */
  --nav-bg:       #172F56;
  --nav-bg-stuck: #172F56;
  --shadow-1:  0 22px 46px rgba(4,7,20,.55);
  --shadow-2:  0 40px 90px -24px rgba(0,0,0,.85);

  /* photography */
  /* A gradient map, done with filters: sepia lays every luminance onto one
     warm ramp, hue-rotate swings that ramp to the brand blue, saturate sets
     how strongly. Unlike a lighten/darken pair or a `color` blend it reaches
     the MID greys too, which is what a near-monochrome render is made of. */
  --photo-filter: grayscale(1) sepia(1) hue-rotate(175deg) saturate(2.6)
                  brightness(.78) contrast(1.04);
  --photo-o: 1;
  --photo-plain: brightness(.72) saturate(.92) contrast(1.02);
  --photo-veil:   linear-gradient(180deg, rgba(12,19,48,.5), transparent 42%, rgba(12,19,48,.42));
  --hero-scrim:   rgba(10,15,44,.74);
  --hero-photo-o: .5;
  --hero-photo-filter: saturate(.5) hue-rotate(-18deg) brightness(.85);
  --hero-veil: none;   /* the white wash belongs to the light ground only */

  /* The wheel — read by app.js, so each theme sets its own ramp.
     The ramp stays inside the deeper half of the blues. It used to run all
     the way out to the accent tint, and a tile that pale swallows the rim
     light the client asked for and leaves the ring reading as a gradient
     rather than as thirteen areas. */
  --pie-from: 22,48,92;
  --pie-to:   78,127,196;
  --pie-gap:  #0C1330;
  --seg-dim-ink: #AEB8CC;
  --seg-dim-a: .2;
  --hub-in:  #1B2559;
  --hub-out: #0C1234;
  --pie-glow: #9FD6F0;
  --glow-a: .62;
  --field-photo-o: .26;
  --seg-icon: #FFFFFF;
  --seg-icon-glow: #8FCDEC;
  --mesh-rgb: 171,219,240;

  /* the book's six tints, taken as they are printed: on the deep navy they
     read at full strength */
  --t1:var(--tint-sky);   --t1-rgb:172,219,239;
  --t2:var(--tint-lilac); --t2-rgb:202,193,224;
  --t3:var(--tint-green); --t3-rgb:215,232,180;
  --t4:var(--tint-olive); --t4-rgb:186,184,107;
  --t5:var(--tint-coral); --t5-rgb:239,174,148;
  --t6:var(--tint-sand);  --t6-rgb:241,204,161;
}

/* ── LIGHT ────────────────────────────────────────────────────────────────
   Same brand, inverted ground: Stone Grey and white carry the page, the deep
   brand navy carries the type, and Innovation Blue takes over as the
   interaction colour — the accent tint is too pale to hold on a light
   ground. ---------------------------------------------------------------- */
[data-theme="light"]{
  color-scheme: light;

  /* No grey. The book gives three colours to build a light page out of —
     white, Meitar Blue and Innovation Blue — and Stone Grey is a light touch,
     not a ground. Every surface below is therefore white carrying a little
     Meitar Blue, not a neutral: mixed off #172F56, never off black. Stone Grey
     appears exactly twice on the page, in the footer band and the nav rule. */
  --canvas:      #FFFFFF;
  --canvas-soft: #F5F8FC;
  --canvas-deep: #EAF0F8;

  --surface:      #F2F6FC;   /* cards, panels          */
  --surface-2:    #E5EDF8;   /* raised panel           */
  --surface-soft: #F8FAFD;   /* quiet cell             */
  --surface-hot:  #E2EBF8;   /* hover fill             */
  --surface-deep: var(--stone);   /* the one Stone Grey band  */

  --ink:        var(--navy-700);   /* MEITAR BLUE sets the body ink     */
  --ink-strong: var(--navy-700);   /* ...and the headings, at full value */
  --ink-dim:    #3B5480;
  --ink-faint:  #6B84AC;

  --line:        rgba(23,47,86,.17);
  --line-strong: rgba(23,47,86,.32);
  --grid-line:   rgba(23,47,86,.055);

  --accent:      var(--blue-500);
  --accent-rgb:  59,80,163;
  --on-accent:   #FFFFFF;

  --wash-rgb:  59,80,163;
  --wash-a:    .16;
  --scrim:     rgba(255,255,255,.84);
  --nav-bg:    rgba(255,255,255,.78);
  --nav-bg-stuck: rgba(255,255,255,.92);
  --shadow-1:  0 22px 46px rgba(23,47,86,.14);
  --shadow-2:  0 40px 90px -24px rgba(23,47,86,.30);

  /* NO DUOTONE HERE. The gradient map that makes a photograph sit on navy
     turns the same photograph into something lurid on white. On this ground a
     picture is simply itself, lifted a little and held back a little so the
     copy in front of it still reads. */
  /* IN COLOUR. The pictures were greyscaled and then veiled, and between the
     two the page had no colour left in it at all. They keep their own colour
     now; a single flat veil per section is what makes the copy readable. */
  --photo-filter: brightness(.98) saturate(1.04);
  --photo-o: 1;
  /* How much canvas sits over a picture. FLAT across the whole width — the
     value is per section, not per side, because the pictures differ wildly in
     how much they fight type: a pale skyline needs almost nothing, a saturated
     canyon needs a lot. Set on the section, used by every ::after below. */
  --canvas-rgb: 255,255,255;
  --veil-a: .74;   /* only the wheel's backdrop still uses this */
  --photo-plain: brightness(.98);
  --photo-veil:   linear-gradient(180deg, rgba(255,255,255,.46), transparent 44%, rgba(255,255,255,.40));
  --hero-scrim:   rgba(255,255,255,.42);
  --hero-photo-o: .82;
  --hero-photo-filter: brightness(.82) saturate(1.02);

  /* mirrored: on Stone Grey the tiles stay in the pale half, so the navy
     labels hold on every one of them and the rim light is the dark edge */
  --pie-from: 216,229,242;
  --pie-to:   139,175,213;
  --pie-gap:  #FFFFFF;
  --seg-dim-ink: #3B5480;
  --seg-dim-a: .38;   /* a pale slice on a pale ground needs more body */
  --hub-in:  #FFFFFF;
  --hub-out: #E7EEF9;
  /* a cyan rim light disappears on white; on this ground the light has to be
     darker than what it surrounds, so it is Innovation Blue held back */
  --pie-glow: #3B50A3;
  --glow-a: .28;
  --field-photo-o: .20;
  /* a white mark disappears on a pale tile; here the mark is Meitar Blue and
     the light around it is Innovation Blue */
  --seg-icon: #172F56;
  --seg-icon-glow: rgba(59,80,163,.55);

  /* THE BOOK'S COLOURS, EXACTLY AS PRINTED. They were darkened here so they
     would hold as ink on white; the client asked for them one to one, so the
     derived versions are gone and these are the hexes off the palette page.
     They are used at full opacity everywhere — no alpha, no mixing. */
  --t1:var(--tint-sky);   --t1-rgb:var(--tint-sky-rgb);
  --t2:var(--tint-lilac); --t2-rgb:var(--tint-lilac-rgb);
  --t3:var(--tint-green); --t3-rgb:var(--tint-green-rgb);
  --t4:var(--tint-olive); --t4-rgb:186,184,107;
  --t5:var(--tint-coral); --t5-rgb:var(--tint-coral-rgb);
  --t6:var(--tint-sand);  --t6-rgb:var(--tint-sand-rgb);
  /* Held right back. The cover used to be a dark band, and the white wash that
     is right over navy turned the photograph to paper once it became a light
     one — logo, type and picture all dissolving into each other. */
  --hero-veil: linear-gradient(180deg, rgba(255,255,255,.24), rgba(255,255,255,.06) 52%, rgba(255,255,255,.30));
  --mesh-rgb: 59,80,163;
}




/* ── A DARK BAND, ON DEMAND ───────────────────────────────────────────────
   NOTHING CARRIES THIS CLASS AT THE MOMENT. Every section on the page is
   light. The rule is kept because it is the whole mechanism for a dark band
   and because /zebra — the version that alternated — is built on it, so
   putting one back is a single class on a single section.

   A dark band is NOT a second design. It is this file's dark token set,
   re-declared on a class, so every rule already written keeps working inside
   it — surfaces, ink, lines, the accent, the photography treatment and the
   wheel's ramp all come along. Nothing below this line needed changing.

   In the dark version the class is inert: the selector is scoped to
   [data-theme="light"]. ------------------------------------------------- */
[data-theme="light"] .section--ink,
[data-theme="light"] .hero--cover{
  color-scheme: dark;   /* so <select> drops open dark, not white */
  --hero-veil: none;
  /* ⚠ THE GROUND IS THE BRAND BOOK'S OWN NAVY. It was #0C1330 — the dark
     theme's canvas, which the book's #131A44 was dropped in lightness to
     make — and the client asked, correctly, where it came from. The two
     places on this page that stand on it, the numbers band and the
     recognition panel, now stand on the book colour itself. White measures
     16.7:1 on it against 18.2 before, so nothing about the legibility
     changes; only the provenance does. The soft and deep steps keep their
     old distances from it.
     ⚠ ONLY THIS BLOCK. The same triplet is declared twice more — in the
     dark theme at the top of the file, where dropping the lightness is the
     deliberate choice its own comment explains, and on the bar. */
  --canvas:      #131A44;   /* BRAND deep navy — book p15 */
  --canvas-soft: #161E4D;
  --canvas-deep: #0F1436;

  --surface:      var(--navy-700);   /* cards, panels          */
  --surface-2:    var(--navy-600);   /* raised panel           */
  --surface-soft: var(--canvas-soft);/* quiet cell             */
  --surface-hot:  var(--navy-700);   /* hover fill             */
  --surface-deep: var(--navy-800);

  --ink:        var(--stone);
  --ink-strong: var(--white);
  --ink-dim:    #C2CBDC;
  --ink-faint:  #93A0BC;

  --line:        rgba(171,219,240,.16);
  --line-strong: rgba(171,219,240,.30);
  --grid-line:   rgba(171,219,240,.055);

  --accent:      var(--cyan-200);
  --accent-rgb:  171,219,240;
  --on-accent:   #0C1330;

  --wash-rgb:  23,47,86;             /* section radial washes  */
  --wash-a:    .80;
  --scrim:     rgba(4,7,22,.74);
  /* MEITAR BLUE, solid, at every scroll position. It floated transparent over
     the cover while the cover was dark; now that every section is light, a
     transparent bar would put white type on a pale photograph. One colour is
     the only state that works on a light page. */
  --nav-bg:       #172F56;
  --nav-bg-stuck: #172F56;
  --shadow-1:  0 22px 46px rgba(4,7,20,.55);
  --shadow-2:  0 40px 90px -24px rgba(0,0,0,.85);

  /* photography */
  /* A gradient map, done with filters: sepia lays every luminance onto one
     warm ramp, hue-rotate swings that ramp to the brand blue, saturate sets
     how strongly. Unlike a lighten/darken pair or a `color` blend it reaches
     the MID greys too, which is what a near-monochrome render is made of. */
  --photo-filter: grayscale(1) sepia(1) hue-rotate(175deg) saturate(2.6)
                  brightness(.78) contrast(1.04);
  --photo-o: 1;
  --photo-plain: brightness(.72) saturate(.92) contrast(1.02);
  --photo-veil:   linear-gradient(180deg, rgba(12,19,48,.5), transparent 42%, rgba(12,19,48,.42));
  --hero-scrim:   rgba(10,15,44,.74);
  --hero-photo-o: .5;
  --hero-photo-filter: saturate(.5) hue-rotate(-18deg) brightness(.85);

  /* The wheel — read by app.js, so each theme sets its own ramp.
     The ramp stays inside the deeper half of the blues. It used to run all
     the way out to the accent tint, and a tile that pale swallows the rim
     light the client asked for and leaves the ring reading as a gradient
     rather than as thirteen areas. */
  --pie-from: 22,48,92;
  --pie-to:   78,127,196;
  --pie-gap:  #0C1330;
  --seg-dim-ink: #AEB8CC;
  --seg-dim-a: .2;
  --hub-in:  #1B2559;
  --hub-out: #0C1234;
  --pie-glow: #9FD6F0;
  --glow-a: .8;
  --field-photo-o: .26;
  --seg-icon: #FFFFFF;
  --seg-icon-glow: #8FCDEC;
  --mesh-rgb: 171,219,240;

  /* the book's six tints, taken as they are printed: on the deep navy they
     read at full strength */
  --t1:var(--tint-sky);   --t1-rgb:172,219,239;
  --t2:var(--tint-lilac); --t2-rgb:202,193,224;
  --t3:var(--tint-green); --t3-rgb:215,232,180;
  --t4:var(--tint-olive); --t4-rgb:186,184,107;
  --t5:var(--tint-coral); --t5-rgb:239,174,148;
  --t6:var(--tint-sand);  --t6-rgb:241,204,161;
}
/* the ground itself, and the seam between two bands */
[data-theme="light"] .section--ink{
  background:var(--canvas);
  color:var(--ink);
}
[data-theme="light"] .section--ink + .section--ink{ border-top:0; }



/* THE BAR IS ALWAYS DARK — in both versions, over every band. It used to
   follow whatever was under it, which meant it changed colour as you scrolled
   and flashed white for a frame before the first measurement. Taking the dark
   token set here, in CSS alone, means it is right from the first paint and
   never moves. */
[data-theme="light"] .nav{

  --hero-veil: none;
  --canvas:      #0C1330;
  --canvas-soft: #0F1739;
  --canvas-deep: #080D22;

  --surface:      var(--navy-700);   /* cards, panels          */
  --surface-2:    var(--navy-600);   /* raised panel           */
  --surface-soft: var(--canvas-soft);/* quiet cell             */
  --surface-hot:  var(--navy-700);   /* hover fill             */
  --surface-deep: var(--navy-800);

  --ink:        var(--stone);
  --ink-strong: var(--white);
  --ink-dim:    #C2CBDC;
  --ink-faint:  #93A0BC;

  --line:        rgba(171,219,240,.16);
  --line-strong: rgba(171,219,240,.30);
  --grid-line:   rgba(171,219,240,.055);

  --accent:      var(--cyan-200);
  --accent-rgb:  171,219,240;
  --on-accent:   #0C1330;

  --wash-rgb:  23,47,86;             /* section radial washes  */
  --wash-a:    .80;
  --scrim:     rgba(4,7,22,.74);
  /* MEITAR BLUE, solid, at every scroll position. It floated transparent over
     the cover while the cover was dark; now that every section is light, a
     transparent bar would put white type on a pale photograph. One colour is
     the only state that works on a light page. */
  --nav-bg:       #172F56;
  --nav-bg-stuck: #172F56;
  --shadow-1:  0 22px 46px rgba(4,7,20,.55);
  --shadow-2:  0 40px 90px -24px rgba(0,0,0,.85);

  /* photography */
  /* A gradient map, done with filters: sepia lays every luminance onto one
     warm ramp, hue-rotate swings that ramp to the brand blue, saturate sets
     how strongly. Unlike a lighten/darken pair or a `color` blend it reaches
     the MID greys too, which is what a near-monochrome render is made of. */
  --photo-filter: grayscale(1) sepia(1) hue-rotate(175deg) saturate(2.6)
                  brightness(.78) contrast(1.04);
  --photo-o: 1;
  --photo-plain: brightness(.72) saturate(.92) contrast(1.02);
  --photo-veil:   linear-gradient(180deg, rgba(12,19,48,.5), transparent 42%, rgba(12,19,48,.42));
  --hero-scrim:   rgba(10,15,44,.74);
  --hero-photo-o: .5;
  --hero-photo-filter: saturate(.5) hue-rotate(-18deg) brightness(.85);

  /* The wheel — read by app.js, so each theme sets its own ramp.
     The ramp stays inside the deeper half of the blues. It used to run all
     the way out to the accent tint, and a tile that pale swallows the rim
     light the client asked for and leaves the ring reading as a gradient
     rather than as thirteen areas. */
  --pie-from: 22,48,92;
  --pie-to:   78,127,196;
  --pie-gap:  #0C1330;
  --seg-dim-ink: #AEB8CC;
  --seg-dim-a: .2;
  --hub-in:  #1B2559;
  --hub-out: #0C1234;
  --pie-glow: #9FD6F0;
  --glow-a: .8;
  --field-photo-o: .26;
  --seg-icon: #FFFFFF;
  --seg-icon-glow: #8FCDEC;
  --mesh-rgb: 171,219,240;

  /* the book's six tints, taken as they are printed: on the deep navy they
     read at full strength */
  --t1:var(--tint-sky);   --t1-rgb:172,219,239;
  --t2:var(--tint-lilac); --t2-rgb:202,193,224;
  --t3:var(--tint-green); --t3-rgb:215,232,180;
  --t4:var(--tint-olive); --t4-rgb:186,184,107;
  --t5:var(--tint-coral); --t5-rgb:239,174,148;
  --t6:var(--tint-sand);  --t6-rgb:241,204,161;
}


/* ---------------------------------------------------------- theme switch -- */
/* an icon, not a labelled switch — the nav has no room for a word */
.theme-toggle{
  position:relative; flex:none;
  width:34px; height:34px; display:grid; place-items:center;
  background:none; border:0; padding:0; cursor:pointer;
  color:var(--ink-faint);
  transition:color var(--t-fast) var(--ease);
}
.theme-toggle:hover{ color:var(--accent); }
.theme-toggle svg{
  grid-area:1/1; width:19px; height:19px;
  transition:opacity var(--t) var(--ease), transform var(--t) var(--ease);
}
.theme-toggle__sun{ opacity:0; transform:rotate(-70deg) scale(.6); }
[data-theme="light"] .theme-toggle__moon{ opacity:0; transform:rotate(70deg) scale(.6); }
[data-theme="light"] .theme-toggle__sun { opacity:1; transform:none; }

/* The switch is gone from THIS site: the page alternates ground down its
   length and that alternation is the design, so there is nothing to switch
   between. The rules above stay because /old still uses them, and because
   restoring the choice should be a one-line change. */
.theme-toggle{ display:none; }


/* ── LAPTOP STEP ──────────────────────────────────────────────────────────
   On a laptop everything was running large — type, measure, the lot — while
   the same page reads correctly on a desktop monitor. Rather than re-tuning
   forty clamps, the root size and the content width step down together across
   the widths a laptop actually is. Every clamp's ends are in rem, so they all
   come with it; above 1600px nothing changes. --------------------------- */
@media (min-width:1024px) and (max-width:1600px){
  html{ font-size:92%; }
  :root{ --wrap:1100px; }
  /* the running size is otherwise governed by its vw term, which would sit
     out the step */
  html body{ font-size:1rem; }   /* out-specifies the base clamp */
}
@media (min-width:1024px) and (max-width:1330px){
  html{ font-size:89%; }
  :root{ --wrap:1020px; }
}
/* the bar's own sizing lives at the foot of this file, with the lockup: the
   base `.nav__links`/`.nav__logo` rules are declared AFTER this point, so a
   media query written here of the same specificity never wins. */

/* --------------------------------------------------------------- base --- */
*,*::before,*::after{ box-sizing:border-box; }
[hidden]{ display:none !important; }
/* the bar is sticky, so an anchor has to stop clear of it */
section[id], .section[id]{ scroll-margin-top:96px; }
/* the practice's own block carries the `#patents` anchor (the section starts
   with the client walls now), so it needs the same margin the sections get */
.edge__patents[id]{ scroll-margin-top:96px; }
/* The closing block is arrived at deliberately, so it should land flush under
   the bar with nothing of the previous section left showing above it. --nav-h
   is the bar's measured height, set by app.js. */
#cta{ scroll-margin-top:var(--nav-h, 74px); }
html{ scroll-behavior:smooth; -webkit-text-size-adjust:100%; overflow-x:clip; }
body{
  margin:0;
  font-family:var(--font);
  font-weight:400;
  font-size:clamp(.9375rem,1.05vw,1.0625rem);   /* rem, so the laptop step below scales it */
  line-height:1.6;
  color:var(--ink);
  background:var(--canvas);
  overflow-x:clip;   /* clip, not hidden — hidden would break the sticky nav */
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
img{ max-width:100%; display:block; }
button{ font:inherit; color:inherit; }
a{ color:inherit; }
ul{ margin:0; padding:0; list-style:none; }
h1,h2,h3,h4,p{ margin:0; }

::selection{ background:var(--accent); color:var(--on-accent); }

:focus-visible{
  outline:2px solid var(--accent);
  outline-offset:3px;
  border-radius:4px;
}

.wrap{ width:100%; max-width:var(--wrap); margin-inline:auto; padding-inline:var(--pad); }

.skip-link{
  position:fixed; top:-100px; left:16px; z-index:200;
  background:var(--accent); color:var(--on-accent);
  padding:10px 18px; border-radius:var(--r-sm); font-weight:500;
}
.skip-link:focus{ top:16px; }

/* --------------------------------------------------------- typography --- */
.eyebrow{
  font-size:.72rem; font-weight:500; letter-spacing:.22em; text-transform:uppercase;
  color:var(--accent); margin-bottom:20px;
  display:flex; align-items:center; gap:12px;
}
.eyebrow::before{
  content:''; width:26px; height:1px; background:var(--accent); opacity:.55; flex:none;
}
.section__head--center .eyebrow{ justify-content:center; }

.h2{
  font-size:clamp(1.9rem,4vw,3.15rem);
  font-weight:500; line-height:1.1; letter-spacing:-.02em;
  max-width:19ch;
}
.h2--xl{ font-size:clamp(2.1rem,5.2vw,4rem); max-width:16ch; }
.section__head--center .h2{ margin-inline:auto; text-align:center; }

.lede{
  font-size:clamp(1rem,1.35vw,1.2rem);
  color:var(--ink-dim); max-width:62ch; margin-top:22px; font-weight:300;
}
.lede--sm{ font-size:clamp(.95rem,1.15vw,1.05rem); max-width:52ch; }
.section__head--center .lede{ margin-inline:auto; text-align:center; }

/* -------------------------------------------------------------- button -- */
.btn{
  --btn-bg:transparent; --btn-fg:var(--ink); --btn-bd:var(--line-strong);
  position:relative; display:inline-flex; align-items:center; gap:10px;
  padding:15px 28px; border-radius:100px;
  background:var(--btn-bg); color:var(--btn-fg);
  border:1px solid var(--btn-bd);
  font-size:.92rem; font-weight:500; letter-spacing:.01em;
  text-decoration:none; cursor:pointer; white-space:nowrap;
  transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease),
             border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease),
             box-shadow var(--t-fast) var(--ease);
}
.btn--sm{ padding:10px 20px; font-size:.84rem; }
/* MEITAR BLUE carries the primary action. The accent (Innovation Blue) stays
   on links, focus rings and the quieter interactions, which is the division
   the book draws between the two. */
.btn--primary{ --btn-bg:var(--navy-700); --btn-fg:#FFFFFF; --btn-bd:var(--navy-700); }
.btn--primary:hover{
  --btn-bg:var(--navy-600); --btn-bd:var(--navy-600);
  box-shadow:0 10px 34px -10px rgba(23,47,86,.55); transform:translateY(-2px);
}
.btn--ghost:hover{ --btn-bd:var(--accent); background:rgba(var(--accent-rgb),.08); transform:translateY(-2px); }

/* --------------------------------------------------------- demo ribbon -- */
.demo-notice{
  position:relative; z-index:120;
  display:flex; align-items:center; gap:12px;
  padding:9px var(--pad);
  background:rgba(var(--accent-rgb),.10);
  border-bottom:1px solid var(--line);
  font-size:.78rem; color:var(--ink-dim);
}
.demo-notice__dot{
  width:7px; height:7px; border-radius:50%; background:var(--accent); flex:none;
  box-shadow:0 0 0 4px rgba(var(--accent-rgb),.18);
}
.demo-notice p{ flex:1; }
.demo-notice__close{
  background:none; border:0; cursor:pointer; font-size:1.2rem; line-height:1;
  color:var(--ink-faint); padding:4px 6px;
}
.demo-notice__close:hover{ color:var(--ink); }

/* ----------------------------------------------------------------- nav -- */
/* OUT OF FLOW, AT EVERY WIDTH.
   It used to be sticky and in flow, with a negative bottom margin equal to its
   own height so the cover could sit underneath it. That works while the bar is
   one height — but the bar SHRINKS on scroll, so the margin had to be
   re-published from JS on every frame of the shrink, one frame behind the
   height it was cancelling. Every frame the page below stepped by the
   difference. That was the jump: not the bar easing badly, the whole document
   sliding a pixel at a time under a finger that was already scrolling.
   Fixed, the bar's height costs the page nothing and it can change as freely
   as it likes. --nav-h is now published once, at its full height, and is only
   an anchor offset. */
.nav{
  position:fixed; inset-inline:0; top:0; z-index:100;
  background-color:var(--nav-bg);
  border-bottom:1px solid transparent;
  /* background-COLOR, not the shorthand: only the longhand is reliably
     animatable, and the shorthand was leaving the bar painted blue after the
     class had already come off at the top of the page. */
  transition:border-color var(--t-nav) var(--ease-nav), background-color var(--t-nav) var(--ease-nav),
             padding var(--t-nav) var(--ease-nav);
}
/* It draws itself in once you start to scroll. This wants to be barely
   noticed, so it is deliberately small and slow: six pixels off the padding
   and four off the lockup, over half a second on a soft curve. Two things it
   does NOT do, both of which read as a jump rather than a settle — it does not
   animate the link type (a font-size change reflows the row, and type snaps
   between whole pixels on the way), and it does not re-measure --nav-h, which
   would drag the page up behind it. app.js gives the class hysteresis so a
   slow scroll near the top cannot flutter it. */
.nav__inner{ transition:padding var(--t-nav) var(--ease-nav); }
.nav.is-stuck .nav__inner{ padding-block:7px; }
/* The mark shrinks by WIDTH — it used to be height, back when the box and the
   artwork were the same thing. A scale transform was tried and thrown away: a
   scale is cheaper, it goes to the compositor and costs the frame nothing, but
   it scales the RASTER and the artwork came back soft and stayed soft after
   the ease had settled. A width change re-rasterises at the new size, so the
   mark stays a mark. It buys a layout per frame inside the bar, which is a
   flex row of five items and out of flow, so the page never feels it. */
.nav__logo{ transition:width var(--t-nav) var(--ease-nav); }
.nav__links a{ transition:color var(--t-fast) var(--ease); }
@media (prefers-reduced-motion: reduce){
  .nav, .nav__inner, .nav__logo, .nav__links a{ transition:none; }
}

/* an open menu needs a ground of its own, wherever the page happens to be */
.nav:has(.nav__links.is-open){ background-color:var(--nav-bg-stuck); }
.nav.is-stuck{ border-bottom-color:var(--line); background-color:var(--nav-bg-stuck); }
.nav__inner{
  max-width:var(--wrap); margin-inline:auto; padding:17px var(--pad);
  display:flex; align-items:center; gap:clamp(12px,1.8vw,28px);
}
.nav__brand{
  display:flex; align-items:center; gap:11px; text-decoration:none; flex:none;
}
/* THE BOX STAYS 36px TALL AND THE ARTWORK NO LONGER FILLS IT, which is the
   point. An <img> with an SVG source letterboxes (`xMidYMid meet`), so the
   mark is drawn at whatever the WIDTH allows and centred in this box — and
   the box is what the bar's height is measured from. Keeping it means the
   wordmark, which is 10.4:1 where the old lockup was 5.6:1, can be set purely
   by width without the bar getting shorter and dragging every scroll-margin
   on the page with it. The ladder at the foot of the file sets that width. */
.nav__logo{ height:36px; width:auto; flex:none; display:block; }
/* Both weights ship; only the one that suits the ground is drawn. The
   doubled class is deliberate — `.hero__logo{display:block}` is declared
   later in the file and would otherwise win on source order. */
/* The bar is dark in both versions, so its lockup is ALWAYS the reversed one
   and never swaps. Only the cover's lockup follows the ground. */
.nav__logo.nav__logo--light{ display:none; }
.nav__logo.nav__logo--dark { display:block; }
.nav__divider{ width:1px; height:16px; background:var(--line-strong); }
.nav__section{ font-size:.8rem; letter-spacing:.16em; text-transform:uppercase; color:var(--ink-faint); }

.nav__links{ display:flex; gap:clamp(14px,2vw,30px); margin-inline-start:auto; }
/* the menu's own Contact exists only where the pill is hidden — above 860px
   the bar carries the pill and this would be the same word twice */
.nav__links-cta{ display:none; }
.nav__links a{
  position:relative; text-decoration:none; font-size:calc(.86rem + 2px); color:var(--ink-dim);
  padding:6px 0; transition:color var(--t-fast) var(--ease);
  white-space:nowrap;   /* "The Practice" is two words, not two lines */
}
.nav__links a::after{
  content:''; position:absolute; left:0; bottom:0; height:1px; width:100%;
  background:var(--accent); transform:scaleX(0); transform-origin:left;
  transition:transform var(--t) var(--ease);
}
.nav__links a:hover, .nav__links a.is-active{ color:var(--ink); }
.nav__links a.is-active::after, .nav__links a:hover::after{ transform:scaleX(1); }
.nav__cta{ flex:none; }
.nav__burger{ display:none; }
.nav__progress{
  height:1px; background:var(--accent); width:0%; transform-origin:left;
  box-shadow:0 0 12px rgba(var(--accent-rgb),.8);
}

/* ---------------------------------------------------------- background -- */
.grid-plane{
  position:absolute; inset:0;
  background-image:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
  background-size:72px 72px;
  mask-image:radial-gradient(120% 78% at 50% 10%, #000 15%, transparent 72%);
  -webkit-mask-image:radial-gradient(120% 78% at 50% 10%, #000 15%, transparent 72%);
}
.grid-plane--soft{ opacity:.6; background-size:56px 56px; }

/* ---------------------------------------------------------------- hero -- */
/* THE FULL SCREEN, WHATEVER THE SCREEN. It was `min(100svh, 880px)` — the
   cap kept a tall desktop window from stretching the opening — and the client
   asked for the hero to take the whole height at every size. `svh` and not
   `dvh`: the small viewport is the one measured with the browser's own UI
   showing, so the number does not change when a phone's address bar hides
   itself and the section never reflows mid-scroll. */
.hero{
  position:relative; min-height:100svh;
  display:flex; align-items:center;
  padding:clamp(80px,12vh,140px) 0 clamp(70px,10vh,110px);
  overflow:hidden;
  background:
    radial-gradient(90% 70% at 78% 12%, rgba(var(--wash-rgb),var(--wash-a)), transparent 62%),
    radial-gradient(70% 60% at 12% 86%, rgba(var(--wash-rgb),var(--wash-a)), transparent 64%),
    linear-gradient(180deg, var(--canvas-deep), var(--canvas) 62%, var(--canvas-soft));
}
/* clip-path:inset(0) would trap the fixed frame inside the hero's own box,
   which is precisely what must not happen now that it carries three sections */
.hero__bg{ position:absolute; inset:0; }
/* once the cover is well behind us the pinned frame stops painting */
.hero__bg.is-past{ visibility:hidden; }
/* once the cover is well behind us the pinned frame stops painting */
.hero__bg.is-past{ visibility:hidden; }
/* deck cover photography, pushed well back so the type stays the subject */
/* Pinned. The page scrolls over a still frame — no parallax offset, no
   translate driven from the scroll position. */
/* No bottom fade any more. The still used to dissolve before the end of the
   first screen because nothing was meant to sit on it; now the two opening
   sections DO sit on it, and what holds them legible is their own translucent
   ground, not a mask on the picture. It is taller than the viewport so the
   gentle drift app.js gives it never uncovers an edge. */
/* ⚠ THE BOX IS THE VIEWPORT, EXACTLY. It used to be 112svh tall hung 6svh
   above the top — headroom for a parallax drift that this cover does not
   have: nothing in app.js touches `.hero__photo`, and the rule above says in
   as many words that the page scrolls over a STILL frame. The twelve per
   cent of extra height was therefore paid for in width: `cover` scales to
   the taller box and throws the difference off the sides. At 1440x900 that
   was twelve per cent of the picture gone from each edge, which took a whole
   drawing with it; at 100svh it is five. */
.hero__photo{
  position:fixed; inset:0 0 auto 0; width:100%; height:100svh;
  object-fit:cover; object-position:50% 50%;
  /* the render runs hot magenta; pulled toward the brand blues and held
     well back so it reads as texture, not as a picture. */
  filter:var(--hero-photo-filter);
  opacity:0; transform:scale(1.12);
  animation:heroPhotoIn 2.2s var(--ease-out) .15s forwards;
  will-change:transform;
}
@keyframes heroPhotoIn{ to{ opacity:var(--hero-photo-o); transform:scale(1); } }


/* optional hero loop — sits over the still, which acts as its poster */
.hero__video{
  position:fixed; inset:0 0 auto 0; width:100%; height:100svh;
  object-fit:cover; object-position:50% 50%;
  filter:var(--hero-photo-filter);
  mask-image:linear-gradient(180deg, #000 12%, rgba(0,0,0,.45) 62%, transparent 96%);
  -webkit-mask-image:linear-gradient(180deg, #000 12%, rgba(0,0,0,.45) 62%, transparent 96%);
  opacity:0; pointer-events:none;
  transition:opacity 1.4s var(--ease-out);
}
.hero__video.is-ready{ opacity:var(--hero-photo-o); }
#heroCanvas{ position:absolute; inset:0; width:100%; height:100%; }
.hero__glow{
  position:absolute; border-radius:50%; filter:blur(90px); opacity:.5;
  animation:drift 22s var(--ease) infinite alternate;
}
.hero__glow--a{ width:44vw; height:44vw; right:-8vw; top:-6vw; background:rgba(var(--wash-rgb),var(--wash-a)); }
.hero__glow--b{ width:34vw; height:34vw; left:-6vw; bottom:-10vw; background:rgba(var(--accent-rgb),.12); animation-delay:-8s; }
@keyframes drift{ to{ transform:translate3d(4%,5%,0) scale(1.12); } }

.hero__inner{ position:relative; }
.hero__title{
  font-size:clamp(2.5rem,6.6vw,5.4rem);
  font-weight:400; line-height:1.03; letter-spacing:-.035em;
  max-width:15ch;
}
.hero__title .line{ display:block; overflow:hidden; }
.hero__title .line span{
  display:block;
  transform:translateY(105%);
  animation:riseIn 1.05s var(--ease-out) forwards;
}
.hero__title .line:nth-child(2) span{ animation-delay:.11s; color:var(--accent); }
@keyframes riseIn{ to{ transform:translateY(0); } }

.hero__actions{ display:flex; flex-wrap:wrap; gap:14px; margin-top:38px; }

/* ---- cover variant: the deck's own lockup — logo centred, practice title
   directly beneath it, nothing else competing for the frame. ---- */
.hero--cover .hero__inner{ text-align:center; }
/* the corridor render is bright down its centre line, so the lockup sits on
   its own scrim rather than dimming the whole photograph */
.hero--cover .hero__bg::after{
  content:''; position:absolute; inset:0;
  background:
    radial-gradient(46% 40% at 50% 46%, var(--hero-scrim), transparent 100%),
    var(--hero-veil, transparent);
}
.hero--cover .hero__photo{ opacity:0; animation:heroCoverIn 2.2s var(--ease-out) .15s forwards; }
@keyframes heroCoverIn{ to{ opacity:var(--hero-photo-o); transform:scale(1); } }
/* The plate is back — smaller than it was, and the reversed lockup sits on
   it. On a pale corridor a block of Meitar Blue is what actually holds the
   mark; the halo alone was not enough. */
.hero__brand{
  display:block; width:max-content; max-width:92vw;
  margin:0 auto clamp(26px,4vh,48px);
  transition:transform var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.hero__brand:hover{ transform:translateY(-2px); }
.hero__brand--plate{
  padding:clamp(13px,1.6vw,20px) clamp(20px,2.4vw,32px);
  background:var(--navy-700);
  border-radius:var(--r-md);
  box-shadow:0 16px 44px -20px rgba(8,13,34,.5);
}
.hero__brand--plate:hover{ background:var(--navy-600); }
.hero__logo{
  display:block; width:min(320px,52vw); height:auto; margin:0;
  /* on the plate the lockup needs no halo of its own */
}
.hero--cover .hero__title{
  max-width:22ch; margin-inline:auto;
  font-size:clamp(1.85rem,4.4vw,3.5rem); font-weight:500; letter-spacing:-.02em;
}
.hero--cover .hero__title .line:nth-child(2) span{ color:inherit; }
.hero--cover .hero__actions{ justify-content:center; margin-top:clamp(30px,5vh,52px); }

.hero__scroll{
  position:absolute; bottom:34px; left:50%; transform:translateX(-50%);
  width:24px; height:54px; display:grid; place-items:center;
}
.hero__scroll-line{
  width:1px; height:44px; background:linear-gradient(var(--accent), transparent);
  animation:scrollCue 2.2s var(--ease) infinite;
}
@keyframes scrollCue{ 0%,100%{ opacity:.25; transform:scaleY(.5); transform-origin:top; } 45%{ opacity:1; transform:scaleY(1); } }

/* ------------------------------------------------------------ sections -- */
.section{ position:relative; padding:clamp(78px,11vh,150px) 0; }
.section__head{ margin-bottom:clamp(44px,6vh,76px); }

/* One photograph stands behind both opening sections. The copy is a plain
   two-column editorial block — heading in a narrow column, body in a wider
   one, a hairline between them — used identically in both, which is what
   makes the pair read as one spread. */
.band{ position:relative; isolation:isolate; }
.band .section{ position:relative; z-index:1; background:none; }

.band__text{
  display:grid; align-items:start;
  grid-template-columns:minmax(0,.36fr) minmax(0,.64fr);
  column-gap:clamp(20px,2.4vw,46px);
}
/* The eyebrow takes a row of its own in the left column, so the body starts
   level with the HEADING rather than with the top of the column. That is what
   keeps the two sections consistent: the second has no eyebrow, and without
   this its copy would ride higher than the first's. */
.band__eyebrow{ grid-column:1; grid-row:1; }
.band__title  { grid-column:1; grid-row:2; max-width:14ch; }
.band__body   { grid-column:2; grid-row:2; }

.prose.band__body{ margin-top:0; }   /* .prose's own top margin is declared later */
.band__body{
  border-inline-start:1px solid var(--line);
  padding-inline-start:clamp(20px,2.4vw,40px);
}
/* Sit the first line of the running copy on the heading's own cap height.
   Both start on the same grid row, so what has to be cancelled is only the
   difference between where each one's INK begins inside its line box:

     ink offset = half-leading + (ascender - cap height) x font-size

   For Rubik that second term is about .225em. The heading runs at
   line-height 1.1 (half-leading .05em) and the copy at 1.72 (.36em), so the
   two offsets are .275 x heading-size and .585 x copy-size. The difference is
   what this margin is. Written against the same clamp the heading uses, so it
   stays true as the heading scales. */
.band__body p:first-child{
  --band-title-fs: clamp(1.9rem, 4vw, 3.15rem);
  margin-top: calc(.275 * var(--band-title-fs) - .585em);
}
.band__body p{ max-width:56ch; }

@media (max-width:900px){
  .band__text{ grid-template-columns:minmax(0,1fr); row-gap:clamp(18px,3vh,28px); }
  .band__eyebrow, .band__title, .band__body{ grid-column:1; grid-row:auto; }
  .band__title{ max-width:none; }
  .band__body{ border-inline-start:0; padding-inline-start:0; }
  .band__body p:first-child{ margin-top:0; }
}
.section--practice{ position:relative; overflow:hidden; 
  background:
    radial-gradient(75% 60% at 20% 30%, rgba(var(--wash-rgb),var(--wash-a)), transparent 62%),
    var(--canvas);
}
.section--complexity{ background:var(--canvas-deep); }

.section--advisory{ position:relative; overflow:hidden; }
.section--advisory > .wrap{ position:relative; z-index:1; }
.section--why{ position:relative; overflow:hidden; }
.section--why > .wrap{ position:relative; z-index:1; }
/* Full page width, behind the whole block, and faded top and bottom so it does
   not begin or end on a line. The copy sits over it on a scrim heavy enough to
   read against. */
/* doubled class: this block sits ABOVE the generic .section__bg::after in the
   file, and at equal specificity the later rule would win */
/* ------------------------------------------------------------- pillars -- */
/* Hairlines, not a filled panel — the section's own ground shows through the
   cells, including the part a short paragraph leaves empty. */
.pillars{
  display:grid; margin-top:clamp(46px,6vh,70px);
  grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  border:1px solid var(--line); border-radius:var(--r-md); overflow:hidden;
}
.pillars li{
  position:relative; background:var(--canvas-soft);
  padding:clamp(24px,3vw,38px) clamp(24px,3vw,38px) clamp(24px,3vw,38px) clamp(52px,5vw,74px);
  transition:background var(--t) var(--ease);
}
.pillars b{
  display:block; font-weight:500; font-size:1.05rem; margin-bottom:10px; color:var(--ink-strong);
  transition:color var(--t-fast) var(--ease);
}
.pillars span{ display:block; color:var(--ink-dim); font-size:.94rem; font-weight:300; }

/* Hover lifts the block into Meitar Blue, runs an accent rule down its inner
   edge and brings the index forward — three cues, one gesture. */
.pillar__idx{
  position:absolute; inset-inline-start:clamp(20px,2.4vw,30px); top:clamp(24px,3vw,38px);
  font-size:.72rem; letter-spacing:.18em; color:var(--tint,var(--accent));
  font-variant-numeric:tabular-nums; opacity:1;
  transition:opacity var(--t) var(--ease), transform var(--t) var(--ease);
}
.pillar__bar{
  position:absolute; inset-inline-start:0; top:50%; translate:0 -50%;
  width:2px; height:0; background:var(--tint,var(--accent));
  transition:height var(--t) var(--ease);
}
/* the cell's own surface, not a diluted tint — the bar and the index carry
   the colour, at full strength */
.pillars li:hover{ background:var(--surface-hot); }
.pillars li:hover .pillar__bar{ height:100%; }
.pillars li:hover .pillar__idx{ opacity:1; transform:translateY(-2px); }
.pillars li:hover b{ color:var(--ink-strong); }
.pillar__body{ display:block; color:var(--ink-dim); font-size:.94rem; font-weight:300; }
@media (hover:none){
  .pillars li:hover{ background:var(--canvas-soft); }
  .pillars li:hover b{ color:var(--ink-strong); }
}

/* ═════════════════════════════════════ COMPLEXITY DOMAINS (deck p3) ══ */
.domains{
  display:grid; gap:12px;
  grid-template-columns:repeat(auto-fit,minmax(300px,1fr));
  align-items:stretch;
}
/* Every card is the same height whatever its title length, and the body is
   an overlay rather than an in-flow panel — so opening one on hover never
   nudges its neighbours. */
.domain{
  position:relative;
  border:1px solid var(--line); border-radius:var(--r-md);
  background:var(--surface);
  transition:border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease),
             box-shadow var(--t-fast) var(--ease);
}
.domain:hover, .domain.is-open{
  border-color:var(--line-strong); background:var(--surface-2); z-index:6;
}
.domain__btn{
  width:100%; min-height:88px;
  display:flex; align-items:center; gap:14px;
  padding:20px; background:none; border:0; text-align:start; cursor:pointer;
  border-radius:var(--r-md);
}
.domain__num{
  font-size:.7rem; letter-spacing:.16em; color:var(--accent); flex:none;
  font-variant-numeric:tabular-nums; opacity:.75;
}
.domain__title{ flex:1; font-size:1rem; font-weight:400; line-height:1.35; }
.domain__plus{
  flex:none; width:26px; height:26px; border-radius:50%;
  border:1px solid var(--line-strong); position:relative;
  transition:all var(--t) var(--ease);
}
.domain__plus::before, .domain__plus::after{
  content:''; position:absolute; top:50%; left:50%; background:var(--ink);
  transform:translate(-50%,-50%); transition:all var(--t) var(--ease);
}
.domain__plus::before{ width:10px; height:1px; }
.domain__plus::after{ width:1px; height:10px; }
.domain.is-open .domain__plus{
  background:var(--accent); border-color:var(--accent); transform:rotate(135deg);
}
.domain.is-open .domain__plus::before, .domain.is-open .domain__plus::after{ background:var(--on-accent); }
/* An overlay, so it fades in at its natural height instead of animating a
   grid track — nothing below it moves, so there is no reflow to hide. */
.domain__panel{
  position:absolute; inset-inline:-1px; top:calc(100% - 1px); z-index:7;
  background:var(--surface-2);
  border:1px solid var(--line-strong); border-top:0;
  border-radius:0 0 var(--r-md) var(--r-md);
  opacity:0; visibility:hidden; transform:translateY(-8px);
  transition:opacity var(--t-fast) var(--ease), transform var(--t) var(--ease),
             visibility 0s linear var(--t);
}
.domain.is-open .domain__panel{
  opacity:1; visibility:visible; transform:none;
  box-shadow:var(--shadow-1);
  transition:opacity var(--t-fast) var(--ease), transform var(--t) var(--ease),
             visibility 0s;
}
.domain__body{
  padding:16px 20px 20px 48px; color:var(--ink); font-size:.95rem; font-weight:300;
}

/* ══════════════════════════════════════════════════ PIE (slide 3) ════ */
/* Centred on its own until something is chosen. Selecting an area moves the
   wheel with a transform rather than by re-flowing the grid — nothing is
   re-laid out mid-animation, so it glides instead of stepping. The partners
   are absolutely placed, which is also what keeps a clear gap between them
   and the rim. */
/* --stage is the wheel's own size. The backdrop is measured against IT and
   not against the layout, so when the layout grows to fit a tall panel of
   partners the picture stays exactly where and as big as it was. */
/* The line that introduces the wheel. Set larger than the section's own lede
   and given room on both sides, because it is doing the job of a heading for
   everything below it. */
.pie-lede{
  /* flush left with the heading and the four cards above it — centring the
     block would leave it hanging at neither edge */
  margin:clamp(34px,4.5vh,56px) 0 0;
  max-width:44ch;
  font-size:clamp(1.3rem,2.2vw,1.8rem);
  font-weight:300; line-height:1.35; letter-spacing:-.01em; color:var(--ink);
  text-wrap:balance;
}

.pie-layout{
  --stage: min(774px, 78vh);
  position:relative;
  display:flex; justify-content:center; align-items:flex-start;
  margin-top:clamp(38px,6vh,86px);
}
.pie-stage, .pie-side{ min-width:0; }

/* Bound by the VIEWPORT HEIGHT as well as the width. At 760px the wheel was
   taller than a laptop screen and ran off the bottom of it; 68vh keeps the
   whole ring on screen at any window a laptop actually has, and the width cap
   keeps it from swelling on a large monitor. */
.pie-stage{
  position:relative; width:100%; max-width:var(--stage); flex:0 1 auto;
  transition:transform .72s cubic-bezier(.28,.9,.28,1);
  will-change:transform;
}
/* THE WHEEL STEPS ASIDE, AND IT HAS TO STEP FURTHER NOW.
   The panel grew when its cards were laid down, and at -30% the first card was
   sitting on the rim. Two numbers, not one: pushing left alone runs the wheel
   off the left edge at 1100, and shrinking alone leaves the rim where it was.
   Together they clear a gutter of 24-36px at every desktop width while the
   wheel keeps at least 12px of air on its left. */
.pie-layout.is-open .pie-stage{ transform:translateX(-33%) scale(.73); }

/* Anchored to the TOP of the wheel, not its middle. Centred, a four-partner
   panel is taller than the wheel and its heading rides up over the block
   above — which is exactly what it was doing. */
.pie-side{
  position:absolute; inset-inline-end:0; top:0;
  width:min(36%, 420px);
  opacity:0; transform:translateX(28px); pointer-events:none;
  transition:opacity .42s var(--ease) .1s, transform .66s cubic-bezier(.28,.9,.28,1) .04s;
}
.pie-layout.is-open .pie-side{ opacity:1; transform:none; pointer-events:auto; }
/* while the panel is a sheet it is fixed to the viewport, so its host stops
   being a positioned, translated box — see applyMode() in app.js */
.pie-side.is-sheet-host{
  position:static; translate:none; transform:none; width:auto;
  opacity:1; pointer-events:auto; transition:none;
}

/* ── the ground the wheel stands on ───────────────────────────────────────
   The section gives the wheel far more width than it uses, and the band on
   either side of it was reading as a hole. A photograph fills it — the same
   frame the deck uses where transmission meets the hall — held right back and
   masked to nothing long before it reaches a section edge. It is a still
   backdrop: it does NOT take the wheel's transform when an area opens, and it
   carries no motion of its own. */
.pie-field{
  /* centred on the WHEEL, not on the layout: top = half the stage minus half
     the field, so growth below it moves nothing */
  position:absolute; top:calc(var(--stage) * -0.17); left:50%;
  width:100vw; height:calc(var(--stage) * 1.34);
  translate:-50% 0;
  z-index:0; pointer-events:none; overflow:hidden;
  opacity:0; transition:opacity 1.6s var(--ease) .2s;
  /* two masks, intersected: the radial keeps it off the side edges, the
     linear fades the top and the bottom so the picture never starts or stops
     on a hard line */
  /* a long, soft fall-off at top and bottom: a short one reads as an edge,
     which is what made the join to the next section look abrupt */
  -webkit-mask-image:
    radial-gradient(66% 62% at 50% 50%, #000 0%, #000 40%, rgba(0,0,0,.5) 72%, transparent 100%),
    linear-gradient(180deg, transparent 0%, #000 30%, #000 70%, transparent 100%);
  -webkit-mask-composite:source-in;
          mask-image:
    radial-gradient(66% 62% at 50% 50%, #000 0%, #000 40%, rgba(0,0,0,.5) 72%, transparent 100%),
    linear-gradient(180deg, transparent 0%, #000 30%, #000 70%, transparent 100%);
          mask-composite:intersect;
}
/* THE WHEEL STANDS ON NOTHING BUT LIGHT.
   No landscape and no drawing either: the wheel is already a diagram, and a
   grid under a diagram is two of them. What fills the band of empty width the
   section leaves either side is a single soft lift, held inside the disc the
   masks above already cut. The grid this used to carry now sits above, behind
   the four partners, where there is nothing else competing for the ground. */
.pie-field{
  /* Two soft lifts off-centre from each other and a slow diagonal under them,
     all in Innovation Blue — the pastels are marks and are never washed. The
     masks above cut the whole thing to a disc, so what this reads as is a
     light that the wheel is standing in rather than a panel it sits on. */
  background-image:
    radial-gradient(34% 54% at 41% 24%, rgba(var(--wash-rgb), .16), transparent 70%),
    radial-gradient(30% 46% at 61% 78%, rgba(var(--wash-rgb), .13), transparent 72%),
    linear-gradient(158deg, rgba(var(--wash-rgb), .07), rgba(var(--wash-rgb), 0) 58%);
}
/* it carries `reveal` so the observer lights it; it must not inherit the
   reveal transform, only the fade */
.pie-field.reveal{ transform:none; }
.pie-field.is-in{ opacity:1; }
@media (prefers-reduced-motion: reduce){ .pie-field{ transition:none; } }

/* the wheel and its readout sit on top */
.pie-stage{ z-index:1; }

.pie-stage__ring{ display:none;  position:relative; z-index:1; }

@media (max-width:820px){
  /* on one column there is no empty band left to fill, and the field would
     only crowd the labels */
  .pie-field{ display:none; }
}

.pie-stage__ring{
  /* sits just outside the rim — the wheel itself now fills almost the whole
     stage, so an inset ring would cut across the segments */
  position:absolute; inset:-2%; border-radius:50%;
  border:1px dashed var(--line);
  animation:spin 90s linear infinite;
  pointer-events:none;
}
@keyframes spin{ to{ transform:rotate(360deg); } }

.pie{ width:100%; height:auto; display:block; overflow:visible; cursor:pointer; }



/* The rim light. The client's own chart drew each area as a separate tile
   with a lit edge, and that is the "glow" they missed here: the outline of
   every tile, blurred, laid back over the wheel. Outlines only and one
   colour, so it lights the wheel without touching the fills underneath. */
.pie__halo{
  pointer-events:none;
  /* two shadows off a hairline stroke: the edge stays crisp and the light
     falls off around it, which is what makes it read as lit rather than
     simply blurred. Held back from where it started — at full strength the
     wheel read as heavy. */
  filter:drop-shadow(0 0 3px var(--pie-glow)) drop-shadow(0 0 8px var(--pie-glow));
  opacity:0; transition:opacity 1.1s var(--ease) .3s;
}
.pie.is-lit .pie__halo{ opacity:var(--glow-a,.75); }
.halo__p{
  fill:none; stroke:var(--pie-glow); stroke-width:1.1; stroke-linejoin:round;
  transition:stroke-width var(--t) var(--ease), opacity var(--t) var(--ease);
}
/* while one area is open the rest of the ring goes quiet with its fills */
.pie.has-selection .pie__halo{ opacity:.28; }
@media (prefers-reduced-motion: reduce){ .pie__halo{ transition:none; } }

/* the hub carries the same light: a lit ring, and a wider blurred copy of it */
.pie__core-ring{ stroke:var(--pie-glow); stroke-width:1.1; opacity:.7; }
.pie__core-lit{
  stroke:var(--pie-glow); stroke-width:1.1; opacity:0;
  filter:drop-shadow(0 0 5px var(--pie-glow)) drop-shadow(0 0 14px var(--pie-glow));
  transition:opacity 1.2s var(--ease) .4s;
}
.pie.is-lit .pie__core-lit{ opacity:var(--glow-a,.75); }

/* The per-area mark, near the rim. The client's own chart draws these big and
   lit rather than as small labels-with-a-glyph, so they are set at the same
   weight and carry their own light: one colour for every tile — white on
   navy, Meitar Blue on Stone — with the glow falling off around the line. */
.seg__i{
  fill:none; stroke:var(--seg-icon); stroke-width:1.3;
  stroke-linecap:round; stroke-linejoin:round;
  pointer-events:none;
  filter:drop-shadow(0 0 2px var(--seg-icon-glow))
         drop-shadow(0 0 6px var(--seg-icon-glow));
  transition:opacity var(--t) var(--ease), stroke var(--t) var(--ease);
}
.pie.has-selection .seg:not(.is-selected):not(:hover):not(:focus-visible) .seg__i{
  stroke:var(--seg-dim-ink); filter:none;
}
.pie__core{ pointer-events:none; }
#pieCore stop:first-child{ stop-color:var(--hub-in); }
#pieCore stop:last-child { stop-color:var(--hub-out); }
.pie__ticks line{ stroke:var(--line-strong); stroke-width:1; }

/* Entrance: the segments unwind into place one after another, each starting
   rotated back and undersized, so the wheel draws itself as a quick spiral
   rather than appearing whole. --i is set per segment in app.js. */
/* Entrance: the segments unwind into place one after another. Kept shallow
   and long — a big rotate/scale on thirteen groups of SVG text re-rasterises
   the labels every frame, which is what made it stutter. */
.seg{
  cursor:pointer; outline:none;
  transform-origin:340px 340px;
  transform:rotate(-18deg) scale(.88); opacity:0;
}
.pie.is-lit .seg{
  animation:segIn .9s cubic-bezier(.19,.86,.26,1) forwards;
  animation-delay:calc(var(--i) * 42ms);
  will-change:transform, opacity;
}
.pie.is-lit .seg{ animation-fill-mode:forwards; }
@keyframes segIn{ to{ transform:none; opacity:1; } }

.seg__t{
  transform-origin:340px 340px;
  transition:transform var(--t) var(--ease);
}
/* Fill and stroke both come from the tokens app.js sets on the group, so the
   pastel can arrive on hover without touching the element. The stroke matches
   the fill — that is what rounds the corners. */
.seg__p{
  fill:var(--seg-fill); stroke:var(--seg-fill);
  transition:opacity var(--t) var(--ease), filter var(--t) var(--ease),
             fill var(--t) var(--ease), stroke var(--t) var(--ease);
  stroke-width:4; stroke-linejoin:round;
}
/* the book's pastel, only under the cursor */
.seg:hover .seg__p, .seg:focus-visible .seg__p,
.seg.is-hot .seg__p, .seg.is-selected .seg__p{
  fill:var(--seg-tint); stroke:var(--seg-tint);
}
.seg:hover .seg__l, .seg:focus-visible .seg__l,
.seg.is-hot .seg__l, .seg.is-selected .seg__l{ fill:var(--seg-ink-hot); }
.seg:hover .seg__i, .seg:focus-visible .seg__i,
.seg.is-hot .seg__i, .seg.is-selected .seg__i{ stroke:var(--seg-ink-hot); }

/* ── THE PASTELS, WITHOUT A CURSOR ────────────────────────────────────────
   The book's five colours are the wheel's own, and on a phone there is no
   pointer to bring them out — so every four seconds a light runs round the
   ring and each tile shows its colour in turn. The ring also ARRIVES wearing
   them: each tile is pastel on the first frame it is drawn and settles into
   its blue immediately after, following the entrance stagger.

   This is `is-warm` and not `is-hot` on purpose: it changes the COLOUR and
   nothing else. No scale, no glow, and above all no readout in the hub — a
   name that changed thirteen times every four seconds would be noise, and
   the hub is there to answer what you are pointing at. */
.seg.is-warm .seg__p{ fill:var(--seg-tint); stroke:var(--seg-tint); }
.seg.is-warm .seg__l{ fill:var(--seg-ink-hot); }
.seg.is-warm .seg__i{ stroke:var(--seg-ink-hot); }
/* sizes are SVG user units, so they scale with the wheel — the mobile step
   keeps the rendered size around 12px once the wheel shrinks. */
/* a group now, with one <text> per line inside it — the font and the fill are
   set here and inherited; the transition has to be on the texts themselves,
   because transition is not an inherited property */
.seg__l{
  font-family:var(--font); font-size:15px; font-weight:500; letter-spacing:.005em;
  fill:var(--seg-ink);
  pointer-events:none; user-select:none;
}
.seg__ln{ transition:opacity var(--t) var(--ease), fill var(--t) var(--ease); }
@media (max-width:1080px){ .seg__l{ font-size:17px; } }
/* SVG user units against a 680 viewBox: at a 350px-wide wheel an 18px label
   lands at nine physical pixels. Twenty takes it past eleven now that the
   stage runs the full width of the screen — and twenty-two, which was the
   first try, pushed the four-line labels wider than their own wedge. */
/* SVG user units against a 680 viewBox: at a full-width wheel this lands
   just over twelve physical pixels. It is only readable at that size because
   the wedges are cut to fit their own labels — see `sweeps()` in app.js. */
@media (max-width:820px){  .seg__l{ font-size:22px; } }

.pie.has-selection .seg__p{ opacity:var(--seg-dim-a); }
/* A dimmed segment goes nearly background-dark, so the dark ink that was
   readable on a light slice disappears. Swap those labels to a light fill
   while dimmed — and back to their own ink the moment they are hovered. */
.pie.has-selection .seg:not(.is-selected):not(:hover):not(:focus-visible) .seg__l{
  fill:var(--seg-dim-ink);
}

.seg:hover .seg__p, .seg:focus-visible .seg__p,
.seg.is-hot .seg__p, .seg.is-selected .seg__p,
.seg:hover .seg__l, .seg:focus-visible .seg__l,
.seg.is-hot .seg__l, .seg.is-selected .seg__l,
.seg:hover .seg__i, .seg:focus-visible .seg__i,
.seg.is-hot .seg__i, .seg.is-selected .seg__i{ opacity:1; }

.seg:hover .seg__t, .seg.is-hot .seg__t{ transform:scale(1.045); }
.seg:hover .seg__p, .seg.is-hot .seg__p{ filter:url(#pieGlow); }
.seg.is-selected .seg__t{ transform:scale(1.075); }
.seg.is-selected .seg__p{
  filter:url(#pieGlow) brightness(1.28);
  stroke:var(--accent); stroke-width:1.5;
}
.seg:focus-visible .seg__p{ stroke:var(--accent); stroke-width:2.5; }


/* The hub readout. Everything is centred in the hub itself — idle label and
   the hovered/selected area swap in the same place rather than stacking, so
   nothing ever sits low in the circle. */
.pie-centre{
  position:absolute; inset:0; pointer-events:none;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  text-align:center;
}
/* the hub circle is 35% of the stage across; the readout takes almost all of
   it, so the words sit at a size you read rather than decipher */
.pie-centre > *{ width:33%; }

/* 3px off what the wheel's own scale would give it — the hub was the one
   place the type ran ahead of everything around it */
.pie-centre__hub{
  font-size:calc(clamp(.62rem,2.28vw,1.08rem) - 3px); font-weight:500; line-height:1.3;
  letter-spacing:-.005em; color:var(--ink-strong); text-wrap:balance;
}
.pie-centre__hint{
  margin-top:12px;
  /* .5rem was resolving to eight pixels on a tablet — the floor is the number
     that matters in a clamp, not the preferred value */
  font-size:clamp(.7rem,.98vw,.78rem); letter-spacing:.2em; text-transform:uppercase;
  color:var(--accent); opacity:.85;
}
.pie-centre__name{
  font-size:clamp(.92rem,1.42vw,1.2rem); font-weight:500; line-height:1.3;
  color:var(--ink-strong); text-wrap:balance;
}
.pie-centre__meta{
  margin-top:10px;
  font-size:clamp(.5rem,.98vw,.72rem); letter-spacing:.16em; text-transform:uppercase;
  color:var(--ink-faint);
}
.pie-centre__name, .pie-centre__meta{ display:none; }
.pie-centre.is-active .pie-centre__hub,
.pie-centre.is-active .pie-centre__hint{ display:none; }
.pie-centre.is-active .pie-centre__name,
.pie-centre.is-active .pie-centre__meta{ display:block; animation:hubIn .32s var(--ease-out) both; }
@keyframes hubIn{ from{ opacity:0; } to{ opacity:1; } }

.partners{ position:relative; animation:panelIn .5s var(--ease-out) both; }
.partners__close{ display:none; }

/* ---- overlay mode (single-column widths) ---- */
.pie-scrim{
  position:fixed; inset:0; z-index:110;
  background:var(--scrim);
  -webkit-backdrop-filter:blur(5px); backdrop-filter:blur(5px);
  animation:fadeIn .3s var(--ease) both;
}
@keyframes fadeIn{ from{ opacity:0; } }
body.is-locked{ overflow:hidden; }

.partners.is-modal{
  position:fixed; z-index:111;
  left:50%; top:50%; translate:-50% -50%;
  width:min(93vw,540px); max-height:84vh; overflow-y:auto;
  -webkit-overflow-scrolling:touch; overscroll-behavior:contain;
  padding:24px 22px 26px;
  background:linear-gradient(180deg,var(--surface-2),var(--canvas-soft));
  border:1px solid var(--line-strong); border-radius:var(--r-lg);
  box-shadow:var(--shadow-2);
  animation:modalIn .42s var(--ease-out) both;
}
@keyframes modalIn{ from{ opacity:0; translate:-50% -44%; } }
.partners.is-modal .partners__close{
  display:block; position:absolute; top:14px; inset-inline-end:14px;
  width:34px; height:34px; border-radius:50%;
  background:var(--surface-2); border:1px solid var(--line);
  font-size:1.3rem; line-height:1; cursor:pointer; color:var(--ink-dim);
}
.partners.is-modal .partners__close:hover{ color:var(--ink); border-color:var(--line-strong); }
.partners.is-modal .partners__back{  padding-bottom:22px; }
.partners.is-modal:focus{ outline:none; }
.partners.is-modal .partners__title{ padding-inline-end:38px; }
@keyframes panelIn{ from{ opacity:0; transform:translateY(14px); } }
.partners__back{
  display:inline-flex; align-items:center; gap:8px;
  background:none; border:0; cursor:pointer; padding:0 0 20px;
  font-size:.8rem; letter-spacing:.1em; text-transform:uppercase; color:var(--accent);
}
.partners__back:hover{ opacity:.7; }
.partners__title{ font-size:clamp(1.2rem,2vw,1.6rem); font-weight:500; line-height:1.2; }
.partners__blurb{ color:var(--ink-dim); font-size:.94rem; font-weight:300; margin-top:12px; max-width:46ch; }
.partners__list{ display:flex; flex-direction:column; gap:10px; margin-top:24px; }

.pcard{
  display:flex; align-items:flex-start; flex-wrap:wrap; gap:14px;
  padding:16px 16px; border:1px solid var(--line); border-radius:var(--r-md);
  background:var(--surface);
  transition:border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease),
             transform var(--t-fast) var(--ease);
  animation:panelIn .5s var(--ease-out) both;
}
/* no lift: a two-pixel nudge under the cursor reads as a jump, not a hover */
.pcard:hover{
  border-color:var(--tint,var(--accent));
  background:var(--surface-2);
}
.pcard__avatar{
  width:90px; height:90px; border-radius:50%; flex:none;
  transition:transform var(--t) var(--ease);
  display:grid; place-items:center; font-weight:500; font-size:1rem; letter-spacing:.04em;
  color:var(--accent);
  background:linear-gradient(140deg, var(--surface-2), var(--surface));
  border:1px solid var(--line-strong);
  overflow:hidden;
}
/* A person is never put through the page's picture treatment — in either
   ground. These are Meitar's own headshots and they stay exactly as supplied. */
.pcard__avatar img{ width:100%; height:100%; object-fit:cover; filter:none; }
.pcard__body{ width:100%; min-width:0; }
.pcard__name{ font-size:.94rem; font-weight:500; line-height:1.25; }
.pcard__name a{ text-decoration:none; border-bottom:1px solid transparent; transition:border-color var(--t-fast); }
.pcard__name a:hover{ border-bottom-color:var(--accent); }
.pcard__role{ font-size:.78rem; color:var(--ink-faint); margin-top:4px; }
/* a sibling of the body now, so it takes a row of its own once the card wraps */
.pcard__actions{ display:flex; flex-wrap:wrap; gap:7px; margin-top:12px; flex:1 0 100%; }
.pcard .chip{ padding:6px 11px; font-size:.72rem; }
/* A CARD LYING DOWN, AT A DESK.
   Stacked — portrait, then the name, then the two controls under it — the card
   was a tall block with a column of air beside the name, and four of them made
   a panel taller than the wheel. Narrowing it only made the block narrower. As
   one ROW it is the shape of what it holds: the portrait, the person beside
   it, and their two controls at the far end. The panel widens a little to
   carry that, which it can afford — the wheel steps aside and shrinks when a
   segment opens, and the room was going spare.

   Only where the panel is a panel. Below 1080 it becomes a sheet across the
   screen, and stacked is the right card there. */
@media (min-width:1081px){
  /* the row has to fit a portrait, a name and two controls; the panel is
     given the width that lets the longest name on the bench —
     "Shani Buchnick-Salomon" — sit on one line */
  .pie-side{ width:min(44%, 500px); }
  .pcard{ flex-wrap:nowrap; align-items:center; gap:14px; }
  .pcard__avatar{ width:64px; height:64px; }
  .pcard__body{ width:auto; flex:1 1 auto; }
  .pcard__actions{
    flex:0 0 auto; width:auto; margin-top:0; margin-inline-start:auto;
    flex-wrap:nowrap;
  }
}
.chip{
  display:inline-flex; align-items:center; gap:7px;
  padding:7px 13px; border-radius:100px; border:1px solid var(--line);
  font-size:.76rem; text-decoration:none; color:var(--ink-dim);
  transition:all var(--t-fast) var(--ease);
}
/* The call chip is a phone control. Above 900px it comes off every partner
   card — the card still carries Email and Full bio, and the number is in the
   closing block where it can be read rather than dialled.
   Doubled class AND placed after `.chip`: a media query adds no specificity,
   so `.chip{display:inline-flex}` below it would simply have won. */
@media (min-width:900px){ .chip.chip--tel{ display:none; } }
.chip:hover{
  color:var(--canvas); background:var(--tint,var(--accent)); border-color:var(--tint,var(--accent));
}
.chip svg{ width:13px; height:13px; }
.partners__all{ 
  display:inline-block; margin-top:22px; font-size:.85rem; color:var(--accent);
  text-decoration:none; border-bottom:1px solid transparent;
}
.partners__all:hover{ border-bottom-color:var(--accent); }

/* ═══════════════════════════════════════════ SERVICES FLOW (slide 4) ══ */
.flow{ position:relative; padding-inline-start:clamp(0px,4vw,54px); }
.flow__rail{
  position:absolute; inset-block:8px; inset-inline-start:0; width:1px;
  background:var(--line);
}
.flow__rail-fill{
  position:absolute; top:0; left:0; width:100%; height:0%;
  background:linear-gradient(180deg,var(--accent),var(--blue-500));
  box-shadow:0 0 14px rgba(var(--accent-rgb),.5);
}
.flow__list{ display:flex; flex-direction:column; }

.step{
  position:relative; border-bottom:1px solid var(--line);
  opacity:0; transform:translateY(26px);
  transition:opacity .7s var(--ease-out), transform .7s var(--ease-out);
}
.step.is-in{ opacity:1; transform:none; }
.step:first-child{ border-top:1px solid var(--line); }
.step__node{
  position:absolute; inset-inline-start:calc(-1 * clamp(0px,4vw,54px)); top:30px;
  width:9px; height:9px; border-radius:50%; margin-inline-start:-4px;
  background:var(--canvas); border:1px solid var(--line-strong);
  transition:all var(--t) var(--ease);
}
/* the node marks WHERE YOU ARE on the rail, so it lights for the open row
   only — hovering a row is not the same as being on it */
.step.is-open .step__node{
  background:var(--accent); border-color:var(--accent); box-shadow:0 0 0 5px rgba(var(--accent-rgb),.14);
}
@media (max-width:700px){ .step__node{ display:none; } }

.step__head{
  width:100%; display:flex; align-items:flex-start; gap:clamp(14px,2.5vw,32px);
  padding:clamp(20px,2.4vw,30px) 0; background:none; border:0;
  text-align:start; cursor:pointer;
}
.step__idx{
  /* the heading's colour, not the row's pastel — at this size a pastel on
     white is not a quiet mark, it is an invisible one */
  font-size:.74rem; letter-spacing:.14em; color:var(--ink-strong);
  font-variant-numeric:tabular-nums; padding-top:8px; flex:none; width:34px;
  transition:color var(--t-fast) var(--ease);
}
.step__titles{ flex:1; min-width:0; }
.step__title{
  display:block;
  font-size:clamp(1.1rem,2.1vw,1.6rem); font-weight:400; line-height:1.25; letter-spacing:-.015em;
  transition:color var(--t-fast) var(--ease);
}
.step__head:hover .step__title, .step.is-open .step__title{ color:var(--accent); }
.step__head:hover .step__idx, .step.is-open .step__idx{ color:var(--ink-strong); }

.step__plus{
  flex:none; width:38px; height:38px; border-radius:50%;
  border:1px solid var(--line-strong); position:relative;
  transition:all var(--t) var(--ease); margin-top:2px;
}
.step__plus::before, .step__plus::after{
  content:''; position:absolute; top:50%; left:50%; background:var(--ink);
  transform:translate(-50%,-50%); transition:all var(--t) var(--ease);
}
.step__plus::before{ width:13px; height:1px; }
.step__plus::after{ width:1px; height:13px; }
/* the row's own tint, so running down the list gives six colours rather than
   one repeated — the book's "light touches for variety", on the thing you
   actually touch */
.step__head:hover .step__plus{
  border-color:var(--tint,var(--accent)); background:var(--surface-hot);
}
.step.is-open .step__plus{
  background:var(--tint,var(--accent)); border-color:var(--tint,var(--accent));
  transform:rotate(135deg);
}
.step.is-open .step__plus::before, .step.is-open .step__plus::after{ background:var(--canvas); }

.step__panel{
  display:grid; grid-template-rows:0fr;
  transition:grid-template-rows var(--t) var(--ease);
}
.step.is-open .step__panel,
.step.is-measuring .step__panel{ grid-template-rows:1fr; }
.step.is-measuring .step__panel{ transition:none; }
.step__panel > div{ overflow:hidden; }
.step__body{
  padding:0 0 30px calc(34px + clamp(14px,2.5vw,32px));
  max-width:74ch; color:var(--ink-dim); font-weight:300; font-size:.98rem;
}

/* ══════════════════════════════════════════ IMAGERY — ONE TREATMENT ══ */
/* The deck's art is a mix of colour photography, greyscale renders and blue
   renders. Every picture goes through the same duotone — see --photo-filter —
   so they read as one set rather than three.

   And none of them is a picture box. An image is either a full-height panel
   running off the side of the page, dissolving into the copy across its inner
   edge, or the background of its whole section. */
.duo{
  display:block; position:absolute; inset:0; isolation:isolate; overflow:hidden;
}
.duo img{
  width:100%; height:100%; object-fit:cover;
  filter:var(--photo-filter);
  opacity:0; transform:scale(1.04);
  transition:opacity 1.2s var(--ease-out), transform 1.8s var(--ease-out);
}
.is-in .duo img{ opacity:var(--photo-o,1); transform:none; }

/* A photograph OF PEOPLE never goes through the duotone — same rule as the
   headshots. It is only held back far enough to sit on its ground. */
.duo--plain img{ filter:var(--photo-plain) !important; }

.edge{
  position:absolute; top:0; bottom:0; margin:0; z-index:0;
  width:min(50%, 820px); overflow:hidden;
  --fade:linear-gradient(90deg, transparent, #000 38%);
}
.edge--end  { inset-inline-end:0; }
.edge--start{ inset-inline-start:0; --fade:linear-gradient(270deg, transparent, #000 38%); }
.edge{ -webkit-mask-image:var(--fade); mask-image:var(--fade); }
/* held back top and bottom so a bright sky never out-shouts the copy */
.edge::before{
  content:''; position:absolute; inset:0; z-index:2; pointer-events:none;
  background:var(--photo-veil);
}

.section--edge{ position:relative; overflow:hidden; }
.section--edge > .wrap{ position:relative; z-index:1; }
.edge__text{ max-width:min(50%, 620px); }
.edge__text--end{ margin-inline-start:auto; }

/* full-bleed section background — only the wheel's ground still uses one */
.section__bg{ position:absolute; inset:0; overflow:hidden; z-index:0; }

/* ── GROUNDS WITHOUT PHOTOGRAPHS ──────────────────────────────────────────
   Four sections carried a landscape and now carry light instead. The line is
   taken from the cover: a pale blue-white that lifts toward one corner and
   settles to white, so the page reads as one clean surface rather than as a
   run of framed pictures. Each is angled differently so consecutive sections
   do not look identical, and every one of them ends on --canvas at both
   edges, which is what makes the joins disappear. */
/* THE BAND SITS ON THE COVER'S PHOTOGRAPH. Its ground is therefore a scrim,
   not a surface: translucent at the top so the server room carries on out of
   the hero without a seam, closing to solid --canvas by the bottom so the join
   to the wheel below is invisible. Nothing inside this block may be opaque. */
/* THE BAND SITS ON THE COVER'S PHOTOGRAPH. Its ground is therefore a scrim,
   not a surface: translucent at the top so the server room carries on out of
   the hero without a seam, closing to solid --canvas by the bottom so the join
   to the wheel below is invisible. Nothing inside this block may be opaque. */
.band{
  background:
    radial-gradient(120% 80% at 78% 0%, rgba(var(--wash-rgb),.10), transparent 62%),
    /* THE HANDOVER BELONGS TO THE BAND, NOT TO THE COVER. The white scrim
       used to open at 62% on its first pixel, and against a near-black
       photograph that is a hard line across the picture — so the cover was
       given a matching ramp at its foot, and that ramp is the white cloud the
       client saw over the bulb.

       It is the same fade, moved to the other side of the join. The band opens
       at NOTHING and reaches 62% by 130px — inside its own top padding,
       clamp(78px,11vh,150px), so the ramp lands in empty space and no line of
       copy is ever read off it, and the cover keeps its picture to its last
       row.

       Measured down the join at x=60: the cover's foot is (23,33,54), the
       band's first row (113,117,130), and 110px later (198,197,199). The step
       at the seam is the GROUND changing, not the picture — the cover carries
       the dark token set, so `--canvas` under its photograph is #0C1330 while
       the band's is white, and the same photograph at the same .5 reads dark
       over one and pale over the other. That is a dark section meeting a
       light one, which is a clean edge to have; what it is not is a white
       haze over the picture, which is what came off. */
    linear-gradient(180deg,
      rgba(var(--canvas-rgb), 0) 0,
      rgba(var(--canvas-rgb), .62) 130px,
      rgba(var(--canvas-rgb), .86) 30%,
      rgba(var(--canvas-rgb), .95) 76%,
      var(--canvas) 100%);
}
.cover{ position:relative; }
.section--services{
  background:
    radial-gradient(90% 70% at 12% 8%, rgba(var(--wash-rgb),.20), transparent 62%),
    radial-gradient(70% 60% at 92% 96%, rgba(var(--tint-sky-rgb),.16), transparent 66%),
    linear-gradient(180deg, var(--canvas), var(--canvas-soft) 60%, var(--canvas));
}
.section--why{
  background:
    radial-gradient(85% 65% at 88% 12%, rgba(var(--wash-rgb),.17), transparent 64%),
    linear-gradient(180deg, var(--canvas), var(--canvas-soft) 50%, var(--canvas));
}
.section--advisory{
  background:
    radial-gradient(95% 75% at 8% 88%, rgba(var(--wash-rgb),.19), transparent 66%),
    radial-gradient(60% 55% at 90% 6%, rgba(var(--tint-sky-rgb),.14), transparent 68%),
    linear-gradient(180deg, var(--canvas), var(--canvas-soft) 58%, var(--canvas));
}
.section--cta{
  background:
    radial-gradient(110% 85% at 50% 100%, rgba(var(--wash-rgb),.22), transparent 66%),
    linear-gradient(180deg, var(--canvas), var(--canvas-soft) 62%, var(--canvas-deep));
}
/* what each picture needs to sit under, judged one at a time */
/* no veil on this one: its picture is a plain half-panel now */
/* a section background is not a reveal — it is simply there */
.section__bg .duo img{ object-position:72% 50%; opacity:var(--photo-o,1); transform:none; }
.section__bg::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(90deg, var(--canvas) 4%,
              color-mix(in srgb, var(--canvas) 88%, transparent) 42%,
              color-mix(in srgb, var(--canvas) 22%, transparent) 78%,
              transparent 100%);
}
/* ── ONE GROUND ACROSS TWO SECTIONS ───────────────────────────────────────
   "Why Meitar" and the advisory streams share a single photograph, the same
   way the cover block and the tower each carry one across a pair.

   It is a STICKY WINDOW, not a panel. Stretched over both sections the picture
   would be blown up to two thousand pixels of height it does not have, and it
   would re-scale every time a row of the advisory list opened — the whole
   picture lurching. A window one viewport tall sticks to the top of the screen
   instead: constant size, a downscale of about 0.8 at 1440, and completely
   indifferent to what the sections below it are doing.

   overflow:CLIP on the wrapper, not hidden — `hidden` would make it a scroll
   container and the sticky child would stick to that instead of to the page,
   which is to say it would never move.

   The veil is FLAT. The generic `.section__bg::after` scrim is one-sided, for
   a section whose copy sits in a left column; here six cells run the whole
   measure in one section and the list runs the full width in the other, and
   only an even weight keeps the reading even. A bare colour is legal solely as
   the last layer of a multi-layer background, hence the one-colour gradient. */
.pair{ position:relative; overflow:clip; }
/* THE STICKY MUST NEVER REACH ITS FLOOR.
   A sticky element stops at the bottom of its containing block, and by the
   time you are reading the advisory list the window HAS stopped there. Open a
   row, the wrapper grows, the floor drops away and the picture jumps down to
   follow it — which is exactly what it was doing. The ground is given a
   viewport of slack below the pair so the floor is never in play while
   anything is being read; `overflow:clip` on the wrapper cuts it off again.
   The fades move to the wrapper for the same reason: a mask on a box that now
   ends off-screen would put its bottom fade off-screen with it. */
.pair::after{
  content:''; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:
    linear-gradient(to bottom, var(--canvas), rgba(var(--canvas-rgb),0) 90px),
    linear-gradient(to top,    var(--canvas), rgba(var(--canvas-rgb),0) 120px);
}
.pair > .section{ position:relative; z-index:1; background:none; }
.pair > .section > .wrap{ position:relative; z-index:1; }
/* a section standing on a photograph takes neither the plan grid nor a head
   rule — the same rule the tower's pair follows */
.pair > .section::before, .pair > .section::after{ display:none; }
.pair__bg{
  position:absolute; inset:0 0 -100svh 0; z-index:0; pointer-events:none;
}
.pair__bg .duo{
  position:sticky; top:0; inset-inline:0; bottom:auto;
  height:100svh; overflow:hidden;
}
.pair__bg .duo img{
  width:100%; height:100%; object-fit:cover; object-position:60% 50%;
  opacity:.7; filter:none; transform:none; transition:none;
}
.pair__bg::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(rgba(var(--canvas-rgb), .80) 0 100%);
}
/* This one was still reading as a wash. It carries the whole of the two
   opening sections, so it gets more presence than a section background
   normally would, and its scrim is pulled back to let it through. */
/* The one background with copy running across its WHOLE width, so it is the
   one that keeps a flat veil rather than a one-sided scrim. */

.section--services{ position:relative; overflow:hidden; }
.section--services .wrap{ position:relative; z-index:1; }


/* headings rise out of a mask instead of just fading */
.rise{ overflow:hidden; padding-bottom:.1em; }
.rise__i{ display:block; transform:translateY(105%); opacity:0; }
.rise.is-in .rise__i{
  transform:none; opacity:1;
  transition:transform 1s var(--ease-out), opacity .75s var(--ease-out);
}

/* ══════════════════════════════════════════════════════ WHY MEITAR ══ */
/* Deliberately not the deck's tick list: a hairline grid of lit cells, each
   with its own index, that respond to the pointer. The highlight follows the
   cursor inside the cell (--mx/--my come from app.js), which is what makes
   the six read as one surface rather than six boxes. */
.whys{
  display:grid;
  background:none;   /* a fill here shows through any cell still revealing */ gap:1px; background:var(--line);
  border:1px solid var(--line); border-radius:var(--r-lg); overflow:hidden;
  grid-template-columns:repeat(auto-fit,minmax(290px,1fr));
}
/* THE LIGHT TRAVELS ALONG THE EDGE, NOT THROUGH THE MIDDLE.
   The circle that used to follow the cursor sat BEHIND the words: a coloured
   film over a near-white ground, with navy type on top of it, which is exactly
   how a hover comes to read as "blurry". Moving the same circle onto the
   border keeps the effect — a light that follows you around the grid — and
   puts it somewhere it can never touch the text.

   The light is the cell's own pastel at FULL strength through its middle,
   easing out at the rim so it reads as a light and not as a patch. The colour
   is never substituted — it is the book's hex — only its reach is shaped. */
.why__edge{
  position:absolute; inset:0; z-index:2; pointer-events:none;
  padding:2px; opacity:0;
  background:radial-gradient(210px circle at var(--mx,50%) var(--my,50%),
             var(--tint,var(--accent)) 0%,
             var(--tint,var(--accent)) 30%,
             transparent 72%);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor; mask-composite:exclude;
  transition:opacity .32s var(--ease);
}
.why:hover .why__edge{ opacity:1; }
@media (hover:none){ .why__edge{ display:none; } }

.why{
  position:relative; overflow:hidden;
  background:var(--canvas-soft);
  padding:clamp(28px,3.2vw,42px) clamp(24px,2.8vw,36px);
  transition:background var(--t) var(--ease);
}

.why__idx{
  display:block; font-size:.72rem; letter-spacing:.2em; color:var(--tint,var(--accent));
  font-variant-numeric:tabular-nums; opacity:1; margin-bottom:20px;
  transition:opacity var(--t) var(--ease);
}
.why__title{
  display:block; font-size:1.06rem; font-weight:500; line-height:1.3; color:var(--ink-strong);
  transition:color var(--t-fast) var(--ease);
}
.why__rule{
  display:block; width:40px; height:3px; margin:14px 0 14px; border-radius:2px;
  background:var(--tint,var(--accent)); opacity:1;
  transition:width var(--t) var(--ease), opacity var(--t) var(--ease);
}
.why__body{ display:block; color:var(--ink-dim); font-size:.93rem; font-weight:300; }

.why:hover{ background:var(--surface-hot); }
.why:hover .why__idx{ opacity:1; }
.why:hover .why__rule{ width:78px; opacity:1; }
/* the TITLE stays Meitar Blue. A pastel is printed to be a mark on the page,
   not ink for words — as a heading colour on white it disappears. The rule
   under it, which is 3px thick, carries the cell's colour instead. */
.why:hover .why__title{ color:var(--ink-strong); }
@media (hover:none){
  .why:hover{ background:var(--canvas-soft); }
  .why:hover .why__title{ color:var(--ink-strong); }
}

.flow--plain{ padding-inline-start:0; }
/* the rail dots belong to the timeline; against the advisory photograph they
   just read as stray circles */
.flow--plain .step__node{ display:none; }


/* ════════════════════════════════════════════════════════ FINAL CTA ══ */
/* the ground itself is declared with the other grounds further up */
.section--cta{ position:relative; overflow:hidden; }
.cta-bg{ position:absolute; inset:0; }
.section--cta > .wrap{ position:relative; z-index:1; }
/* Two columns rather than one half-width stack: the copy states the offer on
   the left and the form sits beside it, so the section is as wide as every
   other one on the page. */
.cta__inner{
  position:relative; max-width:none;
  display:grid; gap:clamp(20px,2.4vw,34px) clamp(28px,4vw,72px);
  grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  /* the third row takes the slack, so the heading and its lede stay together
     at the top instead of being pushed apart by the form's height */
  grid-template-rows:auto auto 1fr;
  align-items:start;
}
.cta__inner .section__head, .cta__inner .lede{ grid-column:1; }
.cta__inner .lede{ margin-inline:0; max-width:34ch; }
.cta__inner .cform{ grid-column:2; grid-row:1 / -1; margin-top:0; }
@media (max-width:900px){
  .cta__inner{ grid-template-columns:minmax(0,1fr); }
    .cta__inner{ grid-template-rows:none; }
  .cta__inner .cform{ grid-column:1; grid-row:auto; }
  .cta__inner .lede{ max-width:none; }
}
/* One cell per pair, label over value. It used to be one flat grid with every
   label in the first row and every value in the second, which lines up only
   while the grid has exactly as many columns as there are pairs — narrowed to
   two for a phone, the same markup gave a block of four labels followed by a
   block of four values. The pair is the unit now, at every width.

   THE COLUMNS ARE SIZED BY WHAT IS IN THEM, and the row is the full measure
   rather than 940. The four values measure 121 / 231 / 77 / 131 at desk size,
   so EQUAL columns hand the address exactly what they hand "meitar.com" —
   inside 940 that was 196px each, leaving the address 35px short and breaking
   "Israel" onto a second line while the website column sat on 119px it had no
   use for. Widening alone does not fix it: at the full measure the equal
   column is 271px at 1240, but the wrap steps down to 1100 and 1020 faster
   than the type does, so between 1024 and 1600 it is 203–206 against a need
   of 206–212 and the line still breaks. Content-width tracks give each value
   what it actually needs and hand the slack to the gaps, which holds one line
   at every width with room to spare, and the last detail lands on the end of
   the rule. The cap was not earning its keep either — it stopped that rule
   172px short of the form standing directly above it.

   justify-content is a no-op on the two steps below, where the tracks are
   fractions and already fill the row. */
.cta__lines{
  position:relative; z-index:1;
  display:grid;
  grid-template-columns:repeat(var(--cols,4), auto);
  justify-content:space-between;
  max-width:100%;
  column-gap:clamp(24px,3.4vw,52px); row-gap:clamp(18px,2.4vh,26px);
  margin-top:clamp(30px,4vh,46px);
  padding-top:clamp(24px,3vh,34px); border-top:1px solid var(--line);
}
.cta__line{ display:flex; flex-direction:column; gap:7px; min-width:0; }
.cta__lines-v{ font-size:.92rem; }
.cta__lines-k{
  font-size:.68rem; letter-spacing:.2em; text-transform:uppercase; color:var(--accent);
}

/* The four-column step survives on content tracks down to its own end at 900.
   420 was too late for the last one: two columns there are 182 against an
   address that wants 261, so the single column starts while it still fits. */
@media (max-width:900px){
  .cta__lines{ grid-template-columns:repeat(2, minmax(0,1fr)); }
}
@media (max-width:640px){
  .cta__lines{ grid-template-columns:minmax(0,1fr); }
}
/* inline-block, so the rule under the link is exactly as wide as the link and
   not as wide as the cell it sits in */
.cta__lines a{
  display:inline-block;
  text-decoration:none; border-bottom:1px solid transparent; transition:border-color var(--t-fast);
}
.cta__lines a:hover{ border-bottom-color:var(--accent); }

/* ══════════════════════════════════ PARAGRAPH BLOCKS + SPLIT LAYOUT ══ */
/* The client's copy is fixed and long, so readability is bought with measure,
   leading and rhythm rather than by cutting words. */
.prose{ margin-top:clamp(26px,3.4vh,40px); display:flex; flex-direction:column; gap:1.15em; }
.prose p{
  font-size:clamp(1rem,1.25vw,1.16rem); line-height:1.72; font-weight:300;
  color:var(--ink-dim); max-width:68ch;
}
/* the opening paragraph is set exactly like the ones under it — same size,
   colour and weight. Rhythm carries the emphasis, not type. */


.split{
  display:grid; gap:clamp(30px,4.5vw,72px);
  grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  align-items:center;
}

/* ── THE TOWER, ACROSS TWO SECTIONS ───────────────────────────────────────
   The panel belongs to the wrapper, not to either section, so one photograph
   runs the whole height of "Legal Core Services" and "How we work" together
   and the building is seen entire rather than cropped twice. "Why Meitar"
   follows it at full page width and has a ground of its own. */
/* clip, because the picture column is deliberately taller than this wrapper —
   see the note on the sticky's floor below */
.tower{ position:relative; overflow:clip; }
/* Same device as `.pair`: the fades belong to the WRAPPER, because the column
   they would otherwise mask now ends a viewport below it. */
.tower::after{
  content:''; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:
    linear-gradient(to bottom, var(--canvas), rgba(var(--canvas-rgb),0) 80px),
    linear-gradient(to top,    var(--canvas), rgba(var(--canvas-rgb),0) 110px);
}
/* A STICKY WINDOW, NOT A TALL PANEL.
   The column is as tall as the two sections together — about 2500px — and a
   `cover` fit made the browser blow the 978x2078 photograph up by 1.73 to
   fill it. That, and not the compositing, is why the building went soft: the
   file was being asked for detail it does not have.

   So the column is only the CLIP. Inside it a window one viewport tall sticks
   to the top of the screen, and the picture is laid into it at its own aspect
   — 662 wide, which is a DOWNSCALE of about 0.68 and therefore as sharp as the
   file can be. app.js then travels the picture through the window as the two
   sections go by, so the whole building is seen, top to bottom, and the motion
   is the whole height of it rather than a nudge.

   overflow:CLIP, not hidden: `hidden` would make this column a scroll
   container and the sticky child would stick to it instead of to the page,
   which is to say it would never move at all. */
/* THE STICKY MUST NEVER REACH ITS FLOOR.
   A sticky element stops at the bottom of its containing block, and by the
   time you are down at "How we work" the window HAS stopped there. Open a row
   of the services list, the wrapper grows, the floor drops away and the
   picture jumps down after it. A viewport of slack below keeps the floor out
   of play while anything is being read; the wrapper's `overflow:clip` cuts the
   overhang off again, and the fades live on the wrapper for the same reason.
   No fade across the inner edge: half the width is the photograph as it is,
   and the copy sits clear of it. */
.tower__pic{
  position:absolute; top:0; bottom:-100svh; inset-inline-start:0; z-index:0;
  width:min(46%, 760px); overflow:clip; margin:0;
}
.tower__pic::before{ display:none; }
.tower__pic .duo{
  position:sticky; top:0; inset-inline:0; bottom:auto;
  height:100svh; overflow:hidden;
}
/* laid in at its own aspect and moved with a transform — no object-fit, so
   nothing is stretched, and the travel is a composited translate.
   filter:none, explicitly. Every other picture goes through --photo-filter,
   and in the light ground that is a whisper — brightness .98, saturate 1.04 —
   but this one is the building and it is shown as photographed. */
.tower__pic .duo img{
  position:absolute; top:0; left:50%;
  /* NO TRANSITION. `.duo img` carries `transition:transform 1.8s` for the
     reveal, and with the travel written into the same property every scroll
     tick started an eighteen-hundred-millisecond ease — so the building went
     on climbing for nearly two seconds after the page had stopped. */
  transition:none;
  /* Half again as wide as the window, capped at the file's own 978px so it is
     never enlarged — at 1440 that lands on a scale of 0.98, which is as close
     to one-to-one as this photograph gets. The wider lay-in is what keeps the
     signage on the crown at the size it reads at, and it buys more than a
     thousand pixels of travel besides.
     55.2%, not 50%: that is where the tower actually stands in the frame, so
     centring on it puts the building in the middle of the window rather than
     the picture. `translate` is used for this and `transform` for the travel —
     they are separate properties and compose, so app.js never has to know. */
  width:calc(100% * var(--tower-zoom, 1.45)); max-width:978px; height:auto;
  translate:-55.2% 0;
  opacity:1; filter:none; transform:none;
  will-change:transform;
}
@media (prefers-reduced-motion: reduce){
  .tower__pic .duo img{ will-change:auto; }
}
.tower .section{ position:relative; z-index:1; background:none; }
/* The wrap's own measure is what was leaving a canyon on both sides of the
   copy: the tower takes the left 46% and the centred 1100px wrap then held the
   text to a 486px column with 400px of nothing to the right of it. Inside the
   tower the wrap is released, and the column is placed off the PICTURE instead
   — a fixed gap clear of its edge, and a page margin on the right. */
.tower .section > .wrap{ position:relative; z-index:1; max-width:none; padding-inline:0; }
/* Inside the tower a section has no ground of its own and no ground furniture
   either: the plan grid would be drawn across the photograph and the head
   rule's pastel block would land on it. The building IS the interest here. */
.tower .section::before, .tower .section::after{ display:none; }
/* the copy in both sections clears the panel */
/* min(46%, 760px) is the picture's own width, and it only resolves to the same
   number as the picture while the wrap it sits in is the full width of the
   section — hence no padding on the wrap above, and the page margin taken here
   instead. Get that wrong and the column creeps in under the photograph. */
.tower .edge__text{
  position:relative; max-width:none;
  margin-inline-start:calc(min(46%, 760px) + clamp(32px, 4vw, 88px));
  margin-inline-end:clamp(24px, 5vw, 112px);
}
@media (max-width:1080px){
  .tower .section > .wrap{ max-width:var(--wrap); padding-inline:var(--pad); }
  .tower .edge__text{ max-width:none; margin-inline-start:0; }
}
/* On a phone the sticky column has nowhere to stand — half the width IS the
   whole width — so the building stops being a column beside the copy and
   becomes the GROUND under both sections instead, behind a scrim heavy enough
   to read against. Still a sticky window one screen tall, for the same reason
   as everywhere else: a picture stretched over the height of a pair is blown
   up past what the file holds.

   The doubled class is deliberate: the generic `.edge` mobile rule further
   down the file pulls edge panels out by the page gutter and turns them into
   bands, and at equal weight it would win on source order.

   app.js needs no breakpoint of its own — the window is one screen tall and
   the picture is `cover`, so its travel comes out at zero and initTower has
   nothing to do. */
@media (max-width:1080px){
  .tower .tower__pic{
    position:absolute; inset:0 0 -100svh 0; width:auto; height:auto; margin:0;
  }
  .tower .tower__pic .duo{
    position:sticky; top:0; inset-inline:0; bottom:auto;
    height:100svh; overflow:hidden;
  }
  .tower .tower__pic .duo img{
    position:absolute; inset:0; width:100%; height:100%; max-width:none;
    object-fit:cover; object-position:50% 26%;
    translate:none; transform:none;
  }
  /* The scrim, over the picture and under the copy. Pulled back from .87 so
     the building actually reads — the copy that stands on it is Meitar Blue at
     full strength on a light photograph, which holds at this weight. */
  .tower .tower__pic::after{
    content:''; position:absolute; inset:0;
    background:linear-gradient(rgba(var(--canvas-rgb), .74) 0 100%);
  }
  /* the picture is held back a little as well as veiled: a heavier sheet of
     white greys the building out, where pulling the picture back keeps its
     colour and takes the edge off the city detail behind the small type */
  .tower .tower__pic .duo img{ opacity:.9; }
}

.section--expertise{
  background:
    radial-gradient(80% 55% at 80% 25%, rgba(var(--wash-rgb),var(--wash-a)), transparent 64%),
    var(--canvas);
}
/* THREE ACROSS. They were a stack from the days when this copy stood in a
   half-width slot; they are three parallel claims and they read as three.

   The index has to come off the side to make that work. In a stack there is
   room for a 74px gutter down the left of every cell to hang the number in;
   in a third of the column beside the tower that gutter is most of the cell,
   and the copy was coming out at a dozen characters a line. So here the number
   sits ABOVE the title, in flow, and the cell keeps ordinary padding — which
   is most of the measure handed back. */
.section--expertise .pillars{
  grid-template-columns:repeat(3, minmax(0,1fr));
  margin-top:clamp(28px,3.5vh,44px);
}
.section--expertise .pillars li{
  padding:clamp(22px,2.4vw,32px) clamp(20px,2.2vw,28px);
}
.section--expertise .pillar__idx{
  position:static; display:block; margin-bottom:14px;
}
.section--expertise .pillars b{ font-size:1rem; }
/* ONE BASELINE ACROSS THE THREE.
   The three cells are three parallel claims, and they only read as parallel if
   the running text starts at the same height in each. One title wraps to two
   lines and the other two do not, so the paragraph under it used to sit a line
   lower than its neighbours. The cells share the section's rows instead: the
   number, the title and the body are three rows of the PARENT grid, and each
   cell borrows them with `subgrid`, so the tallest title sets the height of
   that row for all three and every paragraph begins on the same line. */
@supports (grid-template-rows: subgrid){
  .section--expertise .pillars{ grid-template-rows:auto auto auto; }
  .section--expertise .pillars li{
    display:grid; grid-row:span 3; grid-template-rows:subgrid; align-content:start;
  }
  /* The spacing between the three parts is now the GRID's row gap rather
     than each part's own margin — it has to be, because the rows are shared
     and a margin inside one cell would not move the others. Only the rows gap;
     the columns stay flush so the hairlines between the cells still meet. */
  .section--expertise .pillars{ row-gap:10px; column-gap:0; }
  .section--expertise .pillars b{ margin-bottom:0; align-self:start; }
  .section--expertise .pillar__idx{ margin-bottom:4px; }
}
/* Older engines keep the stacked cell and get the same result the plain way:
   two lines of room for the title, which is the longest of the three. */
@supports not (grid-template-rows: subgrid){
  .section--expertise .pillars b{ min-height:2.6em; }
}
/* a hairline between them rather than a gap with a fill behind it: a fill on
   the grid shows through any cell that is still revealing */
.section--expertise .pillars li + li{ border-inline-start:1px solid var(--line); }
@media (max-width:720px){
  .section--expertise .pillars{ grid-template-columns:minmax(0,1fr); }
}
.section--advisory .section__head{ margin-bottom:clamp(30px,4vh,52px); }
/* the row numbers were sitting on the photograph's edge on a laptop */
/* the copy sits on the LEFT of this one, clear of the picture on the right */
/* There is no picture beside this one now, so the block takes the section's
   full width — held to half of it, it read as an unfinished column. The
   heading and its lede keep a measure of their own so the lines stay
   readable; only the three streams run the whole way across. */
.section--advisory .edge__text{ padding-inline-start:0; max-width:none; }
/* NOT `ch` on the head: that unit resolves against the CONTAINER's font size,
   which here is the small eyebrow, and the heading collapsed to a word a
   line. The measure belongs on the elements that carry the type. */
.section--advisory .h2{ max-width:min(100%, 18ch); }
.section--advisory .lede{ max-width:min(100%, 58ch); }
.section--advisory .eyebrow{ white-space:nowrap; }

.section--advisory > .wrap{ position:relative; z-index:1; }

/* Two headings come from the deck as full sentences rather than display
   lines, so they are set at statement size instead of poster size. */
.section--practice .h2{ max-width:26ch; font-size:clamp(1.5rem,2.7vw,2.15rem); line-height:1.24; }
/* this block sits over the section's own wash, so it is set in full ink
   rather than the dimmed tone used for body copy on a flat ground */
.section--practice .lede{ color:var(--ink); }
.section--practice .lede--sm{ color:var(--ink-dim); }
.section--why .h2{ max-width:38ch; font-size:clamp(1.3rem,2.1vw,1.75rem); line-height:1.4; font-weight:300; }

/* the "Deliverables:" line the client appends to each advisory stream */
.step__deliverables{
  margin-top:20px; padding-top:18px; border-top:1px solid var(--line);
  font-size:.88rem; line-height:1.65; color:var(--ink-dim); font-weight:300;
}
.step__deliverables b{
  color:var(--accent); font-weight:500;
  letter-spacing:.02em;
}

/* ═══════════════════════════════════════════════════════════ FOOTER ══ */
.footer{ background:var(--canvas-deep); border-top:1px solid var(--line); padding:36px 0; }
.footer__inner{
  display:flex; flex-wrap:wrap; gap:16px; justify-content:space-between; align-items:center;
  font-size:.8rem; color:var(--ink-faint);
}
.footer__links{ display:flex; gap:22px; }
.footer__links a{ text-decoration:none; transition:color var(--t-fast); }
.footer__links a:hover{ color:var(--accent); }

/* ═══════════════════════════════════════ THE BOOK'S PASTEL TINTS ══
   FIVE, not six. The client marked sky, lilac, green, coral and sand; olive
   (#BAB86B) is the one they left unmarked, and it is the one that goes muddy
   next to the others, so it is out of the cycle. It stays declared as --t4 for
   anything that wants it by name.

   Thirteen segments over five tints never puts two of the same next to each
   other, including across the wrap — 13 mod 5 = 3. */
.tints > *:nth-child(5n+1){ --tint:var(--t1); --tint-rgb:var(--t1-rgb); }
.tints > *:nth-child(5n+2){ --tint:var(--t2); --tint-rgb:var(--t2-rgb); }
.tints > *:nth-child(5n+3){ --tint:var(--t3); --tint-rgb:var(--t3-rgb); }
.tints > *:nth-child(5n+4){ --tint:var(--t5); --tint-rgb:var(--t5-rgb); }
.tints > *:nth-child(5n+5){ --tint:var(--t6); --tint-rgb:var(--t6-rgb); }
/* anything that has not been given one falls back to the accent, so a list
   without .tints is unchanged */
.tints > *{ --tint:var(--accent); --tint-rgb:var(--accent-rgb); }

/* The same five, led by the warm end — coral, lilac, sand — for the two lists
   the client wanted carrying orange/purple/pink. Declared after the plain
   cycle so it wins on the lists that ask for it. */
.tints--warm > *:nth-child(5n+1){ --tint:var(--t5); --tint-rgb:var(--t5-rgb); }
.tints--warm > *:nth-child(5n+2){ --tint:var(--t2); --tint-rgb:var(--t2-rgb); }
.tints--warm > *:nth-child(5n+3){ --tint:var(--t6); --tint-rgb:var(--t6-rgb); }
.tints--warm > *:nth-child(5n+4){ --tint:var(--t1); --tint-rgb:var(--t1-rgb); }
.tints--warm > *:nth-child(5n+5){ --tint:var(--t3); --tint-rgb:var(--t3-rgb); }

/* The one place the book's OLIVE is used. It is out of the cycle everywhere
   else — it goes muddy beside the other four — but the client wants the pale
   green in this cell replaced by it. */
#whyList > li:nth-child(3){ --tint:var(--tint-olive); --tint-rgb:186,184,107; }


/* ═══════════════════════════════════════ THE DATA CENTER CORE TEAM ══
   Four cards above the wheel. They read left, like every other block of text
   on the page — the wheel below is the one centred thing in this section, and
   it is centred because it is a circle, not because its words are. */
/* THE FOUR PARTNERS STAND ON THE PLAN GRID.
   It came up from behind the wheel, where it was competing with a diagram.
   Here there is nothing else on the ground, and four people on a drawn floor
   is the picture this section wants. Full bleed, because the block itself is
   held to the wrap — the grid runs out past it to both edges and is masked to
   nothing before it reaches them. */
.core{ position:relative; margin-top:clamp(34px,4.5vh,58px); }
.core::before{
  content:''; position:absolute; z-index:0; pointer-events:none;
  /* It runs well past the four cards — up behind the section's heading and
     down toward the line that introduces the wheel — so it reads as the floor
     the whole upper half of the section stands on rather than as a panel
     tucked behind a row of portraits. The section clips it. */
  top:calc(-1 * clamp(150px, 26vh, 320px)); bottom:calc(-1 * clamp(130px, 22vh, 280px));
  left:50%; width:100vw; translate:-50% 0;
  background-image:
    linear-gradient(90deg,  rgba(var(--wash-rgb), .11) 0 1px, transparent 1px),
    linear-gradient(180deg, rgba(var(--wash-rgb), .11) 0 1px, transparent 1px);
  background-size:var(--plan-step) var(--plan-step);
  background-position:50% 50%;
  -webkit-mask-image:radial-gradient(74% 104% at 50% 50%, #000 34%, transparent 92%);
          mask-image:radial-gradient(74% 104% at 50% 50%, #000 34%, transparent 92%);
}
.core__title, .core__list{ position:relative; z-index:1; }
.core__title{
  font-size:clamp(1.05rem,1.7vw,1.35rem); font-weight:500; letter-spacing:-.01em;
  color:var(--ink-strong);
}
/* FIVE ACROSS, and the count is written here rather than left to auto-fit:
   the row is the client's own order and it should break where we say, not
   wherever a min-width happens to run out. Below 1180 five of these are
   narrower than their own two buttons, so it goes to three and then two. */
.core__list{
  display:grid; gap:clamp(14px,1.8vw,24px);
  grid-template-columns:repeat(5,minmax(0,1fr));
  margin-top:clamp(22px,3vh,34px);
}
@media (max-width:1180px){ .core__list{ grid-template-columns:repeat(3,minmax(0,1fr)); } }
/* WHERE THERE ARE FIVE, THE TWO BUTTONS SHARE A ROW — AND THE MARKS COME OFF.
   The fifth card takes the row from ~290px a card to ~180, which leaves each
   chip between 52 and 73 pixels while it wants 70 to 74. Measured, at five
   widths, the shortfall is 1px at 1920 and 18px at 1280.

   The 20px that buys it back is the icon and the gap beside it: 13 and 7.
   They are the right thing to give up, because the mark and the word beside
   it say the same thing — "Email" next to an envelope — so dropping the mark
   costs a decoration while dropping the word would cost the meaning. A little
   comes off the card's side padding too, which is 16px of measure returned to
   both chips at once.

   The wheel's own partner cards keep their icons; they are twice this wide.
   So does the phone, where a card is the width of the screen. */
/* THE FIVE CARDS ARE CENTRED — PORTRAIT, NAME AND TITLE.
   A DELIBERATE EXCEPTION, asked for and recorded rather than drifted into:
   everywhere else on this page the type is left-aligned and the wheel is the
   only centred thing. It stops at these five cards. The buttons are left
   alone — they already fill the row between them, so there is nothing to
   centre.

   Above 700px only: below that the card turns into a row with the portrait
   beside the name rather than above it, and there is no middle to sit in. */
@media (min-width:701px){
  .core__list .ccard__avatar{ margin-inline:auto; }
  .core__list .ccard__name,
  .core__list .ccard__role{ text-align:center; }
}
@media (min-width:1181px){
  .core__list .ccard{ padding-inline:16px; }
  .core__list .ccard__actions{ flex-direction:row; gap:7px; }
  .core__list .ccard__actions .chip{
    flex:1 1 0; min-width:0; width:auto;
    padding-inline:7px; white-space:nowrap;
  }
  .core__list .ccard__actions .chip svg{ display:none; }
}
.ccard{
  display:flex; flex-direction:column; align-items:flex-start;
  /* the body is a wrapper now, so the desk layout has to keep filling the card */
  padding:clamp(20px,2.2vw,28px) clamp(18px,1.8vw,24px);
  background:var(--canvas-soft);
  border:1px solid var(--line); border-radius:var(--r-md);
  transition:background var(--t) var(--ease), border-color var(--t) var(--ease),
             transform var(--t) var(--ease);
  transition-delay:var(--d,0ms);
}
.ccard:hover{
  background:var(--surface-hot);
  border-color:var(--tint,var(--accent));
  transform:translateY(-3px);
}
.ccard__avatar{
  position:relative; width:clamp(84px,8vw,116px); aspect-ratio:1;
  border-radius:50%; overflow:hidden; flex:none;
  background:var(--surface-2);
  /* no ring: the portraits sit on the card's own ground */
  transition:transform var(--t) var(--ease);
}
.ccard:hover .ccard__avatar{ transform:scale(1.04); }
.ccard__avatar img{ width:100%; height:100%; object-fit:cover; filter:none; }  /* headshots stay as supplied */
.ccard__body{ width:100%; }
.ccard__name{ margin-top:18px; font-size:1rem; font-weight:500; color:var(--ink-strong); }
.ccard__name a{ text-decoration:none; border-bottom:1px solid transparent; transition:border-color var(--t-fast); }
.ccard__name a:hover{ border-bottom-color:var(--tint); }
.ccard__role{ margin-top:4px; font-size:.82rem; color:var(--ink-faint); }
/* Two to a row, always. On a laptop the cards are narrow enough that three
   full-width chips stacked into three lines, which looked broken. */
.ccard__actions{
  display:grid; grid-template-columns:repeat(2, minmax(0,1fr));
  gap:8px; margin-top:16px; width:100%;
}
.ccard__actions .chip{ justify-content:center; padding:7px 8px; font-size:.72rem; }
.ccard__actions .chip:last-child:nth-child(odd){ grid-column:1 / -1; }
/* AT A DESK THE ROW COUNTS WHAT IS DRAWN, NOT WHAT IS IN THE MARKUP.
   The call chip comes off above 900px — but it is still in the DOM, and
   `nth-child` counts it there. So of the two chips that are actually drawn,
   the second was the THIRD child: odd, and last, and therefore spanning the
   whole row on a line of its own. Email sat in one column and Full bio ran
   full width underneath it, which is not two actions on a card, it is a
   mistake. A flex row places only the boxes that exist, so the count cannot
   be got wrong; the grid stays below 900 where all three chips are drawn. */
@media (min-width:900px){
  .ccard__actions{ display:flex; flex-wrap:wrap; }
  .ccard__actions .chip{ flex:1 1 0; }
}
@media (max-width:900px){ .core__list{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
/* two across on a phone, not one — 460 was collapsing them on every handset
   the client actually holds */
@media (max-width:359px){ .core__list{ grid-template-columns:minmax(0,1fr); } }


/* ═══════════════════════════════════════ CONTACT A PARTNER — FORM ══
   In the page, in the closing block, under the copy that asks the question.
   Two columns on the desktop width the block gives it, one below 640px. */
.cform{ margin-top:clamp(26px,3.2vh,38px); }
.cform__grid{
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(11px,1.4vw,16px);
}
.field{ display:flex; flex-direction:column; gap:6px; min-width:0; }
.field--wide{ grid-column:1 / -1; }
.field label{
  font-size:.72rem; letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink); font-weight:500;
}
/* On a phone the same 500 reads as bold: the labels are small, tracked out and
   upper-case, and every one of those adds weight of its own. Back to the
   regular cut, with the colour doing the work instead. */
@media (max-width:700px){ .field label{ font-weight:400; } }
.field__opt{ text-transform:none; letter-spacing:.02em; font-weight:400; color:var(--ink-dim); }
/* The fields sit on a photograph, so they are glass rather than panels: no
   fill at all, and the outline carrying them instead — a little stronger than
   the page's hairline so it still reads against moving water. */
.field input, .field select, .field textarea{
  font:inherit; font-size:.94rem; color:var(--ink);
  background:transparent;
  border:1px solid color-mix(in srgb, var(--ink) 30%, transparent);
  border-radius:var(--r-sm); padding:10px 13px; width:100%;
  transition:border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease),
             background var(--t-fast) var(--ease);
}
.field input:hover, .field select:hover, .field textarea:hover{
  border-color:color-mix(in srgb, var(--ink) 45%, transparent);
}
/* The list a <select> drops open is drawn by the browser, not by this
   stylesheet — the only reliable lever is the colour scheme of the element
   itself, which the dark bands now declare. The option colours below are for
   the engines that do honour them. */
.field select option{ background:var(--canvas); color:var(--ink); }
.field input::placeholder, .field textarea::placeholder{ color:var(--ink-faint); }
.field textarea{ resize:vertical; min-height:80px; }
.field input:focus, .field select:focus, .field textarea:focus{
  outline:none; border-color:var(--accent);
  box-shadow:0 0 0 3px rgba(var(--accent-rgb),.22);
}
/* the trap: present to a robot reading the markup, gone to everything else */
.cform__trap{
  position:absolute; width:1px; height:1px; overflow:hidden;
  clip-path:inset(50%); white-space:nowrap; pointer-events:none;
}
.cform__error{ margin-top:14px; font-size:.85rem; color:var(--t5); }
.cform__foot{
  display:flex; flex-wrap:wrap; gap:12px; align-items:center;
  margin-top:clamp(18px,2.2vh,26px);
}
@media (max-width:640px){
  /* one column, and the rows get real air between them: at 11px the fields
     read as one block of boxes rather than as separate questions */
  .cform__grid{ grid-template-columns:minmax(0,1fr); gap:20px; }
  .field{ gap:9px; }
}

/* ── THE ANSWER, AS THE CLIENT DREW IT ────────────────────────────────────
   A light card on a dark, blurred server room, with the lockup beneath it.
   Everything in it is live text set from content.js — nothing here is a
   picture of words.

   TWO RULES OF THIS PAGE ARE SUSPENDED INSIDE THIS BOX, and only inside it.
   The type is CENTRED, where everywhere else on the site it is left-aligned
   and the wheel is the only centred thing. And its ground is DARK, where the
   page has one ground and it is light. Both because this is the client's own
   design, drawn and handed over; the exception stops at the card's edge. */
.cmodal[hidden]{ display:none; }

/* the photograph, out of focus and taken down. Inset past the edges so the
   blur has no soft border of its own to show at the sides. */
.cmodal__scrim{
  position:fixed; inset:0; z-index:140; overflow:hidden;
  background:var(--navy-900, #0A1226);
  animation:fadeIn .34s var(--ease) both;
}
.cmodal__scrim::before{
  content:''; position:absolute; inset:-7%;
  background:url('../img/server-room.jpg') center/cover no-repeat;
  filter:blur(15px) brightness(.42) saturate(.85);
}
/* and a little more weight in the middle, so the card never sits on a bright
   patch of the corridor */
.cmodal__scrim::after{
  content:''; position:absolute; inset:0;
  background:radial-gradient(120% 90% at 50% 50%, rgba(6,11,30,.55), rgba(6,11,30,.82));
}

/* card and lockup as one column, and the column is what scrolls when a screen
   is too short to hold them */
.cmodal__stack{
  position:fixed; z-index:141;
  left:50%; top:50%; translate:-50% -50%;
  width:min(92vw, 560px); max-height:92vh; overflow-y:auto;
  -webkit-overflow-scrolling:touch; overscroll-behavior:contain;
  display:flex; flex-direction:column; align-items:center;
  animation:modalIn .46s var(--ease-out) both;
}
.cmodal__card{
  width:100%;
  padding:clamp(38px,5vw,62px) clamp(26px,4vw,54px) clamp(34px,4.4vw,54px);
  border-radius:26px; border:0; outline:none;
  /* STONE GREY, the book's own off-white. The card in the client's drawing is
     this colour, so there was nothing to invent. */
  background:var(--stone);
  box-shadow:0 44px 90px -30px rgba(2,6,20,.7);
  text-align:center;
}
/* THE MARKS: two rules and a dot, in the book's sand, printed as printed —
   full opacity, no mix, no fade. They are marks, and the words near them are
   ink; ink on this page is never a pastel. */
.csent__rule{
  display:block; width:58px; height:2px; margin:0 auto;
  background:var(--tint-sand);
}
.csent__dot{
  display:block; width:7px; height:7px; border-radius:50%; margin:0 auto;
  background:var(--tint-sand);
}
/* ── THE SENTENCE WRAPS AT THE HEADLINE'S WIDTH ───────────────────────────
   Not at a guessed measure in `ch`, and not by shrinking the type: the box
   itself is the headline's own width, so the sentence fills that line exactly
   and only goes narrower when a word will not fit on it.

   CSS cannot read one element's width from another, so this is the table
   trick. `display:table` makes the box shrink to the widest thing in it. The
   headline contributes its longest line — `white-space:pre-line` means the
   newline in the copy is honoured, so that is "for reaching out!" rather than
   the whole sentence. The paragraph is then given `width:0`, which removes it
   from that calculation entirely, and `min-width:100%`, which makes it fill
   whatever width the headline settled on. Take either half away and the box
   sizes to the paragraph instead, which is the thing being prevented. */
.csent__measure{ display:table; margin-inline:auto; }
.csent__measure .csent__body{ width:0; min-width:100%; }
.csent__title{
  margin:clamp(22px,2.6vw,30px) auto;
  /* the break after "Thank you" is a newline in content.js — a decision about
     the copy, kept with the copy. No max-width fights it: no width both breaks
     after "you" AND keeps "for reaching out!" whole, which is why the drawing
     has an explicit break in it. */
  white-space:pre-line; max-width:100%;
  /* +2px on the client's ask, and as a calc rather than by nudging the clamp:
     the clamp is three numbers that each govern a different width, and adding
     the two pixels outside it moves all three by exactly two. */
  font-size:calc(clamp(1.85rem,4.4vw,2.65rem) + 8px); font-weight:500;
  line-height:1.14; letter-spacing:-.02em;
  color:var(--navy-700);
}
.csent__body{
  margin:clamp(22px,2.6vw,30px) auto 0;
  font-size:calc(clamp(1rem,1.35vw,1.12rem) + 8px); font-weight:400; line-height:1.5;
  color:var(--navy-700);
}
.csent__note{
  margin:clamp(20px,2.4vw,26px) auto 0;
  max-width:34ch;
  font-size:calc(.9rem + 4px); font-weight:400; line-height:1.55;
  color:var(--ink-dim);
}
.csent__dot{ margin-top:clamp(22px,2.6vw,28px); }
.csent__link{
  color:var(--navy-700); text-decoration:none;
  border-bottom:1px solid rgba(23,47,86,.45);
  transition:border-color var(--t-fast) var(--ease);
}
.csent__link:hover{ border-bottom-color:var(--navy-700); }
.cmodal__logo{
  display:block; width:min(210px,46vw); height:auto;
  margin-top:clamp(24px,3vw,34px); flex:none;
}

/* The way out, on the scrim rather than in the card — the drawing has nothing
   in the card but the message. A drawn cross in a box: centred because the box
   says so, with nothing left to nudge. */
.cmodal__x{
  position:fixed; z-index:142; top:22px; inset-inline-end:22px;
  width:42px; height:42px; border-radius:50%; padding:0;
  display:grid; place-items:center;
  background:rgba(255,255,255,.10); border:1px solid rgba(255,255,255,.34);
  color:#FFFFFF; cursor:pointer;
  transition:background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.cmodal__x svg{ width:15px; height:15px; display:block; }
.cmodal__x:hover{ background:rgba(255,255,255,.2); border-color:rgba(255,255,255,.6); }

@media (max-width:560px){
  .cmodal__card{ border-radius:20px; }
  .cmodal__x{ top:14px; inset-inline-end:14px; width:38px; height:38px; }
}
/* THE SMALLEST PHONES GIVE A LITTLE OF THE HEADLINE BACK.
   "for reaching out!" wants 259px and a 320px screen leaves it 242, so it
   split into "for reaching" / "out!" — which is worse than a slightly smaller
   line, and it also dragged the headline narrower than the sentence beneath
   it. Two points down and the phrase holds together again. */
@media (max-width:370px){
  .csent__title{ font-size:34px; }
}



/* ══════════════════════════════════════════════════════════════ FAB ══ */
/* ── LIQUID GLASS ─────────────────────────────────────────────────────────
   A blurred translucency is not glass. Three things separate them, and all
   three are here:

   1. REFRACTION. #lgRefract (see index.html) displaces the backdrop by the
      gradients in a lens normal map, so the page BENDS at the rim exactly as
      it would through a real curved edge. This is the effect the eye reads as
      glass; everything else is supporting detail.
   2. SPECULAR EDGE. A bright highlight on the upper-left rim and a dimmer one
      opposite, drawn as a gradient ring and masked to the border only.
   3. THICKNESS. Inset shadows top and bottom so the pill has a body rather
      than being a hole in the page.

   The tint is deliberately faint — real glass is nearly clear and lets the
   blur and the bending do the work. The label carries a shadow of its own so
   it stays legible over whatever the button happens to be floating above. */
.fab{
  position:fixed; inset-inline-end:24px; bottom:24px; z-index:90;
  display:inline-flex; align-items:center; isolation:isolate;
  padding:15px 28px; border-radius:100px; text-decoration:none;
  font-size:.86rem; font-weight:500;
  color:#FFFFFF;
  /* MORE GLASS, LESS PAINT — AND A REAL EDGE. Both were the phone's, and are
     now every width's. The tint used to do most of the work and the blur very
     little, so the pill read as a white lozenge rather than as something you
     look through: half the fill, twice the blur, and the label keeps its own
     shadow, which is what lets it stay legible over whatever passes behind.
     The border is the other half. The specular ring below draws a gradient
     that is bright at two corners and almost nothing in the middle — beautiful
     on a still, but on its own it makes an edge that visibly changes weight as
     it goes round. A hairline underneath it evens the whole circumference and
     the ring becomes the highlight it was meant to be. */
  background-color:rgba(255,255,255,.06);
  backdrop-filter:url(#lgRefract) blur(16px) saturate(210%) brightness(1.1);
  -webkit-backdrop-filter:blur(22px) saturate(210%) brightness(1.08);
  border:1px solid rgba(255,255,255,.55);
  box-shadow:
    inset 0  1px 0 rgba(255,255,255,.55),
    inset 0 -1px 0 rgba(255,255,255,.16),
    inset 0  0 22px rgba(255,255,255,.10),
    0 18px 44px -16px rgba(6,11,30,.62);
  opacity:0; transform:translateY(20px) scale(.95); pointer-events:none;
  transition:opacity var(--t) var(--ease), transform var(--t) var(--ease),
             background-color var(--t-fast) var(--ease);
}
/* At every width. It was a phone control for a while; it is back on the
   desktop too — it appears once the cover is behind you and tucks itself away
   again as the closing block comes into view, so it is never over the form it
   is pointing at. */
.fab__label{
  position:relative; z-index:2;
  text-shadow:0 1px 10px rgba(6,11,30,.85), 0 0 2px rgba(6,11,30,.55);
}
/* the specular ring: a gradient drawn only where the border would be */
.fab::before{
  content:''; position:absolute; inset:0; border-radius:inherit; z-index:1;
  padding:1px; pointer-events:none;
  background:linear-gradient(135deg,
    rgba(255,255,255,.9) 0%, rgba(255,255,255,.25) 26%,
    rgba(255,255,255,.06) 52%, rgba(255,255,255,.35) 78%, rgba(255,255,255,.7) 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor; mask-composite:exclude;
}
/* the sheen that sits on the upper half of a real curved surface */
.fab::after{
  content:''; position:absolute; inset:1px; border-radius:inherit; z-index:1;
  pointer-events:none;
  background:linear-gradient(180deg, rgba(255,255,255,.22), rgba(255,255,255,0) 46%);
}
.fab:hover{ background-color:rgba(255,255,255,.18); }

/* Over a pale band the film turns white and the ink turns navy — the same
   piece of glass, lit from the other side. app.js decides which. */
.fab.is-on-light{
  color:var(--navy-800);
  background-color:rgba(255,255,255,.26);
  /* no refraction on this one: over a pale band there is nothing behind it
     worth bending, and the displacement only softened its own edge */
  backdrop-filter:blur(18px) saturate(180%) brightness(1.04);
  -webkit-backdrop-filter:blur(18px) saturate(180%) brightness(1.04);
  border-color:rgba(var(--accent-rgb), .45);
  box-shadow:
    inset 0  1px 0 rgba(255,255,255,.95),
    inset 0 -1px 0 rgba(23,47,86,.10),
    inset 0  0 22px rgba(255,255,255,.35),
    0 18px 44px -18px rgba(23,47,86,.34);
}
.fab.is-on-light .fab__label{ text-shadow:0 1px 10px rgba(255,255,255,.95), 0 0 3px rgba(255,255,255,.8); }
.fab.is-on-light::before{
  background:linear-gradient(135deg,
    rgba(255,255,255,1) 0%, rgba(23,47,86,.14) 30%,
    rgba(23,47,86,.05) 55%, rgba(255,255,255,.7) 80%, rgba(255,255,255,1) 100%);
}
.fab.is-on-light::after{
  background:linear-gradient(180deg, rgba(255,255,255,.55), rgba(255,255,255,0) 48%);
}
.fab.is-on-light:hover{ background-color:rgba(255,255,255,.4); }

/* nothing to see through: fall back to something the label can sit on */
@supports not (backdrop-filter: blur(1px)){
  .fab{ background-color:color-mix(in srgb, var(--navy-700) 92%, transparent); }
}

/* the SVG holding the filter takes no space */
.glass-defs{ position:absolute; width:0; height:0; overflow:hidden; }

.fab.is-tucked{ opacity:0 !important; transform:translateY(14px) scale(.94) !important; pointer-events:none; }
.fab.is-visible{ opacity:1; transform:none; pointer-events:auto; }

/* ═════════════════════════════════════════════════════════ REVEALS ══ */
.reveal{ opacity:0; transform:translateY(22px); }
.reveal.is-in{
  opacity:1; transform:none;
  transition:opacity .85s var(--ease-out), transform .85s var(--ease-out);
}

/* ═══════════════════════════════════════════════════════ RESPONSIVE ══ */
@media (max-width:900px){
  /* stacked: the side panel becomes a band above the copy */
  .edge{
    position:relative; inset:auto; width:auto; height:clamp(210px,34vw,300px);
    margin-inline:calc(-1 * var(--pad)); margin-bottom:clamp(28px,4vh,44px);
    -webkit-mask-image:none; mask-image:none;
  }
  .section--edge > .wrap{ display:flex; flex-direction:column; }
  .edge__text, .edge__text--end{ max-width:none; margin-inline:0; }
  /* stacked: the wheel keeps the full column and the panel opens over it */
  .pie-layout{ flex-direction:column; }
  .pie-layout.is-open .pie-side{ flex:0 0 auto; width:100%; }

}

@media (max-width:1080px){
  .pie-layout{ grid-template-columns:minmax(0,1fr); }
  .pie-stage{ max-width:480px; }
  /* THE WHEEL DOES NOT STEP ASIDE WHERE THE PANEL IS A SHEET.
     Below this width the partners open as a modal OVER the page — there is
     nothing for the wheel to make room for, and stepping aside only meant it
     slid back across the screen when the sheet was closed. Same breakpoint as
     MODAL_Q in app.js; the two have to agree. */
  .pie-layout.is-open .pie-stage{ transform:none; }
}

@media (max-width:860px){
  .nav__links{
    position:absolute; inset-inline:0; top:100%;
    flex-direction:column; gap:0;
    background:var(--nav-bg-stuck); backdrop-filter:blur(20px);
    border-bottom:1px solid var(--line);
    padding:6px var(--pad) 18px;
    clip-path:inset(0 0 100% 0); pointer-events:none;
    transition:clip-path var(--t) var(--ease);
  }
  .nav__links.is-open{ clip-path:inset(0 0 0 0); pointer-events:auto; }
  .nav__links a{ padding:14px 0; border-bottom:1px solid var(--line); font-size:.95rem; }
  .nav__links a::after{ display:none; }
  .nav__cta{ margin-inline-start:auto; }
  .nav__section, .nav__divider{ display:none; }
  .nav__logo{ height:28px; }

  .nav__burger{
    /* flex:none — at 320px the bar squeezed it into an ellipse */
    display:flex; flex:none; flex-direction:column; justify-content:center; gap:5px;
    width:38px; height:38px; padding:0 8px;
    background:none; border:1px solid var(--line-strong); border-radius:50%;
    cursor:pointer;
  }
  .nav__burger span{ height:1px; background:var(--ink); transition:transform var(--t) var(--ease), opacity var(--t); }
  .nav__burger[aria-expanded="true"] span:first-child{ transform:translateY(3px) rotate(45deg); }
  .nav__burger[aria-expanded="true"] span:last-child{ transform:translateY(-3px) rotate(-45deg); }

  .mlayer{
    border:1px solid var(--line); border-radius:var(--r-md); overflow:hidden;
    background:var(--surface); transition:border-color var(--t-fast) var(--ease);
  }
  .mlayer.is-open{ border-color:var(--line-strong); }
  .mlayer__head{
    width:100%; display:flex; align-items:center; gap:14px;
    padding:18px; background:none; border:0; text-align:start; cursor:pointer;
  }
  .mlayer__idx{ font-size:.72rem; letter-spacing:.16em; color:var(--accent); flex:none; }
  .mlayer__titles{ flex:1; min-width:0; }
  .mlayer__title{ display:block; font-size:1.1rem; font-weight:500; }
  .mlayer__sub{ display:block; font-size:.72rem; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-faint); margin-top:4px; }
  .mlayer__plus{
    flex:none; width:30px; height:30px; border-radius:50%; border:1px solid var(--line-strong);
    position:relative; transition:all var(--t) var(--ease);
  }
  .mlayer__plus::before,.mlayer__plus::after{
    content:''; position:absolute; top:50%; left:50%; background:var(--ink); transform:translate(-50%,-50%);
  }
  .mlayer__plus::before{ width:11px; height:1px; }
  .mlayer__plus::after{ width:1px; height:11px; }
  .mlayer.is-open .mlayer__plus{ background:var(--accent); border-color:var(--accent); transform:rotate(135deg); }
  .mlayer.is-open .mlayer__plus::before,.mlayer.is-open .mlayer__plus::after{ background:var(--on-accent); }
  .mlayer__panel{ display:grid; grid-template-rows:0fr; transition:grid-template-rows var(--t) var(--ease); }
  .mlayer.is-open .mlayer__panel{ grid-template-rows:1fr; }
  .mlayer__panel > div{ overflow:hidden; }
  .mlayer__inner{ padding:0 18px 20px; }
}

/* Under 400px the bar simply does not fit: lockup, Contact and the burger came
   to 348px inside a 320px screen and the burger was pushed nine pixels past the
   edge. Everything in it gives a little rather than one thing being dropped. */
/* ── THE LOCKUP ARRIVES ─────────────────────────────────────────────────────
   On a phone the bar opens with nothing in it but Contact and the menu, and
   the lockup slides in from the left as soon as the page starts to move —
   and slides back out again at the top. It keeps its box the whole time, so
   the bar's height never changes and nothing below it shifts: only opacity
   and a transform, both composited, and the clip is what makes it read as
   arriving rather than fading up.
   `visibility` rather than `display` so the transition has both ends. */
@media (max-width:860px){
  /* ── THE BAR IS SIMPLY THERE ────────────────────────────────────────────
     For several rounds the lockup started on the cover and flew up into the
     bar as the page moved. It was measured right at both ends on every size
     and condition that could be driven here, and it still came out wrong on a
     handset — because the journey depended on a transform written by the main
     thread while the browser's own compositor was moving the bar underneath
     it, and during a touch flick the main thread is the slower of the two.

     So there is no journey. The bar carries the lockup from the moment the
     page opens, exactly as it does at a desk, and the cover carries the title
     and its two buttons. Nothing is measured, nothing is timed against
     anything else, and there is no state that can be arrived at late. */
  /* position is set once, for every width, up at the top of the file */
  /* one lockup, and it is the bar's */
  .hero__brand{ display:none; }

  /* Contact moves into the menu; the bar carries the lockup and the burger,
     and the burger takes over pushing itself to the far edge — that job used
     to belong to the pill's `margin-inline-start:auto`. */
  .nav__cta{ display:none; }
  .nav__burger{ margin-inline-start:auto; }
  .nav__links-cta{
    display:block;
    color:var(--accent) !important; font-weight:500;
    border-bottom:0 !important;
  }

  /* The bar does not shrink here. It is the same bar from the first frame to
     the last, and a phone has no height to spare for a second state of it. */
  .nav.is-stuck .nav__inner{ padding-block:17px; }
  .nav.is-stuck .nav__logo{ height:28px; }
}

@media (max-width:400px){
  .nav__inner{ gap:8px; padding-inline:16px; }
  /* both states, or the "do not shrink" rule one band up becomes a "grow on
     scroll" rule down here */
  .nav__logo, .nav.is-stuck .nav__logo{ height:24px; }
  .nav__cta{ padding:8px 14px; font-size:.76rem; }
  .nav__burger{ width:34px; height:34px; }
}

@media (max-width:700px){
  /* THE BAR IS 80px TALL HERE. A flat 64px of padding put the lockup sixteen
     pixels UNDER it — and because the hero centres its content, padding is not
     even the binding constraint once the block is taller than the space left.
     The bar's own measured height plus a margin.

     THE HEIGHT IS THE SCREEN'S, as it is at every other width: this rule used
     to cap the phone at `min(78svh, 640px)` and the client asked for the hero
     to fill the screen whatever the screen. Only the top padding is the
     phone's own, because only here does the bar sit over the type. */
  .hero{ padding-top:calc(var(--nav-h, 80px) + 28px); }
  .hero__scroll{ display:none; }
  /* Every pixel of stage is a sixth of a pixel of label, so the wheel takes
     the whole screen width, gutters included. */
  .pie-stage{
    width:calc(100% + 2 * var(--pad));
    max-width:min(100vw - 6px, 460px);
    margin-inline:calc(-1 * var(--pad));
    /* the caption hangs 14px under the wheel inside this margin, so most of it
       is spoken for — the wheel needs the rest of it as air below the caption */
    margin-bottom:62px;
  }
  /* 8.3px. The floor of the clamp was doing the work at every phone width and
     it was two sizes below anything else on the page. */
  /* THE HUB COMES IN.
     The labels start at radius 130 and the hub's disc reached 118, which left
     the inner end of a long label all but touching it. The disc is drawn as
     three concentric circles and all three take the same radius — `r` is a
     geometry property and is set here rather than on the markup, so the wheel
     itself is untouched at a desk. The segments still begin at 120, so what
     opens up is the white ring between the two, which is where the label's
     inner end now sits. */
  .pie__core, .pie__core-ring, .pie__core-lit{ r:104px; }
  .pie-centre__hub{
  font-size:clamp(.74rem,3vw,.92rem); font-weight:500; line-height:1.3;
  letter-spacing:.02em; color:var(--ink-strong);
  max-width:13ch; margin-inline:auto; text-wrap:balance;
  transition:opacity var(--t) var(--ease);
}
.pie-centre.is-active .pie-centre__hub{ opacity:0; }
/* THE HINT COMES OUT OF THE HUB.
   The hub circle is about 120px across on a phone. "SELECT A SEGMENT" is
   125px at any size still worth reading, so inside the circle it either wrapped
   to two lines and pushed the whole readout out through the bottom, or ran
   flat across the segments. Below the wheel it is a caption, at full size, with
   nothing to fight — and the hub keeps the circle to itself. */
.pie-centre__hint{
  position:absolute; top:100%; left:50%; translate:-50% 14px;
  width:max-content; margin-top:0;
  font-size:.72rem; letter-spacing:.1em; white-space:nowrap;
}


  .partners__list{ gap:10px; }

  .step__head{ gap:12px; }
  .step__idx{ display:none; }
  .step__body{ padding-inline-start:0; }
  .flow{ padding-inline-start:0; }
  .flow__rail{ display:none; }

  .fab{ inset-inline:16px; bottom:16px; justify-content:center; }
  .footer__inner{ flex-direction:column; align-items:flex-start; }

}

/* ── TAP TARGETS ────────────────────────────────────────────────────────────
   Three sets of links were coming out seventeen or eighteen pixels tall, which
   is a line of text, not something a thumb can hit. They are given the height
   back with padding and it is taken off again with an equal negative margin,
   so every one of them grows without moving a pixel of the layout around it.
   Not phone-only: a tablet in portrait is a touch screen too. */
@media (max-width:900px){
  .ccard__name a,
  .pcard__name a,
  .cta__lines a{ padding-block:10px; margin-block:-10px; }
  .nav__brand{ padding-block:9px; margin-block:-9px; }
  /* the two places that set their own chip padding have to be named, or the
     more specific rule simply keeps its 7px and the chip stays 34 tall */
  .chip,
  .ccard__actions .chip,
  .pcard .chip{ padding-block:10px; }
  .cta__lines-k{ font-size:.76rem; letter-spacing:.14em; }
}

/* ═══════════════════════════════ THE GROUND, GIVEN SOMETHING TO SAY ══
   The four sections that carry no photograph were four soft washes in a row,
   and a soft wash repeated four times is a blank page. They keep the wash —
   it is what makes the joins disappear — and gain two things over it.

   ONE, a plan grid. Hairlines at a fixed 76px pitch, drawn in Innovation Blue
   at five per cent, masked to a single corner so it reads as a drawing that
   happens to run under the copy rather than as wallpaper. It is a floor plan,
   which is what this practice is about; each section takes it from a different
   corner so no two look alike. It never crosses a photograph — "How we work"
   and "Why Meitar" have the tower, and the wheel has its own picture.

   TWO, a rule at the head of the section: a hairline the full width of the
   page with a short block of one brand pastel sitting on it at the gutter.
   The pastel is printed as printed — full opacity, no mix, no fade — and it
   is a mark, never ink for words. Five sections, five colours, in the book's
   order, so the page indexes itself as you go down it. */
:root{
  --plan-step: 76px;
  --plan-a: .065;
  --rule-w: 84px;
  /* where the copy actually starts: the page gutter until the wrap centres
     itself, and half the leftover after that. The head rule's pastel block
     begins here, so it lines up with the heading under it rather than with
     the edge of the screen. */
  --gutter: calc(max(0px, (100% - var(--wrap)) / 2) + var(--pad));
}
.band::before,
.section--services::before,
.section--cta::before{
  content:''; position:absolute; inset:0; z-index:0; pointer-events:none;
  background-image:
    repeating-linear-gradient(90deg,
      rgba(var(--wash-rgb), var(--plan-a)) 0 1px, transparent 1px var(--plan-step)),
    repeating-linear-gradient(180deg,
      rgba(var(--wash-rgb), var(--plan-a)) 0 1px, transparent 1px var(--plan-step));
  -webkit-mask-image:radial-gradient(var(--plan-r, 92% 78%) at var(--plan-at, 100% 0%), #000 12%, transparent 78%);
          mask-image:radial-gradient(var(--plan-r, 92% 78%) at var(--plan-at, 100% 0%), #000 12%, transparent 78%);
}
.band::before        { --plan-at: 88% 4%;   }
.section--services::before{ --plan-at: 6% 96%;  }
.section--cta::before     { --plan-at: 50% 100%; --plan-a:.06; }
/* Advisory carries a photograph now, and a drawing on top of a photograph is
   two grounds arguing. Same reason a section inside the tower has neither. */

/* ── THE SECOND SECTION ───────────────────────────────────────────────────
   The opening band is where the page states what the practice is, and it was
   the quietest surface on it. The plan is drawn across the WHOLE of it here
   rather than into one corner — it is the reading section, so the drawing
   under the reading is the point — and it is the one place where the grid is
   not only lines. Six of its intersections carry a solid square of one brand
   pastel, printed as printed: eleven pixels, full opacity, no mix, no fade.
   They are marks on a drawing, and they sit in the outer columns where the
   copy does not run, so nothing is ever read off a colour.

   The geometry only works because everything here is anchored to the RIGHT
   edge and to a single 76px tile: the two line layers and the six nodes share
   one background-size, so a node offset by a multiple of the tile lands on a
   crossing at every width. Change --plan-step and the offsets must follow. */
.band::before{
  --plan-r: 132% 112%;
  --plan-a: .075;
  background-image:
    linear-gradient(var(--tint-sky),   var(--tint-sky)),
    linear-gradient(var(--tint-lilac), var(--tint-lilac)),
    linear-gradient(var(--tint-sand),  var(--tint-sand)),
    linear-gradient(var(--tint-coral), var(--tint-coral)),
    linear-gradient(var(--tint-green), var(--tint-green)),
    linear-gradient(var(--tint-sky),   var(--tint-sky)),
    /* one line per tile, NOT a repeating-gradient: a repeating gradient sizes
       itself to the whole box and ignores background-position, which would
       anchor the lattice to the left edge while the nodes are measured from
       the right. Tiled at --plan-step from `100% 0`, both agree. */
    linear-gradient(90deg,  rgba(var(--wash-rgb), var(--plan-a)) 0 1px, transparent 1px),
    linear-gradient(180deg, rgba(var(--wash-rgb), var(--plan-a)) 0 1px, transparent 1px);
  background-repeat:no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, repeat, repeat;
  background-size:11px 11px, 11px 11px, 11px 11px, 11px 11px, 11px 11px, 11px 11px,
                  var(--plan-step) var(--plan-step), var(--plan-step) var(--plan-step);
  background-position:
    calc(100% - var(--nA))  71px,   /* 1 tile in, 1 down  */
    calc(100% - var(--nB)) 223px,   /* 2 in, 3 down       */
    calc(100% - var(--nA)) 375px,   /* 1 in, 5 down       */
    calc(100% - var(--nC)) 451px,   /* 3 in, 6 down       */
    calc(100% - var(--nB)) 603px,   /* 2 in, 8 down       */
    calc(100% - var(--nA)) 755px,   /* 1 in, 10 down      */
    100% 0, 100% 0;
}
/* A node is never allowed under a line of type. Each tile column only turns
   on once the page is wide enough that the column falls OUTSIDE the copy —
   the thresholds are read off --wrap, which itself steps at 1330 and 1600.
   Parked at -300px a node is positioned past the right edge and simply is
   not painted, which is the cheapest way to switch one off. */
.band::before{ --nA:-300px; --nB:-300px; --nC:-300px; }
@media (min-width:1100px){ .band::before{ --nA: 81px; } }
@media (min-width:1250px){ .band::before{ --nB:157px; } }
@media (min-width:1470px){ .band::before{ --nC:233px; } }

/* the head rule. `top:0` on a section whose padding starts below it, so it
   sits exactly on the join with the section above.

   FOUR SECTIONS, NOT FIVE. The closing section had it and has lost it: the
   line was drawing a border across a join where the photograph above it
   already ends — two edges on one seam — and with the line gone the pastel
   block that sits on it has nothing to sit on. So both come off there, and the
   page's colour index runs sky, lilac, green, coral and stops. */
.band::after,
.section--practice::after,
.section--services::after,
.section--advisory::after{
  content:''; position:absolute; top:0; left:0; right:0; height:3px;
  z-index:2; pointer-events:none;
  background-image:
    linear-gradient(90deg,
      transparent 0 var(--gutter),
      var(--rule-c) var(--gutter) calc(var(--gutter) + var(--rule-w)),
      transparent calc(var(--gutter) + var(--rule-w))),
    linear-gradient(180deg, var(--line) 0 1px, transparent 1px);
}
.band::after            { --rule-c: var(--tint-sky);   }
.section--practice::after{ --rule-c: var(--tint-lilac); }
.section--services::after{ --rule-c: var(--tint-green); }
.section--advisory::after{ --rule-c: var(--tint-coral); }
/* the band's own two sections sit above its grid and its rule */
.band .section{ z-index:1; }
/* on a phone the grid is finer than the type and just makes noise */
@media (max-width:720px){
  .band::before, .section--services::before, .section--cta::before{ display:none; }
  :root{ --rule-w:56px; }
}

/* The marker `initChrome` watches to know whether the page has left the top.
   ONE pixel, so its edge is the same one the scroll path uses — two answers
   to the same question have to be set to the same boundary or they will spend
   the first twenty pixels of every scroll contradicting each other. Pulled
   straight back out of the flow, so it costs nothing. */
#top{ display:block; height:1px; margin-bottom:-1px; pointer-events:none; }

/* ═══════════════════════════════════════ THE PHONE, LAST WORD ═══════════
   Everything below is the phone only, and everything in it was measured on a
   handset rather than guessed at a desk. */
@media (max-width:700px){

  /* ── RUNNING TEXT, TWO PIXELS UP ────────────────────────────────────────
     Headings are already display size and are left alone; it is the copy you
     actually read for a minute at a time that was set at desk sizes on a
     screen held at arm's length. Every one of these is the same value it had
     plus two. */
  .prose p, .band__body p{ font-size:1.13rem; }
  .lede{ font-size:1.13rem; }
  .pillar__body{ font-size:1.06rem; }
  .why__body{ font-size:1.05rem; }
  .step__body, .step__body p, .step__deliverables{ font-size:1.1rem; }
  .cta__lines-v{ font-size:1.04rem; }
  .ccard__role, .pcard__role{ font-size:.94rem; }
  .ccard__name, .pcard__name{ font-size:1.06rem; }
  .partners__all{ font-size:.98rem; }
  .csent__body{ font-size:calc(1.05rem + 8px); }   /* keeps the increase below 700 */
  .chip{ font-size:.85rem; }
  .chip svg{ width:16px; height:16px; }

  /* ── THE COVER'S SECOND BUTTON ──────────────────────────────────────────
     A hairline outline on a photograph is not a button. It keeps the ghost's
     shape and gains a ground of its own to sit on. */
  .hero--cover .btn--ghost,
  .hero--cover .btn--primary{
    background:rgba(var(--canvas-rgb), .82);
    border-color:var(--navy-700);
    color:var(--navy-700);
    backdrop-filter:blur(6px);
  }

  /* ── THE FLOATING PILL ──────────────────────────────────────────────────
     It was a wide, low, faint bar across the foot of the screen. Narrower so
     it reads as a button, taller so it is worth hitting, a size of type you
     can see, and a hairline of its own so it has an edge against a pale
     section rather than dissolving into one. */
  /* Only the SIZE is the phone's own now. The glass and the edge that used to
     live here are the button's at every width — a pill that reads as glass on
     a handset and as paint at a desk was two buttons. */
  .fab{
    inset-inline:auto 16px; bottom:18px;
    width:auto; max-width:calc(100% - 32px);
    padding:17px 30px;
    font-size:1rem; font-weight:500;
  }

  /* ── THE FOUR PARTNERS' BUTTONS ─────────────────────────────────────────
     Two-up left them at sixty pixels of width with a nine-pixel mark in them.
     One under another, at a size that reads. */
  .ccard__actions{ grid-template-columns:minmax(0,1fr); gap:9px; }
  .ccard__actions .chip{ justify-content:center; padding:12px 10px; font-size:.9rem; }
  .ccard__actions .chip svg{ width:17px; height:17px; }

  /* ── THE PANEL THAT OPENS OFF THE WHEEL ─────────────────────────────────
     The card stacked avatar over name and left the whole right half of itself
     empty, and the three chips sat in a row that stopped short. Avatar beside
     the name, chips across the full width. */
  .pcard{ flex-direction:row; align-items:center; gap:14px; flex-wrap:wrap; }
  .pcard__avatar{ width:64px; height:64px; }
  .pcard__body{ flex:1 1 0; width:auto; min-width:0; }
  .pcard__actions{
    display:grid; grid-template-columns:repeat(3, minmax(0,1fr));
    gap:8px; flex:1 0 100%; margin-top:4px;
  }
  .pcard .chip{ justify-content:center; padding:11px 6px; font-size:.82rem; }
  .pcard .chip svg{ width:15px; height:15px; }

  /* ── SPACING ────────────────────────────────────────────────────────────
     A section's full top padding under another section's full bottom padding
     is a hundred and eighty pixels of nothing on a screen this size. Where two
     sections belong to one block, the second one gives most of it back. */
  /* ── THE HEAD RULE COMES OFF ────────────────────────────────────────────
     A hairline the full width of the page with a short pastel dash on it is an
     editorial device that needs room around it to read as one. On a phone it
     is just a line above a heading, and it was the first thing the eye caught.
     The pastels stay where they do work here — the wheel, the cell tints, the
     marks. */
  .band::after, .section--practice::after, .section--services::after,
  .section--advisory::after{ display:none; }

  /* ── THE FOUR PARTNERS, LIKE THE PANEL'S ────────────────────────────────
     One under another and laid out exactly as the cards in the wheel's panel
     are: portrait beside the name, the three actions across a row of their
     own. Two to a row left them 168px wide with the buttons stacked inside. */
  .core__list{ grid-template-columns:minmax(0,1fr); gap:12px; }
  .ccard{
    flex-direction:row; align-items:center; flex-wrap:wrap;
    gap:14px; padding:16px;
  }
  .ccard__avatar{ width:64px; height:64px; }
  .ccard__body{ flex:1 1 0; min-width:0; width:auto; }
  .ccard__name{ margin-top:0; }
  .ccard__actions{
    grid-template-columns:repeat(3, minmax(0,1fr));
    gap:8px; flex:1 0 100%; margin-top:4px;
  }
  .ccard__actions .chip{ padding:11px 6px; font-size:.82rem; }
  .ccard__actions .chip svg{ width:15px; height:15px; }
  /* three across, so the odd-one-out rule that spans the last chip has to go */
  .ccard__actions .chip:last-child:nth-child(odd){ grid-column:auto; }

  /* Both halves of the join give, not just the second one: a full bottom
     padding under a trimmed top padding is still most of the hole. */
  .section--practice{ padding-top:48px; padding-bottom:34px; }
  /* air under the wheel and its caption before the next section starts */
  .pie-layout{ margin-bottom:34px; }
  /* the same measure on both sides of the join, so the whitespace before
     "A high-complexity sector" sits evenly across the seam */
  .tower > .section:first-of-type{ padding-top:36px; }
  /* and the closing block starts closer to the streams above it */
  .section--advisory{ padding-bottom:24px; }
  .section--cta{ padding-top:64px; }
  .band .section + .section{ padding-top:26px; }
  .section--intro{ padding-bottom:26px; }
  .pair > .section + .section{ padding-top:68px; }
  .section--why{ padding-bottom:34px; }
  .tower > .section + .section{ padding-top:72px; }
  .section--services{ padding-bottom:38px; }
  /* the page's last edge: the closing block does not need a full section's
     worth of air under its last line */
  .section--cta{ padding-bottom:38px; }
}

/* ═════════════════════════════════════════════════ REDUCED MOTION ═══ */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .reveal, .step, .rise__i{ opacity:1 !important; transform:none !important; }
  .hero__title .line span{ transform:none; }
  .edge img{ opacity:1 !important; transform:none !important; }
  .seg{ transform:none !important; opacity:1 !important; animation:none !important; }
  .hero__photo{ animation:none; opacity:.34; transform:none; }
  #heroCanvas{ display:none; }
}

/* ═══════════════════════════════════════════════════════════ PRINT ═══ */
@media print{
  .nav,.fab,.hero__bg,.hero__scroll,.demo-notice{ display:none !important; }
  body{ background:#fff; color:#111; }
}

/* ═════════════════════════════════════════════════════════════════════════
   MEITAR PATENTS — the sections this page has and the first one did not.
   Appended rather than woven in, so nothing above is disturbed; source order
   means these win where they overlap, which is the point in two places
   (the hero lockup, and the head rule).
   ════════════════════════════════════════════════════════════════════════ */

/* The head rule and its pastel block are gone at the client's request. The
   page's colour index now lives only where a pastel is doing a job: the
   sheet's active row, the plate's marked cell, the stat tiles and the group
   headings. */

.section__head--mid{ margin-top:clamp(56px,8vh,104px); }

/* ── the plan grid, on the sections that carry no photograph ──────────────
   Same pitch and same ink as the first page's; masked into one corner so it
   reads as a drawing running under the words and not as wallpaper. It never
   crosses a photograph: a drawing over a photograph is two grounds arguing. */
/* `.section--numbers` IS BACK IN THIS LIST: it stood on the tower's
   photograph for two rounds and the rule above this one is that the plan
   never crosses a picture. It is on its own ground again. */
.section--practices, .section--numbers, .section--sectors,
.section--services, .section--clients, .section--team{ position:relative; }
.section--practices::before, .section--numbers::before, .section--sectors::before,
.section--services::before, .section--clients::before, .section--team::before{
  content:''; position:absolute; inset:0; z-index:0; pointer-events:none;
  background-image:
    repeating-linear-gradient(90deg,
      rgba(var(--wash-rgb), var(--plan-a)) 0 1px, transparent 1px var(--plan-step)),
    repeating-linear-gradient(180deg,
      rgba(var(--wash-rgb), var(--plan-a)) 0 1px, transparent 1px var(--plan-step));
  -webkit-mask-image:radial-gradient(86% 74% at var(--plan-at,100% 0%), #000 12%, transparent 78%);
          mask-image:radial-gradient(86% 74% at var(--plan-at,100% 0%), #000 12%, transparent 78%);
}
.section--practices::before{ --plan-at: 4% 4%; }
.section--numbers::before  { --plan-at: 96% 8%; }
.section--sectors::before  { --plan-at: 96% 2%; }
.section--services::before { --plan-at: 6% 96%; }
.section--clients::before  { --plan-at: 50% 0%; }
.section--team::before     { --plan-at: 2% 90%; }
.section--practices > .wrap, .section--numbers > .wrap, .section--sectors > .wrap,
.section--services > .wrap, .section--clients > .wrap, .section--team > .wrap{
  position:relative; z-index:1;
}
@media (max-width:720px){
  .section--practices::before, .section--numbers::before, .section--sectors::before,
  .section--services::before, .section--clients::before, .section--team::before{ display:none; }
}

/* ══════════════════════════════════════════════════════════ COVER ═══════
   Built as the data centers cover is, so almost nothing is needed here: the
   pinned photograph, the plate, the centred headline and the centred actions
   are all rules that page already carries. Only the lockup's own proportion
   differs — the patents lockup is one wide line (13:1) where the firm's is
   5.6:1, so it is sized by WIDTH here rather than by height. */
.hero__logo{ width:min(360px,62vw); }
.hero__title:empty{ display:none; }

/* ══════════════════════════════════════════════════════════ PROSE ══════ */
.prose--two{ columns:2; column-gap:clamp(30px,4vw,64px); }
.prose--two p{ break-inside:avoid; }
@media (max-width:860px){ .prose--two{ columns:1; } }

/* ══════════════════════════════════════════════════════════ PLATE ══════
   THREE ACROSS, FLUSH, SQUARE — and WIDER THAN THE COPY.

   THE LATTICE IS NOW DRAWN BY THE CELLS, not by the grid. It used to be a
   `gap:1px` over a `--line` ground, which is the cheapest way to get one
   hairline between any two cells — but it means the grey is the PLATE's, and
   a cell that has not arrived yet shows it. That is fine when the plate
   arrives as one object and fatal now that the client wants it to fill cell
   by cell: eighteen grey holes, closing one at a time.

   So every cell carries its own full 1px frame and a -1px trailing margin,
   which slides its right border onto its neighbour's left and its bottom onto
   the next row's top. One hairline between any two cells, one frame around
   the whole plate, and every line of it ARRIVES WITH THE CELL THAT OWNS IT.
   There is no shared ground left to show through.

   And the min-height stays, because it is what answers the original
   complaint: measured, every one of the eighteen is the same height, so no
   row can be dragged out of true by one cell's wording. */
.plate{
  margin-top:clamp(38px,5vh,64px);
  display:grid; gap:0; background:none;
  grid-template-columns:1fr;
}
/* FOUR ACROSS, now that there are NINETEEN — four full rows and a last row
   of three. Three columns left a row of one hanging off the end; four leaves
   one empty cell, and because every cell carries its own frame that cell is
   simply not drawn: the last row ends three quarters of the way across, which
   is what a list that ran out should look like. The steps below it are the
   same halving: two at 600, three at 900, four at 1100. */
@media (min-width:600px){  .plate{ grid-template-columns:repeat(2,1fr); } }
@media (min-width:900px){  .plate{ grid-template-columns:repeat(3,1fr); } }
@media (min-width:1100px){ .plate{ grid-template-columns:repeat(4,1fr); } }

/* ── AND IT BREAKS THE MEASURE ────────────────────────────────────────────
   Eighteen linked cells are not a paragraph, and the client asked for them to
   run past the column the copy is set in. The plate is taken out of the
   wrap's padding and re-centred on the VIEWPORT — `left:50%` with a -50%
   translate — then capped: never wider than the wrap plus 60px, and never
   closer than a gutter to the edge of the screen, so the cap is whichever of
   the two runs out first. At 1440 that is 1160 against the copy's 975.

   Only from 900px up. Below that the wrap has barely any padding to escape
   from and the plate is a single column of full-width rows. */
@media (min-width:900px){
  .plate{
    position:relative; left:50%; translate:-50% 0;
    width:min(calc(var(--wrap) + 60px), calc(100vw - 2 * clamp(24px,3vw,64px)));
  }
}

.plate__cell{
  position:relative; isolation:isolate;
  display:grid; grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center; gap:clamp(13px,1.4vw,18px);
  /* 110, AND THE NUMBER IS MEASURED. The cells are all one height, which is
     what answered the original complaint — but the bigger label put
     `Technology & Intellectual Property & Patents`, the longest of the
     eighteen at forty-four characters, onto a third line between about 1200
     and 1600, where the root font is at 92% and the column is at its
     narrowest. That row came out 106 against the others' 100. This clears
     the three-liner at every width instead of leaving one row taller. */
  min-height:110px;
  padding:clamp(16px,1.7vw,22px) clamp(17px,1.8vw,23px);
  background:var(--canvas);
  border:1px solid var(--line); margin:0 -1px -1px 0;
  text-decoration:none; color:var(--ink-dim);
  transition:background-color var(--t-fast) var(--ease),
             color var(--t-fast) var(--ease);
}

/* ── AND IT FILLS CELL BY CELL ────────────────────────────────────────────
   The logo wall's entrance, which is what the client asked to see here: each
   cell waits its own `--d` — a straight index — and the wave runs top left to
   bottom right in reading order.

   OPACITY ONLY ON THE TILE, no rise. The wall's cells are separate boxes with
   gaps between them and can afford to travel; these are eighteen flush tiles,
   and a tile arriving 20px out of line shears the lattice it is part of for
   as long as it is moving. */
.plate__cell{ opacity:0; }
.plate.is-in .plate__cell{
  opacity:1;
  transition:opacity .84s var(--ease-out) var(--d),
             background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}

/* ── AND THE MARK HAS NO ENTRANCE OF ITS OWN ─────────────────────────────
   It drew itself once, then faded and rose 22px like a logo. Neither is what
   the client wants: the mark should arrive EXACTLY as the words beside it do,
   and the words have no animation at all — they are content inside a tile
   that fades, so they fade with it.

   So there is no rule here. Deleting the mark's own entrance is the whole
   change: the tile's opacity carries everything inside it, mark and label
   together, on one duration and one delay. A rise would have been the one
   thing in the cell that moved. */

/* ── THE RING THE LIGHT TRAVELS ───────────────────────────────────────────
   A one-pixel frame painted as a gradient: a box whose padding is the border
   width, filled with a radial light at the pointer, masked so only that one
   pixel is drawn. `mask-composite:exclude` subtracts the content box from the
   whole, which leaves the frame.

   It is the ONE effect left on hover, and it is on the border: round 25 of
   the first page put a coloured glow under a cell's text, and that is exactly
   what made a hover read as blurred rather than lit. */
.plate__ring{
  position:absolute; inset:0; z-index:-1;
  /* TWO PIXELS, AND THE PASTEL HOLDS THE NEAR HALF OF THE LIGHT.
     At 1px and with the pastel only at the gradient's very centre, the frame
     came out blue whatever cell you were on: the pointer sits in the middle
     of a 395x110 cell, the nearest frame is 55px away, and 55 of a 150px
     circle is already past the pastel and into the wash. So the circle is
     bigger, the pastel runs flat to 46% of it — which reaches the top and
     bottom edges from anywhere in the cell — and the wash is what is left at
     the far ends of the long sides. Two pixels because these are pale
     colours: the same light at one pixel of #ACDBEF on white is a rumour. */
  /* ONE COLOUR, NOT TWO. The far ends of the long sides used to carry a
     wash of Innovation Blue, so a frame ran pastel at the pointer and blue
     away from it — two colours in one light, which is what the client saw.
     The pastel now runs flat to 52% of the circle and then falls straight to
     transparent, so the light is one colour that simply gets fainter. */
  padding:2px; opacity:0;
  background:radial-gradient(190px circle at var(--mx,50%) var(--my,50%),
             var(--m) 0%, var(--m) 52%, transparent 96%);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor; mask-composite:exclude;
  transition:opacity var(--t) var(--ease);
}

.plate__cell svg{ width:clamp(32px,2.7vw,38px); height:auto; display:block; overflow:visible; }
.plate__cell svg *{
  fill:none; stroke:var(--ink-strong); stroke-width:1.3;
  stroke-linecap:round; stroke-linejoin:round;
  transition:stroke var(--t-fast) var(--ease);
}
.plate__cell b{
  font-size:clamp(14px,1.15vw,15.8px); font-weight:400; line-height:1.3;
  letter-spacing:.005em; color:inherit;
}
/* the arrow, which is the affordance: it says this one leaves the page */
.plate__go{
  width:22px; height:22px; display:grid; place-items:center;
  opacity:0; transform:translateX(-6px);
  transition:opacity var(--t) var(--ease), transform var(--t) var(--ease);
}
.plate__go svg{ width:20px; }
.plate__go svg path{ stroke:var(--accent); stroke-width:1.6; }

/* ── THE HOVER, AND WHAT IS NOT IN IT ─────────────────────────────────────
   No lift: the cells are flush now, and a card rising out of a lattice tears
   the grid it belongs to. No dimming of the others either, and the drawing
   does not re-ink under the cursor — both were asked for and both are gone.
   What is left is the ground, the light on the frame, the ink, and the
   arrow. */
@media (hover:hover){
  .plate__cell:hover{ background:var(--canvas-soft); color:var(--ink-strong); }
  .plate__cell:hover .plate__ring{ opacity:1; }
  .plate__cell:hover svg *{ stroke:var(--accent); }
  .plate__cell:hover .plate__go{ opacity:1; transform:none; }
}
.plate__cell:focus-visible{
  outline:2px solid var(--accent); outline-offset:-2px; color:var(--ink-strong);
}
.plate__cell:focus-visible .plate__go{ opacity:1; transform:none; }
/* no cursor, no hover: the arrow is simply there */
@media (hover:none){ .plate__go{ opacity:.55; transform:none; } }

/* NO CELL IS MARKED AT REST. `Technology & Intellectual Property & Patents`
   carried a pastel bar and a heavier weight because it is the area this whole
   page sits in — and the client's question about it is the answer: a cell
   emphasised without being hovered reads as a cell that is STUCK, not as a
   cell that is ours. The eighteen are alike now and only the pointer picks
   one out. `practices.ours` is still in the content; three lines here and one
   in `initPlate` bring the mark back if it is ever wanted.
*/

/* ══════════════════════════════════════════════════════════ STATS ══════ */
.stats{
  list-style:none; margin:clamp(34px,5vh,60px) 0 0; padding:0;
  display:grid; gap:1px; background:var(--line);
  border-block:1px solid var(--line);
  grid-template-columns:1fr;
}
@media (min-width:640px){ .stats{ grid-template-columns:repeat(3,1fr); } }
.stat{
  position:relative; background:var(--canvas);
  padding:clamp(26px,3.6vw,44px) clamp(18px,2vw,28px);
}
.stat::before{
  content:''; position:absolute; top:0; left:0; width:52px; height:3px; background:var(--m);
}
.stat__n{
  display:block; font-size:clamp(44px,5.6vw,76px); font-weight:400; line-height:1;
  letter-spacing:-.02em; color:var(--ink-strong); font-variant-numeric:tabular-nums;
}
.stat__k{
  display:block; margin-top:10px; font-size:13px; font-weight:500;
  letter-spacing:.16em; text-transform:uppercase; color:var(--ink-faint);
}

/* ══════════════════════════════════════════════════════════ SHEET ══════ */
.sheetstack{
  display:grid; gap:clamp(28px,4vw,64px); margin-top:clamp(36px,5vh,62px);
  grid-template-columns:1fr;
}
/* on a phone the sheet is the hero and comes FIRST; an eleven-row list above
   it would bury it */
.sheetwrap{ order:-1; }
@media (min-width:900px){
  .sheetstack{ grid-template-columns:minmax(0,1fr) minmax(0,.92fr); align-items:start; }
  .sheetwrap{ order:0; position:sticky; top:calc(var(--nav-h,78px) + 24px); }
}

.sindex{ list-style:none; margin:0; padding:0; border-top:1px solid var(--line); }
.sindex li{ border-bottom:1px solid var(--line); }
.srow{
  display:grid; grid-template-columns:auto 1fr auto; align-items:center; gap:16px;
  width:100%; background:none; border:0; padding:15px 4px; text-align:left;
  font-family:inherit; color:var(--ink-faint); cursor:default;
  transition:color var(--t-fast) var(--ease);
}
.srow:focus-visible{ outline:2px solid var(--accent); outline-offset:3px; }
.srow__n{
  font-size:12px; font-weight:500; letter-spacing:.1em; color:var(--ink-faint);
  min-width:2.2em; transition:color var(--t-fast) var(--ease);
}
.srow__name{
  font-size:clamp(16.5px,1.5vw,21px); font-weight:400; letter-spacing:.005em;
  color:var(--ink-dim); transition:color var(--t-fast) var(--ease);
}
/* the pastel is a mark: a bar, never a letterform */
.srow__mark{
  width:0; height:4px; border-radius:2px; background:var(--m);
  transition:width var(--t) var(--ease-out);
}
/* COLOUR ONLY, NO WEIGHT. The active row used to go to 500 as well, and a
   word that thickens moves: Rubik 500 is wider than Rubik 400, so the name
   grew a pixel or two to the right and every row jumped as the sheet changed
   under the pointer. The row is already marked three ways — the ink goes to
   full strength, the number with it, and the pastel bar opens on the right.
   The weight was the one of the four that cost a reflow. */
.srow[aria-current="true"] .srow__name{ color:var(--ink-strong); }
.srow[aria-current="true"] .srow__n{ color:var(--ink-strong); }
.srow[aria-current="true"] .srow__mark{ width:clamp(34px,4vw,54px); }
@media (hover:hover){ .srow:hover .srow__name{ color:var(--ink-strong); } }

.sheet{
  position:relative; border:1px solid var(--line); background:var(--canvas);
  aspect-ratio:1/1; max-width:560px; width:100%; margin-inline:auto;
}
/* the sheet carries its own finer grid — a drawing sheet, not the page */
.sheet::before{
  content:''; position:absolute; inset:0;
  background-image:
    repeating-linear-gradient(90deg, rgba(var(--wash-rgb),.05) 0 1px, transparent 1px 38px),
    repeating-linear-gradient(180deg, rgba(var(--wash-rgb),.05) 0 1px, transparent 1px 38px);
}
.sheet__tick{ position:absolute; width:13px; height:13px; border:0 solid var(--line-strong); }
.sheet__tick--tl{ top:9px; left:9px; border-top-width:1px; border-left-width:1px; }
.sheet__tick--tr{ top:9px; right:9px; border-top-width:1px; border-right-width:1px; }
.sheet__tick--bl{ bottom:9px; left:9px; border-bottom-width:1px; border-left-width:1px; }
.sheet__tick--br{ bottom:9px; right:9px; border-bottom-width:1px; border-right-width:1px; }

.sheet__fig{ position:absolute; inset:11%; display:grid; place-items:center; }
.sheet__fig svg{ width:100%; height:100%; overflow:visible; }
/* LINE WEIGHT IN USER UNITS, never vector-effect:non-scaling-stroke — that
   computes the dash pattern in device space while getTotalLength() answers in
   user units, so the dasharray comes out short by the viewBox scale and every
   stroke inks part way and then gaps. It looks like an animation that did not
   finish rather than like a bug. A technical drawing wants its line to grow
   with the drawing anyway. */
.sheet__fig svg *{
  fill:none; stroke:var(--ink-strong); stroke-width:1.05;
  stroke-linecap:round; stroke-linejoin:round;
}
.sheet__fig svg .hot{ stroke:var(--m); }

.sheet__block{
  position:absolute; left:0; bottom:0; padding:14px 18px 15px;
  border-top:1px solid var(--line); border-right:1px solid var(--line);
  background:var(--canvas); min-width:57%;
}
.sheet__block b{
  display:block; font-size:11.5px; font-weight:500; letter-spacing:.16em;
  color:var(--ink-faint); margin-bottom:5px;
}
.sheet__block span{
  display:block; font-size:clamp(14px,1.15vw,17px); font-weight:500;
  color:var(--ink-strong); line-height:1.25;
}
.sheet__stamp{
  position:absolute; right:5.5%; top:6%; width:84px; height:84px; border-radius:50%;
  border:2px solid var(--m); display:grid; place-items:center;
  transform:rotate(-13deg); opacity:0; transition:opacity .5s var(--ease);
}
.sheet__stamp::before{
  content:''; position:absolute; inset:5px; border-radius:50%; border:1px solid var(--m);
}
.sheet__stamp i{
  font-style:normal; font-size:23px; font-weight:400; line-height:1; color:var(--ink-strong);
}
.sheet.is-inked .sheet__stamp{ opacity:1; }

/* ══════════════════════════════════════════════════════════ DIAL ═══════
   TEN SERVICES ON A RING, and the timeline is gone. The ring carries the ten
   marks, a segment of the ring's own circumference travels to the one you are
   on, the hub magnifies it and draws it again, and the sentence is read
   beside it at a size worth reading.

   THE GEOMETRY IS ALL PER CENT. Every spoke is placed at 44% of the stage
   from its centre by `initDial`, and the ring is an SVG circle of r=44 in a
   100-unit box — the same number, so the two agree at every size without a
   pixel being measured anywhere. */
.dial{
  margin-top:clamp(34px,5vh,58px);
  display:grid; gap:clamp(28px,4vw,56px);
  grid-template-columns:minmax(0,1fr);
  align-items:center;
}
@media (min-width:900px){
  /* the text gets the wider half. At 1440 an even split left it 458px while
     the type had already reached its ceiling, and the longest of the ten ran
     six lines there against four everywhere else. */
  .dial{ grid-template-columns:minmax(320px,.88fr) minmax(0,1.12fr); }
}

.dial__stage{
  position:relative; width:100%; max-width:min(560px,86vw);
  aspect-ratio:1; margin-inline:auto;
}
.dial__ring{ position:absolute; inset:0; width:100%; height:100%; overflow:visible;
  pointer-events:none;   /* the track and the arc are decoration */ }
.dial__ring circle{ fill:none; }
/* ── THE PIZZA ────────────────────────────────────────────────────────────
   Ten invisible slices, each a tenth of the stage, each the hover target for
   its own service. `fill:transparent` and not `none`: a shape filled with
   `none` does not exist for the pointer, which is the whole trick.
   `cursor:default` for the same reason the spokes carry it — nothing here
   navigates, so nothing should promise that it does. */
.dial__hit{ pointer-events:auto; }
.dial__wedge{ cursor:default; }
.dial__track{ stroke:var(--line); stroke-width:.4; }
/* the travelling segment. It is a MARK — a pastel at full opacity, never
   diluted — and it is the only coloured thing in the section. */
.dial__arc{
  stroke:var(--tint-sky); stroke-width:2.4; stroke-linecap:round;
  transform:rotate(-90deg); transform-origin:50% 50%;
  transition:stroke-dashoffset .6s var(--ease-out), stroke .45s var(--ease);
}

/* ── THE HUB ──────────────────────────────────────────────────────────────
   The mark you are on, drawn large in the middle, and drawn AGAIN every time
   you move: `reink` is the sheet's device and this is it spent on one small
   drawing. It is what makes turning the ring worth doing. */
.dial__hub{
  position:absolute; left:50%; top:50%; translate:-50% -50%;
  width:38%; display:grid; place-items:center;
  /* it is a BOX over the middle of the stage, and its corners reach 27 units
     out where the wedges start at 21 — so on the four diagonals it was
     swallowing the hover meant for the slice underneath. It is decoration;
     it has no business taking a pointer. */
  pointer-events:none;
}
.dial__hub svg{ width:100%; height:auto; display:block; overflow:visible; }
.dial__hub svg *{
  fill:none; stroke:var(--ink-strong); stroke-width:1.1;
  stroke-linecap:round; stroke-linejoin:round;
}

/* ── THE SPOKES ───────────────────────────────────────────────────────────
   Ten buttons on the ring. Buttons because a phone has to be able to reach
   them; `cursor:default` because they navigate nowhere, which is the same
   contract the sectors index runs on. */
.dial__spokes{ list-style:none; margin:0; padding:0; }
.dial__spoke{
  position:absolute; translate:-50% -50%;
  width:clamp(42px,8.4%,58px); aspect-ratio:1;
  display:grid; place-items:center;
  padding:0; border:0; border-radius:50%;
  background:var(--canvas); cursor:default;
  transition:background var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease),
             scale var(--t) var(--ease-out);
  box-shadow:0 0 0 1px var(--line);
}
.dial__spoke svg{ width:58%; height:auto; display:block; overflow:visible; }
/* the mark is drawn in a 48-unit box and lands at about thirty pixels, so a
   1.7 stroke arrives at one physical pixel and reads as a smudge. 2.2 keeps
   it a drawn line at the size it is actually seen. */
.dial__spoke svg *{
  fill:none; stroke:var(--ink-dim); stroke-width:2.2;
  stroke-linecap:round; stroke-linejoin:round;
  transition:stroke var(--t-fast) var(--ease);
}
.dial__spoke[aria-current="true"]{
  background:var(--canvas); scale:1.22;
  box-shadow:0 0 0 1px var(--m), 0 10px 26px -12px rgba(23,47,86,.4);
}
.dial__spoke[aria-current="true"] svg *{ stroke:var(--ink-strong); }
@media (hover:hover){
  .dial__spoke:hover svg *{ stroke:var(--ink-strong); }
}
.dial__spoke:focus-visible{ outline:2px solid var(--accent); outline-offset:3px; }

/* ── THE SENTENCE ─────────────────────────────────────────────────────────
   Read beside the ring, not inside it: the longest of the ten is a hundred
   and thirty characters, and a hundred and thirty characters inside a circle
   is a paragraph fighting a shape.

   AND IT IS READ LARGE. Beside a ring four hundred and sixty pixels across,
   a paragraph at body size left the whole right half of the section looking
   like something had failed to load. The sentence is the section's content;
   it is now set at the size of a pull quote, with the count and a rule of the
   item's own pastel above it. */
.dial__read{ text-align:center; }
@media (min-width:900px){ .dial__read{ text-align:left; } }
.dial__n{
  margin:0 0 clamp(8px,1.1vh,13px);
  font-size:clamp(13px,1.05vw,15px); font-weight:500; letter-spacing:.2em;
  color:var(--ink-faint); font-variant-numeric:tabular-nums;
}
/* a mark, not a rule of ink: it wears the pastel the arc is wearing */
.dial__rule{
  display:block; width:56px; height:3px; border-radius:2px;
  background:var(--m, var(--tint-sky));
  margin:0 auto clamp(16px,2.2vh,26px);
  transition:background .45s var(--ease);
}
@media (min-width:900px){ .dial__rule{ margin-inline:0; } }
.dial__text{
  margin:0; font-size:clamp(20px,2.3vw,33px); line-height:1.33;
  /* the measure is the COLUMN, not a character count. Capped at 21ch the
     longest of the ten ran six lines against a two-line minimum, and a box
     cut to six left four empty lines under most of them — the same sparse
     right-hand side, only taller. Filling the column it is four against two:
     measured across every width. 34ch is a ceiling that only bites above
     1900, where the column finally gets wider than a readable line. */
  letter-spacing:-.012em; color:var(--ink-strong); max-width:34ch;
  /* THE BOX DOES NOT MOVE. The ten sentences run one to four lines at every
     width the page has (measured, not guessed), so the box is cut to four.
     On a phone the dial advances itself: a box that resized every 3.6s would
     shove the whole page below it. Three empty lines under a short sentence
     cost nothing — there is no ground under them to see. */
  min-height:calc(4 * 1.33em);
}
@media (min-width:900px){ .dial__text{ margin-inline:0; } }
@media (max-width:899px){ .dial__text{ margin-inline:auto; } }

/* ══════════════════════════════════════════════════════════ WALLS ══════
   Third-party marks. CSS does the fitting so every one of them sits in the
   same box whatever its aspect; none of them is recoloured or filtered. */
.wall{
  list-style:none; margin:clamp(30px,4vh,52px) 0 0; padding:0;
  display:grid; gap:clamp(14px,2vw,26px);
  grid-template-columns:repeat(2,1fr);
}
@media (min-width:560px){ .wall{ grid-template-columns:repeat(3,1fr); } }
@media (min-width:900px){ .wall{ grid-template-columns:repeat(6,1fr); } }
.wall__cell{
  display:grid; place-items:center; padding:clamp(12px,1.6vw,20px);
  min-height:clamp(70px,7vw,94px);
}
.wall__cell img{
  max-width:100%; max-height:clamp(34px,3.4vw,46px); width:auto; height:auto;
  display:block;
}
.wall--boxed .wall__cell{ border:1px solid var(--line); background:var(--canvas); }

/* ══════════════════════════════════════════════════════ CHAMBERS ═══════ */
.section--chambers{ position:relative; overflow:clip; }
.section--chambers .section__bg{ position:absolute; inset:0; z-index:0; }
.section--chambers .section__bg img{
  width:100%; height:100%; object-fit:cover; object-position:64% 42%;
}
/* the scrim is flat, not one-sided: the words run in one half and an even
   weight is the only thing that keeps the reading even */
.section--chambers .section__bg::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(90deg,
    var(--navy-700) 0 38%, rgba(23,47,86,.86) 58%, rgba(23,47,86,.34) 100%);
}
.chambers{ position:relative; z-index:1; }
.chambers__text{ max-width:46ch; }
.chambers__lede{
  margin:0; font-size:clamp(17px,1.5vw,22px); line-height:1.6; color:var(--ink);
}
.chambers__quote{ margin:clamp(28px,4vh,48px) 0 0; }
.chambers__quote p{
  position:relative; margin:0; font-size:clamp(20px,2.2vw,30px); font-weight:300;
  line-height:1.35; color:var(--ink-strong);
}
/* A PAIR OF MARKS THE SIZE OF THE WORDS. They were a 2.1em glyph hanging
   off the left edge and a second one set inline, which is two different
   objects rather than a pair. Both are 1em now, both inline, both the
   accent, and neither moves the measure. */
.chambers__quote p::before{
  content:'“'; margin-right:.08em; color:var(--accent);
}
.chambers__quote cite{
  display:block; margin-top:clamp(18px,2.4vh,28px); font-style:normal;
  font-size:12.5px; font-weight:500; letter-spacing:.2em; text-transform:uppercase;
  color:var(--ink-faint);
}
@media (max-width:820px){
  .section--chambers .section__bg::after{
    background:linear-gradient(180deg, rgba(23,47,86,.94) 0 62%, rgba(23,47,86,.66) 100%);
  }
}

/* ══════════════════════════════════════════════════════════ TEAM ═══════ */
.tgroups{ display:grid; gap:clamp(34px,5vh,60px); margin-top:clamp(34px,5vh,58px); }
.tgroup{ position:relative; }
.tgroup__name{
  margin:0 0 clamp(14px,2vh,22px); padding-top:13px;
  border-top:3px solid var(--m);
  font-size:clamp(15px,1.25vw,18px); font-weight:500; letter-spacing:.02em;
  color:var(--ink-strong);
}
.tgroup__list{ list-style:none; margin:0; padding:0; display:grid; gap:1px; background:var(--line); }
.tgroup .pcard{
  display:grid; grid-template-columns:auto 1fr; align-items:center;
  gap:14px; padding:14px; background:var(--canvas);
}
.tgroup .pcard__img{
  width:64px; height:64px; border-radius:50%; object-fit:cover;
  border:1px solid var(--line-strong);
}
.tgroup .pcard__body{ min-width:0; }
.tgroup .pcard__name{
  display:block; font-size:clamp(14.5px,1.1vw,16.5px); font-weight:500;
  color:var(--ink-strong); text-decoration:none;
}
.tgroup .pcard__role{
  display:block; margin-top:3px; font-size:12.5px; color:var(--ink-faint);
}
.tgroup .pcard__note{ color:var(--ink-faint); }
/* the actions are a SIBLING of the body and span the card, never a child of
   it: nested, they are trapped in the width of the name column */
.tgroup .pcard__actions{
  grid-column:1 / -1; display:flex; flex-wrap:wrap; gap:7px;
}

/* ══════════════════════════════════════════════════════════ FOOTER ═════ */
.footer{
  background:var(--surface-deep); padding-block:clamp(26px,3.4vh,40px);
  border-top:1px solid var(--line);
}
.footer p{
  margin:0; font-size:13px; font-weight:500; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-faint);
}

@media (prefers-reduced-motion:reduce){
  .plate__cell{ opacity:1; }
}

/* ═════════════════════════════════════════════════════════════════════════
   THE CLIENT'S REVIEW — eleven notes, the ones that are style.
   Appended, so source order settles every overlap deliberately.
   ════════════════════════════════════════════════════════════════════════ */

/* ── the bar's lockup ─────────────────────────────────────────────────────
   Sized by WIDTH, not height, because a lockup's job in a bar is to hold a
   width; the height follows from the artwork.

   THE ARTWORK CHANGED IN ROUND 82 and the numbers here changed with it. The
   patents lockup was 13:1, so 250px of width arrived 19px tall and its
   Hebrew sub-line about four — present, decorative, not readable. The firm's
   own mark is 5.62:1: 175px of width is 31px tall and the sub-line is a line
   of type again. It is SEVENTY-FIVE PIXELS NARROWER than what it replaced,
   which is seventy-five pixels the six long labels get back. */
.nav__logo{ width:200px; height:auto; transition:width var(--t-nav) var(--ease-nav); }
.nav.is-stuck .nav__logo{ width:174px; height:auto; }
/* and air between it and the first menu item */
.nav__brand{ margin-inline-end:clamp(20px,3.4vw,58px); }
/* ON A PHONE THERE IS NOTHING ELSE IN THE BAR — the links are a drawer and
   Contact went into it, so the row is the mark and the burger and nothing
   between them. Measured at 390: 132px of mark and 34 of burger inside 358 of
   usable width, which left a hundred and eighty pixels doing nothing while the
   mark arrived twelve pixels tall. It takes some of them. */
@media (max-width:860px){
  .nav__logo{ width:196px; }
  .nav.is-stuck .nav__logo{ width:176px; }
  .nav__brand{ margin-inline-end:0; }
}
@media (max-width:400px){
  .nav__logo{ width:176px; }
  .nav.is-stuck .nav__logo{ width:158px; }
}

/* ── the quotation closes ─────────────────────────────────────────────────
   It opened and never shut. Both marks are the accent and both are set off
   the text's own box, so neither one moves the measure. */
.chambers__quote p::after{
  content:'”'; margin-left:.06em; color:var(--accent);
}

/* ── THE TEAM ─────────────────────────────────────────────────────────────
   The grey slivers between the cards were a 1px grid gap over `--line`, and
   what made them read as gaps rather than as hairlines is that `.pcard`
   arrives from the first page with a radius AND a shadow — so each card sat
   on the grey with a soft edge all round it. The list is one block now: no
   gap, no shadow, no radius, and a single hairline between rows. */
.tgroup__list{
  gap:0; background:none;
  border:1px solid var(--line); border-radius:var(--r-sm); overflow:hidden;
}
.tgroup .pcard{
  border:0; border-radius:0; box-shadow:none; background:var(--canvas);
  transition:background-color var(--t-fast) var(--ease);
}
.tgroup__list li + li .pcard{ border-top:1px solid var(--line); }
@media (hover:hover){ .tgroup .pcard:hover{ background:var(--canvas-soft); } }


/* ── and a ground under them ──────────────────────────────────────────────
   Three columns of white cards on white was the flattest surface on the page.
   The wash is built from the ACCENT, never from a pastel — a pastel is a mark
   and is never diluted — and the plan grid opens up from the corner it was
   masked into so the cards read as standing on a drawn floor. */
.section--team{ background:linear-gradient(180deg, var(--canvas) 0, var(--canvas-soft) 46%, var(--canvas) 100%); }
.section--team::before{
  --plan-at: 50% 42%;
  --plan-a: .075;
  -webkit-mask-image:radial-gradient(104% 88% at 50% 40%, #000 22%, transparent 82%);
          mask-image:radial-gradient(104% 88% at 50% 40%, #000 22%, transparent 82%);
}
/* two soft lifts off the accent, sitting behind the columns and cut by the
   section's own edges so no band shows at the join */
.section--team::after{
  content:''; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(52% 44% at 14% 22%, rgba(var(--wash-rgb),.10), transparent 68%),
    radial-gradient(46% 40% at 88% 78%, rgba(var(--wash-rgb),.08), transparent 70%);
}

/* ── no underline on hover, anywhere ──────────────────────────────────────
   The accent already says a thing is a link, and on this page that is the one
   signal that has to be learned. */
a:hover, a:focus-visible{ text-decoration:none; }

/* ── THE PINNED PHOTOGRAPH STAYS IN THE COVER ─────────────────────────────
   `.hero__photo` is `position:fixed` — that is what makes the page scroll
   over a still frame rather than parallax it. On the first page three
   sections stand on that picture, so it is wrapped in `.cover` and an
   observer releases it when the last of them leaves. Here only the cover
   stands on it, and without that machinery the photograph simply never let
   go: it showed through every section that has no opaque ground of its own,
   which was most of them.

   `clip-path` on the holder is the fix, and it is the mechanism round 32 of
   the first page had to REMOVE in order to extend the picture past the hero:
   a clip-path creates a containing block for a fixed descendant, so the
   photograph is pinned within the hero and clipped at its foot. No observer,
   no wrapper, nothing to get into the wrong state. */
.cover{ clip-path:inset(0); }
.cover{ position:relative; isolation:isolate; }

/* ── THE QUOTATION ON ONE LINE ────────────────────────────────────────────
   It is thirty-five characters and it was breaking across two, which is what
   made the marks read as stranded. The text column opens up for it and the
   line is held together; below 820px it wraps again, because a phone has no
   width to hold it and a line that runs off the screen is worse than two. */
.chambers__text{ max-width:none; }
.chambers__lede{ max-width:44ch; }
@media (min-width:821px){
  .chambers__quote p{ white-space:nowrap; font-size:clamp(20px,2vw,28px); }
}

/* ── THE TEAM, THE FIRST PAGE'S CARD ─────────────────────────────────────
   `.ccard` brings its own ground, border, radius and hover from that page —
   the ground warms, the border takes the group's pastel, the card lifts 3px
   and the portrait scales 1.04 — so there is nothing to restyle here. What
   is needed is the column, and for the list to stop being the bordered block
   the old card wanted. */
.tgroups{
  display:grid; gap:clamp(20px,2.4vw,30px);
  margin-top:clamp(34px,5vh,58px);
  grid-template-columns:1fr;
}
/* ── EACH AREA SPREADS ACROSS, NOT DOWN ──────────────────────────────────
   Four columns put each group in a tall stack. What the client asked for is
   each area laid out horizontally, so a GROUP IS A ROW: its heading, then its
   partners side by side across the full measure, and the four rows stack.

   The cards are a grid with a WRITTEN track count rather than a flex row,
   and the count is the largest group's — six. A flex row would let the group
   of two grow its cards to fill the measure and the group of one grow its
   card to the whole of it, so a partner's card would be a different size in
   every area. Six fixed tracks give every card in every group the same width,
   and the shorter groups simply leave their tracks empty: Patents fills the
   row, IP Litigation takes the first two of six, Ron Peleg the first one. */
.tgroups{ grid-template-columns:1fr; }
@media (min-width:920px){ .tgroups{ gap:clamp(30px,4.5vh,58px); } }

.tgroup__list{
  list-style:none; margin:0; padding:0;
  display:grid; gap:clamp(11px,1.2vw,15px);
  grid-template-columns:minmax(0,1fr);
  background:none; border:0; border-radius:0; overflow:visible;
}
/* ── FOUR IS THE WIDEST ROW, AND SIX IS GONE ─────────────────────────────
   Six across could not hold `Dr. Daniel Kligler` on one line, and not only at
   the widths the client reported. Measured, with the real font:

     1180–1360   card 136–139, room for text 104–107, the name wants 101
     1360–1600   card 150,     room 118,               the name wants 116
     above 1600  card 173,     room 141,               the name wants 126

   The middle band clears it by TWO PIXELS and the top by fifteen — and two
   pixels is inside the difference between one machine's text rasterisation
   and another's, which is exactly why it broke on the client's screen and not
   on mine. The top band cannot be rescued either: `--wrap` caps at 1240, so
   the card never gets wider than 173 however wide the screen is. There is no
   width at which six is safe.

   Four is. The card is 215 at 1180 and 267 above 1600, which leaves the
   longest name 74% to 86% more room than it needs — a margin no platform can
   close. The cost is that the group of six reads as four and two rather than
   as one row, and that is the client's own proposal.

   The steps: one card to a row on a phone, then three, then four. */
@media (min-width:701px){ .tgroup__list{ grid-template-columns:repeat(3,minmax(0,1fr)); } }
@media (min-width:920px){ .tgroup__list{ grid-template-columns:repeat(4,minmax(0,1fr)); } }


/* ── THE BUTTONS ARE AT THE SAME HEIGHT IN EVERY CARD ────────────────────
   `Dr. Yoav Oestreicher` takes two lines where his neighbour's name takes
   one, which pushed his buttons a line further down than everybody else's in
   that row. The card is already the same height as the others — the grid
   stretches it — so the room is there; it was just at the bottom.

   So the body fills the card and the actions are pushed to its foot with
   `margin-top:auto`. The gap above them then belongs to the ROLE, not to the
   actions: an `auto` margin collapses to nothing in the one card that has no
   slack, and Yoav's buttons would have come to rest against the word under
   his name. */
.tgroup__list .ccard__body{ display:flex; flex-direction:column; flex:1 1 auto; }
.tgroup__list .ccard__actions{ margin-top:auto; }
.tgroup__list .ccard__role{ margin-bottom:16px; }

/* AND THEY ARE CENTRED — PORTRAIT, NAME AND TITLE — as they are on the
   first page. Those five cards are the one centred thing on that page, a
   declared exception to the left-alignment rule rather than a drift, and the
   instruction here was that these cards be those cards one for one. Above
   701px only: below it the card turns into a row with the portrait beside
   the name, and there is no middle to sit in. The buttons are left alone,
   they already fill the row between them. */
@media (min-width:701px){
  .tgroup__list .ccard__avatar{ margin-inline:auto; }
  .tgroup__list .ccard__name,
  .tgroup__list .ccard__role{ text-align:center; }
  /* AND THE NAME TAKES THE ROOM IT NEEDS, NOT TWO LINES ALWAYS. Reserving
     the second line squared every card's height, but it did it by leaving a
     24px hole between a one-line name and the word under it, in all thirteen
     cards, to spare one card a ragged baseline. That is the wrong trade and
     the client called it: `Dr. Yoav Oestreicher` may sit lower than his
     neighbour. The card boxes stay equal — the grid stretches them. */
}

/* AND THE MARKS ARE BACK ON THE CHIPS. They came off at six across, where a
   card was 150px and the two drawn chips had 48 apiece against the 70 they
   want. At four the card is 215 to 267 and a chip gets 97 to 123, which holds
   the icon, its gap and the word with room to spare — so the trade that bought
   those 20px is no longer a trade. These are the first page's cards again,
   whole. */
@media (min-width:920px){
  .tgroup__list .ccard__actions{ gap:7px; }
  .tgroup__list .ccard__actions .chip{
    flex:1 1 0; min-width:0; width:auto; white-space:nowrap;
  }
}
.tgroup__name{
  margin:0 0 clamp(13px,1.8vh,20px); padding-top:12px;
  border-top:3px solid var(--m);
  font-size:clamp(14.5px,1.2vw,17px); font-weight:500; letter-spacing:.02em;
  color:var(--ink-strong);
}
/* ── THE HEADING LINE ────────────────────────────────────────────────────
   The group's name under a 3px rule in its own pastel, running the whole
   measure. The rule belongs to the LINE rather than to the name, which is
   what let the line carry a second name while the sub-niche existed — and
   what costs nothing now that it does not.

   EVERYTHING THE SUB-NICHE NEEDED IS DELETED: `.tsub`, `.tgroup__sub`,
   `.tgroup__list--sub`, `.ccard--sub`, `.tgroup__head--split` and the
   `--c3`/`--c6` column arithmetic, in the markup and here. Ron Peleg is off
   the page and there is no second sub-niche waiting to use any of it.

   `.tgroup--sub .ccard{ background:var(--canvas) }` stays deleted with them:
   it matched `.ccard:hover` in specificity and came later in the file, so it
   won every hover, and that is why his was the one card on the page whose
   ground never warmed. */
.tgroup__head{
  margin:0 0 clamp(13px,1.8vh,20px); padding-top:12px;
  border-top:3px solid var(--m);
}
.tgroup__head .tgroup__name{ margin:0; padding:0; border:0; }



/* ═══════════════════════════════════════════════════ THE NEW COVER ══════
   THE PHOTOGRAPH IS DARK NOW. The corridor render was pale, which is why the
   cover was the one place on this page where Meitar Blue type sat straight on
   a picture. A wireframe bulb on near-black cannot carry that: at 39 of 255
   mean luminance the headline would have been navy on navy.

   So the cover — and only the cover — takes the DARK TOKEN SET, the same one
   `.section--ink` re-declares for the recognition band. Every rule already
   written keeps working inside it: the type inverts, the lines invert, the
   accent becomes the cyan, and `--hero-scrim`, `--hero-photo-o` and
   `--hero-photo-filter` become the values that set were always given.

   What it does NOT take is `.section--ink`'s opaque `background:var(--canvas)`
   — that rule is a separate selector, and putting an opaque ground on the
   cover would paint over the very photograph this is all about.

   The band below is untouched. It is outside `.hero--cover`, it keeps the
   light set, and its own white scrim (62% at the top closing to solid canvas)
   turns the same picture pale as it goes down — which is exactly the handover
   the pair was built for, and it now has a real gradient to make rather than
   a nominal one. */
.hero--cover{
  --hero-veil:none;
  /* THE COLOUR ITSELF, not only the tokens. `body` resolved its `color` from
     the light `--ink` before this block redefined it, and a descendant
     inherits the computed colour rather than the declaration — which is why
     `.section--ink` has always re-applied `color:var(--ink)` on the section.
     Same job here, without that rule's opaque `background`, which on the
     cover would paint over the photograph. */
  color:var(--ink);
  /* AND THE PHOTOGRAPH STAYS AT THE DARK SET'S OWN .5, which is worth saying
     because an override was tried here and could not work: the token block
     above is `[data-theme="light"] .hero--cover`, two selectors to this
     one's one, so a plain `.hero--cover{ --hero-photo-o }` loses on
     specificity however late it comes in the file. It is the right value
     anyway — the picture is texture on the dark ground, not the subject, and
     the bulb reads through it. */
}

/* WHERE THE PICTURE IS CROPPED. The bulb sits in the right third of a 2:1
   frame and the cover is nowhere near 2:1, so a centred crop cuts it in half.
   Pulled right, the crop eats the empty starfield on the left instead and the
   whole bulb survives; on a phone, where the frame is taller than it is wide
   and almost everything goes, the crop sits just inside the glass. */
.hero--cover .hero__photo{ object-position:74% 50%; }
@media (max-width:900px){ .hero--cover .hero__photo{ object-position:66% 50%; } }

/* AND THE PLATE UNDER THE LOCKUP COMES OFF. It was a block of Meitar Blue
   put there because a pale corridor could not hold a navy mark — round 62's
   note says so in as many words. On a near-black photograph it is a navy box
   on a navy ground, and the reversed lockup holds the frame by itself. */
.hero--cover .hero__brand--plate{
  padding:0; background:none; box-shadow:none; border-radius:0;
}
.hero--cover .hero__brand--plate:hover{ background:none; }
.hero--cover .hero__logo{ width:min(300px,62vw); }

/* ── THE COVER'S FIRST BUTTON, LIKE ITS SECOND ────────────────────────────
   A filled Meitar Blue pill on a near-black photograph is a navy shape on a
   navy ground — it was the one element on the cover with no contrast left.
   The client asked for it to be the button beside it, so it is: the same
   outline, the same light ink, the same hover. Order still says which is
   the primary action; colour no longer has to.

   Scoped to the cover. `.btn--primary` everywhere else on the page stands on
   a light ground, where the fill is exactly right. */
/* `.btn--ghost` has no rule of its own — it IS `.btn`'s own set of tokens.
   So the primary is made a ghost by handing those three back, and by dropping
   the navy shadow the filled state casts. */
.hero--cover .btn--primary{
  --btn-bg:transparent; --btn-fg:var(--ink); --btn-bd:var(--line-strong);
}
.hero--cover .btn--primary:hover{
  --btn-bg:rgba(var(--accent-rgb),.08); --btn-bd:var(--accent);
  box-shadow:none; transform:translateY(-2px);
}

/* ══════════════════════════════════ ONE AFTER ANOTHER, TWICE MORE ══════
   The plate's entrance is now the page's way of introducing a set of things:
   each one waits its turn, and the order is the reading order. The client
   asked for the partners' cards and the sectors' index to do the same.

   BOTH ARE DRIVEN BY AN ANIMATION, NOT BY A TRANSITION, and that is the whole
   trick. A card carries a hover — the ground warms, the border takes the
   group's pastel, the whole card lifts 3px — and `.reveal.is-in` would
   replace the card's own `transition` list with one that names only opacity
   and transform, so the hover would stop easing and start snapping. An
   animation runs beside the transitions instead of over them.

   AND THE KEYFRAMES TOUCH OPACITY ONLY. `animation-fill-mode:forwards` holds
   an animated property above any declaration, so a keyframe ending at
   `transform:none` would win against the hover's own `translateY(-3px)` and
   kill the lift for good. Opacity is the one property nothing here competes
   for. */
@keyframes oneByOne{ from{ opacity:0; } to{ opacity:1; } }

/* ── THE PARTNERS ─────────────────────────────────────────────────────────
   THE GRID IS ONLY THE TRIGGER. It does not fade itself: a container fading
   while its cards fade inside it multiplies the two — every card doubly dim
   for the first half-second, which softens the very stagger it is there to
   show. So the grid stands still and the twelve arrive one after another.

   ⚠ THE TRIGGER MOVED IN ROUND 82. It used to be `.tgroup`, one per area,
   and when the areas went the cards were left with `opacity:0` and nothing
   to turn them on — the whole team rendered invisible. The selector now
   names the grid itself. */
.tgrid.reveal{ opacity:1; transform:none; }
/* ── FADE IN UP, AND THE LIFT SURVIVES IT ────────────────────────────────
   The cards faded without moving, because `animation-fill-mode:forwards`
   holds an animated property above any declaration — a keyframe ending at
   `transform:none` would have beaten the hover's own `translateY(-3px)` and
   killed the 3px lift for good. The client asked for fade in up, so the rise
   is back, and `backwards` is what makes it safe:

     · before the group is in view — the base rule below, opacity 0;
     · after it, through the card's own delay — the `from` keyframe, which is
       what `backwards` fills a delay with;
     · during the run — interpolating, the 22px the whole page rises by;
     · once it ends — THE ANIMATION STOPS APPLYING, so opacity comes from the
       rule below and `transform` is free again. The hover has it back.

   The only window where the lift is overridden is the 850ms a card is
   arriving in, and that is the one moment nobody is pointing at it. */
@keyframes fadeInUp{ from{ opacity:0; transform:translateY(22px); } to{ opacity:1; transform:none; } }
.tgroup__list .ccard{ opacity:0; }
.tgrid.is-in .ccard{
  opacity:1;
  /* 1.7s, twice the .85 it ran at, and the step in `initTeam` doubles with it
     — the whole entrance halved in speed rather than only stretched out */
  animation:fadeInUp 1.7s var(--ease-out) var(--cd,0ms) backwards;
}

/* ── THE SECTORS ──────────────────────────────────────────────────────────
   Same again on the index, and for the same reason: the list was one fade,
   and now the eleven write themselves down the column. The rule goes on the
   `<li>` rather than on the `.srow` inside it, so the row's own hover and its
   `aria-current` state are left completely alone. */
.sindex.reveal{ opacity:1; transform:none; }
.sindex > li{ opacity:0; }
.sindex.is-in > li{ animation:oneByOne .92s var(--ease-out) var(--rd,0ms) forwards; }

@media (prefers-reduced-motion:reduce){
  .tgroup__list .ccard, .sindex > li{ opacity:1; animation:none; }
}

/* THE NUMBERS' TILES ARE OPAQUE AGAIN. They went translucent for two rounds
   because they stood on the tower's photograph and nothing on that picture
   may be opaque; they are back on their own ground, so the grey lattice and
   the tile's own canvas come back with them — which is the `.stats` rule as
   it was first written, and there is nothing left here to override. */

/* ══════════════════ THE RECOGNITION PANEL, BESIDE THE PEOPLE ════════════
   Round 81 made it a full-bleed band across the team section, between the
   heading and the first group. Round 82 moves it again, and this time it is
   a COLUMN: a tall navy panel on the left with the partners to its right.

   As a band it was a wall between the heading and the first face. As a
   column it is the thing the faces are evidence for, and it holds its place
   — `position:sticky` — while all twelve of them scroll past it. */
.section--team > .wrap .section__head{ margin-bottom:clamp(22px,3vh,36px); }

.teamlay{
  display:grid; gap:clamp(26px,3vw,44px);
  grid-template-columns:minmax(0,1fr);
  margin-top:clamp(20px,3vh,34px);
}
@media (min-width:1000px){
  .teamlay{ grid-template-columns:minmax(252px,.82fr) minmax(0,2.3fr); align-items:start; }
  /* it stands still while the grid runs past. 96px clears the bar in both
     its states — 71 tall at rest and 57 stuck. */
  .teamlay__side > .chambers--panel{ position:sticky; top:96px; }
}

.chambers--panel{
  position:relative; overflow:clip;
  border-radius:var(--r-md);
  padding:clamp(26px,2.4vw,38px);
  min-height:clamp(330px,40vh,440px);
  /* FLEX, NOT GRID. A grid's implicit column is `auto`, whose maximum is
     max-content — so the quote sized the track to the length of its longest
     line and the panel overflowed its own 252px by a hundred and twenty,
     cutting every line at the edge. A column flexbox stretches its items to
     the cross axis instead, which is the behaviour this wants. */
  display:flex; flex-direction:column; justify-content:center;
}
/* a column is read top to bottom, so the scrim runs that way too. The 90deg
   version is cut for a band the width of the page and would have put its
   dark end against one narrow edge of this. */
.chambers--panel .section__bg::after{
  background:linear-gradient(180deg,
    var(--navy-700) 0 42%, rgba(23,47,86,.88) 74%, rgba(23,47,86,.55) 100%);
}
.chambers--panel .chambers__text{ max-width:none; }
.chambers--panel .chambers__lede{ max-width:none; }
.chambers--panel .chambers__lede{ font-size:clamp(15px,1.05vw,17.5px); }
.chambers--panel .chambers__quote{ margin-top:clamp(22px,3vh,34px); }
/* ⚠ AND IT WRAPS AGAIN. Above 821px the quote is held on ONE LINE — added
   when it stood in a band the width of the page, where thirty-five
   characters breaking in two left the quotation marks stranded. In a 183px
   column that rule cut the line off at the panel's edge. */
.chambers--panel .chambers__quote p{
  font-size:clamp(19px,1.55vw,25px); white-space:normal;
}

/* ── ONE GRID OF TWELVE ──────────────────────────────────────────────────
   Four areas of six, two, three and one made a large firm look like four
   small departments: a row holding a single card reads as a gap, not as a
   speciality, and that is exactly what the client saw. The headings are gone
   and the area moved onto the card.

   It keeps `.tgroup__list` so every card rule already written — the centred
   portrait, the buttons pushed to the foot of the body, the chips that grow
   to fill the row — goes on applying unchanged. `.tgrid` only re-cuts the
   track count, because the column it now lives in is not the whole page:
   THREE ACROSS, AND NOT FOUR AT ANY WIDTH. Round 78 measured what a row of
   four costs: `Dr. Daniel Kligler` wants 126px of text and the card has to
   be about 200 to hold it. Beside a 252px panel there is no screen wide
   enough — at 1440 a quarter of the main column is 158px and at 1920 it is
   186, and both break the name. At three the card is 216 at 1440 and 273 at
   1920. Twelve partners then read as four full rows, which is also the
   better answer to what the client asked: the firm should look large. */
.tgrid{ margin-top:0; }
@media (min-width:1000px){ .tgrid{ grid-template-columns:repeat(3,minmax(0,1fr)); } }

/* ── THE DEPARTMENT, AS A FILLED LABEL ───────────────────────────────────
   A line of faint small caps was not enough to tell four departments apart —
   the client read the grid as one undifferentiated block. It is a pastel
   label now, and `initTeam` gives the card's hover frame the same pastel, so
   everything about a card says which department it belongs to.

   ⚠ THE PASTEL IS THE GROUND AND THE INK ON IT IS MEITAR BLUE. A pastel is a
   mark; it is never ink for words. That rule is why this is a filled label
   and not coloured type.

   The ROW is what holds the height — two lines of it, because
   `Commercial IP and Copyrights` takes two in a card this wide — and the
   label inside it is only as wide as its words. Reserve the height on the
   label itself and a one-line department comes out a tall lozenge. */
.ccard__area{
  margin:9px 0 16px; padding:0;
  min-height:calc(2 * 1.5em + 11px);
  display:grid; place-items:center;
}
.ccard__area > span{
  display:inline-block; max-width:100%;
  padding:5px 12px; border-radius:999px;
  background:var(--area, var(--tint-sky)); color:var(--navy-700);
  font-size:10.5px; font-weight:500; letter-spacing:.1em; line-height:1.5;
  text-transform:uppercase; text-align:center;
}
/* the role's own bottom margin belongs to the area now */
.tgrid .ccard__role{ margin-bottom:0; }

/* ═════════════════════════════════ THE BAR AND SIX LONG LABELS ══════════
   The client's menu labels run to twenty-one characters — "Meitar Practice
   Areas", "Technological Fields" — and six of them will not share a bar with
   a 250px lockup and a Contact pill.

   MEASURED before this block: the row overflowed its own box at every width
   below about 1900 and pushed the pill off the right edge of the screen —
   six pixels at 1440, a hundred and fifty-four at 1024, three hundred and
   seventeen at 900. Nothing scrolled, because the bar clips; the pill simply
   was not there.

   Three things give, in this order:
     1. the pill, below 1600 — "Contact a Partner" floats over every scroll
        position of the page and is the same errand. (The menu's own Contact
        stays hidden: there is no menu above 860 to put it in.)
     2. the lockup and the air beside it, below 1400.
     3. the label size and the gaps, below 1330 — last, because they are what
        the client is actually reading.

   These sit at the foot of the file on purpose: the base `.nav__links` and
   `.nav__logo` declarations come after the breakpoint block up top, so a
   media query written there of the same specificity is dead on arrival. */
@media (min-width:861px){
  /* the pill goes on every desktop width, not only the narrow ones: a bar
     that carries the pill at 1900 and drops it at 1500 is two bars. */
  .nav__cta{ display:none; }
}
/* ⚠ AND THE WIDTHS WENT UP WITH THE WORDMARK. At the old numbers the swap was
   a wash: 188px of the lockup drew its letters 17.8px tall and 188px of the
   wordmark draws them 18.0px, because the letters were always the top half of
   the artwork — all that came off was the line nobody could read. So the width
   is where the size is, and it was raised into the slack each band actually
   has. Measured slack before this block: 58px at 1920, 4.7px at 1600, 11.6 at
   1440, 30 at 900. The 1331–1750 band had nothing to give, so it is given
   some: six pixels off the link gap and six off the lockup's own margin, both
   of which leave the LABELS — the thing the client reads — untouched. */
@media (min-width:1751px){
  .nav__logo{ width:216px; }
  .nav.is-stuck .nav__logo{ width:188px; }
  .nav__brand{ margin-inline-end:34px; }
  .nav__links{ gap:26px; }
}
@media (min-width:861px) and (max-width:1750px){
  .nav__logo{ width:200px; }
  .nav.is-stuck .nav__logo{ width:174px; }
  .nav__brand{ margin-inline-end:12px; }
  .nav__links{ gap:clamp(13px,1.3vw,20px); }
}
@media (min-width:861px) and (max-width:1330px){
  .nav__links{ gap:13px; }
  .nav__links a{ font-size:13px; }
  .nav__brand{ margin-inline-end:16px; }
}
/* 861–1023 is the one band with no root-font step under it, so the labels
   arrive at full size in the narrowest bar there is. */
/* ⚠ AND THIS BAND TAKES NOTHING, it gives. Measured at 861 with the mark at
   162: the links row already ran four pixels past the inner padding, which the
   bar simply clipped — a hairline that predates this round and that raising
   the mark to 178 turned into twenty. So the mark stays where it was and two
   pixels come off each of the five gaps, which puts the row six pixels inside
   its box for the first time. */
@media (min-width:861px) and (max-width:1023px){
  .nav__logo{ width:162px; }
  .nav.is-stuck .nav__logo{ width:146px; }
  .nav__links{ gap:9px; }
  .nav__links a{ font-size:12.5px; }
  .nav__brand{ margin-inline-end:12px; }
}


/* ═════════════════════════ THE WALLS, IN THE TOWER'S COLUMN ═════════════
   The client walls used to be a section of their own between the numbers and
   the tower. They now stand in the tower's own column, above the heading of
   the practice they are credentials for.

   THE COLUMN IS HALF A PAGE, so the grid is three across and not six: at
   1440 the column is about 650px and three cells come out 162px, which is
   the same cell the six-across wall had in a 972px section. The logos did
   not change size; only the number of them per row did. */
.towerwalls{ margin-bottom:clamp(48px,7vh,92px); }
.towerwalls .wall{ grid-template-columns:repeat(2,1fr); }
@media (min-width:560px){ .towerwalls .wall{ grid-template-columns:repeat(3,1fr); } }
/* and the second head inside the block needs less air than a section head */
.towerwalls .section__head--mid{ margin-top:clamp(34px,4.5vh,58px); }

/* ═════════════════════════════ THE NUMBERS, ON NAVY ═════════════════════
   Six white sections ran end to end from the practice areas to the sheet.
   The numbers are the shortest of them and the one with no picture, so it is
   the one that can carry a ground: `.section--ink` re-declares the whole dark
   token set, and `.stat`'s own `background:var(--canvas)` follows it down
   without a single rule of its own. The hairlines between the three cells
   invert with it. */


/* ═══════════════════════ THE COVER'S PICTURE — ROUND 82 ═════════════════
   THE BULB IS GONE. A glowing wireframe light bulb is the most worn image in
   the whole of intellectual property, and the client's note was exact about
   what it costs: it does not put the firm in front, it puts it in line.

   What replaced it is a sheet of PATENT FIGURES — an exploded mechanical
   assembly with its lead lines, a wafer, a lens and its optical path, a
   turbine, a circuit layout, a robot arm, a protein ribbon — drawn in white
   hairlines on Meitar Blue, with translucent panes laid across them. It is
   the thing this practice actually files, drawn the way it is actually
   filed.

   ⚠ TWO CROPS OF IT. The subject is around the EDGES and the middle is
   deliberately empty, for the headline. A portrait screen cropping the
   landscape file to `cover` keeps only that empty middle, so below 820px the
   markup serves a tall file whose drawings run along the top and bottom
   instead. Anything that replaces either one has to keep that property.

   The declarations here are written twice, the second time scoped to
   `[data-theme="light"]`, because the cover's own token block is 0-2-0 and a
   bare `.hero--cover` loses to it. Round 81 lost a whole declaration that
   way and it took a browser to find out. */
.hero--cover,
[data-theme="light"] .hero--cover{
  /* the file is already Meitar Blue and already dark: nothing to correct,
     nothing to hold back. The old filter was pulling a magenta render toward
     the brand and the old .82 was holding a bright corridor down. */
  --hero-photo-o: 1;
  --hero-photo-filter: none;
  /* THE SCRIM DOES THE WORK THE PICTURE USED TO DO. Until round 87 the file
     kept a calm hole in its middle for the headline, which is exactly what
     made every version read as a ring — the drawings had nowhere to go but
     the border. The picture is strewn across its whole surface now, so the
     page darkens its own centre instead.

     ⚠ AND THEN IT CAME BACK DOWN. Round 87's full scatter needed .40 to
     calm the pool under the type; round 88's picture leaves that room
     itself, and the measurement says the scrim now does nothing at all —
     with the type hidden, the brightest five per cent of the ground under
     the lockup, the headline and the buttons gives white 15.1:1 at .18 and
     15.3:1 at .40. A whisper that changes two tenths of a contrast ratio
     should be a whisper. */
  --hero-scrim: rgba(10,15,44,.22);
}
/* centred, both crops. The 74%/66% above were measured off the bulb, which
   sat in the right third of its frame; this one is symmetrical. */
.hero--cover .hero__photo{ object-position:50% 50%; }
@media (max-width:900px){ .hero--cover .hero__photo{ object-position:50% 50%; } }

/* ═════════════════════ THE NUMBERS ARE THE NUMBERS ═════════════════════
   Three tries at this section. Grey boxes on navy were a slab; the figure
   sheet that replaced them — corner ticks, a figure index, an inked leader —
   the client turned down as a concept. So the furniture is gone and the
   QUANTITY is the design.

   Three numerals at a size nothing else on the page comes near, standing on
   ONE hairline that runs the whole measure — type on a baseline, not three
   cells in a frame. The section is called Scale; this is the one place on
   the page where size is the argument, so size is what it uses.

   The pastel survives as a single dot beside each label: a mark, the
   smallest one on the page, against the largest thing on it. */
.section--numbers .stats{
  background:none; border-block:0;
  border-bottom:1px solid var(--line);
  gap:clamp(20px,3vw,52px);
  /* the same escape as the practice plate and the dial, and the same 60 */
  position:relative; left:50%; translate:-50% 0;
  width:min(calc(var(--wrap) + 60px), calc(100vw - 2 * clamp(24px,3vw,64px)));
  margin-top:clamp(40px,6vh,76px);
}
/* three points along one rule, not three cells of equal width. Equal
   columns left a numeral floating at the left of each third with a ragged
   gap after it; set to their own widths and pushed apart, the first sits at
   the start of the rule, the last at its end, and the middle between. */
@media (min-width:640px){
  .section--numbers .stats{
    grid-template-columns:repeat(3,auto);
    justify-content:space-between;
  }
}
.section--numbers .stat{
  background:none;
  padding:0 0 clamp(24px,3.2vh,42px);
  display:grid; justify-items:start; align-content:end;
}
/* the 52x3 tab went with the box it sat on */
.section--numbers .stat::before{ content:none; }
.section--numbers .stat__n{
  font-size:clamp(58px,9.4vw,152px); font-weight:300; line-height:.9;
  letter-spacing:-.045em; color:var(--ink-strong);
}
.section--numbers .stat__k{
  display:flex; align-items:center; gap:10px;
  margin-top:clamp(13px,1.8vh,22px);
  font-size:12.5px; letter-spacing:.18em;
}
.stat__dot{
  width:9px; height:9px; border-radius:50%; background:var(--m); flex:none;
}
/* stacked, the one rule under three of them lands only under the last, so
   each takes its own */
@media (max-width:639px){
  .section--numbers .stats{ border-bottom:0; }
  .section--numbers .stat{
    border-bottom:1px solid var(--line);
    padding-bottom:clamp(20px,2.6vh,30px);
  }
  .section--numbers .stat + .stat{ padding-top:clamp(24px,3vh,34px); }
}

/* ═════════════════ THE WALLS' HEADINGS, CUT TO THE COLUMN ═══════════════
   Both of them arrived at the page's own h2 size — 46px — inside a column
   half a page wide, so both wrapped to two lines and the whole block read as
   headings with logos squeezed between them. In this column they are
   sub-headings: one line each, and the air goes where it was missing. */
/* and `max-width:19ch` comes off with the size. That cap is what actually
   broke both of them across two lines — thirty-one characters cannot sit in
   nineteen — and at this size the column itself is the measure. */
.towerwalls .h2{ font-size:clamp(21px,1.95vw,30px); line-height:1.22; max-width:none; }
.towerwalls .section__head{ margin-bottom:clamp(14px,1.8vh,22px); }
.towerwalls .wall{ margin-top:clamp(20px,2.4vh,30px); }
/* the second heading was 41px off the wall above it. It is a new subject. */
.towerwalls .section__head--mid{ margin-top:clamp(62px,8vh,102px); }

/* and the heading beside the building sits closer to the words under it:
   54px of air under two words is a gap, not a break. The `>` keeps this off
   the walls' own two heads, which are nested a level deeper. */
.tower .section--patents .edge__text > .section__head{
  margin-bottom:clamp(16px,2.2vh,26px);
}

/* ═════════════════════════════ A BIGGER DIAL ════════════════════════════
   The ring was 403px across at 1440 — smaller than the sentence beside it,
   and it is the section's subject. It takes the same escape the practice
   plate takes: out of the wrap's padding, re-centred on the VIEWPORT, and
   capped at the wrap plus 60 or a gutter short of the screen, whichever runs
   out first. At 1440 that is 1160 against the copy's 972, and the ring comes
   out 524 — up from 403.

   ⚠ THE 60 IS THE PLATE'S NUMBER, not a number of its own. Two things on one
   page that both break the measure have to break it by the same amount, or
   the wider one reads as a mistake. */
@media (min-width:900px){
  .dial{
    position:relative; left:50%; translate:-50% 0;
    width:min(calc(var(--wrap) + 60px), calc(100vw - 2 * clamp(24px,3vw,64px)));
    grid-template-columns:minmax(360px,.95fr) minmax(0,1.05fr);
  }
  .dial__stage{ max-width:min(640px,86vw); }
}

/* ═══════════════════════════ THE REVIEW CONTROL ═════════════════════════
   A pill at the foot of the screen that opens the thank-you dialog without
   sending a form. It is DELIBERATELY UNLIKE the page: dashed, monospace,
   stone on navy — nothing on this site looks like this, so nobody can mistake
   it for part of the design or forget it is there.

   ⚠ It is switched in content.js (`PREVIEW.thanks`), and when off the button
   is never appended. This block is then dead and can come out with it. */
.previewbtn{
  position:fixed; left:16px; bottom:16px; z-index:60;
  padding:9px 14px; border-radius:999px;
  background:rgba(19,26,68,.92); color:var(--stone);
  border:1px dashed rgba(235,235,230,.55);
  font:500 11.5px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing:.08em; cursor:pointer;
  backdrop-filter:blur(8px);
  transition:background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.previewbtn:hover{ background:rgba(19,26,68,1); border-color:rgba(235,235,230,.9); }
.previewbtn:focus-visible{ outline:2px solid var(--accent); outline-offset:3px; }
/* the floating Contact pill sits bottom-right, so these two never meet */
@media (max-width:520px){
  .previewbtn{ left:12px; bottom:12px; padding:7px 11px; font-size:10.5px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE CLIENT'S PHONE REVIEW — twelve notes, PHONE ONLY.
   "כל אלו התאמות למובייל בלבד (לא להחיל את זה על דסקטופ)". Every block below
   is inside a max-width query for that reason, and the desktop numbers above
   are left exactly as they are.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 1 · THE COVER IS TWO THIRDS OF THE SCREEN ────────────────────────────
   ⚠ THIS REVERSES A DECISION, and the earlier one is recorded a few hundred
   lines up: "the client asked for the hero to fill the screen whatever the
   screen". On a phone a full screen of it reads empty — one lockup, one line
   and two buttons in 844px — and nothing tells the reader there is a page
   under it. Two thirds puts the top of the next section on screen, which is
   the only reliable instruction to scroll ever invented.

   The photograph is NOT shortened with it. It is `position:fixed` at 100svh
   and the band below the cover is deliberately translucent over it, so the
   picture keeps running under the next section exactly as it did. */
@media (max-width:700px){
  .hero{ min-height:67svh; padding-bottom:clamp(28px,4vh,44px); }
  /* 50px, as asked. `max-width:22ch` was cutting it to two words a line at
     this size, and on a phone the measure is the screen. */
  .hero--cover .hero__title{ font-size:50px; line-height:1.02; max-width:none; }
}

/* ── 2 · THE PRACTICE AREAS GO TWO TO A ROW, ALL THE SAME HEIGHT ──────────
   Nineteen cells one under another is nineteen screens of scrolling. Two to a
   row halves it, and `grid-auto-rows:1fr` is what makes every box the same:
   a grid already equalises the cells WITHIN a row, so a one-column stack had
   nothing to equalise and a two-column one would have had each row sized to
   its own longest label. One track size for every row, taken from the
   tallest, and the lattice reads as a lattice. */
@media (max-width:700px){
  .plate{ grid-template-columns:repeat(2,1fr); grid-auto-rows:1fr; }
}

/* ── 3 · THE THREE FIGURES SHARE ONE ROW ──────────────────────────────────
   Stacked, the section called Scale was three screens tall and the three
   numbers were never once seen together — which is the only thing a row of
   figures is for. They go across, and the type comes down to pay for it:
   measured at 390, the column is 100px and a three-digit numeral at the desk
   size of 58px needs 96 of them with nothing left for the label.

   The label wraps rather than shrinking to fit, and the row reserves two
   lines of it so the three sit on one baseline whether or not their own label
   takes two. The rule under the row comes back, because there is a row again. */
@media (max-width:639px){
  .section--numbers .stats{
    grid-template-columns:repeat(3,minmax(0,1fr));
    gap:14px;
    border-bottom:1px solid var(--line);
  }
  .section--numbers .stat{
    border-bottom:0; padding:0 0 clamp(18px,2.4vh,26px);
  }
  .section--numbers .stat + .stat{ padding-top:0; }
  .section--numbers .stat__n{ font-size:clamp(38px,11.6vw,52px); letter-spacing:-.05em; }
  /* measured at 320, the narrowest phone there is: the longest of the three
     labels needs 77px of an 81px cell, so none of them wraps and no height
     has to be reserved for a second line. The numerals are held in line by
     starting the stack from the top instead of the bottom, which is what the
     desk layout does because there the labels sit under numerals of different
     heights. */
  .section--numbers .stat{ align-content:start; }
  .section--numbers .stat__k{
    align-items:flex-start; gap:6px; margin-top:10px;
    font-size:10px; letter-spacing:.1em; line-height:1.45;
  }
  .stat__dot{ width:7px; height:7px; margin-top:.35em; }
}

/* ── 4 · THE DRAWING STAYS ON SCREEN WHILE THE LIST SCROLLS ───────────────
   The sheet inks itself one stroke at a time as the index advances, and on a
   phone the index is eleven rows under it: by the time you are reading row
   five the drawing is four hundred pixels above the top of the screen and
   every stroke it makes is made where nobody is. The device was invisible on
   a phone, which is the client's note.

   So it sticks. ⚠ AND `.sheetstack` HAS TO STOP BEING A GRID FOR THAT TO
   WORK: a sticky grid item is stuck inside ITS OWN TRACK, and in a one-column
   stack that track is exactly the item's height, so it never moves a pixel. A
   column flexbox gives the same stacking, keeps the `order:-1` that puts the
   sheet first, and makes the item's containing block the whole stack. */
@media (max-width:899px){
  .sheetstack{ display:flex; flex-direction:column; }
  .sheetwrap{
    position:sticky; top:calc(var(--nav-h,70px) + 10px); z-index:2;
    /* it is square, so its width is its height: 300 leaves seven rows of the
       index under it on a 844px screen instead of four */
    padding-bottom:10px; background:var(--canvas);
  }
  .sheet{ max-width:300px; }
}

/* ── 5 · THE DIAL RUNS ITSELF, VISIBLY ────────────────────────────────────
   It already advanced on its own — there is no pointer to hover with — but it
   advanced in 0.6s steps, which reads as the mark jumping rather than as
   anything running, and nothing on screen suggested it could be touched. The
   arc now takes 1.6s of the 4s it has to cross a tenth of the ring, so the
   colour is visibly travelling the whole time; `initDial` winds its offset
   forward for ever rather than back to the start on the tenth, so it runs one
   way round the frame and never rewinds. A tap still takes it there and stops
   it, as it always did. */
/* (the duration is set from initDial now — it changes with what moved the
   dial, four seconds for the automatic run and 600ms for a tap, and a rule
   here could only ever be one of the two) */

/* ── 6 · THE SPACING NOTES ───────────────────────────────────────────────
   A section's full top padding under another's full bottom padding is 185px
   of nothing on a phone. Each of these is the client's own number where they
   gave one. 92.84px is what `clamp(78px,11vh,150px)` resolves to at 844. */
@media (max-width:700px){
  /* "20px above Our Main Practice Areas, and 20 on the other side of the line
     under the paragraph" — the line is the join between the two sections, so
     both of them give 20. A second review took ten more off the heading's side
     and asked for the two to match.

     ⚠ AND THEY ARE MEASURED IN INK, NOT IN BOXES. By box the two gaps read 51
     and 77, which says they are miles apart; by painted pixel — the last row
     of the paragraph to the rule, and the rule to the first row of the
     heading — they were 81 and 76, which is what the eye actually sees. A
     paragraph's box ends well below its last glyph and a heading's box starts
     well above its first, and neither of those is a gap anybody can see. So
     the numbers below are set from the pixel measurement: 67 and 67. */
  .section--firm{ padding-bottom:calc(clamp(78px,11vh,150px) - 32px); }
  .section--practices{ padding-top:calc(clamp(78px,11vh,150px) - 30px); }
  /* 10 above Scale, 10 above Our patent practice */
  .section--numbers{  padding-top:calc(clamp(78px,11vh,150px) - 10px); }
  .section--services{ padding-top:calc(clamp(78px,11vh,150px) - 10px); }
  /* no number given for these two, so they take the largest bite asked for
     anywhere else, plus a little: both sit under a section that ends on air.
     ⚠ THE CTA IS NOT ON THE CLAMP — a phone rule further up already cut it to
     a flat 64px, so subtracting from the clamp here would have left it exactly
     where it was. Its own number, taken off its own value. */
  .section--team{ padding-top:calc(clamp(78px,11vh,150px) - 28px); }
  .section--cta{  padding-top:40px; }
}

/* ── 7 · THE TEAM CARD IS A ROW AGAIN ─────────────────────────────────────
   It was always meant to be one on a phone — "below it the card turns into a
   row with the portrait beside the name" is written against the rule that
   centres the desk card — and it had stopped being one. The phone block sets
   `.ccard__body{ flex:1 1 0 }` so the body takes whatever is left beside a
   64px portrait; `.tgroup__list .ccard__body{ flex:1 1 auto }`, added later
   in the file for the DESK card's "push the buttons to the foot" trick and
   never scoped to a width, overrode the basis with `auto`. The body's natural
   width is the three chips, which do not fit beside a portrait, so it wrapped
   underneath and the card went back to a column — with the department label
   still centred from the desk rule while the name and role were left-aligned.
   That mixture is the client's note.

   So: the body sits beside the portrait, the portrait lines up with the name
   rather than floating in the middle of it, and the label is left-aligned
   with everything above it. The chips keep their own full-width row. */
@media (max-width:700px){
  .tgroup__list .ccard{ align-items:flex-start; gap:13px; }
  .tgroup__list .ccard__body{ flex:1 1 0; min-width:0; }
  .tgroup__list .ccard__avatar{ width:62px; height:62px; margin-top:2px; }
  .tgroup__list .ccard__role{ margin-bottom:0; }
  /* no reserved two-line height and no centring: the label is a chip that
     starts where the name starts */
  .tgroup__list .ccard__area{
    margin:9px 0 0; min-height:0;
    display:flex; justify-content:flex-start;
  }
  .tgroup__list .ccard__area > span{ text-align:left; }
  .tgroup__list .ccard__actions{ margin-top:14px; }
}
/* THE MARKS COME OFF THE TEAM'S CHIPS ON A PHONE, and only there. Three chips
   across a 350px card leaves each one 75px, of which a 15px icon and its gap
   take 22 — and `Full bio` needs more than the 41 that are left, so it wrapped
   to two lines and dragged all three chips to 66px tall. The same trade is
   already made at the other end of the page (`.core__list` above 1181px, where
   four chips share a narrow card): the word is the thing that has to survive.
   `nowrap` then makes the one-line height a guarantee rather than a result. */
@media (max-width:700px){
  .tgroup__list .ccard__actions .chip{
    padding:11px 5px; gap:0; white-space:nowrap; font-size:clamp(11px,3.1vw,13.2px);
  }
  .tgroup__list .ccard__actions .chip svg{ display:none; }
}

/* ── 8 · AND TWO TO A ROW SQUEEZES THE LABELS ─────────────────────────────
   My own doing, and it has to be paid for: a cell that was the width of the
   screen is now half of it, and the row inside it — mark, label, arrow, two
   gaps — leaves the label 60px at 390 and 25px at 320. `Telecommunications`
   is one unbreakable word 136px wide, so it hung 24px out of its cell at
   every phone width, and at 320 three more went with it.

   The mark and the arrow come down to what a phone needs, the gaps with them,
   and the label is allowed to hyphenate. Hyphenation is the part that matters:
   nothing else can break a word of eighteen letters, and `break-word` alone
   would cut it mid-syllable with no mark to say so. */
@media (max-width:700px){
  .plate__cell{ gap:9px; }
  .plate__cell svg{ width:26px; }
  /* ⚠ AND THE ARROW GOES. It is the hover affordance — "it says this one
     leaves the page" — and on a phone there is no hover to reveal it, so it
     sat at .55 opacity taking 27px of every cell including its gap. Those 27
     are the difference between `Construction` fitting on one line and being
     broken after its last letter. The whole cell is the tap target either way.
     Nothing is lost that a phone could have used. */
  .plate__go{ display:none; }
  /* `hyphens:auto` is NOT here, and it was: it needs a hyphenation dictionary
     the engine may not have, and when it does nothing `overflow-wrap` takes
     over and breaks `Construction` into `Constructio / n`. The one word that
     cannot fit carries its own soft hyphen in content.js instead, which is
     the only break that is guaranteed and the only one that prints a mark. */
  .plate__cell b{ font-size:clamp(13px,3.6vw,14px); }
}
/* and under 360 the row itself is the problem, not what is in it: the mark and
   a 9px gap leave 70px of label, which no two-word department fits into. The
   mark goes above the words and the label gets the whole cell. */
@media (max-width:360px){
  .plate__cell{ grid-template-columns:minmax(0,1fr); gap:8px; align-items:start; }
}

/* ═══════════════════════ THE CLIENT'S SECOND PHONE REVIEW ═══════════════
   Eleven notes, PHONE ONLY again, with one exception that is marked where it
   is made (the firm heading, in content.js: a heading cannot read one way on
   a phone and another at a desk).
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 1 · THE SQUARE THAT FLASHES WHEN YOU TAP THE DIAL ────────────────────
   Not the focus ring — that is an outline on a round button and follows its
   radius. It is the browser's own tap highlight, which is drawn over the
   element's BOX, and the box of a round 50px spoke is a square. Default on,
   and nothing on the page had ever turned it off. Off everywhere: the page
   has its own pressed and focus states, and a grey square flashing over a
   drawn mark is not one of them. `:focus-visible` is untouched, so a keyboard
   still gets its ring. */
html{ -webkit-tap-highlight-color:transparent; }

@media (max-width:700px){
  /* ── 2 · THE COVER'S TYPE ──────────────────────────────────────────────
     43/50, the client's own numbers. */
  .hero--cover .hero__title{ font-size:43px; line-height:50px; }

  /* ── 3 · THE TWO BUTTONS SHARE A ROW ───────────────────────────────────
     They wrapped because the pair wants 354px of the 358 a 390px screen has,
     and the 14px gap pushed it over. `nowrap` with a smaller gap and tighter
     pills fits them, and they shrink together rather than one of them
     dropping. */
  .hero--cover .hero__actions{ flex-wrap:nowrap; gap:10px; }
  .hero--cover .hero__actions .btn{
    flex:0 1 auto; min-width:0; white-space:nowrap;
    padding-inline:clamp(14px,4.2vw,22px);
  }

  /* ── 4 · THE PRACTICE CELLS STACK, AND THE MARK GROWS ──────────────────
     The mark goes above the words at every phone width now, not only under
     360. It was the squeeze that made the labels hyphenate in the first
     place: beside the words the mark and its gap took a third of a 176px
     cell. Above them it costs a row and gives the label the whole width — and
     it can be bigger while it is at it, which is what was asked. */
  .plate__cell{
    grid-template-columns:minmax(0,1fr); gap:11px; align-items:start;
    padding-block:18px;
  }
  .plate__cell svg{ width:34px; }

  /* ── 7 · THE TEAM'S CHIPS ARE NOT PILLOWS ──────────────────────────────
     11px of padding around 12px of type is a chip half again as tall as its
     own word. The padding comes down to 8 and the type goes up, so the chip
     is smaller AND the word in it is bigger — the puffiness was the ratio,
     not the height on its own. */
  .tgroup__list .ccard__actions .chip{
    padding:8px 5px; font-size:clamp(11.5px,3.4vw,13.5px);
  }
  .tgroup__list .ccard__actions{ gap:7px; margin-top:12px; }

  /* ── 8 · NEXT STEP, THIRTY MORE ────────────────────────────────────────
     40 was already its own number rather than the section clamp; this takes
     it to 10, which is as close as the two sections can sit while the one
     above still ends on its own bottom padding. */
  .section--cta{ padding-top:10px; }
}

/* ── 9 · THE LINE ABOVE THE PRACTICE AREAS IS A REAL LINE NOW ─────────────
   ⚠ IT WAS NEVER DRAWN. What the client has been calling "the line" is one
   pixel of the COVER PHOTOGRAPH leaking through the seam: `.band` ends on a
   fractional row (300.234 at 390), `.section--practices` has no ground of its
   own, and the fixed picture behind them shows through whatever neither of
   them paints. Sampled at the join: #121F35, which is the photograph, not any
   token on this page. That is also the whole of "at some widths it
   disappears" — the fraction lands differently at every width and every
   device pixel ratio, so the leak is anywhere between a solid dark rule and
   nothing at all. Measured across 430/414/393/390/375/360 at ratios 1, 2 and
   3: the same seam read anywhere from 95 to 203 of contrast.

   So: the section takes a ground, overlaps the band by the pixel that was
   leaking, and draws the rule deliberately in the page's own hairline — the
   same `var(--line)` as the footer's rule and the sectors index. It is
   lighter than the accident was. One token up to `--line-strong` if the
   client wants the old weight back. */
@media (max-width:700px){
  .section--practices{
    background:var(--canvas);
    margin-top:-1px;
    border-top:1px solid var(--line);
  }
}

/* ── 5 · THE LABELS UNDER THE FIGURES, TWO PIXELS UP ──────────────────────
   On the bigger phones only, "למכשירים קטנים אל תגדיל כי אין מקום" — and the
   measurement says the same thing. The three share one row, so the column is
   a third of the screen: at 430 it is 118px and the longest label needs 101 of
   them at 12px, which fits; at 390 it is 105 and the same label needs 101,
   which is four pixels of margin and no more. Below 400 they stay at 10. */
@media (max-width:639px) and (min-width:400px){
  .section--numbers .stat__k{ font-size:12px; }
}
/* and at 320 — the narrowest phone there is — the column is 81px and `LEGAL
   STAFF` wants 77 of them with its tracking at .1em, which is close enough
   that it wrapped. The tracking gives the four pixels back. */
@media (max-width:360px){
  .section--numbers .stat__k{ letter-spacing:.05em; }
}

/* ── 12 · THE PRACTICE LIST READS BIGGER ──────────────────────────────────
   It was cut to 13–14px when the mark sat BESIDE the words and left 60px of
   label; with the mark above them the label has the whole 176px cell and that
   reason is gone. */
@media (max-width:700px){
  .plate__cell b{ font-size:clamp(14px,4.1vw,15.5px); line-height:1.35; }
}

/* ── 13 · AND THE PATENTS COPY OVER THE PHOTOGRAPH ────────────────────────
   "קשה לקרוא את הטקסט של meitar patents בגלל תמונת הרקע."

   MEASURED at 390: the copy was 18.08px of Rubik at WEIGHT 300 — the thinnest
   face on the page — in #3B5480, standing on a photograph of a glass tower. A
   hairline letterform over texture is the whole of the complaint, so the
   weight goes to 400 first and the size up a point with it. Weight buys more
   than size does on a busy ground: every stroke widens, so more of each letter
   is ink and less of it is the building.

   ⚠ AND THE GROUND HAS TO BE MEASURED WITH THE WORDS TAKEN AWAY. Sampling the
   dark tail of the rendered block counts the GLYPHS as though they were
   ground, and the heavier the type the worse that lies — a first pass that way
   said the worst case had got worse, which was its own ink being read back.
   Shot twice, once with the copy and once with it hidden:

                       ink    mean ground    darkest tenth of the ground
     before        .1132        5.09:1                 4.39:1
     after         .0883        6.01:1                 5.18:1

   So it clears AA over the darkest tenth of the picture now, which it did not
   before, and the scrim behind the copy does not have to move — which matters,
   because the client chose this photograph and tuned its transparency over
   four rounds. */
@media (max-width:700px){
  .tower .prose p{ font-weight:400; font-size:1.2rem; }
}
