/* ==========================================================================
   EASE — «PRISME»
   One light entering a solid and coming apart. Near-white ground, one
   electric indigo, and a single family of geometric cuts that runs from the
   band junctions down into the perimeter of every card.
   ========================================================================== */

/* ──────────────────────────────────────────────────────────────────────────
   1. FONTS — three faces, three jobs
   Display carries the voice · a quieter grotesque carries the reading ·
   a monospace carries indices, measurements and data. None can do another's
   job: Space Grotesk tires over a paragraph, Instrument Sans has no voice at
   72px, and neither aligns a column of figures.
   ────────────────────────────────────────────────────────────────────────── */
@font-face{
  font-family:"Space Grotesk";src:url(fonts/space-grotesk-latin.woff2) format("woff2");
  font-weight:300 700;font-style:normal;font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Space Grotesk";src:url(fonts/space-grotesk-latin-ext.woff2) format("woff2");
  font-weight:300 700;font-style:normal;font-display:swap;
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:"Instrument Sans";src:url(fonts/instrument-sans-400-latin.woff2) format("woff2");
  font-weight:400 700;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"Space Mono";src:url(fonts/space-mono-400.woff2) format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"Space Mono";src:url(fonts/space-mono-700.woff2) format("woff2");
  font-weight:700;font-style:normal;font-display:swap;
}

/* ──────────────────────────────────────────────────────────────────────────
   2. TOKENS
   ────────────────────────────────────────────────────────────────────────── */
:root{
  /* ── the indigo ramp. One hue (267°), lightness does the work, chroma
        pulled back at both ends so the pale steps stay paper and the deep
        steps stay ink rather than turning to neon. ───────────────────────── */
  --i05:#F0EEFE;
  --i10:#DDD9FD;
  --i20:#B4A9FB;
  --i30:#8B7BF9;
  --i40:#5D4CF4;
  --i50:#261FEC;   /* primary */
  --i60:#1E17C0;
  --i70:#191394;
  --i80:#151160;
  --i90:#100E3A;

  /* ── paper: the secondary, and two steps under it ───────────────────── */
  --p00:#FCFAFF;   /* secondary */
  --p10:#F5F2FD;
  --p20:#ECE8F9;
  --p30:#DED9F2;

  /* ── ink: the same hue held at low chroma, never neutral grey.
        Spaced against the DEEPEST field, not against paper — the wash sits
        at ~#D2CEF8 and an 11px label has to clear 4.5:1 there. ─────────── */
  --k00:#0B0A22;
  --k40:#3B3760;
  --k60:#514C74;

  /* ── night: the one inverted band ───────────────────────────────────── */
  --night:#0B0A22;

  /* ── signal: functional only, never decorative ──────────────────────── */
  --err:#C2183C;

  /* ── per-band roles. Every band remaps these; no component overrides. ─ */
  --bg:var(--p00);
  --ink:var(--k00); --ink-2:var(--k40); --ink-3:var(--k60);
  --rule:rgba(11,10,34,.12); --rule-2:rgba(11,10,34,.22);
  --field:var(--p20);
  --acc:var(--i50); --acc-hi:var(--i40); --acc-lo:var(--i60);

  /* ── type scale, 1.26 on a 17px body ───────────────────────────────── */
  --t1:11px; --t2:13px; --t3:15px; --t4:17px; --t5:21px;
  --t6:26px; --t7:33px; --t8:42px; --t9:54px; --t10:72px; --t11:92px;

  /* ── spacing, 4px ladder ───────────────────────────────────────────── */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px;
  --s6:32px; --s7:48px; --s8:64px; --s9:96px; --s10:128px;

  /* ── the type ladder. The audit found 24 tracking values, 21 line-heights
        and 23 sizes doing what these do. Anything outside these sets is a
        mistake, not a decision. ───────────────────────────────────────── */
  --tr-d1:-.045em;   /* display, 54px and up */
  --tr-d2:-.032em;   /* display, 26 – 42px   */
  --tr-d3:-.02em;    /* display, 17 – 21px   */
  --tr-cap:.16em;    /* EVERY uppercase label, without exception */
  --tr-ui:.08em;     /* nav and button caps  */

  --lh-tight:.92;    /* display over two lines or more */
  --lh-disp:1.06;    /* display, short                 */
  --lh-lede:1.42;    /* the one large reading size     */
  --lh-body:1.6;     /* every body measure             */
  --lh-cap:1.3;      /* labels and indices             */

  /* ── the cut family. One depth unit and one rise; every junction and
        every card perimeter is built from these two numbers. ──────────── */
  --cut:clamp(14px,2.2vw,34px);
  --rise:clamp(18px,3.2vw,64px);
  --r-s:0px; --r-m:0px; --r-full:999px;   /* the world is cut, not rounded */

  --gut:clamp(18px,4.4vw,72px);
  --maxw:1680px;

  --ez:cubic-bezier(.16,1,.3,1);
  --ez-in:cubic-bezier(.6,0,.9,.3);
  --fast:.16s; --mid:.28s; --slow:.62s;

  --grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}

/* ──────────────────────────────────────────────────────────────────────────
   3. RESET
   ────────────────────────────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;background:var(--p00)}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;background:var(--p00);color:var(--k00);
  font-family:"Instrument Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:var(--t4);line-height:1.6;font-synthesis:none;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  overflow-x:clip;
}
img{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none}
button,input,textarea{font:inherit;color:inherit}
h1,h2,h3,h4,p,figure,blockquote,ul,ol,dl,dd{margin:0}
ul,ol{padding:0;list-style:none}
:focus-visible{outline:2px solid var(--acc);outline-offset:3px}
::selection{background:var(--i50);color:#fff}
.sr{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.skip{position:fixed;left:12px;top:-60px;z-index:200;padding:var(--s3) var(--s4);
  background:var(--i50);color:#fff;font-weight:700;transition:top var(--fast)}
.skip:focus{top:12px}

/* ──────────────────────────────────────────────────────────────────────────
   4. TYPE ROLES
   ────────────────────────────────────────────────────────────────────────── */
.d1,.d2,.d3,.d4,.row__t,.figures b,.pcard b{
  font-family:"Space Grotesk",system-ui,sans-serif;
  overflow-wrap:break-word;hyphens:manual;color:var(--ink);
}
.d1{font-weight:700;font-size:clamp(40px,9vw,var(--t11));line-height:var(--lh-tight);letter-spacing:var(--tr-d1);text-wrap:balance}
/* The hero headline lives in a narrow column, not the viewport: a vw size
   fits at 1440 and overflows the same column at 1024. Size it to its own
   container so the authored line breaks hold at every width. */
.stage__grid>div:first-child{container-type:inline-size}
@supports (container-type:inline-size){
  .d1{font-size:clamp(40px,17.6cqi,var(--t11))}
}
.d2{font-weight:700;font-size:clamp(32px,6vw,var(--t10));line-height:var(--lh-tight);letter-spacing:var(--tr-d1);text-wrap:balance}
.d3{font-weight:700;font-size:clamp(23px,3.4vw,var(--t7));line-height:var(--lh-disp);letter-spacing:var(--tr-d2)}
.d4{font-weight:700;font-size:var(--t5);line-height:var(--lh-disp);letter-spacing:var(--tr-d3)}

.lede{font-size:clamp(var(--t4),1.9vw,var(--t5));line-height:var(--lh-lede);color:var(--ink-2);max-width:52ch}
.body-s{font-size:var(--t3);line-height:var(--lh-body);color:var(--ink-2);max-width:44ch}

/* the data face: indices, measurements, hex, coordinates — never prose */
.mono,.lab,.kick,.row__n,.q__n,.sw span,.curve,.foot__end,.case__tag,.specimen__m,.figures h3{
  font-family:"Space Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  font-feature-settings:"tnum" 1;
}
.lab{font-size:var(--t1);font-weight:700;letter-spacing:var(--tr-cap);text-transform:uppercase;
  color:var(--ink-3);line-height:var(--lh-cap)}
.kick{font-size:var(--t1);font-weight:700;letter-spacing:var(--tr-cap);text-transform:uppercase;
  color:var(--acc);line-height:var(--lh-cap)}
em{font-style:normal;color:var(--acc)}
strong{font-weight:700;color:var(--ink)}

/* ──────────────────────────────────────────────────────────────────────────
   5. THE CUT FAMILY
   Four junction shapes and five card perimeters, all built from --cut and
   --rise. Nothing else in the world is allowed a new corner.
   ────────────────────────────────────────────────────────────────────────── */
.band{position:relative;isolation:isolate;background:var(--bg);color:var(--ink)}
.band>*{position:relative;z-index:2}

/* A · BEVEL — one long shear. The plainest member, used where the change of
   ground should read as a single decisive stroke. */
.cut-bevel{clip-path:polygon(0 var(--rise),100% 0,100% 100%,0 100%)}
.cut-bevel-r{clip-path:polygon(0 0,100% var(--rise),100% 100%,0 100%)}

/* B · STEP — two treads. The stair reads as measured progress. */
.cut-step{clip-path:polygon(
  0 var(--rise),38% var(--rise),38% calc(var(--rise) / 2),
  72% calc(var(--rise) / 2),72% 0,100% 0,100% 100%,0 100%)}

/* C · VEE — an off-centre chevron; the junction folds rather than tilts. */
.cut-vee{clip-path:polygon(0 0,34% 0,46% var(--rise),100% 0,100% 100%,0 100%)}

/* D · TAB — a straight edge broken once, where a band should announce itself
   with a single raised block instead of an angle. */
.cut-tab{clip-path:polygon(
  0 var(--rise),20% var(--rise),20% 0,52% 0,52% var(--rise),
  100% var(--rise),100% 100%,0 100%)}

/* The junction overlaps its neighbour so no paper shows through the cut, and
   buys back the height the shape ate. Doubled: .sec is declared later and
   would otherwise win the padding at equal weight. */
.cut.cut{margin-top:calc(var(--rise) * -1);padding-top:calc(var(--rise) + var(--s7))}

/* ── card perimeters: the same grammar at component scale.
   The cut is held just under the smallest card padding, so no corner ever
   eats into a number or a heading. ─────────────────────────────────────── */
.per{--c:clamp(14px,2vw,30px);position:relative}
/* p1 · chamfer — the bevel, one corner */
.per-1{clip-path:polygon(var(--c) 0,100% 0,100% calc(100% - var(--c)),calc(100% - var(--c)) 100%,0 100%,0 var(--c))}
/* p2 · notch — the step, bitten out of a corner */
.per-2{clip-path:polygon(0 0,calc(100% - var(--c)) 0,calc(100% - var(--c)) calc(var(--c) / 1.6),
  100% calc(var(--c) / 1.6),100% 100%,0 100%)}
/* p3 · tab — the tab, raised off the top edge */
.per-3{clip-path:polygon(0 calc(var(--c) / 1.7),18% calc(var(--c) / 1.7),18% 0,
  56% 0,56% calc(var(--c) / 1.7),100% calc(var(--c) / 1.7),100% 100%,0 100%)}
/* p4 · vee — the chevron, bitten from the foot */
.per-4{clip-path:polygon(0 0,100% 0,100% 100%,62% 100%,52% calc(100% - var(--c)),
  30% 100%,0 100%)}
/* the bite must never reach the copy; .step declares its padding later and
   inside a media query, so this has to outrank it */
.per-4.per-4{padding-bottom:calc(var(--s6) + var(--c))}
/* p5 · ease — one corner released; the only curve the world permits */
.per-5{border-radius:0 0 calc(var(--c) * 1.7) 0;
  clip-path:polygon(var(--c) 0,100% 0,100% 100%,0 100%,0 var(--c))}

/* ──────────────────────────────────────────────────────────────────────────
   6. BACKGROUNDS
   Each band is a composed field, not a flat fill: a value ramp, a two-lobe
   mesh placed off-canvas so no lobe reads as a blob, an optional ruled
   geometry, and grain over everything — an 8-bit ramp on near-white bands
   without it. Gradient midpoints are pushed toward the saturated side so the
   ramp never passes through a dead grey.
   ────────────────────────────────────────────────────────────────────────── */
.band::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:var(--mesh,none);
}
.band::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background-image:var(--grain);background-size:140px 140px;
  opacity:var(--grain-o,.30);mix-blend-mode:multiply;
}

/* ──────────────────────────────────────────────────────────────────────────
   PHOTOGRAPHIC GROUNDS · three bands carry a picture instead of a mesh.
   The three supplied frames are all deep-value, so those bands invert to the
   night token set wholesale. Half-measures were not available here: a dark
   photograph under ink-on-paper type is unreadable at any veil strength that
   still lets the picture exist.

   The layer sits as the section's FIRST child, so `.band>*` gives it z-index 2
   and DOM order puts it under every word. That also keeps it above the grain
   layer at z-index 1, which is deliberate: multiplying film grain over a
   photograph is exactly the noise this world does not have.

   Inset 3px from the top so the cut junction's edge line still draws, and the
   section's own clip-path crops the picture to the junction shape for free.
   ────────────────────────────────────────────────────────────────────────── */
.f-shot .shot{position:absolute;inset:3px 0 0 0;overflow:clip;pointer-events:none}
.f-shot .shot picture,.f-shot .shot img{display:block;width:100%;height:100%}
.f-shot .shot img{object-fit:cover;object-position:var(--sp,50% 50%)}
/* NO SCRIM. There was a full-bleed veil over each picture, art-directed per
   frame, and it did its job on contrast while doing real damage to the images:
   a 92%-black wash over a photograph whose whole subject is light turns a
   specular edge into grey and a deep black into a flat charcoal. Protection
   moved off the picture and onto the things that actually hold words — the
   levers and the FAQ are already smoked glass, and where naked type sits on
   the field the picture's own hotspot is framed away from it with
   object-position. The photographs now render at full strength. */

/* 02 · corridor, under «Cinq leviers» */
.shot--corridor{--sp:50% 42%}
/* The closing note sits opposite the beam. Below 900px the picture's light is
   centred and the column is the full width, so it returns to the left. */
.forme__note{margin-top:var(--s7);max-width:52ch}
@media(min-width:900px){
  .forme__note{margin-left:auto;text-align:right;max-width:46ch}
}
/* 03 · wedge, under «Quatre étapes» */
.shot--wedge{--sp:56% 50%}
/* 01 · plate, under «Les questions d'avant» */
.shot--plate{--sp:50% 46%}
/* Portrait crops are taller than the band, so they anchor on the light rather
   than on the centre: a phone holds the same words in a third of the width. */
@media(max-width:699px){
  .shot--corridor{--sp:50% 38%}
  .shot--wedge{--sp:62% 44%}
  .shot--plate{--sp:50% 42%}
}

/* The levers are the one component that hard-codes paper values, so the
   inversion has to reach them: five pale plates on a night band would punch
   five holes in the photograph. They become glass instead, and the value step
   that separated them survives as a step in translucency.

   SMOKED, not frosted. Lifting them with white — rgba(252,250,255,.07) — was
   the first attempt and it failed exactly where it mattered: the corridor's
   beam runs under lever 05, and a white veil over a white beam is still white,
   so that lever's body copy washed out. A dark tint suppresses a bright
   backdrop instead of joining it, and the picture still reads through at
   around 40%. */
.f-night .lever:not(:nth-of-type(1)){background:rgba(11,10,34,.60)}
.f-night .lever:nth-of-type(3){background:rgba(11,10,34,.54)}
.f-night .lever:nth-of-type(4){background:rgba(11,10,34,.48)}
/* 05 is the one plate the corridor's beam passes directly under, and with the
   veil off the picture that beam is pure white: back-solving the measurement,
   the backdrop behind this cell alone is rgb(249,248,254) and its body copy
   came out at 2.61:1. It takes a deeper smoke than its neighbours — the light
   still reads through as a glow, it just stops bleaching the words. */
.f-night .lever:nth-of-type(5){background:rgba(11,10,34,.80)}
@supports (backdrop-filter:blur(2px)){
  /* the blur is what makes it read as glass rather than as a flat scrim: the
     beam behind it becomes a soft glow held inside the plate */
  .f-night .lever:not(:nth-of-type(1)){backdrop-filter:blur(10px) saturate(1.15)}
}
/* The index is the accent, and --acc at #9E92FB measured 3.76:1 at 13px over a
   plate lit from behind by the beam. It takes the step above, which keeps it
   tinted rather than going plain white and clears with room. */
.f-night .lever__i{color:var(--i10)}

/* The FAQ takes the same treatment for the same reason, and it earns it: the
   plate frame is the one picture whose subject is a single large object dead
   centre, and the tablist is a single large object dead centre. Left opaque it
   would punch a hole straight through the glass it is sitting on. Smoked, the
   plate reads THROUGH the instrument and the five questions become panes of
   the same material. The selected tab stays solid indigo, so the one lit cell
   still carries the state.

   The smoke is set by the BRIGHTEST thing behind it, not the average. At .52
   the even rows measured a backdrop of rgb(91,90,108) — back-solving, the plate
   puts a near-white specular edge behind exactly those cells, and 11px
   metadata came out at 2.07:1. The values below are the ones that clear AA
   against that worst case while still passing about a third of the picture. */
.f-night .faq__q{background:rgba(11,10,34,.74)}
.f-night .faq__q:nth-child(even){background:rgba(11,10,34,.68)}
.f-night .faq__pane{background:rgba(11,10,34,.70)}
@media(hover:hover){.f-night .faq__q:hover{background:rgba(38,31,236,.52)}}
.f-night .faq__q[aria-selected="true"]{background:var(--i50)}
@supports (backdrop-filter:blur(2px)){
  .f-night .faq__q,.f-night .faq__pane{backdrop-filter:blur(12px) saturate(1.15)}
}
/* metadata is the smallest type on the band and it sits on the busiest part of
   the picture, so it takes the step up from --ink-3 */
.f-night .faq__q small,.f-night .faq__n{color:var(--ink-2)}
.f-night .faq__pane .lab{color:var(--acc-hi)}

/* ── THE GROUND · the WebGL layer.
      Five hosts, on every third block. Each sits inside its own band, above
      the CSS mesh and below every word, behind an aperture cut for that
      band's empty region so no text column is ever crossed. The mesh stays
      underneath as the real design: without WebGL, on a coarse pointer, under
      reduced motion or on a hidden tab, nothing runs and the band is exactly
      what it was.
      ─────────────────────────────────────────────────────────────────────── */
.ground{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:clip}
.ground canvas{display:block;width:100%;height:100%;
  opacity:0;transition:opacity 1.1s var(--ez)}
.ground[data-on] canvas{opacity:1}
.stage>.wrap,.stage>.mark{z-index:2}

/* The apertures were the real reason four of the five were invisible, and the
   first fix was the wrong one. Hunting for the empty region in each band was
   never going to work: on the card bands there ISN'T one, so the ground was
   being squeezed into scraps and then dimmed by a .5–.8 layer opacity on top.

   The hero was the proof of the correct model all along — the portrait is an
   opaque plate and the slabs live all around it. So the aperture now covers the
   band, the opaque cards sit ON the ground and protect their own text, and the
   ground reads through every gutter, margin and seam. It only pulls back where
   type sits directly on the field: a headline or a naked pull-quote. Layer
   opacity is gone entirely; the mask alone decides where the ground exists. */

/* 01 · the portrait's room. Held below the nav rule so the menu keeps paper. */
.ground{-webkit-mask-image:radial-gradient(46% 56% at 56% 56%,#000 44%,rgba(0,0,0,.6) 74%,transparent 96%);
        mask-image:radial-gradient(46% 56% at 56% 56%,#000 44%,rgba(0,0,0,.6) 74%,transparent 96%)}
/* 04 · travaux — over the case cluster, fading out before the header row */
.ground--eclats{
  -webkit-mask-image:radial-gradient(74% 34% at 58% 95%,#000 36%,rgba(0,0,0,.6) 70%,transparent 96%);
  mask-image:radial-gradient(74% 34% at 58% 95%,#000 36%,rgba(0,0,0,.6) 70%,transparent 96%)}
/* 07 · secteurs — the one band with no gutters at all: the mass is a tiling
        with 2px seams, so nothing shows through it. The open field is the
        upper right, beside the pivot headline, and the strates run into it as
        a wide low stack that the mass then sits down on top of. */
.ground--strates{
  -webkit-mask-image:radial-gradient(50% 26% at 78% 15%,#000 32%,rgba(0,0,0,.52) 68%,transparent 96%);
  mask-image:radial-gradient(50% 26% at 78% 15%,#000 32%,rgba(0,0,0,.52) 68%,transparent 96%)}
/* 10 · avis — the quotes are naked type on the field, so this one keeps its
        weight to the right and lets the reading column stay paper */
.ground--halo{
  -webkit-mask-image:radial-gradient(58% 92% at 90% 46%,#000 30%,rgba(0,0,0,.5) 66%,transparent 96%);
  mask-image:radial-gradient(58% 92% at 90% 46%,#000 30%,rgba(0,0,0,.5) 66%,transparent 96%)}
/* 13 · footer, glowing off the right edge behind the closing block */
.ground--nuit{
  -webkit-mask-image:radial-gradient(34% 86% at 100% 70%,#000 26%,rgba(0,0,0,.55) 62%,transparent 94%);
  mask-image:radial-gradient(34% 86% at 100% 70%,#000 26%,rgba(0,0,0,.55) 62%,transparent 94%)}
@media(max-width:999px){
  .ground{-webkit-mask-image:radial-gradient(66% 44% at 50% 58%,#000 34%,transparent 92%);
          mask-image:radial-gradient(66% 44% at 50% 58%,#000 34%,transparent 92%)}
  .ground--eclats,.ground--strates,.ground--halo,.ground--nuit{opacity:.78;
    -webkit-mask-image:radial-gradient(88% 38% at 50% 82%,#000 30%,transparent 92%);
    mask-image:radial-gradient(88% 38% at 50% 82%,#000 30%,transparent 92%)}
}

/* F1 · DAWN — paper with the light entering high; the lightest field */
.f-dawn{
  --bg:var(--p00);
  --mesh:
    radial-gradient(78% 62% at var(--gx,8%) -14%,rgba(38,31,236,.26),rgba(93,76,244,.11) 42%,transparent 74%),
    radial-gradient(52% 48% at 96% 18%,rgba(139,123,249,.20),transparent 66%),
    linear-gradient(178deg,var(--p10),var(--p00) 44%,var(--p00));
}
/* F2 · SHELF — a ruled floor under a deeper wash; the reading field.
   Held a clear step below dawn so the junction between them is a real edge
   and not a guess. */
.f-shelf{
  --bg:var(--p20);
  --mesh:
    repeating-linear-gradient(90deg,rgba(11,10,34,.05) 0 1px,transparent 1px var(--rule-gap,92px)),
    radial-gradient(70% 54% at var(--gx,86%) 4%,rgba(38,31,236,.16),transparent 70%),
    linear-gradient(180deg,var(--p10),var(--p20) 56%,var(--p30));
}
/* F3 · PRISM — the loud one: the indigo owns the whole region */
.f-prism{
  --bg:var(--i60);
  --ink:#fff; --ink-2:rgba(255,255,255,.90); --ink-3:rgba(255,255,255,.82);
  --rule:rgba(255,255,255,.28); --rule-2:rgba(255,255,255,.44);
  --acc:#fff; --acc-hi:#fff; --acc-lo:rgba(255,255,255,.9);
  --field:rgba(255,255,255,.12);
  --grain-o:.18;
  /* The refraction lobe is held at .30: any brighter and the ground rises
     past the point where even pure white clears 4.5:1 over it. */
  --mesh:
    conic-gradient(from 210deg at 84% -10%,rgba(180,169,251,.30),rgba(38,31,236,0) 38%),
    radial-gradient(66% 74% at 10% 108%,rgba(11,10,34,.66),transparent 66%),
    linear-gradient(154deg,var(--i50),var(--i60) 46%,var(--i70));
}
/* F4 · NIGHT — the single inverted band */
.f-night{
  --bg:var(--night);
  --ink:var(--p00); --ink-2:#B6B1D4; --ink-3:#8F8AB4;
  --rule:rgba(252,250,255,.14); --rule-2:rgba(252,250,255,.26);
  --acc:#9E92FB; --acc-hi:#B4A9FB; --acc-lo:#8B7BF9;
  --field:rgba(252,250,255,.07);
  --grain-o:.22;
  --mesh:
    radial-gradient(64% 56% at var(--gx,88%) -8%,rgba(93,76,244,.46),transparent 68%),
    radial-gradient(48% 44% at 6% 92%,rgba(38,31,236,.30),transparent 70%),
    linear-gradient(178deg,#14123C,var(--night) 58%);
}
/* F5 · WASH — indigo-tinted paper, between dawn and shelf in value */
.f-wash{
  --bg:var(--i10);
  --mesh:
    radial-gradient(70% 58% at var(--gx,92%) -12%,rgba(38,31,236,.24),transparent 70%),
    radial-gradient(46% 42% at 4% 98%,rgba(93,76,244,.28),transparent 68%),
    linear-gradient(180deg,var(--i05),var(--i10) 58%,#CEC8FC);
}

/* Every junction draws its own edge. Between two pale fields the cut is only
   a value change, and at these lightnesses that reads as a printing artefact
   rather than a decision.

   Two clipped layers, not drop-shadow: a shadow offset upward only ever
   reveals itself along the TOPMOST horizontal segment, so on a step or a
   chevron the lower treads get nothing. Here the section itself is painted in
   the edge colour and the real field sits on ::before, pushed down 3px and
   re-clipped to the same shape — so the edge appears along the entire
   silhouette, whatever the silhouette is. */
.cut{background:var(--edge,var(--i50))}
.cut::before{inset:3px 0 0 0;clip-path:inherit;background-color:var(--bg)}
.f-prism.cut,.f-night.cut{--edge:var(--i30)}

/* ──────────────────────────────────────────────────────────────────────────
   7. FRAME
   ────────────────────────────────────────────────────────────────────────── */
.wrap{max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gut)}
.sec{padding-block:clamp(var(--s8),8vw,var(--s10))}
.sec--tight{padding-block:clamp(var(--s7),6vw,var(--s9))}

.head{display:grid;gap:var(--s4) var(--s7);margin-bottom:var(--s8)}
.head>*{min-width:0}
@media(min-width:900px){
  .head{grid-template-columns:minmax(0,.22fr) minmax(0,1fr);align-items:start}
  .head>.lab{padding-top:.5em}
}
.head .lede{margin-top:var(--s5)}
.head--stack{display:grid;gap:var(--s4);margin-bottom:var(--s8);max-width:min(100%,860px)}
.head--split{display:grid;gap:var(--s5) var(--s7);margin-bottom:var(--s8);
  padding-bottom:var(--s5);border-bottom:1px solid var(--rule)}
.head--split>*{min-width:0}
@media(min-width:900px){.head--split{grid-template-columns:minmax(0,1.1fr) minmax(0,.72fr);align-items:end}}
.head--split .lede{margin:0}

/* ──────────────────────────────────────────────────────────────────────────
   8. SURFACES — one card material, five perimeters
   ────────────────────────────────────────────────────────────────────────── */
.card{
  position:relative;padding:var(--s6);background:var(--p00);
  box-shadow:inset 0 0 0 1.5px var(--rule-2);
  transition:box-shadow var(--mid) var(--ez),translate var(--mid) var(--ez);
}
.f-night .card,.f-prism .card{background:var(--field);box-shadow:inset 0 0 0 1.5px var(--rule)}
.card:hover{translate:0 -3px;box-shadow:inset 0 0 0 1.5px var(--acc)}
/* the cut edge is drawn, so a clipped card still reads as an object */
.card::after{
  content:"";position:absolute;inset:0;z-index:3;pointer-events:none;
  background:linear-gradient(135deg,var(--acc) 0 calc(var(--c,var(--cut)) * .707),transparent 0);
  opacity:.9;
  -webkit-mask:linear-gradient(135deg,#000 0 calc(var(--c,var(--cut)) * .707 + 1.5px),transparent 0);
  mask:linear-gradient(135deg,#000 0 calc(var(--c,var(--cut)) * .707 + 1.5px),transparent 0);
}
.per-2::after,.per-3::after,.per-4::after{display:none}

/* ──────────────────────────────────────────────────────────────────────────
   9. CONTROLS
   ────────────────────────────────────────────────────────────────────────── */
.cta,.btn{
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  gap:var(--s3);cursor:pointer;border:0;white-space:nowrap;
  /* sentence case, not caps: the label tracking belongs to uppercase only,
     and +.08em on a nowrap button pushes it straight out of its track */
  font-family:"Space Grotesk",system-ui,sans-serif;font-weight:700;letter-spacing:var(--tr-d3);
  transition:translate var(--fast) var(--ez),box-shadow var(--fast) var(--ez),
             background var(--fast),color var(--fast),clip-path var(--mid) var(--ez);
}
.cta{
  --c:14px;padding:var(--s4) var(--s5) var(--s4) var(--s6);font-size:var(--t4);
  max-width:100%;
  background:var(--i50);color:#fff;
  clip-path:polygon(var(--c) 0,100% 0,100% calc(100% - var(--c)),calc(100% - var(--c)) 100%,0 100%,0 var(--c));
  box-shadow:0 12px 30px -14px rgba(38,31,236,.85);
}
.cta i{font-style:normal;font-size:var(--t5);line-height:1;transition:translate var(--mid) var(--ez)}
/* the chamfer travels round the perimeter on hover — the cut is alive */
.cta:hover{background:var(--i40);translate:0 -2px;
  clip-path:polygon(0 0,calc(100% - var(--c)) 0,100% var(--c),100% 100%,var(--c) 100%,0 calc(100% - var(--c)))}
.cta:hover i{translate:4px -4px}
.cta:active{translate:0 1px;background:var(--i60);box-shadow:0 4px 12px -8px rgba(38,31,236,.9)}

.btn{--c:11px;padding:var(--s3) var(--s5);font-size:var(--t2);
  background:transparent;color:var(--ink);box-shadow:inset 0 0 0 1px var(--rule-2);
  clip-path:polygon(var(--c) 0,100% 0,100% calc(100% - var(--c)),calc(100% - var(--c)) 100%,0 100%,0 var(--c))}
.btn:hover{box-shadow:inset 0 0 0 1px var(--acc);color:var(--acc);translate:0 -1px}
.btn--solid{background:var(--i50);color:#fff;box-shadow:none}
.btn--solid:hover{background:var(--i40);color:#fff}
.f-prism .btn--solid{background:#fff;color:var(--i50)}
.f-prism .btn--solid:hover{background:var(--p00);color:var(--i60)}

.arw{
  display:inline-grid;place-items:center;width:clamp(46px,4vw,56px);aspect-ratio:1;
  cursor:pointer;border:0;background:transparent;font-size:var(--t4);line-height:1;
  color:var(--ink);box-shadow:inset 0 0 0 1px var(--rule-2);
  clip-path:polygon(12px 0,100% 0,100% calc(100% - 12px),calc(100% - 12px) 100%,0 100%,0 12px);
  transition:translate var(--fast) var(--ez),background var(--fast),color var(--fast),
             box-shadow var(--fast),rotate var(--mid) var(--ez);
}
.arw:hover{background:var(--i50);color:#fff;box-shadow:none;translate:0 -2px}
.arw--solid{background:var(--i50);color:#fff;box-shadow:none}
.arw--solid:hover{background:var(--i40)}
.arwpair{display:flex;gap:var(--s3)}

/* ──────────────────────────────────────────────────────────────────────────
   10. MASTHEAD + STAGE
   ────────────────────────────────────────────────────────────────────────── */
.top{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s5);padding-top:var(--s5)}
.top__logo img{width:clamp(96px,8vw,124px)}
.top__tag{font-size:var(--t2);line-height:var(--lh-body);color:var(--ink-2);text-align:right;max-width:20ch}
.nav{display:flex;flex-wrap:wrap;justify-content:space-between;gap:var(--s3) var(--s5);
  margin-top:clamp(var(--s6),4vw,var(--s7));padding-bottom:var(--s4);border-bottom:1px solid var(--rule)}
.nav a{font-family:"Space Mono",monospace;font-size:var(--t2);font-weight:700;letter-spacing:var(--tr-ui);
  text-transform:uppercase;position:relative;padding-bottom:2px;transition:color var(--fast)}
.nav a::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;background:var(--acc);
  scale:0 1;transform-origin:left;transition:scale var(--mid) var(--ez)}
.nav a:hover{color:var(--acc)}
.nav a:hover::after{scale:1 1}

.stage{padding-top:var(--s5);padding-bottom:clamp(var(--s7),6vw,var(--s9))}
.stage__grid{display:grid;gap:var(--s7);align-items:start;margin-top:clamp(var(--s7),6vw,var(--s9))}
@media(min-width:1000px){.stage__grid{grid-template-columns:minmax(0,1.05fr) minmax(0,.86fr) minmax(0,.6fr)}}
.stage__grid>*{min-width:0}

.subject{position:relative;justify-self:center;align-self:start;width:min(100%,460px);
  --c:clamp(22px,3vw,44px);
  clip-path:polygon(var(--c) 0,100% 0,100% calc(100% - var(--c)),calc(100% - var(--c)) 100%,0 100%,0 var(--c));
  background:var(--i90)}
.subject img{width:100%;filter:grayscale(1) contrast(1.12) brightness(1.06);mix-blend-mode:luminosity;opacity:.92}
.subject::after{content:"";position:absolute;inset:0;
  background:linear-gradient(168deg,rgba(38,31,236,.30),rgba(16,14,58,.72) 74%)}

.philo{display:grid;gap:var(--s4);align-content:start}
.philo p:not(.lab){font-size:var(--t3);line-height:var(--lh-body);color:var(--ink-2);max-width:42ch}
.philo .cta{margin-top:var(--s3);justify-self:start}

.data{display:grid;gap:var(--s3);grid-template-columns:repeat(auto-fit,minmax(min(170px,100%),1fr));
  margin-top:var(--s7);max-width:460px}
.dcard{--c:14px;position:relative;padding:var(--s4) var(--s5);background:var(--p00);
  box-shadow:inset 0 0 0 1.5px var(--rule-2)}
.dcard>span{display:block;font-family:"Space Mono",monospace;font-size:var(--t1);
  font-weight:700;letter-spacing:var(--tr-cap);text-transform:uppercase;color:var(--ink-3)}
.dcard b{display:block;margin-top:var(--s2);font-family:"Space Grotesk",sans-serif;
  font-size:clamp(var(--t7),4vw,var(--t8));font-weight:700;line-height:var(--lh-tight);letter-spacing:var(--tr-d1);
  font-variant-numeric:tabular-nums}
.dcard b i{font-style:normal;font-size:.42em;color:var(--acc);margin-left:var(--s1)}
.dcard small{display:block;margin-top:var(--s3);font-size:var(--t2);color:var(--ink-3);line-height:var(--lh-body)}
.meter{margin-top:var(--s3);height:6px;background:var(--p30);overflow:clip}
.meter i{display:block;height:100%;background-repeat:no-repeat;background-size:var(--v,0%) 100%;
  background-image:linear-gradient(90deg,var(--i70),var(--i50) 40%,var(--i30));
  transition:background-size 1s var(--ez)}

/* The wordmark, cropped by the fold. Sized to the wrap so the whole word is
   legible — cropped past about a third it stops reading as EASE and starts
   reading as stray linework. */
.mark{
  position:absolute;left:var(--gut);right:var(--gut);bottom:0;z-index:0;
  font-family:"Space Grotesk",sans-serif;font-weight:700;line-height:.72;letter-spacing:-.055em;
  font-size:clamp(76px,16.5vw,250px);color:transparent;pointer-events:none;user-select:none;
  text-align:center;
  -webkit-text-stroke:1.5px rgba(38,31,236,.30);
  -webkit-mask-image:linear-gradient(to bottom,#000 62%,transparent);
  mask-image:linear-gradient(to bottom,#000 62%,transparent);
}

/* ──────────────────────────────────────────────────────────────────────────
   11. COMPONENTS
   ────────────────────────────────────────────────────────────────────────── */
.presence{display:grid;gap:var(--s6);align-items:end}
@media(min-width:1000px){.presence{grid-template-columns:minmax(0,.24fr) minmax(0,1fr)}}
.presence>*{min-width:0}
.presence__aside .lab{margin-bottom:var(--s5)}
.pcards{display:grid;gap:var(--s4)}
@media(min-width:760px){.pcards{grid-template-columns:repeat(3,1fr)}}
.pcards>*{min-width:0}
.pcard{position:relative;padding:var(--s6);min-height:clamp(250px,24vw,320px);
  display:grid;align-content:space-between;gap:var(--s5);overflow:clip}
.pcard b{font-weight:700;font-size:clamp(var(--t8),4.4vw,var(--t10));line-height:var(--lh-tight);letter-spacing:var(--tr-d1)}
.pcard b span{font-size:.46em;letter-spacing:-.02em}
.pcard h3{font-family:"Space Grotesk",sans-serif;font-size:var(--t3);font-weight:700;margin-bottom:var(--s2)}
.pcard--fill{background:var(--i50);color:#fff;box-shadow:none;
  --ink:#fff;--ink-2:rgba(255,255,255,.90);--ink-3:rgba(255,255,255,.82);
  --acc:#fff;--rule:rgba(255,255,255,.3)}
.pcard--fill .body-s{color:rgba(255,255,255,.84)}
.pcard--photo{background:var(--i90);color:#fff;box-shadow:none;
  --ink:#fff;--ink-2:rgba(255,255,255,.90);--ink-3:rgba(255,255,255,.82);
  --acc:var(--i20);--rule:rgba(255,255,255,.3)}
.pcard--photo>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;
  filter:grayscale(1) brightness(1.1);mix-blend-mode:luminosity;opacity:.6}
.pcard--photo::before{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(184deg,rgba(38,31,236,.42),rgba(11,10,34,.88) 72%)}
.pcard--photo .body-s{color:rgba(255,255,255,.86)}
.pcard>*{position:relative;z-index:2}

.bleed{margin-inline:calc(var(--gut) * -1)}

/* ──────────────────────────────────────────────────────────────────────────
   11b. RÉFRACTION — the two hand-placed grids
   A beam entering a solid does not come apart evenly. Neither of these
   grids repeats a cell: every plate is placed by hand on twelve columns,
   at its own span and its own depth, so the composition drifts instead of
   stacking or lining up.
   ────────────────────────────────────────────────────────────────────────── */

/* ── FORME · expertises. Not five cards on a field — ONE block, subdivided.
      Five cells of five different sizes tile a solid rectangle with no gap
      and no leftover: the composition has weight because there is nothing
      floating in it. Separation comes from value, not from air, and the cut
      family opens a small void at every internal junction where the corners
      meet. Type scale follows cell size, so the hierarchy is set, not styled.
      ─────────────────────────────────────────────────────────────────────── */
.forme{position:relative;display:grid;gap:2px;isolation:isolate;
  background:var(--rule-2);box-shadow:0 0 0 1.5px var(--rule-2)}
@media(min-width:1000px){
  .forme{
    grid-template-columns:repeat(12,minmax(0,1fr));
    grid-template-rows:repeat(6,auto);
  }
  .lever:nth-of-type(1){grid-column:1 / 8;  grid-row:1 / 5}   /* 7 × 4 — the lead */
  .lever:nth-of-type(2){grid-column:8 / 13; grid-row:1 / 3}   /* 5 × 2 */
  .lever:nth-of-type(3){grid-column:8 / 13; grid-row:3 / 5}   /* 5 × 2 */
  .lever:nth-of-type(4){grid-column:1 / 5;  grid-row:5 / 7}   /* 4 × 2 */
  .lever:nth-of-type(5){grid-column:5 / 13; grid-row:5 / 7}   /* 8 × 2 */
  .lever:nth-of-type(1){--ts:var(--t8)}
  .lever:nth-of-type(5){--ts:var(--t7)}
}
.lever{
  --c:clamp(13px,1.6vw,24px); --s:1; --ts:var(--t6);
  position:relative;display:grid;gap:var(--s3);align-content:start;
  padding:calc(var(--s5) * var(--s)) calc(var(--s5) * var(--s)) calc(var(--s5) * var(--s));
  background:var(--p00);
  transition:background var(--mid) var(--ez),color var(--mid) var(--ez);
}
/* The value steps that separate the cells — no rules, no shadows. The
   colour goes on the LEAD cell: on a small one it pulls the eye to the
   wrong lever and the hierarchy inverts. */
/* the lead cell puts all its free space in ONE interval, under the title, so
   the height reads as an editorial hold rather than as leftover room */
.lever:nth-of-type(1){background:var(--i50);color:#fff;
  --ink:#fff;--ink-2:rgba(255,255,255,.92);--acc:#fff}
.lever:nth-of-type(1) .lever__h{margin-bottom:auto}
.lever:nth-of-type(1):hover{background:var(--i70)}
.lever:nth-of-type(2){background:var(--p00)}
.lever:nth-of-type(3){background:var(--p10)}
.lever:nth-of-type(4){background:var(--p20)}
.lever:nth-of-type(5){background:var(--p00)}
/* the cut family opens the junctions: each cell releases the corner that
   faces the middle of the block, so the seams meet in small diamond voids */
.lever:nth-of-type(1){clip-path:polygon(0 0,100% 0,100% calc(100% - var(--c)),calc(100% - var(--c)) 100%,0 100%)}
.lever:nth-of-type(2){clip-path:polygon(var(--c) 0,100% 0,100% 100%,0 100%,0 var(--c))}
.lever:nth-of-type(3){clip-path:polygon(var(--c) 0,100% 0,100% 100%,var(--c) 100%,0 calc(100% - var(--c)),0 var(--c))}
.lever:nth-of-type(4){clip-path:polygon(0 var(--c),var(--c) 0,100% 0,100% 100%,0 100%)}
.lever:nth-of-type(5){clip-path:polygon(var(--c) 0,100% 0,100% 100%,0 100%,0 var(--c))}
.lever:hover{background:var(--i50);color:#fff;
  --ink:#fff;--ink-2:rgba(255,255,255,.90);--acc:#fff}
.lever:hover .lever__go{translate:5px -5px}

/* the index and the title share one baseline; the index is set smaller and
   opened up, so the pair reads as one typographic unit and needs no chip */
.lever__h{display:flex;align-items:baseline;gap:calc(var(--s3) * var(--s));flex-wrap:wrap}
.lever__i{font-family:"Space Mono",monospace;font-size:var(--t2);letter-spacing:var(--tr-cap);
  font-weight:700;line-height:var(--lh-cap);color:var(--acc);transition:color var(--mid) var(--ez)}
/* the scale is the cell's, not a fixed step: a bigger cell carries a bigger
   title, which is what makes the block read as composed rather than tiled */
.lever__t{font-family:"Space Grotesk",sans-serif;font-weight:700;color:var(--ink);
  font-size:var(--ts);line-height:var(--lh-disp);letter-spacing:var(--tr-d2);
  transition:color var(--mid) var(--ez)}
.lever p{font-size:var(--t3);line-height:var(--lh-body);color:var(--ink-2);max-width:42ch;
  transition:color var(--mid) var(--ez)}
.lever:nth-of-type(1) p{font-size:var(--t4);max-width:34ch}
.lever__go{justify-self:end;align-self:end;font-size:var(--t5);line-height:1;
  margin-top:auto;padding-top:var(--s5);
  color:var(--acc);transition:translate var(--mid) var(--ez),color var(--mid) var(--ez)}

/* ── LA MASSE · secteurs.
      The earlier attempt put a headline, a floating image, a text column and
      six loose plates in the same area and hoped they would relate. They did
      not: three zones, a scatter of equal boxes, and dead space on the right.

      This is one block. The subject and the set column are CELLS of the same
      grid as the terrains, at eight different sizes, tiling a rectangle with
      no gap and no leftover. The two heavy masses — the image top-left and
      the one indigo plate bottom-right — sit on a diagonal so the block has a
      direction. Type scale follows cell size, so the hierarchy is composed
      rather than styled.
      ─────────────────────────────────────────────────────────────────────── */
.stagev{position:relative;display:grid;gap:clamp(var(--s6),4vw,var(--s8));isolation:isolate}
.stagev>*{position:relative;z-index:2;min-width:0}
.stagev__top{display:grid;gap:var(--s4)}
@media(min-width:820px){
  .stagev__top{grid-template-columns:minmax(0,1fr) auto;align-items:start}
  .stagev__lab{justify-self:end;text-align:right;padding-top:.7em}
}
/* This label sits in the exact corner the strates occupy. Colour alone cannot
   save it: measured against the brightest slab behind it, even full ink reaches
   only 4.28:1. It gets a plate instead — which is the world's own answer, the
   same one the levers and the FAQ use — and the chamfer keeps it in the cut
   family rather than reading as a stray chip. */
.stagev__lab{
  margin:0;color:var(--ink);--c:9px;
  padding:.5em .75em .45em;background:var(--p00);
  box-shadow:inset 0 0 0 1px var(--rule);
  clip-path:polygon(var(--c) 0,100% 0,100% calc(100% - var(--c)),
                    calc(100% - var(--c)) 100%,0 100%,0 var(--c));
}

.masse{display:grid;gap:2px;background:var(--rule-2);box-shadow:0 0 0 1.5px var(--rule-2)}
.masse>*{position:relative;min-width:0}
@media(min-width:1000px){
  .masse{grid-template-columns:repeat(12,minmax(0,1fr));grid-template-rows:repeat(6,auto)}
  .masse__subject{grid-column:1 / 6;  grid-row:1 / 5}   /* 5 × 4 — the anchor */
  .masse__text   {grid-column:6 / 13; grid-row:1 / 3}   /* 7 × 2 */
  .terr:nth-child(3){grid-column:6 / 10; grid-row:3}  /* 4 × 1 */
  .terr:nth-child(4){grid-column:10 / 13;grid-row:3}  /* 3 × 1 */
  .terr:nth-child(5){grid-column:6 / 9;  grid-row:4}  /* 3 × 1 */
  .terr:nth-child(6){grid-column:9 / 13; grid-row:4}  /* 4 × 1 */
  .terr:nth-child(7){grid-column:1 / 6;  grid-row:5 / 7}  /* 5 × 2 */
  .terr:nth-child(8){grid-column:6 / 13; grid-row:5 / 7}  /* 7 × 2 — the mass */
  .terr:nth-child(7){--ts:var(--t6)}
  .terr:nth-child(8){--ts:var(--t6)}
}
/* 820–999: the same principle on eight columns, still a complete tiling */
@media(min-width:820px) and (max-width:999px){
  .masse{grid-template-columns:repeat(8,minmax(0,1fr));grid-template-rows:repeat(5,auto)}
  .masse__subject{grid-column:1 / 5; grid-row:1 / 3}
  .masse__text   {grid-column:5 / 9; grid-row:1 / 3}
  .terr:nth-child(3){grid-column:1 / 4; grid-row:3}
  .terr:nth-child(4){grid-column:4 / 9; grid-row:3}
  .terr:nth-child(5){grid-column:1 / 6; grid-row:4}
  .terr:nth-child(6){grid-column:6 / 9; grid-row:4}
  .terr:nth-child(7){grid-column:1 / 4; grid-row:5}
  .terr:nth-child(8){grid-column:4 / 9; grid-row:5}
}
/* narrow: wide · pair · pair · wide, so it never reads as a stack */
@media(max-width:819px){
  .masse{grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:repeat(7,auto)}
  .masse__subject{grid-column:1 / 5; grid-row:1 / 3}
  .masse__text   {grid-column:1 / 5; grid-row:3}
  .terr:nth-child(3){grid-column:1 / 5; grid-row:4}
  .terr:nth-child(4){grid-column:1 / 3; grid-row:5}
  .terr:nth-child(5){grid-column:3 / 5; grid-row:5}
  .terr:nth-child(6){grid-column:1 / 3; grid-row:6}
  .terr:nth-child(7){grid-column:3 / 5; grid-row:6}
  .terr:nth-child(8){grid-column:1 / 5; grid-row:7}
}

/* the set column, opposite a display cascade */
.masse__text{background:var(--p00);padding:clamp(var(--s5),2.4vw,var(--s7));
  display:grid;gap:var(--s4);align-content:start}
.masse__text p{font-size:var(--t3);line-height:var(--lh-body);color:var(--ink-2);
  max-width:46ch;text-align:justify;hyphens:auto}
.masse__text .cta{justify-self:start;margin-top:var(--s2)}
@media(min-width:1000px){
  .masse__text{align-content:space-between}
  .masse__text p{max-width:34ch}
}
@media(max-width:560px){.masse__text p{text-align:left;hyphens:manual}}

/* An indigo duotone at MID value. Near-black would punch a hole in a pale
   field and spend the one inversion the scroll gives to the identity band. */
.masse__subject{overflow:clip;background:var(--i70);
  /* width:100% is load-bearing: with aspect-ratio and only a min-height the
     box sizes itself from the height and overflows the viewport */
  width:100%;min-height:clamp(240px,26vw,440px)}
.masse__subject img{width:100%;height:100%;object-fit:cover;position:absolute;inset:0;
  filter:grayscale(1) brightness(2.1) contrast(.96);mix-blend-mode:luminosity;opacity:.78}
.masse__subject::after{content:"";position:absolute;inset:0;
  background:linear-gradient(196deg,rgba(93,76,244,.44),rgba(25,19,148,.62) 74%)}

/* The word is a mass, not a caption: full bleed, cropped by the band's own
   bottom edge. Paper-white on a pale field would be a ghost. */
.stagev__mark{
  position:absolute;left:0;right:0;bottom:calc(var(--rise) * -.16);z-index:1;
  font-family:"Space Grotesk",sans-serif;font-weight:700;color:var(--i20);
  font-size:clamp(52px,14.6vw,222px);line-height:.74;letter-spacing:-.055em;
  text-align:center;pointer-events:none;user-select:none;white-space:nowrap;
}

/* ── the terrain cells. Not plates on a field — subdivisions of the mass.
      No ring: the 2px seams already separate them. Each releases the corner
      that faces the block's centre, so the seams meet in small diamond voids,
      the same move the levers forme makes. ────────────────────────────────── */
.terr{
  --c:clamp(13px,1.6vw,24px); --s:1; --ts:var(--t5);
  display:grid;gap:var(--s3);align-content:start;
  padding:calc(var(--s5) * var(--s));background:var(--p00);
  transition:background var(--mid) var(--ez),color var(--mid) var(--ez);
}
/* the value steps, and the ONE indigo cell — placed bottom-right so it sits
   diagonally opposite the image and gives the block a direction */
.terr:nth-child(4){background:var(--p10)}
.terr:nth-child(5){background:var(--p20)}
.terr:nth-child(6){background:var(--p10)}
.terr:nth-child(7){background:var(--p20)}
.terr:nth-child(8){background:var(--i50);color:#fff;
  --ink:#fff;--ink-2:rgba(255,255,255,.92);--acc:#fff}
.terr:nth-child(3){clip-path:polygon(0 0,100% 0,100% calc(100% - var(--c)),calc(100% - var(--c)) 100%,0 100%)}
.terr:nth-child(4){clip-path:polygon(var(--c) 0,100% 0,100% 100%,0 100%,0 var(--c))}
.terr:nth-child(5){clip-path:polygon(0 0,calc(100% - var(--c)) 0,100% var(--c),100% 100%,0 100%)}
.terr:nth-child(6){clip-path:polygon(var(--c) 0,100% 0,100% 100%,var(--c) 100%,0 calc(100% - var(--c)),0 var(--c))}
.terr:nth-child(7){clip-path:polygon(0 0,100% 0,100% calc(100% - var(--c)),calc(100% - var(--c)) 100%,0 100%)}
.terr:nth-child(8){clip-path:polygon(var(--c) 0,100% 0,100% 100%,0 100%,0 var(--c))}
/* These cells are content, not controls: a background flip on hover promises
   a click that does not exist, and touch never sees it anyway. */
@media(hover:hover){
  .terr:hover{background:var(--i05)}
  .terr:nth-child(8):hover{background:var(--i60)}
}
.terr__h{display:flex;align-items:baseline;gap:var(--s3);flex-wrap:wrap}
.terr__i{font-family:"Space Mono",monospace;font-size:var(--t1);letter-spacing:var(--tr-cap);
  font-weight:700;line-height:var(--lh-cap);color:var(--acc)}
/* the scale is the cell's own, which is what makes the block read as
   composed rather than merely tiled */
.terr__t{font-family:"Space Grotesk",sans-serif;font-weight:700;color:var(--ink);
  font-size:var(--ts);line-height:var(--lh-disp);letter-spacing:var(--tr-d2);
  overflow-wrap:break-word}
.terr p{font-size:var(--t3);line-height:var(--lh-body);color:var(--ink-2);max-width:38ch}

/* ══════════════════════════════════════════════════════════════════════════
   NON-CARD ELEMENTS
   Thirty-six boxed elements is not a system, it is a habit. These three
   families carry content with no container at all — a ledger of figures, a
   rail of steps, and pull-quotes set straight on the field — so the plates
   that remain read as deliberate rather than as the only tool available.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── LEDGER · présence. Figures on a shared baseline, no boxes. One filled
      plate among them keeps the mix from becoming a rule of its own. ────── */
.ledger{display:grid;gap:var(--s7) var(--s6)}
@media(min-width:760px){.ledger{grid-template-columns:repeat(3,minmax(0,1fr));align-items:end}}
.ledger>*{min-width:0;display:grid;gap:var(--s4);align-content:end}
.ledger b{font-family:"Space Grotesk",sans-serif;font-weight:700;color:var(--ink);
  font-size:clamp(var(--t9),9vw,124px);line-height:var(--lh-tight);letter-spacing:var(--tr-d1);
  font-variant-numeric:tabular-nums}
.ledger b span{font-size:.4em;letter-spacing:var(--tr-d2)}
.ledger h3{font-family:"Space Grotesk",sans-serif;font-size:var(--t5);font-weight:700;
  line-height:var(--lh-disp);letter-spacing:var(--tr-d3);margin-bottom:var(--s2)}
.ledger p{font-size:var(--t3);line-height:var(--lh-body);color:var(--ink-2);max-width:34ch}
/* the one filled entry: a plate, not a card — no ring, no shadow */
.ledger__plate{--c:clamp(14px,2vw,30px);position:relative;overflow:clip;
  padding:var(--s6);background:var(--i90);color:#fff;align-content:space-between;
  --ink:#fff;--ink-2:rgba(255,255,255,.92);--acc:var(--i20);
  clip-path:polygon(var(--c) 0,100% 0,100% 100%,0 100%,0 var(--c))}
.ledger__plate>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;
  filter:grayscale(1) brightness(1.9);mix-blend-mode:luminosity;opacity:.55}
.ledger__plate::before{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(188deg,rgba(38,31,236,.42),rgba(11,10,34,.88) 74%)}
.ledger__plate>*{position:relative;z-index:2}
.ledger__plate b{color:#fff}

/* ── RAIL · méthode. The ladder without its plates: the indent alone carries
      the progression, and only the last step is a filled block. ─────────── */
.rail{display:grid}
.rail>*{display:grid;gap:var(--s3) var(--s6);align-items:baseline;
  grid-template-columns:auto minmax(0,1fr);padding:var(--s6) 0;margin-left:var(--in,0)}
@media(min-width:900px){
  .rail>*{grid-template-columns:auto minmax(0,.34fr) minmax(0,1fr);padding:var(--s7) 0}
  .rail>*:nth-child(2){--in:6%}
  .rail>*:nth-child(3){--in:12%}
  .rail>*:nth-child(4){--in:18%}
}
.rail>*>.body-s{grid-column:1/-1}
@media(min-width:900px){.rail>*>.body-s{grid-column:auto}}
.rail__n{font-family:"Space Grotesk",sans-serif;font-weight:700;line-height:.8;
  letter-spacing:var(--tr-d1);font-size:clamp(38px,4.4vw,var(--t9));
  color:transparent;-webkit-text-stroke:1.5px var(--i20)}
.rail__h{display:grid;gap:var(--s2);align-content:start}
/* the single filled step keeps the mix honest */
.rail__last{--c:clamp(14px,2vw,30px);background:var(--i50);color:#fff;
  padding:var(--s6);margin-top:var(--s5);
  --ink:#fff;--ink-2:rgba(255,255,255,.92);--acc:#fff;
  clip-path:polygon(var(--c) 0,100% 0,100% 100%,0 100%,0 var(--c))}
.rail__last .rail__n{-webkit-text-stroke-color:rgba(255,255,255,.68)}
@media(min-width:900px){.rail__last{margin-left:18%}}

/* ── PULL-QUOTES · avis. Set on the field. A testimonial in a box reads as a
      component; set open, it reads as somebody talking. ─────────────────── */
.voices{display:grid;gap:var(--s8) var(--s7)}
@media(min-width:900px){.voices{grid-template-columns:repeat(3,minmax(0,1fr))}}
.voices>*{min-width:0;display:grid;gap:var(--s5);align-content:start}
.voices blockquote{font-family:"Space Grotesk",sans-serif;font-weight:500;color:var(--ink);
  font-size:clamp(var(--t5),1.9vw,var(--t6));line-height:1.28;letter-spacing:var(--tr-d3);
  max-width:26ch}
.voices figcaption{display:grid;gap:var(--s1)}
.voices b{font-family:"Space Grotesk",sans-serif;font-size:var(--t2);font-weight:700;
  text-transform:uppercase;letter-spacing:var(--tr-ui)}
.voices span{font-family:"Space Mono",monospace;font-size:var(--t2);color:var(--ink-3)}

/* ── CASES · travaux. One lead, two followers. ─────────────────────────── */
.cases{display:grid;gap:var(--s4)}
@media(min-width:1000px){
  .cases{grid-template-columns:minmax(0,1.3fr) minmax(0,1fr)}
  .cases__side{grid-auto-rows:1fr}
}
.cases>*{min-width:0}
.cases__side{display:grid;gap:var(--s4);align-content:start}
.cases__side>*{min-width:0}
.case{position:relative;display:grid;align-content:start;background:var(--p00);
  box-shadow:inset 0 0 0 1.5px var(--rule-2);overflow:clip;
  transition:box-shadow var(--mid) var(--ez),translate var(--mid) var(--ez)}
.case:hover{translate:0 -3px;box-shadow:inset 0 0 0 1.5px var(--acc)}
.case>*{min-width:0}
.case__fig{position:relative;aspect-ratio:16/9;background:var(--i90);overflow:clip}
.case__fig img{width:100%;height:100%;object-fit:cover;
  filter:grayscale(1) brightness(1.5) contrast(1.05);mix-blend-mode:luminosity;opacity:.72;
  transition:scale var(--slow) var(--ez)}
.case:hover .case__fig img{scale:1.04}
.case__fig::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(38,31,236,.34),rgba(11,10,34,.86))}
.case__tag{position:absolute;left:var(--s4);bottom:var(--s3);z-index:2;font-size:var(--t1);
  font-weight:700;letter-spacing:var(--tr-cap);text-transform:uppercase;color:rgba(255,255,255,.86)}
.case__body{padding:var(--s6);display:grid;gap:var(--s3);align-content:start}
/* the lead case earns more room than the two followers */
.case--lead{padding:clamp(var(--s6),2.6vw,var(--s7))}
@media(min-width:620px){
  /* align-content:start on .case packs the single row to the top and leaves
     the stretched card empty below it; this row wants the full height */
  .case--row{grid-template-columns:minmax(0,.44fr) minmax(0,1fr);
    align-items:stretch;align-content:stretch}
  .case--row .case__fig{aspect-ratio:auto;height:100%;min-height:172px}
  .case--row .case__body{align-content:center}
}

/* ── FIGURES · the flooded band ────────────────────────────────────────── */
.flood__lead{display:grid;gap:var(--s4);margin-bottom:var(--s8);max-width:min(100%,680px)}
.figures{display:grid;gap:var(--s6) var(--s5)}
@media(min-width:760px){.figures{grid-template-columns:repeat(3,1fr)}}
.figures>*{min-width:0;display:grid;gap:var(--s3);align-content:start;
  padding-top:var(--s5);border-top:1px solid var(--rule-2)}
.figures b{font-weight:700;line-height:var(--lh-tight);letter-spacing:var(--tr-d1);
  font-size:clamp(52px,8vw,110px);font-variant-numeric:tabular-nums}
.figures b i{font-style:normal;font-size:.36em;opacity:.72;margin-left:var(--s1)}
.figures h3{font-size:var(--t2);letter-spacing:var(--tr-cap);text-transform:uppercase;font-weight:700}
.figures p{font-size:var(--t3);line-height:var(--lh-body);color:var(--ink-2);max-width:34ch}

/* ── LADDER · méthode. Each step further in. ───────────────────────────── */
.ladder{display:grid;gap:var(--s4)}
.step{position:relative;display:grid;gap:var(--s3) var(--s6);align-items:start;
  grid-template-columns:auto minmax(0,1fr);padding:var(--s5);margin-left:var(--in,0px);
  background:var(--p00);box-shadow:inset 0 0 0 1.5px var(--rule-2);
  transition:box-shadow var(--mid) var(--ez),translate var(--mid) var(--ez)}
.step:hover{translate:0 -3px;box-shadow:inset 0 0 0 1.5px var(--acc)}
.step .body-s{grid-column:1/-1}
@media(min-width:900px){
  .step{grid-template-columns:auto minmax(0,.36fr) minmax(0,1fr);padding:var(--s6)}
  .step .body-s{grid-column:auto}
  .step:nth-child(2){--in:5%}
  .step:nth-child(3){--in:10%}
  .step:nth-child(4){--in:15%}
}
.step>*{min-width:0}
.step__n{font-family:"Space Grotesk",sans-serif;font-weight:700;line-height:.8;
  letter-spacing:var(--tr-d1);font-size:clamp(38px,4.4vw,var(--t9));
  color:transparent;-webkit-text-stroke:1.5px var(--i20)}
.step__h{display:grid;gap:var(--s2);align-content:start}
.step--last{background:var(--i50);color:#fff;box-shadow:none;
  --ink:#fff;--ink-2:rgba(255,255,255,.90);--ink-3:rgba(255,255,255,.82);--acc:#fff}
.step--last .step__n{-webkit-text-stroke-color:rgba(255,255,255,.62)}

/* ──────────────────────────────────────────────────────────────────────────
   11c. CINEMATIC TYPE
   Two headline compositions, built out of the setting alone — scale, weight,
   colour, indent and the break itself. No rules, no numerals, no ornament.
   ────────────────────────────────────────────────────────────────────────── */

/* CASCADE — the sentence steps down and inward as it resolves, the way the
   grid beside it drifts. Used once, on the levers. */
.cine{display:block;font-family:"Space Grotesk",sans-serif;font-weight:700;
  color:var(--ink);text-wrap:nowrap}
.cine>span{display:block;overflow-wrap:break-word;text-wrap:pretty}
.cine>span:nth-child(1){font-size:clamp(38px,8vw,var(--t11));line-height:var(--lh-tight);letter-spacing:var(--tr-d1)}
.cine>span:nth-child(2){font-size:clamp(27px,5vw,var(--t9));line-height:var(--lh-disp);letter-spacing:var(--tr-d2);
  margin-left:clamp(0px,3.4vw,64px);margin-top:.12em}
.cine em{font-style:normal;color:var(--acc)}
/* the annotation hangs off the composition instead of stacking above it */
.cine-note{display:block;font-family:"Space Mono",monospace;font-size:var(--t2);
  letter-spacing:var(--tr-cap);font-weight:700;text-transform:uppercase;color:var(--ink-3);
  margin-left:clamp(0px,6.8vw,128px);margin-top:var(--s4)}
.cine-block{margin-bottom:clamp(var(--s7),5vw,var(--s9))}

/* PIVOT — the sentence holds one size, then the verb breaks scale and colour
   in the middle and the sentence closes back down. Used once, on the fields. */
.pivot{display:block;font-family:"Space Grotesk",sans-serif;font-weight:700;color:var(--ink)}
.pivot>span{display:block;font-size:clamp(24px,3.9vw,52px);
  line-height:var(--lh-disp);letter-spacing:var(--tr-d2);overflow-wrap:break-word}
.pivot>em{display:block;font-style:normal;font-weight:700;color:var(--acc);
  font-size:clamp(44px,9.8vw,118px);line-height:var(--lh-tight);letter-spacing:var(--tr-d1);
  margin-left:clamp(0px,4.4vw,84px);margin-block:.04em .02em}

.kit{display:grid;gap:var(--s4)}
@media(min-width:900px){.kit{grid-template-columns:repeat(12,1fr)}
  .k-a{grid-column:span 5} .k-b{grid-column:span 7}
  .k-c{grid-column:span 7} .k-d{grid-column:span 5}}
.kit>*{min-width:0}
.markbox{display:grid;place-items:center;min-height:200px;margin-top:var(--s4);padding:var(--s7);
  position:relative;overflow:clip;background:var(--i90)}
.markbox img{width:min(70%,290px)}
.markbox i{position:absolute;inset:var(--s4);border:1px dashed rgba(252,250,255,.24)}
.swatches{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(80px,100%),1fr));gap:var(--s2);margin-top:var(--s4)}
.sw{padding:var(--s2);display:grid;gap:var(--s2);min-width:0;box-shadow:inset 0 0 0 1px var(--rule)}
.sw i{display:block;height:48px;background:var(--c-sw)}
.sw b{font-family:"Space Grotesk",sans-serif;font-size:var(--t1);letter-spacing:var(--tr-ui);
  text-transform:uppercase;font-weight:700}
.sw span{font-size:var(--t1);color:var(--ink-3)}
.specimen{display:grid;gap:var(--s3);margin-top:var(--s4)}
.specimen__row{display:flex;align-items:baseline;gap:var(--s4);flex-wrap:wrap;
  padding-bottom:var(--s3);border-bottom:1px solid var(--rule)}
.specimen__row:last-child{border-bottom:0;padding-bottom:0}
.specimen__a{font-family:"Space Grotesk",sans-serif;font-weight:700;line-height:var(--lh-disp);letter-spacing:var(--tr-d1);
  font-size:clamp(var(--t7),3.2vw,var(--t8))}
.specimen__a--body{font-family:"Instrument Sans",sans-serif;font-weight:400;letter-spacing:0}
.specimen__a--mono{font-family:"Space Mono",monospace;font-weight:400;letter-spacing:0;font-size:var(--t6)}
.specimen__m{font-size:var(--t1);font-weight:700;letter-spacing:var(--tr-cap);text-transform:uppercase;color:var(--ink-3)}
.glyphs{margin-top:var(--s3);font-family:"Space Grotesk",sans-serif;font-size:var(--t3);
  font-weight:500;letter-spacing:var(--tr-ui);color:var(--ink-2);overflow-wrap:break-word}
.rules{display:grid;gap:var(--s3);margin-top:var(--s4)}
.rules li{display:grid;grid-template-columns:auto minmax(0,1fr);gap:var(--s3);align-items:baseline;
  font-size:var(--t3);line-height:var(--lh-body);color:var(--ink-2)}
.rules li::before{content:"";width:8px;height:8px;background:var(--acc);translate:0 -1px;
  clip-path:polygon(3px 0,100% 0,100% 5px,5px 100%,0 100%,0 3px)}
.curve{margin-top:var(--s4);padding:var(--s3) var(--s4);font-size:var(--t2);color:var(--ink);
  background:var(--field);box-shadow:inset 0 0 0 1px var(--rule);overflow-wrap:break-word}

.statement{display:grid;gap:var(--s7);align-items:start}
@media(min-width:900px){.statement{grid-template-columns:minmax(0,.40fr) minmax(0,1fr)}}
.statement>*{min-width:0}
.statement__img{--c:clamp(20px,2.6vw,38px);position:relative;aspect-ratio:1;overflow:clip;background:var(--i90);
  clip-path:polygon(var(--c) 0,100% 0,100% calc(100% - var(--c)),calc(100% - var(--c)) 100%,0 100%,0 var(--c))}
.statement__img img{width:100%;height:100%;object-fit:cover;object-position:52% 24%;
  filter:grayscale(1) contrast(1.1) brightness(1.08);mix-blend-mode:luminosity;opacity:.9}
.statement__img::after{content:"";position:absolute;inset:0;
  background:linear-gradient(172deg,rgba(38,31,236,.30),rgba(11,10,34,.62))}
.statement__body{display:grid;gap:var(--s5)}
.statement__top{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--s5)}
.qmark{font-family:"Space Grotesk",sans-serif;font-size:var(--t9);line-height:.6;color:var(--acc);font-weight:700}
.statement__ref{font-family:"Space Mono",monospace;font-size:var(--t2);line-height:var(--lh-cap);
  color:var(--ink-3);text-align:right}
.statement__say{font-family:"Space Grotesk",sans-serif;font-weight:500;
  font-size:clamp(var(--t5),2.4vw,var(--t6));line-height:var(--lh-lede);letter-spacing:var(--tr-d3);
  color:var(--ink);max-width:44ch}
.statement__foot{display:flex;justify-content:space-between;align-items:flex-end;gap:var(--s5);flex-wrap:wrap}
.statement__who{font-family:"Space Mono",monospace;font-size:var(--t2);line-height:var(--lh-cap);
  color:var(--ink-2);text-transform:uppercase;font-weight:700;letter-spacing:var(--tr-cap)}

.cards{display:grid;gap:var(--s4)}
.cards>*{min-width:0}
@media(min-width:760px){.cards--2{grid-template-columns:1fr 1fr}
  .cards--3{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1080px){.cards--3{grid-template-columns:repeat(3,1fr)}}
.quote{display:grid;gap:var(--s4);align-content:start}
.quote blockquote{font-size:var(--t4);line-height:var(--lh-body);color:var(--ink)}
.quote figcaption{display:grid;gap:var(--s1);padding-top:var(--s4);border-top:1px solid var(--rule)}
.quote b{font-family:"Space Grotesk",sans-serif;font-size:var(--t2);font-weight:700;
  text-transform:uppercase;letter-spacing:var(--tr-ui)}
.quote span{font-family:"Space Mono",monospace;font-size:var(--t2);color:var(--ink-3)}
.stars{font-size:var(--t2);letter-spacing:var(--tr-cap);color:var(--acc)}

/* ── FAQ · one contained instrument, not a stack of rows.
      The questions are an index down the left, the answer opens in a fixed
      pane on the right, and the whole thing sits inside a single cut frame
      with the same 2px seam the masse uses. It is a tablist, so the keyboard
      gets arrows, Home and End rather than five separate disclosures. ───── */
.faq{position:relative;display:grid;gap:2px;background:var(--rule-2);
  box-shadow:0 0 0 1.5px var(--rule-2);--c:clamp(16px,2.2vw,34px);
  clip-path:polygon(var(--c) 0,100% 0,100% calc(100% - var(--c)),
                    calc(100% - var(--c)) 100%,0 100%,0 var(--c))}
@media(min-width:900px){.faq{grid-template-columns:minmax(0,.86fr) minmax(0,1fr)}}
.faq__index{display:grid;align-content:start;gap:2px;background:var(--rule-2)}
.faq__q{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;
  gap:var(--s4);padding:var(--s5) var(--s6);text-align:left;cursor:pointer;
  background:var(--p00);border:0;color:var(--ink);
  transition:background var(--mid) var(--ez),color var(--mid) var(--ez);
}
.faq__q:nth-child(even){background:var(--p10)}
.faq__q:hover{background:var(--i05)}
.faq__q[aria-selected="true"]{background:var(--i50);color:#fff;
  --ink:#fff;--ink-2:rgba(255,255,255,.92);--ink-3:rgba(255,255,255,.82);--acc:#fff}
.faq__n{font-family:"Space Mono",monospace;font-size:var(--t1);font-weight:700;
  letter-spacing:var(--tr-cap);line-height:var(--lh-cap);color:var(--ink-3)}
.faq__t{display:grid;gap:var(--s2);min-width:0}
.faq__t small{font-family:"Space Mono",monospace;font-size:var(--t1);font-weight:700;
  letter-spacing:var(--tr-cap);line-height:var(--lh-cap);text-transform:uppercase;color:var(--ink-3)}
.faq__t span{font-family:"Space Grotesk",sans-serif;font-weight:700;color:var(--ink);
  font-size:clamp(var(--t4),1.6vw,var(--t5));line-height:var(--lh-disp);
  letter-spacing:var(--tr-d3);overflow-wrap:break-word}
.faq__go{font-size:var(--t5);line-height:1;color:var(--acc);
  transition:translate var(--mid) var(--ez)}
.faq__q[aria-selected="true"] .faq__go{translate:4px 0}

.faq__pane{position:relative;background:var(--p00);display:grid}
/* the pane's height comes from the index beside it, so the answer sits on
   the optical centre rather than stranded at the top of a tall box */
.faq__a{grid-area:1/1;padding:clamp(var(--s6),3vw,var(--s8));
  align-content:center;display:grid;gap:var(--s4)}
@media(max-width:899px){.faq__a{align-content:start}}
.faq__a[hidden]{display:none}
.faq__a p{font-size:var(--t4);line-height:var(--lh-body);color:var(--ink-2);max-width:52ch}
.faq__a .lab{color:var(--acc)}
/* the answer arrives by the same cut as everything else */
.js .faq__a{
  -webkit-mask-image:linear-gradient(100deg,#000 38%,rgba(0,0,0,.3) 52%,transparent 64%);
  mask-image:linear-gradient(100deg,#000 38%,rgba(0,0,0,.3) 52%,transparent 64%);
  -webkit-mask-size:250% 100%;mask-size:250% 100%;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:0 0;mask-position:0 0;
}
.js .faq__a[data-enter]{animation:faqin .55s var(--ez) both}
@keyframes faqin{
  from{-webkit-mask-position:100% 0;mask-position:100% 0;opacity:.2}
  to{-webkit-mask-position:0 0;mask-position:0 0;opacity:1}
}
@media(prefers-reduced-motion:reduce){
  .js .faq__a,.js .faq__a[data-enter]{animation:none;-webkit-mask-image:none;mask-image:none}
}

/* ──────────────────────────────────────────────────────────────────────────
   12. FORM
   ────────────────────────────────────────────────────────────────────────── */
.form{display:grid;gap:var(--s4)}
.f{display:grid;gap:var(--s2)}
.f label{font-family:"Space Mono",monospace;font-size:var(--t1);letter-spacing:var(--tr-cap);
  text-transform:uppercase;color:var(--ink-3);font-weight:700}
/* 16px, not the 15px of --t3. Under 16px iOS Safari zooms the page in on tap
   and never zooms back out, which strands the visitor mid-form at 1.3x. */
.f input,.f textarea{--c:9px;width:100%;padding:var(--s3) var(--s4);background:var(--p00);
  color:var(--ink);border:0;box-shadow:inset 0 0 0 1px var(--rule-2);font-size:16px;
  clip-path:polygon(var(--c) 0,100% 0,100% calc(100% - var(--c)),calc(100% - var(--c)) 100%,0 100%,0 var(--c));
  transition:box-shadow var(--fast),background var(--fast)}
.f input::placeholder,.f textarea::placeholder{color:var(--ink-4,#6b6690);opacity:1}
.f textarea{resize:vertical;min-height:118px}
/* The row is reserved whether or not there is an error in it. Growing the
   layout on blur moved the submit button out from under a click that was
   already in flight: mousedown landed on the button, mouseup landed on the
   error text below it, and the browser dispatched the click on their common
   ancestor instead — so the first press of "Envoyer ma demande" did
   nothing at all. */
.f small{font-size:var(--t2);line-height:1.35;color:var(--err);min-height:1.35em}
.f[data-bad] input,.f[data-bad] textarea{box-shadow:inset 0 0 0 2px var(--err)}
/* Focus comes AFTER the error rule and carries both rings: an errored field is
   exactly the field a keyboard user is being sent back to, and the error style
   was winning on source order and erasing the focus indicator at that moment. */
.f input:focus,.f textarea:focus{outline:none;box-shadow:inset 0 0 0 2px var(--acc)}
.f[data-bad] input:focus,.f[data-bad] textarea:focus{
  box-shadow:inset 0 0 0 2px var(--err),inset 0 0 0 5px var(--p00),inset 0 0 0 7px var(--acc)}
/* box-shadow is discarded in Windows High Contrast, so `outline:none` above
   would leave those users with no focus indicator at all. Give the outline
   back, in the system colour. */
@media (forced-colors:active){
  .f input:focus,.f textarea:focus,
  .f[data-bad] input:focus,.f[data-bad] textarea:focus{outline:3px solid Highlight;outline-offset:-3px}
}
.form__row{display:grid;gap:var(--s4)}
/* Keyed to the VIEWPORT while the form itself sits inside a two-column card
   grid: between 764 and 1124 the row went two-up inside a container barely
   130px wide, which wrapped one label and dropped its input 12px below its
   neighbour. Two columns only once the card is genuinely wide enough. */
@media(min-width:1132px){.form__row{grid-template-columns:1fr 1fr}}
.form__row>*{min-width:0}
.form__note{font-size:var(--t2);line-height:var(--lh-body);color:var(--ink-3);max-width:52ch;
  padding-top:var(--s4);border-top:1px solid var(--rule)}
.sent{display:grid;gap:var(--s3);justify-items:start;align-content:center;padding:var(--s7);
  background:var(--i50);color:#fff;
  /* a flipped ground must remap the ACCENT too, or the kicker goes
     indigo-on-indigo and disappears */
  --ink:#fff;--ink-2:rgba(255,255,255,.90);--ink-3:rgba(255,255,255,.82);--acc:#fff}
.sent .body-s{color:rgba(255,255,255,.86)}
.sent .btn{color:#fff;box-shadow:inset 0 0 0 1px rgba(255,255,255,.5)}
.sent .btn:hover{background:#fff;color:var(--i50)}

/* ── the WhatsApp continuation ─────────────────────────────────────────────
   Inside the success panel the button is no longer "start over" — the visitor
   has just sent the thing, so the only useful next move is talking to us. It
   keeps the panel's white-on-indigo treatment and only borrows the glyph.  */
.sent .btn--wa{display:inline-flex;align-items:center;gap:var(--s3);text-decoration:none}
.sent .btn--wa .wa__g{flex:none}

/* ── the side tab ──────────────────────────────────────────────────────────
   Fixed to the right edge so it holds its place while the page moves under
   it. Same chamfer as every button on the site: it belongs to this page
   rather than sitting on top of it like a bought-in widget. The label is
   present at rest, not on hover — a control that hides its name is a puzzle. */
.wa{
  --c:12px;
  /* 78%, not the middle: at 62% the tab clipped the hero's own «Demander un
     devis» button on wide screens. Low on the right keeps it clear of every
     primary action at every width, measured. */
  position:fixed;right:0;top:78%;z-index:150;
  display:inline-flex;align-items:center;gap:var(--s3);
  padding:var(--s3) var(--s4);
  background:var(--i50);color:#fff;text-decoration:none;
  font-family:"Space Mono",monospace;font-size:var(--t1);
  letter-spacing:var(--tr-cap);text-transform:uppercase;font-weight:700;
  clip-path:polygon(var(--c) 0,100% 0,100% 100%,0 100%,0 var(--c));
  box-shadow:-6px 6px 0 rgba(11,10,34,.16);
  transition:translate var(--mid),background var(--fast),opacity var(--mid);
}
.wa:hover,.wa:focus-visible{background:var(--i40);translate:-3px 0}
/* Once the form is on screen the visitor is already doing the thing the tab
   is for, so it steps out of the way instead of floating over the fields.
   Kept in the DOM and focusable-out via pointer-events so nothing traps a
   keyboard user on an invisible target. */
.wa[data-off]{opacity:0;translate:24px 0;pointer-events:none}
.wa:focus-visible{outline:2px solid #fff;outline-offset:-6px}
.wa__g{flex:none}
.wa__t{white-space:nowrap}

/* On a phone the right edge is where the thumb rests and where the page still
   has to be readable, so the tab drops its label and sits in the corner. */
@media(max-width:699px){
  .wa{--c:10px;top:auto;bottom:calc(var(--s4) + env(safe-area-inset-bottom,0px));
      right:var(--s3);padding:var(--s3);
      clip-path:polygon(var(--c) 0,100% 0,100% calc(100% - var(--c)),calc(100% - var(--c)) 100%,0 100%,0 var(--c))}
  /* display:none, not a visually-hidden clip. The anchor carries its own
     aria-label, so this span is never the accessible name on any screen —
     hiding it loses nothing for a screen reader, and a 1px clipped box with
     67px of text spilling out of it is a real clipping defect to every
     geometry and contrast probe, correctly. */
  .wa__t{display:none}
}
/* At the narrowest widths a 48px target is a bigger share of the screen than
   it is anywhere else, so it tucks down to the smallest size that is still a
   comfortable thumb target. */
@media(max-width:400px){
  .wa{--c:8px;padding:10px;bottom:calc(var(--s3) + env(safe-area-inset-bottom,0px));right:var(--s3)}
  .wa__g{width:20px;height:20px}
}
@media(prefers-reduced-motion:reduce){
  .wa{transition:none}.wa:hover{translate:none}
  .wa[data-off]{translate:none}
}

/* Printing a floating chat tab onto paper helps nobody. */
@media print{.wa{display:none}}

.deliver{display:grid;gap:var(--s5);align-content:start}
.deliver__i{display:grid;gap:var(--s2);padding-bottom:var(--s5);border-bottom:1px solid var(--rule)}
.deliver__i:last-of-type{border-bottom:0;padding-bottom:0}

/* ──────────────────────────────────────────────────────────────────────────
   13. FOOTER
   ────────────────────────────────────────────────────────────────────────── */
.foot{padding-block:clamp(var(--s8),7vw,var(--s10)) var(--s5)}
.foot__grid{display:grid;gap:var(--s7)}
@media(min-width:860px){.foot__grid{grid-template-columns:1.5fr 1fr 1fr 1.1fr}}
.foot__grid>*{min-width:0}
.foot__logo{width:150px;margin-bottom:var(--s4)}
.foot h2,.foot h4{font-family:"Space Mono",monospace;font-size:var(--t1);font-weight:700;letter-spacing:var(--tr-cap);
  text-transform:uppercase;color:var(--ink-3);margin-bottom:var(--s4)}
.foot ul{display:grid;gap:var(--s3)}
.foot ul a{font-size:var(--t3);color:var(--ink-2);transition:color var(--fast)}
.foot ul a:hover{color:var(--acc)}
.foot__end{margin-top:var(--s8);padding-top:var(--s5);border-top:1px solid var(--rule);
  display:flex;flex-wrap:wrap;gap:var(--s3) var(--s5);justify-content:space-between;
  font-size:var(--t1);font-weight:700;letter-spacing:var(--tr-cap);text-transform:uppercase;color:var(--ink-3)}

/* ──────────────────────────────────────────────────────────────────────────
   14. MOTION
   One idea: everything arrives by the same cut. Content is visible by
   default so a failed script never hides the page.
   ────────────────────────────────────────────────────────────────────────── */
.js .rv{
  opacity:.001;translate:0 22px;
  transition:opacity var(--slow) var(--ez),translate var(--slow) var(--ez);
}
.js .rv.in{opacity:1;translate:0 0}
/* The wipe rides on MASK, never clip-path: clip-path already carries the
   card's perimeter, and one property cannot hold both the geometry and the
   arrival — the reveal would flatten every cut back to a rectangle. */
.js .rv-cut{
  -webkit-mask-image:linear-gradient(100deg,#000 38%,rgba(0,0,0,.3) 52%,transparent 64%);
  mask-image:linear-gradient(100deg,#000 38%,rgba(0,0,0,.3) 52%,transparent 64%);
  -webkit-mask-size:250% 100%;mask-size:250% 100%;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:100% 0;mask-position:100% 0;
  transition:opacity var(--slow) var(--ez),translate var(--slow) var(--ez),
             -webkit-mask-position .85s var(--ez),mask-position .85s var(--ez);
}
.js .rv-cut.in{-webkit-mask-position:0 0;mask-position:0 0}
.js .rv-d1{transition-delay:.07s}
.js .rv-d2{transition-delay:.14s}
.js .rv-d3{transition-delay:.21s}

/* the hero headline: each line unmasked by a travelling bevel */
.js .ln{display:block;overflow:hidden}
.js .ln>span{display:block;translate:0 108%;transition:translate .8s var(--ez)}
.js .ln.in>span{translate:0 0}
.js .ln:nth-child(2)>span{transition-delay:.09s}
.js .ln:nth-child(3)>span{transition-delay:.18s}

@media(prefers-reduced-motion:reduce){
  .js .rv,.js .rv-cut,.js .ln>span{
    opacity:1;translate:0 0;clip-path:none;transition:none}
  .card,.case,.cta,.btn,.arw,.faq__q,.faq__go,
  .nav a::after,.case__fig img,.meter i,.cta i{transition:none}
}

/* ──────────────────────────────────────────────────────────────────────────
   15. NARROW
   ────────────────────────────────────────────────────────────────────────── */
@media(max-width:999px){
  .stage__grid{gap:var(--s6)}
  .subject{width:min(100%,420px)}
  .mark{font-size:clamp(74px,25vw,220px);bottom:-6px}
  .nav{justify-content:flex-start;gap:var(--s3) var(--s6)}

  /* The forme stays a forme: four columns, five cells, still a complete
     tiling with no leftover. A single stacked column would throw away the
     one thing that makes this section worth looking at. */
  .forme{grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:repeat(5,auto)}
  .lever:nth-of-type(1){grid-column:1 / 5; grid-row:1 / 3; --s:1.5}
  .lever:nth-of-type(2){grid-column:1 / 3; grid-row:3 / 4}
  .lever:nth-of-type(3){grid-column:3 / 5; grid-row:3 / 4}
  .lever:nth-of-type(4){grid-column:1 / 3; grid-row:4 / 6}
  .lever:nth-of-type(5){grid-column:3 / 5; grid-row:4 / 6}
  .lever__h{display:grid;gap:var(--s2);justify-items:start}
  .lever__t{font-size:var(--ts)}
  .lever:nth-of-type(1) p{font-size:var(--t3)}
}
@media(max-width:520px){
  /* two of the four cells would hold two words a line below this */
  .forme{grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:repeat(6,auto)}
  .lever:nth-of-type(1){grid-column:1 / 5; grid-row:1 / 3; --s:1.35}
  .lever:nth-of-type(2){grid-column:1 / 5; grid-row:3 / 4}
  .lever:nth-of-type(3){grid-column:1 / 3; grid-row:4 / 5}
  .lever:nth-of-type(4){grid-column:3 / 5; grid-row:4 / 5}
  .lever:nth-of-type(5){grid-column:1 / 5; grid-row:5 / 7}
  .lever{padding:var(--s5)}
}
@media(max-width:999px){
  .stagev{padding-bottom:clamp(58px,17vw,120px)}
  .stagev__mark{font-size:clamp(46px,17.5vw,150px);bottom:calc(var(--s2) * -1)}
  .masse__subject{min-height:clamp(200px,42vw,320px)}
}
@media(max-width:340px){
  /* the label cannot stay on one line inside a 244px content box */
  .cta{white-space:normal;text-align:center;padding-inline:var(--s5)}
}
@media(max-width:560px){
  .top__tag{max-width:13ch}
  .statement__ref{text-align:left}
  .statement__top{flex-direction:column;gap:var(--s3)}
  .cut-step{clip-path:polygon(0 var(--rise),46% var(--rise),46% 0,100% 0,100% 100%,0 100%)}
}

/* ══════════════════════════════════════════════════════════════════════════
   LEGAL · privacy.html + terms.html
   A Read surface, not a Persuade one: the interface recedes and the document
   leads. Same tokens, same cut family, but almost no ornament — the only jobs
   here are measure, hierarchy and the ability to find a clause again.

   The text is transcribed verbatim from the live site. Legal wording is not
   ours to paraphrase, so nothing in it is edited; only its presentation is.
   ══════════════════════════════════════════════════════════════════════════ */
.legal-head{max-width:74ch;margin-top:var(--s7)}
.legal-head .lede{margin-top:var(--s3)}
.legal-meta{margin-top:var(--s5);font-family:"Space Mono",monospace;
  font-size:var(--t2);line-height:var(--lh-cap);color:var(--ink-3)}
.legal-meta p{margin:0 0 .35em}
/* the source packs "Last updated" and "Effective date" into one paragraph
   separated only by a newline, which collapses to a single space */
.legal-meta strong{display:block;font-weight:400;color:var(--ink-2)}
/* The source ships a caveat telling the owner to have this reviewed by
   counsel. It stays, and it is given the weight of a real notice rather than
   being buried in the body. */
.legal-note{--c:clamp(12px,1.6vw,22px);margin-top:var(--s6);
  padding:var(--s4) var(--s5);background:var(--i50);color:#fff;
  font-size:var(--t3);line-height:var(--lh-body);max-width:72ch}
.legal-note b{font-weight:700}

/* ── the document ─────────────────────────────────────────────────────── */
.legal-grid{display:grid;gap:var(--s7)}
@media(min-width:1000px){
  .legal-grid{grid-template-columns:minmax(0,15rem) minmax(0,1fr);
    gap:clamp(var(--s7),5vw,var(--s9));align-items:start}
}
.legal-grid>*{min-width:0}

/* One <details> at every width. Under 1000px it is a real disclosure, because
   twenty clauses ahead of the text is a wall on a phone. At 1000px and up the
   summary is removed entirely, which also removes the only way to close it,
   so the index simply is the sticky rail. No script, no duplicate markup. */
.legal-idx summary{
  cursor:pointer;list-style:none;padding:var(--s3) 0;
  font-family:"Space Grotesk",sans-serif;font-size:var(--t2);font-weight:700;
  letter-spacing:var(--tr-cap);text-transform:uppercase;color:var(--ink-2);
  border-bottom:1px solid var(--rule);
  display:flex;align-items:center;justify-content:space-between;gap:var(--s3)}
.legal-idx summary::-webkit-details-marker{display:none}
.legal-idx summary::after{content:"+";font-size:var(--t5);line-height:1;color:var(--acc)}
.legal-idx[open] summary::after{content:"–"}
.legal-idx ol{list-style:none;margin:var(--s4) 0 0;padding:0;
  display:grid;gap:.55em;counter-reset:idx}
.legal-idx li{counter-increment:idx;
  display:grid;grid-template-columns:2.4em minmax(0,1fr);align-items:baseline}
.legal-idx li::before{content:counter(idx,decimal-leading-zero);
  font-family:"Space Mono",monospace;font-size:var(--t1);color:var(--ink-3)}
.legal-idx a{color:var(--ink-2);text-decoration:none;font-size:var(--t2);
  line-height:var(--lh-cap);transition:color var(--fast)}
.legal-idx a:hover{color:var(--acc)}
@media(min-width:1000px){
  .legal-idx{position:sticky;top:var(--s6);max-height:calc(100vh - var(--s8));
    overflow:auto;overscroll-behavior:contain}
  .legal-idx summary{display:none}
  .legal-idx ol{margin-top:0}
}

.legal-prose{max-width:74ch;font-size:var(--t4);line-height:var(--lh-body);color:var(--ink-2)}
.legal-prose h2{font-family:"Space Grotesk",sans-serif;font-weight:700;color:var(--ink);
  font-size:clamp(var(--t6),3vw,var(--t7));line-height:var(--lh-disp);
  letter-spacing:var(--tr-d3);margin:var(--s8) 0 var(--s4);scroll-margin-top:var(--s6)}
.legal-prose h2:first-child{margin-top:0}
.legal-prose h3{font-family:"Space Grotesk",sans-serif;font-weight:700;color:var(--ink);
  font-size:var(--t5);line-height:var(--lh-disp);letter-spacing:var(--tr-d3);
  margin:var(--s6) 0 var(--s3);scroll-margin-top:var(--s6)}
.legal-prose p{margin:0 0 var(--s4)}
.legal-prose strong{color:var(--ink);font-weight:700}
.legal-prose a{color:var(--acc);text-underline-offset:3px}
.legal-prose ul,.legal-prose ol{margin:0 0 var(--s4);padding-left:1.35em;display:grid;gap:.5em}
.legal-prose li{padding-left:.2em}
.legal-prose li::marker{color:var(--acc)}
.legal-prose code{font-family:"Space Mono",monospace;font-size:.88em;
  padding:.12em .4em;background:var(--field);color:var(--ink)}
.legal-prose blockquote{margin:0 0 var(--s5);padding-left:var(--s5);
  border-left:2px solid var(--acc);color:var(--ink-3);font-size:var(--t3)}
.legal-prose blockquote p:last-child{margin-bottom:0}

/* Tables get the site's own 2px-seam grammar rather than borders, so they read
   as the same material as the masse and the FAQ. They scroll in their own
   container: a ten-column cookie table cannot be made to fit 320px, and the
   page body must never scroll sideways. */
.legal-prose table{width:100%;border-collapse:separate;border-spacing:2px;
  margin:0 0 var(--s5);background:var(--rule-2);font-size:var(--t2);
  box-shadow:0 0 0 1.5px var(--rule-2)}
.legal-prose th,.legal-prose td{padding:var(--s3) var(--s4);text-align:left;
  vertical-align:top;background:var(--p00);line-height:var(--lh-cap)}
.legal-prose thead th{background:var(--i50);color:#fff;font-weight:700;
  font-family:"Space Grotesk",sans-serif;letter-spacing:var(--tr-ui)}
.legal-prose tbody tr:nth-child(even) td{background:var(--p10)}
.legal-prose td strong{color:var(--ink)}
.legal-return{margin-top:var(--s8);padding-top:var(--s5);border-top:1px solid var(--rule)}
.legal-return a{font-family:"Space Grotesk",sans-serif;font-weight:700;color:var(--acc)}
.legal-table{overflow-x:auto;overscroll-behavior-x:contain;margin:0 0 var(--s5)}
.legal-table table{margin:0;min-width:34rem}

/* The privacy policy quotes raw URLs inside <code>, which are unbreakable
   tokens: at 390px one of them pushed the whole document 124px wide and the
   page scrolled sideways. Long strings break anywhere here; ordinary prose is
   unaffected because it has spaces to break at. */
.legal-prose{overflow-wrap:anywhere}
.legal-prose code,.legal-prose a{word-break:break-word}
