/* ============================================================================
   ORIGAMI DIGITAL — THE SHEET
   The design system. Written from zero on 2026-08-24, replacing origami.css.

   WHY A NEW FILE. origami.css reached 272KB across twenty-three appended
   layers. Every layer fixed a symptom the layer before it caused, and the
   result reads exactly as Danish keeps describing it: "the old site with a
   facelift". You cannot compose on top of that. This file is the composition.

   THE IDEA. The whole site is one sheet of paper under one lamp. It does not
   scroll past you, it turns. Sections are not stacked boxes; they are planes
   of the same surface, each angled a little differently to the light, so the
   ground tone shifts as the sheet turns. Objects that matter — a screenshot,
   a number, a card — lift OFF that surface and cast a real shadow. That is
   the depth in "UI that comes out of the screen", and it belongs to this
   brand instead of being borrowed from a template.

   THE METAPHOR IS ONLY A METAPHOR (doctrine section 0). Paper appears in the
   light, the grain and the fold edges. It never appears in a heading, a
   label, a stage name or an explanation.

   THE RULES THIS FILE KEEPS, from the study of sixteen award-winning sites:
     one typeface (plus a mono for labels)   8 type steps, no more
     display 6x body                          ONE tracking value, in em
     4 colours                                surfaces are alpha tints, never new colours
     accent under 5% of the page              two grounds, hard-alternating
     motion is transform and opacity only     everything rests in its finished state
     section height comes from CONTENT        never from a fraction of the viewport
   ========================================================================= */

/* ---------------------------------------------------------------- 1. FONTS */
@font-face{font-family:'Satoshi';font-style:normal;font-weight:300 900;font-display:swap;
  src:url("fonts/satoshi-variable.woff2") format("woff2")}
@font-face{font-family:'Space Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url("fonts/space-mono-400-latin.woff2") format("woff2")}

/* --------------------------------------------------------------- 2. TOKENS */
:root{
  /* Four colours. Everything else is one of these at an alpha. */
  --ink:#0D0B14;          /* the dark ground */
  --paper:#F0EDF5;        /* the light ground, and text on the dark one */
  --accent:#8B6FD4;       /* accent for text and hairlines — legible on ink */
  --accent-solid:#53279D; /* the same hue at full strength, for filled buttons */

  /* Text on the dark ground. On the light ground these three are re-pointed
     once, in section 4 — no rule anywhere else needs to know which it is on. */
  --t100:var(--paper);
  --t70:rgba(240,237,245,.70);
  --t45:rgba(240,237,245,.64);
  --line:rgba(240,237,245,.14);
  --surface:rgba(240,237,245,.045);
  --surface-2:rgba(240,237,245,.08);

  --sans:'Satoshi','Segoe UI',system-ui,sans-serif;
  --mono:'Space Mono',ui-monospace,Consolas,monospace;

  /* ONE tracking value, expressed in em so it scales with the glyph. */
  --track:-0.028em;

  /* EIGHT type steps. Nothing on this site may use a ninth.
     Display is 6x body, which is the ratio the award set clusters around. */
  --t-label:11px;                                  /* mono, uppercase */
  --t-small:14px;
  --t-body:17px;
  --t-lede:clamp(18px, 1.25vw, 21px);
  --t-h3:clamp(21px, 1.7vw, 26px);
  --t-h2:clamp(29px, min(3.6vw, 5.4svh), 46px);
  --t-h1:clamp(38px, min(5.4vw, 8.2svh), 72px);
  --t-mega:clamp(44px, min(7.2vw, 10.4svh), 96px);  /* homepage hero only */

  /* Vertical rhythm. Four beats, and section height is padding + content —
     never a viewport fraction. Viewport-locked heights are what put a
     380-540px hole under the hero of all fifteen pages. */
  --beat-1:clamp(38px, 5vh, 60px);
  --beat-2:clamp(60px, 8vh, 96px);
  --beat-3:clamp(88px, 12vh, 140px);
  --beat-4:clamp(120px, 17vh, 200px);

  --gut:clamp(22px, 5vw, 68px);
  --wrap:1240px;
  --read:62ch;

  --ease:cubic-bezier(.22,.68,.24,1);
  --radius:14px;
  --radius-s:8px;
}

/* ------------------------------------------------------------- 3. BASELINE */
*,*::before,*::after{box-sizing:border-box}
*{margin:0}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--ink);
  color:var(--t100);
  font-family:var(--sans);
  font-size:var(--t-body);
  font-weight:400;
  line-height:1.62;
  letter-spacing:var(--track);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
img,svg,picture,video{display:block;max-width:100%}
img{height:auto}
a{color:inherit}
button{font:inherit;letter-spacing:inherit;color:inherit;background:none;border:0}
::selection{background:var(--accent-solid);color:#fff}

.skip{position:absolute;left:-9999px;top:0;z-index:99;background:var(--paper);color:var(--ink);
  padding:12px 20px;border-radius:0 0 var(--radius-s) 0;font-weight:700}
.skip:focus{left:0}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px}

/* ------------------------------------------------ 4. THE LAMP AND THE GRAIN
   Fixed to the room, not to the page. The planes move past them, which is
   what makes the sheet feel like one continuous surface rather than a stack
   of separately-lit boxes. --lx drifts a little with scroll (one scalar,
   written by od.js), so the light appears to travel across the sheet. */
.lamp,.grain{position:fixed;inset:0;z-index:0;pointer-events:none}
.lamp{
  --lx:8%;
  background:
    radial-gradient(115% 85% at var(--lx) -14%, rgba(240,237,245,.09) 0%, transparent 56%),
    radial-gradient(150% 130% at 94% 118%, rgba(0,0,0,.55) 0%, transparent 60%);
  transition:background-position .2s linear;
}
.grain{
  inset:-40px;opacity:.05;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='4' seed='5'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23f)'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------- 5. THE PLANES
   --a is the plane's angle to the lamp. Tone and edge are both derived from
   it, so turning a plane changes how it catches light WITHOUT inventing a
   new colour. Two grounds only: ink (default) and paper (.plane--lit). */
.plane{
  position:relative;z-index:2;--a:0;
  padding-block:var(--beat-3);
  background:
    linear-gradient(calc(180deg + var(--a) * 1deg),
      rgba(240,237,245, calc(.018 + var(--a) * .0011)) 0%,
      rgba(240,237,245, calc(.003 + var(--a) * .0003)) 100%),
    var(--ink);
  isolation:isolate;
}
.plane--turn{--a:13}
.plane--turn2{--a:24}
.plane--tight{padding-block:var(--beat-2)}
.plane--air{padding-block:var(--beat-4)}

/* the crease: the hairline where two planes meet, lit from the left */
.plane + .plane::before{
  content:"";position:absolute;inset-inline:0;top:0;height:1px;z-index:3;
  background:linear-gradient(90deg,
    rgba(240,237,245,.26) 0%, rgba(240,237,245,.09) 30%, rgba(240,237,245,0) 74%);
}

/* the sheet turned fully into the light. This is the ONLY light ground, and
   it re-points the three text tokens once so no other rule has to know. */
.plane--lit{
  --a:0;
  --t100:#141120;
  --t70:#3D3753;
  --t45:#615B77;
  --line:rgba(20,17,32,.14);
  --surface:rgba(20,17,32,.04);
  --surface-2:rgba(20,17,32,.07);
  --accent:#53279D;
  background:linear-gradient(177deg,#FFFFFF 0%,var(--paper) 58%,#E6E1F0 100%);
  color:var(--t100);
}
.plane--lit + .plane::before,.plane--lit::before{display:none}

/* ------------------------------------------------------------ 6. MEASURES
   Three, deliberately. A reading column, a wide split, and full bleed. The
   old stylesheet gave every section the same 997px column inside a 1440
   viewport, which left 443px of dead right on seven sections of the
   homepage alone and is most of why the pages read as one template. */
.wrap{width:min(var(--wrap), 100% - 2*var(--gut));margin-inline:auto}
.read{width:min(var(--read), 100% - 2*var(--gut));margin-inline:auto}
.bleed{width:100%}

/* the split: text and its evidence, side by side. Where a section has
   evidence to show, it goes in the rail — that is what fills the right. */
.split{
  display:grid;gap:clamp(28px,4vw,72px);align-items:start;
  grid-template-columns:minmax(0,1fr);
}
@media (min-width:900px){
  .split{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .split--wide{grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr)}
  .split--rail{grid-template-columns:minmax(0,1fr) minmax(0,320px)}
  .split--flip > :first-child{order:2}
}

/* --------------------------------------------------------------- 7. TYPE */
.label{
  font-family:var(--mono);font-size:var(--t-label);letter-spacing:.19em;
  text-transform:uppercase;color:var(--t45);display:block;
  margin-bottom:clamp(14px,1.6vh,22px);
}
.label--accent{color:#9778D8}

h1,.h1{font-size:var(--t-h1);line-height:1.0;font-weight:900;letter-spacing:var(--track)}
.mega{font-size:var(--t-mega);line-height:.94;font-weight:900;letter-spacing:var(--track)}
h2,.h2{font-size:var(--t-h2);line-height:1.06;font-weight:800;letter-spacing:var(--track)}
h3,.h3{font-size:var(--t-h3);line-height:1.2;font-weight:700;letter-spacing:var(--track)}
h1,h2,h3{text-wrap:balance;max-width:20ch}
.h2--long,h2.h2--long{max-width:26ch}

p{max-width:60ch}
.lede{font-size:var(--t-lede);line-height:1.5;color:var(--t70);max-width:52ch}
.small{font-size:var(--t-small);color:var(--t70)}
.note{font-family:var(--mono);font-size:var(--t-label);line-height:1.65;color:var(--t45);
  letter-spacing:.02em;max-width:64ch}
.note b{color:#9778D8;font-weight:400}
b,strong{font-weight:700;color:var(--t100)}

/* the accent is carried by em, and it is the only coloured text on the site.
   #9778D8 is --accent +4% toward white: the raw accent measured 4.48:1 (need 4.5) on
   several small-label cards (od-qa gate, 2026-09-06); this clears 4.8:1+ everywhere
   measured, imperceptibly different, --accent itself untouched for borders/icons/hovers. */
em{font-style:normal;color:#9778D8}
.plane--lit em{color:var(--accent-solid)}
.plane--lit .label--accent{color:var(--accent-solid)} /* was inheriting the dark-ground accent tint at 3.45-3.79:1 on white - pre-existing, found by the gate 2026-09-06, same fix as em above */

.stack > * + *{margin-top:clamp(14px,1.8vh,22px)}
.stack--wide > * + *{margin-top:clamp(20px,2.6vh,32px)}

/* ------------------------------------------------------------ 8. CONTROLS */
.btn{
  display:inline-flex;align-items:center;gap:10px;
  font-size:15px;font-weight:700;letter-spacing:-.006em;text-decoration:none;
  padding:14px 26px;border-radius:999px;min-height:48px;
  transition:transform .35s var(--ease), background-color .25s, border-color .25s;
  will-change:transform;
}
.btn:hover{transform:translateY(-2px)}
.btn--solid{background:var(--accent-solid);color:#fff}
.btn--solid:hover{background:#5F2FB4}
.btn--line{border:1px solid var(--line);color:var(--t100)}
.btn--line:hover{border-color:var(--accent)}
.plane--lit .btn--line{border-color:rgba(20,17,32,.22)}
.actions{display:flex;flex-wrap:wrap;gap:12px;align-items:center}

/* a link that reads as one: the rule draws in from the left on hover */
.tlink{
  text-decoration:none;font-weight:700;position:relative;
  background-image:linear-gradient(var(--accent),var(--accent));
  background-size:0% 1px;background-repeat:no-repeat;background-position:0 100%;
  transition:background-size .4s var(--ease);
  padding-bottom:2px;
}
.tlink:hover{background-size:100% 1px}
.tlink::after{content:" \2192";color:var(--accent)}

/* ------------------------------------------------------- 9. LIFTED OBJECTS
   The things that come out of the screen. One shadow recipe, one hairline
   catching the lamp along the top edge, and a slight rest angle that
   straightens when you point at it — so the object reads as a physical
   thing lying on the sheet rather than a div. */
.lift{
  border-radius:var(--radius);
  background:var(--surface);
  border:1px solid var(--line);
  box-shadow:0 30px 70px rgba(0,0,0,.5), inset 0 1px 0 rgba(240,237,245,.06);
  transition:transform .5s var(--ease), box-shadow .5s var(--ease);
}
.plane--lit .lift{
  background:#fff;
  box-shadow:0 26px 60px rgba(20,17,32,.13), inset 0 1px 0 #fff;
}
.lift--tilt{transform:rotate(-.7deg)}
.lift--tilt:hover{transform:rotate(0deg) translateY(-3px);
  box-shadow:0 40px 90px rgba(0,0,0,.58), inset 0 1px 0 rgba(240,237,245,.08)}
.lift--flat{overflow:hidden}

/* a browser frame, for showing a real screenshot as itself */
.frame{border-radius:var(--radius);overflow:hidden;background:#151221}
.frame__bar{display:flex;align-items:center;gap:10px;padding:9px 13px;
  background:rgba(240,237,245,.05);border-bottom:1px solid var(--line)}
.frame__bar i{width:8px;height:8px;border-radius:50%;background:rgba(240,237,245,.2)}
.frame__url{font-family:var(--mono);font-size:10.5px;color:var(--t45);
  background:rgba(240,237,245,.05);border-radius:999px;padding:4px 12px;flex:1;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.frame__tag{font-family:var(--mono);font-size:9.5px;letter-spacing:.15em;text-transform:uppercase;
  color:#9778D8;border:1px solid rgba(139,111,212,.42);border-radius:999px;padding:3px 9px;
  white-space:nowrap}
.frame img{width:100%}

/* ------------------------------------------------------------ 10. FIGURES
   A number is an object, not a sentence. The baseline sits behind the
   result, ghosted, so the movement is one thing you read at a glance
   instead of two numbers you have to hold in your head. */
.fig{position:relative;padding-block:clamp(10px,1.4vh,18px)}
.fig__from{
  font-size:var(--t-h1);font-weight:900;line-height:1;letter-spacing:var(--track);
  color:var(--t100);opacity:.13;position:absolute;left:0;top:0;
  transform:translate(-4%,-16%);pointer-events:none;user-select:none;
}
.fig__to{font-size:var(--t-h1);font-weight:900;line-height:1;letter-spacing:var(--track);
  position:relative;display:block}
.fig__cap{margin-top:10px;font-size:var(--t-small);color:var(--t70);max-width:30ch}
.fig__src{margin-top:6px;font-family:var(--mono);font-size:var(--t-label);color:var(--t45)}

.figs{display:grid;gap:clamp(26px,3.4vw,52px);grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}

/* --------------------------------------------------------------- 11. CARDS
   Text anchored to the top and the trailing link pinned with margin-top:auto,
   so both edges stay put no matter how many lines the copy runs to. The
   min-height "fix" for this holds at the two widths you happen to test and
   fails at every other one. */
.cards{display:grid;gap:clamp(16px,1.8vw,26px);grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
.card{
  display:flex;flex-direction:column;
  padding:clamp(22px,2.2vw,32px);
  border-radius:var(--radius);border:1px solid var(--line);background:var(--surface);
  transition:border-color .3s, background-color .3s, transform .4s var(--ease);
}
.card:hover{border-color:rgba(139,111,212,.4);background:var(--surface-2);transform:translateY(-3px)}
.card h3{margin-bottom:10px;max-width:none}
.card p{color:var(--t70);font-size:var(--t-small);max-width:38ch}
.card .tlink{margin-top:auto;padding-top:20px}

/* ------------------------------------------------------------- 12. THE NAV
   Six items, one treatment, sentence case. The portal lives in the footer.
   No toy, no badge, no ornament: the nav is the one element on every page,
   so it earns its keep by being quiet and precise. */
.nav{
  position:sticky;top:0;z-index:40;
  display:flex;align-items:center;gap:clamp(16px,2vw,34px);
  padding:14px var(--gut);
  background:rgba(13,11,20,.72);
  backdrop-filter:saturate(140%) blur(14px);
  -webkit-backdrop-filter:saturate(140%) blur(14px);
  border-bottom:1px solid transparent;
  transition:border-color .3s, background-color .3s;
}
.nav[data-scrolled]{border-bottom-color:var(--line);background:rgba(13,11,20,.985);backdrop-filter:saturate(140%) blur(18px);-webkit-backdrop-filter:saturate(140%) blur(18px)}
.nav__mark{display:flex;align-items:center;gap:11px;text-decoration:none;margin-right:auto}
.nav__mark svg{width:40px;height:auto;overflow:visible}
.nav__wm{font-size:16px;font-weight:700;letter-spacing:-.02em;white-space:nowrap}
.nav__wm span{font-weight:400;color:var(--t70)}
.nav__links{display:flex;align-items:center;gap:clamp(14px,1.7vw,30px)}
.nav__links a{
  text-decoration:none;font-size:15px;color:var(--t70);white-space:nowrap;
  padding:6px 0;position:relative;transition:color .25s;
}
.nav__links a:hover{color:var(--t100)}
.nav__links a[aria-current]{color:var(--t100)}
.nav__links a[aria-current]::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--accent);
}
.nav__cta{
  text-decoration:none;font-size:14.5px;font-weight:700;white-space:nowrap;
  padding:11px 20px;border-radius:999px;border:1px solid var(--line);
  transition:border-color .25s,background-color .25s;
}
.nav__cta:hover{border-color:var(--accent);background:var(--surface)}
.nav__toggle{display:none;width:44px;height:44px;align-items:center;justify-content:center;
  border-radius:var(--radius-s);border:1px solid var(--line)}
.nav__toggle span,.nav__toggle span::before,.nav__toggle span::after{
  content:"";display:block;width:17px;height:1.5px;background:var(--t100);
  transition:transform .35s var(--ease),opacity .2s}
.nav__toggle span::before{transform:translateY(-5.5px)}
.nav__toggle span::after{transform:translateY(4px)}
.nav[data-open] .nav__toggle span{background:transparent}
.nav[data-open] .nav__toggle span::before{transform:rotate(45deg)}
.nav[data-open] .nav__toggle span::after{transform:rotate(-45deg) translateY(-1.5px)}

@media (max-width:900px){
  .nav__toggle{display:flex}
  .nav__cta{display:none}
  .nav__links{
    position:fixed;inset:57px 0 auto;flex-direction:column;align-items:stretch;gap:0;
    background:rgba(13,11,20,.98);border-bottom:1px solid var(--line);
    padding:8px var(--gut) 22px;
    transform:translateY(-8px);opacity:0;pointer-events:none;
    transition:opacity .25s, transform .3s var(--ease);
  }
  .nav[data-open] .nav__links{opacity:1;transform:none;pointer-events:auto}
  .nav__links a{padding:14px 0;font-size:19px;border-bottom:1px solid var(--line)}
  .nav__links a[aria-current]::after{display:none}
}

/* ------------------------------------------------------------ 13. THE FOOT */
.foot{position:relative;z-index:2;background:#0A0810;border-top:1px solid var(--line);
  padding:var(--beat-3) 0 var(--beat-1)}
/* 2026-09-08: widened for the fourth column (Guides, matching The work's per-item link
   list). 820-1099 pairs two columns per row so nothing is squeezed before there is
   room; 1100+ opens to the full four with the brand block given extra width. */
.foot__grid{display:grid;gap:clamp(28px,4vw,60px);grid-template-columns:minmax(0,1fr)}
@media (min-width:820px){.foot__grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1100px){.foot__grid{grid-template-columns:minmax(0,1.25fr) repeat(3,minmax(0,1fr))}}
.foot h3,.foot h4{font-family:var(--mono);font-size:var(--t-label);letter-spacing:.19em;
  text-transform:uppercase;color:var(--t45);font-weight:400;margin-bottom:16px}
.foot a{text-decoration:none;color:var(--t70);transition:color .25s}
.foot a:hover{color:var(--t100)}
.foot__links{display:flex;flex-direction:column;gap:9px;font-size:var(--t-small)}
.foot__base{display:flex;flex-wrap:wrap;gap:14px 26px;align-items:center;
  margin-top:var(--beat-2);padding-top:22px;border-top:1px solid var(--line);
  font-family:var(--mono);font-size:var(--t-label);color:var(--t45);letter-spacing:.03em}

/* ------------------------------------------------------- 14. THE HERO
   Full screen ONLY where there is a full screen of content to put in it.
   Everywhere else the hero is generous but sized by what it holds. */
.hero{padding-block:var(--beat-4) var(--beat-3)}
.hero .mega,.hero h1{max-width:16ch}
.hero .lede{margin-top:clamp(18px,2.4vh,26px)}
.hero .actions{margin-top:clamp(24px,3.2vh,36px)}

/* The first screen has to hold the promise AND the proof, caption included —
   an evidence card whose caption is below the fold is an evidence card the
   reader does not know is evidence. Measured at 902px tall: content runs
   193 to 935 with the old padding, so the top pad and the proof's own gap
   both come down until the caption lands inside the viewport. */
/* 88svh, not 100. A hero that fills the viewport exactly leaves the reader no
   evidence there is anything below it; at 88 the next plane's lit crease shows
   at the fold and does the inviting, with no arrow and no word "scroll". */
.hero--screen{
  min-height:88svh;display:flex;flex-direction:column;justify-content:center;
  padding-block:clamp(72px,9svh,104px) clamp(24px,4svh,48px);
}
/* The evidence does NOT live under the hero. Its subject is the AI-answer
   argument, so it sits inside that section, directly beneath the sentence it
   proves. Under the hero it arrived before the reader had any reason to care
   and read as decoration bolted to a headline. */
.proof{margin-top:clamp(26px,4vh,48px)}
.proof .note{margin-top:14px}
.proof__after{margin-top:clamp(20px,2.6vh,30px)}

/* the case-study hero leads with the result, which is also what fills the
   lower half of the screen honestly instead of with padding */
.casehero__meta{
  display:flex;flex-wrap:wrap;gap:8px 30px;margin-top:clamp(20px,2.6vh,30px);
  font-size:var(--t-small);color:var(--t70);
}
.casehero__meta span{display:flex;gap:8px}
.casehero__meta b{color:var(--t100)}
.casehero__meta i{font-style:normal;font-family:var(--mono);font-size:var(--t-label);
  letter-spacing:.15em;text-transform:uppercase;color:var(--t45);align-self:center}

/* ------------------------------------------------------------- 15. MOTION
   One scalar per frame, written by JS onto a custom property; CSS does the
   interpolation. Transform and opacity only. Everything rests in its
   finished state, so a stalled observer degrades to a readable page rather
   than a blank one. */
.rise{opacity:0;transform:translateY(18px);
  transition:opacity .7s var(--ease), transform .7s var(--ease)}
.rise.in{opacity:1;transform:none}
.rise:nth-child(2){transition-delay:.06s}
.rise:nth-child(3){transition-delay:.12s}
.rise:nth-child(4){transition-delay:.18s}

/* the glimpse of origami: a section's top crease unfolds as it arrives */
.unfold{transform-origin:top center;opacity:0;transform:perspective(1200px) rotateX(-7deg);
  transition:opacity .8s var(--ease), transform .8s var(--ease)}
.unfold.in{opacity:1;transform:none}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;transition-duration:.001ms !important}
  .rise,.unfold{opacity:1;transform:none}
  .lift--tilt{transform:none}
  .lamp{--lx:8% !important}
}

/* ------------------------------------------------------- 16. THE LADDER
   An illustration of a results page, and labelled as one, because the honest
   version — a screenshot of the client's Search Console — is not mine to
   publish. It shows the movement as ONE object: the row sits at its result
   position, and its old position is left behind as a ghost, so you read the
   climb at a glance instead of comparing two numbers. */
.ladder{display:flex;flex-direction:column;gap:7px;padding:clamp(18px,2vw,26px);
  border-radius:var(--radius);border:1px solid var(--line);background:var(--surface)}
.ladder__head{display:flex;align-items:center;gap:10px;padding-bottom:12px;margin-bottom:6px;
  border-bottom:1px solid var(--line);font-family:var(--mono);font-size:var(--t-label);
  letter-spacing:.13em;text-transform:uppercase;color:var(--t45)}
.ladder__head b{color:var(--t70);font-weight:400}
.rung{display:grid;grid-template-columns:26px minmax(0,1fr);gap:13px;align-items:center;
  padding:5px 0;position:relative}
.rung__n{font-family:var(--mono);font-size:var(--t-label);color:var(--t45);text-align:right}
.rung__bars{display:flex;flex-direction:column;gap:5px}
.rung__bars i{display:block;height:6px;border-radius:2px;background:rgba(240,237,245,.13)}
.rung__bars i:last-child{height:5px;opacity:.6}
.rung--you .rung__n{color:var(--accent)}
.rung--you .rung__bars i{background:linear-gradient(90deg,var(--accent),rgba(139,111,212,.35))}
.rung--you::before{content:"";position:absolute;inset:-2px -10px;border-radius:8px;
  border:1px solid rgba(139,111,212,.36);background:rgba(139,111,212,.07)}
/* the ghost is where the business used to sit. It carries its own label
   because a bare "9" under a list of 1-8 reads as a ninth result, not as a
   before-and-after. */
.rung--ghost{opacity:.42;margin-top:10px;padding-top:12px;border-top:1px dashed var(--line)}
.rung--ghost .rung__bars i{background:rgba(139,111,212,.26)}
.rung__was{grid-column:2;font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--t45);margin-top:6px}
.ladder__note{margin-top:14px;padding-top:12px;border-top:1px dashed var(--line)}

/* --------------------------------------------------------- 17. THE MARKETS
   Four photographs, held to the sheet's palette by a duotone so they read as
   one family rather than four stock pictures. Pointing at one returns its
   colour, which is the only place on the site where a photograph is allowed
   to be loud. */
.markets{display:grid;gap:clamp(14px,1.6vw,22px);grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
.market{
  position:relative;display:flex;flex-direction:column;justify-content:flex-end;
  min-height:clamp(300px,38vh,420px);padding:clamp(20px,2vw,28px);
  border-radius:var(--radius);overflow:hidden;text-decoration:none;isolation:isolate;
}
.market__img{position:absolute;inset:0;z-index:-2;width:100%;height:100%;object-fit:cover;
  filter:grayscale(1) contrast(1.06);transition:filter .6s var(--ease),transform .8s var(--ease)}
.market::after{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(200deg,rgba(83,39,157,.5) 0%,rgba(13,11,20,.5) 46%,rgba(13,11,20,.9) 100%);
  transition:opacity .6s var(--ease)}
.market:hover .market__img{filter:grayscale(0) contrast(1);transform:scale(1.04)}
.market:hover::after{opacity:.8}
.market__n{font-family:var(--mono);font-size:var(--t-label);color:var(--accent);letter-spacing:.15em}
.market__t{font-size:var(--t-h3);font-weight:800;letter-spacing:var(--track);margin-top:auto}
.market__tag{font-family:var(--mono);font-size:var(--t-label);color:rgba(240,237,245,.62);
  letter-spacing:.09em;margin-top:5px}
.market__b{font-size:var(--t-small);color:rgba(240,237,245,.76);margin-top:12px;max-width:34ch}

/* ----------------------------------------------------------- 18. THE STEPS
   Four stages, always in the same order. The number is the ornament, so no
   other decoration is needed. This is also the one place the metaphor is
   allowed to surface, as a fold in the arrival — never as a word. */
.steps{display:grid;gap:clamp(16px,1.8vw,24px);grid-template-columns:repeat(auto-fit,minmax(238px,1fr));
  list-style:none;padding:0;counter-reset:s}
.step{padding:clamp(20px,2vw,28px) 0 0;border-top:1px solid var(--line);position:relative}
.step__n{font-family:var(--mono);font-size:var(--t-label);color:var(--accent);letter-spacing:.15em;
  display:block;margin-bottom:14px}
.step h3{margin-bottom:9px;max-width:none}
.step p{font-size:var(--t-small);color:var(--t70);max-width:34ch}

/* -------------------------------------------------------- 19. THE REFUSALS
   A list of promises stated as absences. Set on the light ground, which is
   the site's one hard alternation, so the section lands as a change of room
   rather than another dark band. */
.refuse{list-style:none;padding:0;display:grid;gap:0}
.refuse li{display:grid;grid-template-columns:26px minmax(0,1fr);gap:16px;align-items:start;
  padding:clamp(18px,2vh,26px) 0;border-bottom:1px solid var(--line)}
.refuse li:first-child{border-top:1px solid var(--line)}
.refuse__x{font-family:var(--mono);font-size:15px;color:var(--accent);line-height:1.5}
.refuse b{display:block;font-size:var(--t-h3);font-weight:700;letter-spacing:var(--track);margin-bottom:6px}
.refuse p{font-size:var(--t-small);color:var(--t70);max-width:52ch}

/* --------------------------------------------------------- 20. NARROW WIDTHS
   393 is the primary review surface, not an afterthought — Danish reviews on
   his phone. Display type sizes on min(vw, svh) up in section 2 so a short
   landscape window cannot push a headline off the screen. */
@media (max-width:640px){
  :root{--beat-3:clamp(64px,9vh,96px);--beat-4:clamp(80px,11vh,120px)}
  .hero .mega,.hero h1{max-width:none}
  .lift--tilt{transform:none}
  .fig__from{display:none}
  .actions .btn{flex:1 1 auto;justify-content:center}
}

/* ============================================================================
   2026-09-01 · THE BUTTON
   Brief, verbatim: "buttons so exciting or popping or some effect that you
   can't ignore them and their hook."

   Three things happen and every one of them is transform or opacity, so the
   motion budget is untouched (no layout, no paint per frame):
     1. REST   the primary carries a violet halo that breathes once every five
               seconds. It is a pseudo-element scaling and fading, never an
               animated box-shadow.
     2. HOVER  the button lifts, and a corner FOLDS BACK from the top right to
               show the lighter underside of the sheet. That is this brand's own
               gesture rather than a generic shine sweep.
     3. PRESS  it presses into the page.
   No markup has to change on fifteen pages for any of it.
   ============================================================================ */

.btn{position:relative;isolation:isolate;overflow:hidden;
     transition:transform .32s var(--ease), background-color .25s, border-color .25s, color .25s, box-shadow .3s ease}

/* 1 - the folded corner, waiting just outside the top right */
.btn::before{
  content:"";position:absolute;top:0;right:0;width:32px;height:32px;z-index:0;
  background:linear-gradient(225deg, rgba(255,255,255,.9) 0 50%, transparent 50%);
  transform:translate(32px,-32px);
  transition:transform .4s var(--ease);
  pointer-events:none;
}
.btn:hover::before{transform:translate(0,0)}
.btn > *{position:relative;z-index:1}

/* 2 - the halo. Breathes at rest on the primary, holds while hovered. */
.btn--solid{
  background:var(--accent-solid);color:#fff;
  box-shadow:0 14px 34px -18px rgba(83,39,157,.95);
}
.btn--solid::after{
  content:"";position:absolute;inset:3px;border-radius:inherit;
  border:1.5px solid rgba(255,255,255,.85);
  opacity:0;transform:scale(.98);pointer-events:none;z-index:0;
  animation:od-breathe 5s cubic-bezier(.25,.6,.3,1) infinite;
}
.btn--solid:hover{background:#5F2FB4;transform:translateY(-3px);
  box-shadow:0 22px 44px -18px rgba(124,82,199,1)}
.btn--solid:hover::after{animation-play-state:paused;opacity:.95;transform:scale(1.05)}
.btn--solid:active{transform:translateY(-1px) scale(.985)}
@keyframes od-breathe{
  0%   {opacity:0;  transform:scale(.94)}
  8%   {opacity:.85;transform:scale(.96)}
  55%  {opacity:0;  transform:scale(1.02)}
  100% {opacity:0;  transform:scale(1.02)}
}

/* 3 - the secondary. Same gesture, drawn in the accent. */
.btn--line{border:1px solid var(--line);color:var(--t100);background:transparent}
.btn--line::before{background:linear-gradient(225deg, var(--accent) 0 50%, transparent 50%)}
.btn--line:hover{border-color:var(--accent);transform:translateY(-3px)}
.btn--line:active{transform:translateY(-1px) scale(.985)}

/* on the one light section, the fold has to read against paper */
.plane--lit .btn--solid::before{background:linear-gradient(225deg, rgba(255,255,255,.95) 0 50%, transparent 50%)}
.plane--lit .btn--line::before{background:linear-gradient(225deg, var(--accent-solid) 0 50%, transparent 50%)}

/* the arrow, where the markup asks for one */
.btn .ar{display:inline-block;transition:transform .3s var(--ease)}
.btn:hover .ar{transform:translateX(4px)}

@media (prefers-reduced-motion: reduce){
  .btn,.btn::before,.btn .ar{transition:none}
  .btn--solid::after{animation:none;opacity:.5;transform:scale(1)}
  .btn:hover{transform:none}
}

/* ============================================================================
   2026-09-01 · COMPONENTS THE OTHER FOURTEEN PAGES NEED
   The homepage never had a form, a photographic band, a statement of numbers,
   a quote or a question list, so od.css never grew them. Every one of these
   uses the tokens above and nothing new.
   ============================================================================ */

/* ---- the form. The site asked people to write and gave them no way to. ---- */
.form{display:grid;gap:18px;max-width:640px;margin-top:var(--beat-1)}
.form__row{display:grid;gap:18px}
@media(min-width:720px){.form__row--2{grid-template-columns:1fr 1fr}}
.field{display:grid;gap:7px}
.field > span{font:600 var(--t-small)/1.2 var(--sans);color:var(--t70);letter-spacing:-.006em}
.field input,.field textarea,.field select{
  font:400 var(--t-body)/1.5 var(--sans);color:var(--t100);
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-s);
  padding:14px 16px;width:100%;transition:border-color .2s,background-color .2s;
}
.field textarea{min-height:150px;resize:vertical}
.field input::placeholder,.field textarea::placeholder{color:var(--t45)}
.field input:focus,.field textarea:focus,.field select:focus{
  outline:none;border-color:var(--accent);background:var(--surface-2)}
.field--wide{grid-column:1/-1}
.form__note{font:400 var(--t-small)/1.5 var(--sans);color:var(--t45);max-width:52ch}
.form__hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form .btn{justify-content:center}
.form__sent{
  border:1px solid var(--accent);border-radius:var(--radius);padding:20px 22px;
  background:var(--surface);max-width:640px;margin-top:var(--beat-1)}
.form__sent b{display:block;font-size:var(--t-h3);letter-spacing:var(--track);margin-bottom:6px}

/* ---- the photographic band. Full bleed, one line of type, nothing else. ---- */
.breaker{position:relative;margin:0;overflow:hidden}
.breaker img{display:block;width:100%;height:clamp(280px,42vh,460px);object-fit:cover}
.breaker--tall img{height:clamp(360px,62vh,640px)}
.breaker::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg, rgba(13,11,20,.30) 0%, rgba(13,11,20,.10) 42%, rgba(13,11,20,.86) 100%);
}
.breaker figcaption{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  padding:var(--gut);display:grid;gap:8px;
}
.breaker figcaption .label{color:var(--paper);opacity:.72}
.breaker figcaption p{
  margin:0;max-width:22ch;color:var(--paper);
  font:700 var(--t-h2)/1.05 var(--sans);letter-spacing:var(--track)}
.breaker figcaption p em{color:#C9B6F0;font-style:normal}

/* ---- numbers, stated once, with what they are ---- */
.stats{display:grid;gap:var(--beat-1);margin-top:var(--beat-2)}
@media(min-width:760px){.stats{grid-template-columns:repeat(3,1fr);gap:var(--gut)}}
.stat b{display:block;font:800 clamp(38px,5vw,64px)/.95 var(--sans);letter-spacing:var(--track)}
.stat b em{font-style:normal;color:var(--accent)}
.stat span{display:block;margin-top:10px;color:var(--t70);font-size:var(--t-small);max-width:30ch}
.stat small{display:block;margin-top:6px;color:var(--t45);font:400 var(--t-label)/1.4 var(--mono);
            text-transform:uppercase;letter-spacing:.08em}

/* ---- one sentence, given room ---- */
.quote{margin:var(--beat-2) 0 0;padding-left:22px;border-left:2px solid var(--accent)}
.quote p{margin:0;font:600 var(--t-h3)/1.35 var(--sans);letter-spacing:var(--track);max-width:34ch}
.quote cite{display:block;margin-top:10px;font-style:normal;color:var(--t45);font-size:var(--t-small)}

/* ---- questions, answered before they are asked ---- */
.faq{margin-top:var(--beat-1);border-top:1px solid var(--line);max-width:var(--read)}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{
  cursor:pointer;list-style:none;padding:18px 30px 18px 0;position:relative;
  font:700 var(--t-body)/1.4 var(--sans);letter-spacing:-.008em;color:var(--t100)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{
  content:"";position:absolute;right:6px;top:50%;width:10px;height:10px;
  border-right:1.5px solid var(--accent);border-bottom:1.5px solid var(--accent);
  transform:translateY(-70%) rotate(45deg);transition:transform .3s var(--ease)}
.faq details[open] summary::after{transform:translateY(-30%) rotate(-135deg)}
.faq summary:hover{color:var(--accent)}
.faq p{margin:0 0 18px;color:var(--t70);max-width:60ch}

/* ---- a page's own heading block, when it is not the homepage hero ---- */
.pagehead{padding-top:calc(var(--beat-4) + 40px);padding-bottom:var(--beat-2)}
.pagehead h1{max-width:18ch}
.pagehead .lede{margin-top:22px;max-width:56ch}
.pagehead .actions{margin-top:var(--beat-1)}

/* ---- side by side, text and picture, alternating down a page ---- */
.duo{display:grid;gap:var(--beat-1);align-items:center}
@media(min-width:900px){
  .duo{grid-template-columns:1fr 1fr;gap:var(--gut)}
  .duo--flip .duo__art{order:-1}
}
.duo__art img{display:block;width:100%;height:auto;border-radius:var(--radius)}
.duo__art figcaption{margin-top:10px;color:var(--t45);font:400 var(--t-label)/1.5 var(--mono);
                     text-transform:uppercase;letter-spacing:.08em}

/* The reading column, aligned to the page's left edge instead of centred. The pagehead, the
   step rows and the stats all start at the wrap's left edge, so a centred reading column in
   between them reads as a misalignment rather than as a choice. */
.read--left{margin-inline:0}

/* A card that is itself a link. The base link rule underlines everything inside it, so nine case
   cards came out fully underlined, and a portrait photograph inside a grid card grows to twice the
   height of its neighbours. Both are fixed here rather than in the markup. */
a.card{text-decoration:none;color:inherit}
a.card:hover h3{color:var(--accent)}
.card h3{transition:color .25s}
.card img{
  display:block;width:100%;aspect-ratio:16/10;object-fit:cover;
  border-radius:var(--radius-s);margin-bottom:18px;background:var(--surface-2);
}
.card .label{margin-bottom:8px}
.card p{margin-bottom:0}

/* The phone is the primary surface here, and the one action on the page was being hidden behind
   the hamburger on it. The CTA stays, at a size that still leaves the toggle a 44px target. */
@media (max-width:900px){
  .nav__cta{display:inline-flex;padding:10px 16px;font-size:13.5px;min-height:40px;margin-left:auto}
  .nav__toggle{margin-left:10px}
}
@media (max-width:420px){
  .nav__cta{padding:9px 13px;font-size:12.5px}
  .nav__wm{font-size:15px}
}

/* The breadcrumb. It was styled only in the old stylesheet, so the moment every page moved to
   this one it came out as three underlined links jammed against the left edge of the viewport. */
.crumb{
  max-width:var(--wrap);margin:0 auto;padding:calc(var(--beat-3) - 6px) var(--gut) 0;
  font:400 var(--t-label)/1.6 var(--mono);text-transform:uppercase;letter-spacing:.08em;
  color:var(--t45);display:flex;flex-wrap:wrap;align-items:center;gap:8px;
}
.crumb a{color:var(--t45);text-decoration:none}
.crumb a:hover{color:var(--accent)}
.crumb .csep{color:var(--t45)}
.crumb [aria-current]{color:var(--t70)}
/* the breadcrumb is emitted in the header, BEFORE <main>, so it is never the
   pagehead's sibling and the adjacent-sibling rule this used to be never matched.
   Half a screen of nothing sat between the nav and the first word because of it. */
main > .plane.pagehead:first-child{padding-top:var(--beat-2)}

/* ============================================================================
   2026-09-01 · THE REVIEW PASS
   Findings from a zoomed-out look plus a measured audit, fixed in one layer.
   ============================================================================ */

/* 1. The breaker's small kicker was being sized by the caption's own headline
      rule, so "THE WHOLE PLAN, BEFORE THE FIRST MOVE" rendered at 46px next to
      the 46px line it was supposed to introduce. Two headlines, no hierarchy. */
.breaker figcaption p.label{
  font:400 var(--t-label)/1.4 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  max-width:none;opacity:.8;
}

/* 2. Line length. Measured at 82 characters on the case studies and 101 on the
      homepage; comfortable reading tops out around 70. The cap sits on the
      paragraph rather than the section so cards, steps and captions, which are
      already narrow, are untouched. */
.plane .wrap > .stack--wide > p,
.plane .wrap > .stack > p,
.read > p, .read > ul, .read > ol,
.pagehead .lede{max-width:66ch}

/* 3. Body copy inside a full-width block was running the whole 1240 wrap. */
.plane .wrap > p{max-width:66ch}

/* ============================================================================
   2026-09-01 · THE PICTURES GET THEIR ROOM
   Brief: "more dramatic horizontal HD images of local and relevant landscapes,
   towns, more relevant imagery to what the page is about... but still Apple
   style and how they make use of images."
   Apple's use of a photograph is: give it the whole width, give it real height,
   put almost nothing on top of it, and let the type sit low and quiet. So the
   bands grow, the caption shrinks, and the headline over a picture is one line.
   ============================================================================ */
.breaker img{height:clamp(340px,54vh,600px)}
.breaker--tall img{height:clamp(420px,74vh,820px)}
.breaker figcaption{padding:calc(var(--gut) * 1.1) var(--gut)}
.breaker figcaption p{max-width:18ch;font-size:clamp(26px,3.2vw,44px);line-height:1.02}
.breaker figcaption .label{margin-bottom:2px}

/* on a phone the band is the whole story, so it gets more of the screen, and the
   line over it stays short enough to read in one glance */
@media (max-width:640px){
  .breaker img{height:clamp(300px,52vh,420px)}
  .breaker--tall img{height:clamp(380px,64vh,520px)}
  .breaker figcaption p{max-width:14ch;font-size:clamp(24px,7.5vw,34px)}
}


/* ================================================================ V16. THE
   WORK LEDGER (2026-09-02). The work index stops being nine identical cards
   and becomes an evidence ledger: three counting figures on landing, three
   flagship planes with a real artifact, six rows that read like a record
   book. Everything rests in its finished state; the counter only runs when
   motion is allowed. Grounds here are the dark planes, so the default text
   tokens are correct (the ground is the ELEMENT'S backdrop - s16). */

.topline .fig__to .num{font-variant-numeric:tabular-nums}

/* a nowrap url inside a flex bar inside a grid column propagates its
   min-content width all the way up and blows the page out at 393. Grid and
   flex children do not shrink below min-content unless told they may. */
.duo > *{min-width:0}
.frame__url{min-width:0}

.flag{padding-block:clamp(18px,3vh,34px)}
.flag + .flag{border-top:1px solid var(--line)}
.flag__h{font-size:var(--t-h2);letter-spacing:var(--track);line-height:1.08;margin:10px 0 14px}
.flag__stats{display:grid;gap:14px 26px;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  margin:var(--beat-1) 0}
.flag .stat b{display:block;font-size:var(--t-h3);font-weight:900;letter-spacing:var(--track);
  font-variant-numeric:tabular-nums}
.flag .stat span{display:block;margin-top:4px;font-size:var(--t-small);color:var(--t70);max-width:24ch}
.artcap{margin-top:10px;color:var(--t45);font:400 var(--t-label)/1.5 var(--mono);
  text-transform:uppercase;letter-spacing:.08em}

/* the lift: an object that matters comes off the sheet a little further on
   attention. Transform only, and it rests flat. */
.lift{transition:transform .5s var(--ease), box-shadow .5s var(--ease);will-change:transform}
.duo:hover .lift, .duo:focus-within .lift{transform:translateY(-6px) rotate(.35deg)}
@media (prefers-reduced-motion: reduce){ .lift{transition:none} .duo:hover .lift{transform:none} }

/* the ledger: six engagements as one readable record. */
.ledger{margin-top:var(--beat-1);border-top:1px solid var(--line)}
.ledger__row{display:grid;grid-template-columns:170px 1fr auto 24px;gap:10px 22px;align-items:baseline;
  padding:clamp(14px,2.2vh,22px) 4px;border-bottom:1px solid var(--line);text-decoration:none;
  transition:background .35s var(--ease), transform .35s var(--ease)}
.ledger__row:hover, .ledger__row:focus-visible{background:var(--surface);transform:translateX(4px)}
.ledger__tag{font-family:var(--mono);font-size:var(--t-label);letter-spacing:.08em;
  text-transform:uppercase;color:#9778D8}
.ledger__line{font-size:var(--t-h3);font-weight:700;letter-spacing:var(--track);color:var(--t100);line-height:1.25}
.ledger__num{font-family:var(--sans);font-size:var(--t-small);color:var(--t70);white-space:normal;
  font-variant-numeric:tabular-nums}
/* the one ledger row with a genuine sourced before/after delta stays in the
   small quiet mono register that .fig__src already uses for a figure's
   source line (OD_CORE 4: mono may mark a figure's source, quietly). Every
   other row's callout is a phrase, not a figure, so it reads in the same
   sans the row's own headline uses - fixed 2026-09-07 after Danish caught
   all five ledger__num spans rendering in mono regardless of content. */
.ledger__num--fig{font-family:var(--mono);white-space:nowrap}
@media (max-width:760px){ .ledger__num--fig{white-space:normal} }
.ledger__go{color:var(--accent);font-size:var(--t-h3);line-height:1;
  transition:transform .35s var(--ease)}
.ledger__row:hover .ledger__go{transform:translateX(5px)}
@media (max-width:760px){
  .ledger__row{grid-template-columns:1fr 24px;grid-template-areas:"tag go" "line go" "num go"}
  .ledger__tag{grid-area:tag}.ledger__line{grid-area:line}.ledger__num{grid-area:num;white-space:normal}
  .ledger__go{grid-area:go;align-self:center}
}
@media (prefers-reduced-motion: reduce){
  .ledger__row, .ledger__go{transition:none}
  .ledger__row:hover{transform:none}
  .ledger__row:hover .ledger__go{transform:none}
}


/* ============================================================== V17. THE
   WALLET-OUT HERO (2026-09-02). The hero stops being text beside an empty
   half. The right half carries a claim the reader can verify in the next
   thirty seconds, drawn (never a screenshot of a live SERP - the real
   reports belong to clients), lifted off the sheet, tilting slightly to the
   pointer. Plus the one-person questions answered where the doubt forms. */

.herosplit{display:grid;gap:var(--beat-1);align-items:center}
@media(min-width:980px){ .herosplit{grid-template-columns:1.15fr .85fr;gap:var(--gut)} }
.herosplit > *{min-width:0}

.verify{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--radius);
  padding:clamp(18px,2.4vw,28px);max-width:460px;justify-self:end;width:100%;
  box-shadow:0 18px 60px rgba(0,0,0,.42);transform:perspective(900px) rotateX(var(--vx,0deg)) rotateY(var(--vy,0deg));
  transition:transform .25s var(--ease)}
.verify__head{font-family:var(--mono);font-size:var(--t-label);letter-spacing:.14em;
  text-transform:uppercase;color:rgba(240,237,245,.45);margin-bottom:14px}
.verify__serp{background:rgba(13,11,20,.55);border:1px solid var(--line);border-radius:var(--radius-s);
  padding:12px 14px}
.verify__q{display:flex;align-items:center;gap:9px;font-family:var(--mono);font-size:13px;color:var(--t100);
  background:rgba(240,237,245,.07);border-radius:999px;padding:7px 13px;margin-bottom:12px}
.verify__glass{color:var(--t45);font-size:15px;transform:rotate(-45deg);display:inline-block}
.verify__r{display:grid;grid-template-columns:20px 1fr;gap:10px;align-items:center;padding:7px 2px}
.verify__r i{font-family:var(--mono);font-size:11px;color:var(--t45);font-style:normal}
.verify__r span{display:block;height:9px;border-radius:4px;background:rgba(240,237,245,.10);width:82%}
.verify__r--dim:last-child span{width:64%}
.verify__r--you{background:rgba(139,111,212,.10);border:1px solid rgba(139,111,212,.4);border-radius:8px;
  padding:9px 8px}
.verify__r--you b{font-size:var(--t-small);letter-spacing:var(--track);color:var(--t100)}
.verify__cap{margin-top:13px;font-size:var(--t-small);color:var(--t70);line-height:1.55}
.verify .tlink{margin-top:10px;display:inline-block}
@media(max-width:979px){ .verify{justify-self:start} }
@media (prefers-reduced-motion: reduce){ .verify{transform:none;transition:none} }

.qa3{display:grid;gap:clamp(18px,2.4vw,34px);margin-top:var(--beat-1)}
@media(min-width:860px){ .qa3{grid-template-columns:repeat(3,1fr)} }
.qa{border-top:1px solid var(--line);padding-top:18px}
.qa h3{font-size:var(--t-h3);letter-spacing:var(--track);margin-bottom:10px}
.qa p{font-size:var(--t-small);color:var(--t70);line-height:1.65}


/* ================================================== V18 - THE CALM PASS
   Benchmark: the downloads-page school. Elevation comes from a slightly
   lighter surface and a hairline, not from a heavy drop shadow. Cards get
   room to breathe. Nothing here moves layout; value substitution only. */
.lift{
  box-shadow:0 10px 40px rgba(0,0,0,.28), inset 0 1px 0 rgba(240,237,245,.06);
  border-radius:18px;
  background:rgba(240,237,245,.055);
}
.verify{padding:26px 26px 22px}
.verify__cap{margin-top:16px}

/* ============================================== V19 - PRODUCT ARTIFACTS
   The downloads-school rule: the card shows the product doing its job, not
   a photograph standing near it. Six drawn instruments, one per service.
   All flex/grid, no fixed widths, nothing can overflow 393. */
.svcart{border-radius:18px;background:rgba(13,11,20,.55);border:1px solid var(--line);
  padding:clamp(18px,2.4vw,26px);width:100%}
.svcart .cap{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--t45);margin:0 0 16px}
.svcart__note{font-family:var(--mono);font-size:11.5px;line-height:1.6;color:var(--t45);margin:16px 0 0}
.svcart__note b{color:var(--t100);font-weight:600}
/* 01 the wireframe */
.wf{display:flex;flex-direction:column;gap:8px}
.wf i{display:block;background:rgba(240,237,245,.10);border-radius:4px;height:10px}
.wf .wf-nav{height:14px;background:rgba(240,237,245,.06)}
.wf .wf-h{height:20px;width:68%;background:rgba(139,111,212,.45)}
.wf .wf-half{width:44%}
.wf .wf-row{display:flex;gap:8px}
.wf .wf-row i{flex:1;height:32px}
/* 02 the silo tree */
.silo{display:flex;flex-direction:column;align-items:center;gap:0}
.silo b{font-family:var(--mono);font-size:12px;color:var(--t100);background:rgba(139,111,212,.20);
  border:1px solid rgba(139,111,212,.5);border-radius:7px;padding:7px 16px;font-weight:600}
.silo .stem{width:1px;height:14px;background:var(--line)}
.silo .row{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-top:0}
.silo .row+.row{margin-top:8px}
.silo .row span{font-family:var(--mono);font-size:11px;color:var(--t70);
  background:rgba(240,237,245,.05);border:1px solid var(--line);border-radius:7px;padding:5px 11px}
/* 03 the content gates */
.gates{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.gates li{display:flex;gap:11px;align-items:baseline;font-size:14px;color:var(--t70);
  background:rgba(240,237,245,.04);border:1px solid var(--line);border-radius:9px;padding:10px 14px}
.gates b{color:#9778D8;font-weight:600;flex:none} /* accent, +4% toward white: 4.48:1 on this card's composited ground missed AA by .02, this clears 4.8:1 */
/* 04 the technical rows */
.fixrows{display:flex;flex-direction:column;gap:9px;font-family:var(--mono);font-size:11.5px}
.fixrows>div{display:flex;align-items:center;gap:10px;flex-wrap:wrap;color:var(--t45);
  background:rgba(240,237,245,.04);border:1px solid var(--line);border-radius:9px;padding:10px 13px}
.fixrows em{font-style:normal;color:#9778D8;border:1px solid rgba(139,111,212,.5); /* same AA fix as .gates b */
  border-radius:5px;padding:1px 7px;flex:none}
.fixrows .ok{color:var(--t100);margin-left:auto}
/* 05 the listing card */
.gbpcard{display:flex;flex-direction:column;gap:9px}
.gbpcard .gbp-name{display:flex;align-items:center;gap:9px;font-weight:700;font-size:15.5px;color:var(--t100)}
.gbpcard .gbp-pin{width:9px;height:9px;border-radius:50%;background:var(--accent);flex:none;
  box-shadow:0 0 0 4px rgba(139,111,212,.22)}
.gbpcard .gbp-stars{font-family:var(--mono);font-size:12px;color:#E7C878;letter-spacing:.06em}
.gbpcard .gbp-row{font-family:var(--mono);font-size:11.5px;color:var(--t45);
  border-top:1px solid var(--line);padding-top:9px}
.gbpcard .gbp-row b{color:var(--t100);font-weight:600}
/* 06 the report rows */
.repcard{display:flex;flex-direction:column;gap:12px}
.repcard .rep-row span{display:block;font-size:13.5px;color:var(--t70);margin-bottom:6px}
.repcard .rep-row i{display:block;height:8px;border-radius:5px;background:
  linear-gradient(90deg,var(--accent),rgba(139,111,212,.25));width:var(--w,60%)}
/* the-method: each stage carries its number */
.step__proof{font-family:var(--mono);font-size:12px;color:var(--t45);line-height:1.6;
  border-left:2px solid rgba(139,111,212,.5);padding-left:12px;margin:14px 0 0}
.step__proof b{color:var(--t100);font-weight:600}

/* ============================================ V20 - THE MATERIAL AND THE LIGHT
   The ground is a real sheet with light travelling through it. The sheen is
   two violet blooms and one moving-light diagonal over the crumple photograph,
   composited in screen blend. Text sits top-left, instrument line bottom-right. */
.breaker--sheen img{height:clamp(420px,78vh,760px)}
.breaker--sheen::before{
  content:"";position:absolute;inset:-8%;z-index:1;pointer-events:none;
  background:
    radial-gradient(85% 120% at 16% 108%, rgba(139,111,212,.55), transparent 56%),
    radial-gradient(70% 110% at 86% -12%, rgba(83,39,157,.50), transparent 60%),
    linear-gradient(115deg, transparent 32%, rgba(180,156,225,.16) 47%, transparent 63%);
  mix-blend-mode:screen;
}
.breaker--sheen::after{
  background:linear-gradient(180deg, rgba(13,11,20,.55) 0%, rgba(13,11,20,.12) 40%, rgba(13,11,20,.55) 100%);
}
.sheen__cap{
  position:absolute;left:0;right:0;top:0;z-index:2;
  padding:clamp(28px,6vh,64px) clamp(22px,5vw,72px) 0;
}
.sheen__cap .label{color:rgba(240,237,245,.62);margin-bottom:14px}
.sheen__cap p:not(.label){
  font-size:clamp(34px,5.2vw,72px);font-weight:800;line-height:1.04;
  letter-spacing:var(--track);color:var(--paper);max-width:16ch;margin:0;
}
.sheen__cap em{font-style:normal;color:#CBB8F0}
.sheen__stat{
  position:absolute;right:clamp(22px,5vw,72px);bottom:clamp(20px,4vh,40px);z-index:2;
  font-family:var(--mono);font-size:12px;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(240,237,245,.62);margin:0;
}
/* the container rule: the artifact card paints its own dark ground,
   so inside a lit plane it re-declares the light scale */
.plane--lit .svcart{
  background:#16121F;border-color:rgba(20,17,32,.35);
  --t100:#F0EDF5;--t70:rgba(240,237,245,.70);--t45:rgba(240,237,245,.64);
  --line:rgba(240,237,245,.14);--accent:#8B6FD4;
}
/* images are uncovered, never unfolded: no translate on anything holding a photo */
.rise:has(img){transform:none}


/* ==================================================== V21 - THE OFFER BAND
   The first paper moment on the page. Two columns: the deliverables and the
   order they arrive in. One next move. */
.offer__grid{display:grid;grid-template-columns:1.35fr 1fr;gap:clamp(28px,4vw,64px);margin-top:var(--beat-1)}
.offer__h{font-size:15px;letter-spacing:.08em;text-transform:uppercase;color:var(--t45);margin:0 0 18px}
.gets{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:14px}
.gets li{position:relative;padding-left:30px;font-size:16.5px;line-height:1.55;color:var(--t70)}
.gets li::before{content:"\2713";position:absolute;left:0;top:1px;color:var(--accent);font-weight:700}
.gets b{color:var(--t100)}
.offer__how{background:#16121F;border-radius:18px;padding:clamp(22px,3vw,34px);
  --t100:#F0EDF5;--t70:rgba(240,237,245,.70);--t45:rgba(240,237,245,.64);
  --line:rgba(240,237,245,.14);--accent:#8B6FD4}
.offer__how .offer__h{color:var(--t45)}
.hows{list-style:none;margin:0 0 18px;padding:0;display:flex;flex-direction:column;gap:0}
.hows li{display:flex;gap:14px;align-items:baseline;padding:12px 0;border-top:1px solid var(--line)}
.hows li:first-child{border-top:0}
.hows i{font-style:normal;font-family:var(--mono);font-size:12px;color:var(--accent);flex:none}
.hows b{display:block;color:var(--t100);font-size:15.5px}
.hows span{display:block;font-family:var(--mono);font-size:11.5px;color:var(--t45);margin-top:2px}
.offer__note{font-size:13.5px;color:var(--t45);margin:0 0 20px}
.offer__how .btn{width:100%;justify-content:center}
@media (max-width:900px){.offer__grid{grid-template-columns:1fr}}


/* ============================================== V22 - THE ASCENT MARK
   The logo talks: on hover the high wing beats. Transform only, rests flat. */
.nav__mark .wingR{transform-origin:50% 88%;transition:transform .45s cubic-bezier(.2,.8,.2,1)}
.nav__mark:hover .wingR{transform:rotate(-7deg)}
.nav__mark .wingL{transform-origin:50% 88%;transition:transform .45s cubic-bezier(.2,.8,.2,1)}
.nav__mark:hover .wingL{transform:rotate(4deg)}
@media (prefers-reduced-motion: reduce){
  .nav__mark:hover .wingR,.nav__mark:hover .wingL{transform:none}
}


/* ============================================ V23 - THE IMAGERY UPLIFT
   From the 2026-09-03 imagery plan (three buyer personas, inventory, curator,
   craft benchmark). Every picture is owned material, a real receipt, or a
   drawn artifact that says so. Frames hold their shape; nothing paints late. */

/* M06 / M12 / M13 / M15: the sheen takes a bloom position per page */
.breaker--sheen{--ba:16% 108%;--bb:86% -12%}
.breaker--sheen::before{
  background:
    radial-gradient(85% 120% at var(--ba), rgba(139,111,212,.55), transparent 56%),
    radial-gradient(70% 110% at var(--bb), rgba(83,39,157,.50), transparent 60%),
    linear-gradient(115deg, transparent 32%, rgba(180,156,225,.16) 47%, transparent 63%);
}
.breaker--sheen.breaker--tall img{height:clamp(360px,62vh,640px)}
.breaker--sheen:not(.breaker--tall) img{height:clamp(300px,46vh,520px)}

/* M01: frames and split art hold their shape while the picture arrives */
.frame img{display:block;width:100%;height:auto}
.duo__art{min-width:0}
.duo__art > img.lift,.duo__art > picture > img.lift{display:block;width:100%;height:auto;aspect-ratio:3/2;object-fit:cover}
/* height:auto is the point of this rule: the V34 `.duo img{height:clamp(320px,64svh,660px)}` (od.css
   ~L1677) sets an explicit height, which makes the browser IGNORE aspect-ratio and crop the one
   portrait picture in the set into a ~square box. This restores the 4:5 tall silhouette. 2026-09-03. */
.duo__art--tall > img,.duo__art--tall > picture > img{aspect-ratio:4/5;object-fit:cover;height:auto}

/* M02 / M03 / M10 / M11: drawn artifacts placed outside services */
.duo__art .svcart{width:100%}
.svcart .cap b{color:var(--t70);font-weight:400}
.cadence{display:block;width:100%;height:auto;color:var(--lit)}
.plane--lit .cadence{color:var(--accent-solid)}
.cadence text{font-family:var(--mono);fill:var(--t45)}
.step__art{margin-top:18px;max-width:360px}
.step__art .svcart{padding:16px 18px}
.step__art .svcart .cap{font-size:10px;margin-bottom:12px}
.step__art .gates li{font-size:13px;padding:8px 11px}
.step__art .fixrows{font-size:10.5px}
.step__art .fixrows>div{padding:8px 10px}
.step__art .silo b{font-size:11px;padding:6px 12px}
.step__art .silo .row span{font-size:10px;padding:4px 8px}
.step__art .gbpcard .gbp-name{font-size:14px}
.step__art .gbpcard .gbp-row{font-size:10.5px}
.method-steps .step{display:grid;grid-template-columns:1fr;gap:0 clamp(20px,3vw,44px)}
@media (min-width:900px){
  .method-steps.steps{grid-template-columns:1fr}
  .method-steps .step{grid-template-columns:minmax(0,1fr) 360px;align-items:start}
  .method-steps .step > .step__n, .method-steps .step > h3, .method-steps .step > p, .method-steps .step > .step__proof{grid-column:1}
  .method-steps .step > .step__art{grid-column:2;grid-row:1 / span 6;margin-top:0}
}

/* M18: stars in palette */
.gbpcard .gbp-stars{color:var(--lit)}
.plane--lit .gbpcard .gbp-stars{color:var(--accent-solid)}

/* M07: the baseline is a readable line, the ghost stays as desktop decoration */
.fig__was{display:block;font:400 var(--t-label)/1.4 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--t45);margin-bottom:6px;position:relative;z-index:1}

/* M25: two-figure grids do not leave a third-column hole */
.figs--two{grid-template-columns:repeat(2,minmax(220px,1fr));max-width:760px}
@media (max-width:560px){.figs--two{grid-template-columns:1fr}}

/* M05: market tiles paint on the phone, or collapse to rows */
.market__img{filter:grayscale(1) contrast(1.06) brightness(1.12)}
.market::after{background:linear-gradient(200deg,rgba(83,39,157,.5) 0%,rgba(13,11,20,.5) 46%,rgba(13,11,20,.82) 100%)}
@media (max-width:640px){
  .market{display:grid;grid-template-columns:96px 1fr;column-gap:16px;min-height:0;padding:14px;align-items:start;
    background:var(--surface);border:1px solid var(--line)}
  .market__img{position:static;grid-row:1 / 5;width:96px;height:120px;border-radius:8px;z-index:auto}
  .market::after{display:none}
  .market__n,.market__t,.market__tag,.market__b{grid-column:2}
  .market__t{margin-top:0}
}

/* M24: the drawn results page never out-sizes the real capture on the phone */
@media (max-width:640px){
  .ladder{gap:5px;max-height:440px;overflow:hidden}
  .ladder__row{min-height:32px}
}

/* M04: the AI answer reads at natural size */
.frame--proof{max-width:900px;margin-inline:auto}
.artcap .quote-line{display:block;margin-top:8px;font-family:var(--sans);font-size:15px;line-height:1.55;color:var(--t70);letter-spacing:0;text-transform:none}

/* ===== V24 hero listing (2026-09-03): the drawn Google listing inside the hero card, one frame not two ===== */
.verify .svcart{background:transparent;border:0;padding:0;border-radius:0}
.verify .svcart .cap{margin-top:0}
.verify .gbpcard{margin-top:14px}
.verify__cap b{color:var(--t100);font-weight:600}

/* ===== V25 panel fixes (2026-09-03): ghost numerals off, ladder row 9 legible, artefact mono floor at 393, controls ===== */
.fig__from{display:none}
.fig__was{display:block;min-height:22px}
.fig > .fig__to:first-child{margin-top:22px}
.offer__after{margin-top:var(--beat-2)}
.rung--ghost{opacity:1;position:relative}
.rung--ghost .rung__bars i{background:rgba(139,111,212,.45)}
.rung--ghost::after{content:"";position:absolute;left:-10px;right:-10px;top:6px;bottom:-4px;
  border:1px dashed rgba(139,111,212,.6);border-radius:8px;pointer-events:none}
.rung__was{font-size:11px;color:var(--t70)}
.field textarea{resize:none;min-height:9.5em}
.breaker{min-height:240px}
@media(max-width:640px){
  .svcart .cap,.step__art .svcart .cap{font-size:11px;line-height:1.5}
  .fixrows,.step__art .fixrows{font-size:11.5px}
  .silo .row span,.step__art .silo .row span{font-size:11px}
  .gbpcard .gbp-row,.step__art .gbpcard .gbp-row{font-size:11.5px}
  .frame__url{font-size:11px}
  .frame__tag{font-size:10.5px}
  .breaker--tall img{height:clamp(240px,40vh,360px)}
}

/* ===== V26 portal band (2026-09-03): one pinned phone, the screen changes with the paragraph ===== */
/* ===== PORTAL BAND, round 2 (variant B + A's intro): one phone pinned, the screen changes with the paragraph ===== */
.portalb{position:relative}
.portalb .wrap{position:relative}
.portalb__head{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);gap:clamp(28px,5vw,80px);align-items:end;padding-bottom:clamp(28px,5vh,56px)}
.portalb__lines{list-style:none;margin:0;padding:0;display:grid;gap:12px}
.portalb__lines li{display:grid;grid-template-columns:22px 1fr;gap:12px;align-items:baseline;color:var(--t70);font-size:16.5px;line-height:1.5}
.portalb__lines li b{color:var(--t100);font-weight:600}
.portalb__lines li i{font-family:var(--mono);font-style:normal;font-size:var(--t-label);color:var(--accent);letter-spacing:.14em}
.portalb__grid{display:grid;grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr);gap:clamp(28px,5vw,90px);align-items:start}
.portalb__pin{position:sticky;top:0;height:100svh;display:flex;align-items:center;justify-content:center}
.portalb__pin::before{content:"";position:absolute;inset:16% 2%;border-radius:50%;pointer-events:none;
  background:radial-gradient(closest-side, rgba(139,111,212,.30), transparent 74%);filter:blur(30px)}
.phoneb{position:relative;width:clamp(240px,min(23vw,calc((100svh - var(--nav) - 48px)*393/857)),312px);aspect-ratio:393/857;border-radius:44px;background:#0A0812;padding:10px;
  box-shadow:0 40px 90px rgba(0,0,0,.6), inset 0 0 0 1px rgba(240,237,245,.12)}
.phoneb::before{content:"";position:absolute;top:21px;left:50%;width:76px;height:19px;margin-left:-38px;border-radius:12px;background:#0A0812;z-index:3}
.phoneb::after{content:"9:41";position:absolute;top:21px;left:34px;font:600 12px/19px var(--sans);color:#141120;z-index:3}
.phoneb .screen{position:absolute;inset:10px;border-radius:35px;background:#fff;overflow:hidden}
.phoneb img{position:absolute;left:0;right:0;top:40px;width:100%;height:auto;opacity:0;transform:translateY(12px);
  transition:opacity .5s ease, transform .5s cubic-bezier(.2,.8,.2,1)}
.phoneb img.on{opacity:1;transform:none}
.portalb__steps{display:grid;max-width:520px}
.portalb__step{min-height:72svh;display:flex;flex-direction:column;justify-content:center;padding-block:8vh}
.portalb__step h3{font-size:var(--t-h2);font-weight:900;line-height:1.02;letter-spacing:-.02em;max-width:14ch;margin:0 0 18px}
.portalb__step p{font-size:22px;line-height:1.5;color:var(--t70);max-width:34ch;text-wrap:pretty}
.portalb__step .num{display:block;font-family:var(--mono);font-size:var(--t-label);letter-spacing:.14em;color:var(--accent);margin-bottom:12px}
.portalb__cta{margin-top:30px;display:grid;gap:12px;justify-items:start}
.portalb__open{font-family:var(--mono);font-size:var(--t-label);letter-spacing:.14em;text-transform:uppercase;color:var(--t45)}
@media(prefers-reduced-motion:reduce){.phoneb img{transition:none;transform:none}}
@media(max-width:900px){
  .portalb__head{grid-template-columns:1fr;gap:18px;padding-bottom:22px}
  .portalb__grid{grid-template-columns:1fr;gap:0}
  .portalb__pin{position:static;height:auto;padding:6px 0 32px}
  .phoneb{width:min(62vw,280px)}
  .portalb__steps{max-width:none}
  .portalb__step{min-height:0;padding-block:0;margin-top:44px}
  .portalb__step:first-child{margin-top:0}
  .portalb__step h3{max-width:none}
  .portalb__step p{font-size:19px}
}

/* ===== V27 band component (2026-09-03, panel T4): one band, about a third of the viewport, headline centred,
   material painted on first paint (eager, see markup), one type size at each width ===== */
.breaker--sheen.breaker--tall img,.breaker--sheen:not(.breaker--tall) img{height:clamp(320px,44vh,540px)}
.breaker--sheen .sheen__cap{top:0;bottom:0;display:flex;flex-direction:column;justify-content:center;padding-block:0}
.breaker--sheen .sheen__cap p:not(.label){font-size:clamp(32px,4vw,52px);max-width:18ch;text-wrap:balance}
.breaker--sheen .sheen__stat{bottom:clamp(16px,3vh,28px)}
@media(max-width:640px){
  .breaker--sheen.breaker--tall img,.breaker--sheen:not(.breaker--tall) img{height:clamp(240px,36vh,320px)}
  .breaker--sheen .sheen__cap p:not(.label){font-size:32px}
  .breaker--sheen .sheen__cap .label{margin-bottom:10px}
}

/* ===== V28 flat planes (2026-09-03, panel T6): the plane's 2% top-to-bottom gradient was being ordered-dithered
   into a 2px lattice at 1440 (measured: 4 luminance levels, lag-2 autocorrelation .94). Flat fills per turn angle,
   measured single level, zero pattern. The crease hairline is untouched. ===== */
.plane{background:var(--ink)}
.plane--turn{background:color-mix(in srgb, var(--paper) 1.4%, var(--ink))}
.plane--turn2{background:color-mix(in srgb, var(--paper) 2.6%, var(--ink))}
.plane--lit{background:linear-gradient(177deg,#FFFFFF 0%,var(--paper) 58%,#E6E1F0 100%)}

/* ===== V29 structure explainer (2026-09-03): one row of pages settles under the service page as you scroll, the strength flows up ===== */
/* ===== THE STRUCTURE, explained by scrolling. Round 3 (ship candidate).
   One row of five under one parent, stems routed as a bus (a rail under the parent, one drop per page) so nothing
   crosses, a corner tag instead of a pill on the fan, a glow that grows with the strength, the settle and the
   stems scrubbed by scroll, the phone pin at the top with a mask. ===== */
.silob{--k:0;--f:0}
.silob__grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);gap:clamp(28px,5vw,80px);align-items:start}
.silob__pin{position:sticky;top:0;height:100svh;display:flex;align-items:center}
.silob__draw{width:100%;aspect-ratio:720/380}
.silob__draw svg{width:100%;height:100%;display:block;overflow:visible}
.silob__steps{display:grid;max-width:500px}
.silob__step{min-height:76svh;display:flex;flex-direction:column;justify-content:center;padding-block:8vh}
.silob__step .num{display:block;font-family:var(--mono);font-size:13px;letter-spacing:.12em;color:var(--accent);margin-bottom:16px}
.silob__step h3{font-size:var(--t-h2);font-weight:900;line-height:1.02;letter-spacing:-.02em;max-width:12ch;margin:0 0 18px}
.silob__step p{font-size:22px;line-height:1.5;color:var(--t70);max-width:30em;text-wrap:pretty}
.silob__head{padding-bottom:clamp(16px,3vh,32px)}
.silob__note{font-family:var(--mono);font-size:var(--t-label);letter-spacing:.14em;text-transform:uppercase;color:var(--t45);margin-top:16px}
/* the drawing */
.node rect{fill:none;stroke:rgba(240,237,245,.2);stroke-width:1.2}
.node text{font-family:var(--mono);font-size:12.5px;fill:var(--t70);letter-spacing:.02em}
.node text.sub{fill:var(--t45);font-size:11.5px}
.node.svc rect{fill:rgba(240,237,245,.06);stroke:rgba(240,237,245,.36)}
.node.svc text{fill:var(--t100);font-size:15px}
.node{transform-box:fill-box;transform-origin:center;transition:opacity .6s ease}
/* the settle is scrubbed: --k runs 0 (pile) to 1 (tree) */
.n1{transform:translate(calc(-40px*(1 - var(--k))),calc(-150px*(1 - var(--k)))) rotate(calc(-12deg*(1 - var(--k))))}
.n2{transform:translate(calc(90px*(1 - var(--k))),calc(-60px*(1 - var(--k)))) rotate(calc(8deg*(1 - var(--k))))}
.n3{transform:translate(calc(-120px*(1 - var(--k))),calc(-200px*(1 - var(--k)))) rotate(calc(15deg*(1 - var(--k))))}
.n4{transform:translate(calc(60px*(1 - var(--k))),calc(-170px*(1 - var(--k)))) rotate(calc(-6deg*(1 - var(--k))))}
.n5{transform:translate(calc(-90px*(1 - var(--k))),calc(-40px*(1 - var(--k)))) rotate(calc(10deg*(1 - var(--k))))}
.svc{transform:translate(calc(-60px*(1 - var(--k))),calc(170px*(1 - var(--k)))) rotate(calc(-4deg*(1 - var(--k))))}
.node{opacity:calc(.7 + .3*var(--k))}
/* the strength: --f runs 0 to 1 across step 03; the stems appear from the pages upward and keep flowing */
.stem{fill:none;stroke:var(--accent);stroke-width:1.5;stroke-dasharray:6 9;opacity:var(--f);animation:silo-dash 1.3s linear infinite}
.rail{stroke-dasharray:none;opacity:calc(var(--f)*.9)}
.glow{opacity:calc(var(--f)*.55 + var(--g)*.45)}
.tag{opacity:var(--g);transition:opacity .4s ease}
.tag rect{fill:var(--accent-solid)}
.tag text{font-family:var(--mono);font-size:11px;fill:#fff;letter-spacing:.1em}
.silob{--g:0}
.silob.s3{--g:1}
.silob.s3 .svc rect{stroke:var(--accent);fill:rgba(139,111,212,.16)}
@keyframes silo-dash{to{stroke-dashoffset:-30}}
@media(prefers-reduced-motion:reduce){.silob{--k:1;--f:1;--g:1}.stem{animation:none}.node{transition:none}}
@media(max-width:900px){
  .silob__grid{grid-template-columns:1fr;gap:0}
  .silob__pin{position:sticky;top:0;height:auto;display:block;background:var(--ink);padding:70px 0 6px;z-index:2}
  .silob__pin::after{content:"";position:absolute;left:0;right:0;top:100%;height:32px;background:linear-gradient(180deg,var(--ink),transparent);pointer-events:none}
  .silob__draw{max-height:230px;margin-inline:auto}
  .silob__steps{max-width:none;padding-top:40px}
  .silob__step{min-height:0;padding-block:0;margin-top:48px}
  .silob__step:first-child{margin-top:0}
  .silob__step h3{max-width:none;font-size:30px}
  .silob__step p{font-size:18px}
  .node text{font-size:11px}
  .node text.sub{display:none}
}

/* step 04 needs its own dwell: with 18svh the finished state arrived on the last frame of the
   scroll and was gone. 42svh keeps the pin stuck while the last step sits on the measuring line. */
@media(min-width:901px){.silob__steps{padding-bottom:42svh}}

/* ===== V30 hero differentiation (2026-09-03, panel T5): each material hero has its own crop, scale and a few degrees
   of turn, so no two case pages open on the same sheet; photographic heroes get a top-down scrim so the first
   100px sit on ink under the nav ===== */
.breaker--sheen img{object-position:var(--op,50% 50%);transform:scale(var(--sc,1)) rotate(var(--rot,0deg));transform-origin:50% 50%}
.breaker--scrim::after{background:linear-gradient(180deg, rgba(13,11,20,.92) 0%, rgba(13,11,20,.35) 34%, rgba(13,11,20,.10) 55%, rgba(13,11,20,.86) 100%)}

/* ===== V31 wireframe anatomy (2026-09-03, panel T10): the page-before-it-is-built drawing carries recognisable parts,
   labelled in the margin, instead of grey bars ===== */
.wf2{display:block;width:100%;height:auto;overflow:visible}
.wf2 rect,.wf2 circle{fill:rgba(240,237,245,.12)}
.wf2 .wf2-h{fill:rgba(240,237,245,.3)}
.wf2 .wf2-frame{fill:rgba(240,237,245,.035);stroke:rgba(240,237,245,.22);stroke-width:1}
.wf2 .wf2-pill{fill:none;stroke:rgba(240,237,245,.32);stroke-width:1}
.wf2 .wf2-solid{fill:var(--accent-solid)}
.wf2 .wf2-rule{stroke:rgba(240,237,245,.14);stroke-width:1}
.wf2 .wf2-lab{font-family:var(--mono);font-size:10.5px;fill:var(--accent);letter-spacing:.08em}

/* ===== V32 refused-pages explainer (2026-09-03): a field of squares, each about fourteen pages, worked back down as you scroll ===== */
/* ===== THE REFUSED PAGES, explained by scrolling. Round 2 (ship candidate).
   A field of squares, each about fourteen pages. Google refused all 4,144; every page got a decision; the count was
   worked back down to 2,549 one page at a time; nothing was bulk deleted. Same shell as the structure explainer. ===== */
.refb{--g:0}
.refb__grid{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,.8fr);gap:clamp(28px,5vw,80px);align-items:start}
.refb__pin{position:sticky;top:0;height:100svh;display:flex;align-items:center}
.refb__draw{width:100%}
.refb__draw svg{width:100%;height:auto;display:block;overflow:visible}
.refb__steps{display:grid;max-width:500px}
.refb__step{min-height:76svh;display:flex;flex-direction:column;justify-content:center;padding-block:8vh}
.refb__step .num{display:block;font-family:var(--mono);font-size:13px;letter-spacing:.12em;color:var(--accent);margin-bottom:16px}
.refb__step h3{font-size:var(--t-h2);font-weight:900;line-height:1.02;letter-spacing:-.02em;max-width:12ch;margin:0 0 18px}
.refb__step p{font-size:22px;line-height:1.5;color:var(--t70);max-width:30em;text-wrap:pretty}
.refb__head{padding-bottom:clamp(16px,3vh,32px)}
.refb__note{font-family:var(--mono);font-size:var(--t-label);letter-spacing:.14em;text-transform:uppercase;color:var(--t45);margin-top:16px}
/* step 04 needs its own dwell: with 18svh the finished state arrived on the last frame of the
   scroll and was gone. 42svh keeps the pin stuck while the last step sits on the measuring line. */
@media(min-width:901px){.refb__steps{padding-bottom:42svh}}
/* the drawing */
.sq{fill:none;stroke:rgba(240,237,245,.22);stroke-width:1;transition:fill .35s ease,stroke .35s ease}
.sq.decided{stroke:rgba(139,111,212,.9);stroke-width:1.5;fill:rgba(139,111,212,.14)}
.sq.back{fill:var(--accent);stroke:var(--accent)}
.ref-count{font-family:var(--sans);font-weight:900;font-size:64px;fill:var(--t100);letter-spacing:-2px;font-variant-numeric:tabular-nums}
.ref-lab{font-family:var(--mono);font-size:11.5px;fill:var(--t45);letter-spacing:.14em;text-transform:uppercase}
.ref-zero{opacity:var(--g);transition:opacity .5s ease}
.ref-zero .ref-count{fill:var(--accent)}
.ref-legend text{font-family:var(--mono);font-size:12.5px;fill:var(--t70);letter-spacing:.04em}
.ref-legend rect{stroke-width:1.2}
.ref-note{font-family:var(--mono);font-size:11px;fill:var(--t45);letter-spacing:.02em}
@media(prefers-reduced-motion:reduce){.sq{transition:none}}
@media(max-width:900px){
  .refb__grid{grid-template-columns:1fr;gap:0}
  .refb__pin{position:sticky;top:0;height:auto;display:block;background:var(--ink);padding:70px 0 6px;z-index:2}
  .refb__pin::after{content:"";position:absolute;left:0;right:0;top:100%;height:32px;background:linear-gradient(180deg,var(--ink),transparent);pointer-events:none}
  .refb__draw{max-width:360px;margin-inline:auto}
  .refb__steps{max-width:none;padding-top:56px}
  .refb__step{min-height:0;padding-block:0;margin-top:48px}
  .refb__step:first-child{margin-top:0}
  .refb__step h3{max-width:none;font-size:30px}
  .refb__step p{font-size:18px}
  .ref-legend text{font-size:13px}
  .ref-note{font-size:11.5px}
}

/* ===== V33 cadence explainer (2026-09-03): four sites, thirty one days, 195 pieces dated before the month began ===== */
/* ===== THE CADENCE, explained by scrolling. Round 3 (ship candidate).
   Four sites, thirty one days, 195 pieces, every one dated before the month began. Weekends dimmed so the grid reads
   as a calendar; step 03 is one wipe, because the month was built ahead, not day by day; the second stat is a site
   check, not a promise. On the phone the labels sit above each row and the grid takes the full width. ===== */
.cadb{--g:0}
.cadb__grid{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr);gap:clamp(28px,5vw,80px);align-items:start}
.cadb__pin{position:sticky;top:0;height:100svh;display:flex;align-items:center}
.cadb__draw{width:100%}
.cadb__draw svg{width:100%;height:auto;display:block;overflow:visible}
.cadb__steps{display:grid;max-width:480px}
.cadb__step{min-height:76svh;display:flex;flex-direction:column;justify-content:center;padding-block:8vh}
.cadb__step .num{display:block;font-family:var(--mono);font-size:13px;letter-spacing:.12em;color:var(--accent);margin-bottom:16px}
.cadb__step h3{font-size:var(--t-h2);font-weight:900;line-height:1.02;letter-spacing:-.02em;max-width:12ch;margin:0 0 18px}
.cadb__step p{font-size:22px;line-height:1.5;color:var(--t70);max-width:30em;text-wrap:pretty}
.cadb__head{padding-bottom:clamp(16px,3vh,32px)}
.cadb__note{font-family:var(--mono);font-size:10.5px;letter-spacing:.02em;color:var(--t45);margin-top:16px}
/* step 04 needs its own dwell: with 18svh the finished state arrived on the last frame of the
   scroll and was gone. 42svh keeps the pin stuck while the last step sits on the measuring line. */
@media(min-width:901px){.cadb__steps{padding-bottom:42svh}}
/* the drawing */
.cad-day{font-family:var(--mono);font-size:12px;fill:var(--t45);letter-spacing:.02em}
.cad-row{font-family:var(--mono);font-size:12.5px;fill:var(--t70);letter-spacing:.02em}
.cad-row tspan.rate{fill:var(--t45)}
.cad-wk{fill:rgba(240,237,245,.035)}
.cad-slot{fill:none;stroke:rgba(240,237,245,.14);stroke-width:1;opacity:0;transition:opacity .3s ease,fill .35s ease,stroke .35s ease}
.cad-slot.dated{opacity:1;stroke:rgba(139,111,212,.65)}
.cad-slot.done{fill:var(--accent);stroke:var(--accent)}
.cad-line{stroke:rgba(240,237,245,.12);stroke-width:1}
.cad-count{font-family:var(--sans);font-weight:900;font-size:64px;fill:var(--t100);letter-spacing:-2px;font-variant-numeric:tabular-nums}
.cad-lab{font-family:var(--mono);font-size:11.5px;fill:var(--t45);letter-spacing:.14em;text-transform:uppercase}
.cad-check{opacity:var(--g);transition:opacity .5s ease}
.cad-check .cad-count{fill:var(--accent)}
.cad-note{font-family:var(--mono);font-size:11px;fill:var(--t70);letter-spacing:.02em}
@media(prefers-reduced-motion:reduce){.cad-slot{transition:none}}
@media(max-width:900px){
  .cadb__grid{grid-template-columns:1fr;gap:0}
  .cadb__pin{position:sticky;top:0;height:auto;display:block;background:var(--ink);padding:70px 0 6px;z-index:2}
  .cadb__pin::after{content:"";position:absolute;left:0;right:0;top:100%;height:32px;background:linear-gradient(180deg,var(--ink),transparent);pointer-events:none}
  .cadb__draw{max-width:420px;margin-inline:auto}
  .cadb__steps{max-width:none;padding-top:56px}
  .cadb__step{min-height:0;padding-block:0;margin-top:48px}
  .cadb__step:first-child{margin-top:0}
  .cadb__step h3{max-width:none;font-size:30px}
  .cadb__step p{font-size:18px}
  .cad-row{font-size:14px}
  .cad-day{font-size:13px}
  .cad-note{font-size:12px}
  .cad-count{font-size:60px}
  .cad-lab{font-size:11px}
}

/* the step-04 "Drawn" line on all three explainers: a quiet sentence, not shouting capitals (panel, twice) */
.silob__note,.refb__note,.cadb__note{font-family:var(--mono);font-size:10.5px;letter-spacing:.02em;text-transform:none;color:var(--t45);margin-top:16px}

/* ===================================================================== V34 ARCHETYPES (2026-09-03)
   The site had four shapes repeated ninety times: pagehead, numbered steps, read column, stat row. This layer
   gives it a vocabulary instead, and one law: no two sections in a row may share a ground, a height or a shape.
   Every archetype below is a different answer to "what fills a screen".
   Grounds, in order of light: ink -> plate (photograph) -> violet -> paper.
   =================================================================================================== */

:root{
  --t-statement: clamp(34px, 5.4vw, 88px);
  --t-colossal:  clamp(74px, 12.5vw, 210px);
  --seam: 1px solid rgba(240,237,245,.16);
}

/* ------------------------------------------------------------------ STATEMENT
   One sentence, a whole screen, no eyebrow, no lede, nothing to click. The site's only pure claim. */
.statement{
  min-height:100svh; display:grid; align-content:center;
  background:var(--ink); position:relative; z-index:2;
  padding-block:var(--beat-3);
}
.statement p{
  margin:0; max-width:16ch;
  font:900 var(--t-statement)/1.02 var(--sans); letter-spacing:-.032em; color:var(--t100);
  text-wrap:balance;
}
.statement em{font-style:normal; color:var(--accent)}
.statement .after{
  margin-top:clamp(22px,3.4vh,40px); max-width:44ch;
  font-family:var(--mono); font-size:var(--t-label); letter-spacing:.14em;
  text-transform:uppercase; color:var(--t45);
}
.statement--right p{margin-left:auto; text-align:right}

/* ----------------------------------------------------------------------- HINGE
   The site turns over. A hard seam, ink above and paper below, one line of type sitting on the join. */
.hinge{
  position:relative; display:grid; place-items:center; min-height:clamp(220px,34svh,320px);
  background:linear-gradient(180deg, var(--ink) 0 50%, var(--paper) 50% 100%);
  z-index:2;
}
.hinge::before{content:""; position:absolute; left:0; right:0; top:50%; height:1px;
  background:linear-gradient(90deg, rgba(139,111,212,.75) 0%, rgba(139,111,212,.18) 46%, transparent 82%)}
.hinge p{
  margin:0; position:relative; padding:10px 20px; background:var(--ink);
  border:1px solid rgba(240,237,245,.16); border-radius:999px;
  font-family:var(--mono); font-size:var(--t-label); letter-spacing:.16em;
  text-transform:uppercase; color:var(--t70);
}
.hinge--up{background:linear-gradient(180deg, var(--paper) 0 50%, var(--ink) 50% 100%)}
.hinge--up p{background:var(--paper); border-color:rgba(20,17,32,.16); color:#3D3753}

/* ---------------------------------------------------------------- NUMERAL WALL
   Three readings at a size the rest of the site never uses. Paper, so it arrives as light. */
.numwall{
  background:linear-gradient(177deg,#FFFFFF 0%,var(--paper) 58%,#E6E1F0 100%); color:#141120;
  padding-block:clamp(64px,9vh,110px); position:relative; z-index:2;
}
.numwall .label{color:#615B77}
.numwall__grid{display:grid; gap:clamp(30px,4vw,64px); margin-top:clamp(28px,4vh,52px)}
@media(min-width:820px){.numwall__grid{grid-template-columns:repeat(3,1fr)}}
.numwall b{
  display:block; font:900 var(--t-colossal)/.84 var(--sans); letter-spacing:-.05em; color:#141120;
  font-variant-numeric:tabular-nums;
}
.numwall span{display:block; margin-top:14px; font-size:16px; line-height:1.5; color:#3D3753; max-width:26ch}
.numwall small{
  display:block; margin-top:10px; font-family:var(--mono); font-size:var(--t-label);
  letter-spacing:.1em; text-transform:uppercase; color:#615B77;
}

/* --------------------------------------------------------------- VIOLET FIELD
   The one saturated screen on the site. Six words, no picture, no button.
   RENAMED .field -> .vfield 2026-09-03: the bare `.field` collided with the contact form's
   `<label class="field">` primitive (od.css:635) at equal specificity, and being later in the
   cascade it won -- so every form field on the money page rendered as a solid violet 620px
   block, ~4 screens of purple on the phone. That was the "valuables broken in transit". No live
   page currently uses this archetype (homepage section 9 is a .bed with plate-violet), so this
   is dormant styling kept for reuse: add `<section class="plane vfield">` to bring it back. */
.vfield{
  background:var(--accent-solid); color:#F4F1FA; position:relative; z-index:2;
  min-height:clamp(320px,72svh,620px); display:grid; align-content:center;
  padding-block:var(--beat-3); overflow:hidden;
}
.vfield::before{
  content:""; position:absolute; inset:-20%; pointer-events:none; mix-blend-mode:screen;
  background:radial-gradient(58% 74% at 76% 8%, rgba(196,174,234,.42), transparent 62%),
             radial-gradient(52% 68% at 8% 96%, rgba(13,11,20,.55), transparent 64%);
}
.vfield p{
  margin:0; position:relative; max-width:13ch;
  font:900 var(--t-statement)/1.02 var(--sans); letter-spacing:-.032em; text-wrap:balance;
}
.vfield .sub{
  margin-top:clamp(20px,3vh,34px); max-width:40ch; font-family:var(--mono);
  font-size:var(--t-label); letter-spacing:.14em; text-transform:uppercase; color:rgba(244,241,250,.72);
}

/* --------------------------------------------------------------------- LEDGER
   Density, once. Mono rows on paper, a hairline between each, no motion and no art. */
.ledger-wall{
  background:var(--paper); color:#141120; padding-block:clamp(52px,7vh,88px); position:relative; z-index:2;
}
.ledger-wall .label{color:#615B77}
/* The ledger is the best writing on the site and it was rendering as unstyled HTML: every row is an <a>,
   so the global link underline ran continuously across the market label, the sentence AND the figure.
   Three independent reviewers read the whole section as a browser default. Underline the sentence only,
   on hover only. The first column also has to hold "Manchester - cleaning" on ONE line: at 9ch the
   separator was wrapping onto a line of its own. */
.lrow{
  display:grid; grid-template-columns:170px minmax(0,1fr) 150px; gap:18px; align-items:baseline;
  /* measured rule gaps were 73/95/94/73/72/72/116px, so the register visibly stumbled */
  min-height:64px; padding:16px 0; border-top:1px solid rgba(20,17,32,.14);
  font-family:var(--mono); font-size:13.5px; color:#3D3753;
  text-decoration:none;
}
.lrow,.lrow:hover,.lrow:focus-visible{text-decoration:none}
.lrow b{text-decoration:none}
.lrow:hover b{text-decoration:underline; text-underline-offset:3px; text-decoration-thickness:1px}
.lrow:hover{background:rgba(139,111,212,.06)}
.lrow:focus-visible{outline:2px solid var(--accent-solid); outline-offset:2px}
.lrow i{white-space:nowrap}
.lrow span{font-variant-numeric:tabular-nums; white-space:nowrap; text-align:right}
.lrow:last-child{border-bottom:1px solid rgba(20,17,32,.14)}
.lrow b{color:#141120; font-weight:700}
.lrow i{font-style:normal; color:#615B77}
@media(max-width:640px){
  .lrow{grid-template-columns:1fr auto; gap:4px 14px}
  .lrow i{grid-column:1/-1; order:3; white-space:normal}
}

/* ------------------------------------------------------------------- THE RAIL
   The only horizontal axis on the site: cards that travel sideways while the page holds still. */
.rail{background:var(--ink); position:relative; z-index:2; padding-block:var(--beat-2)}
.rail__track{
  display:flex; gap:clamp(14px,1.6vw,24px); overflow-x:auto; scroll-snap-type:x mandatory;
  padding-inline:var(--gut); margin-inline:calc(-1*var(--gut));
  scrollbar-width:none; -webkit-overflow-scrolling:touch;
}
.rail__track::-webkit-scrollbar{display:none}
.railcard{
  flex:0 0 min(78vw,360px); scroll-snap-align:center;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius);
  padding:clamp(20px,2.4vw,30px); display:flex; flex-direction:column; gap:10px;
}
.railcard .k{font-family:var(--mono); font-size:var(--t-label); letter-spacing:.14em;
  text-transform:uppercase; color:var(--accent)}
.railcard h3{font-size:20px; font-weight:800; letter-spacing:-.02em; margin:0}
.railcard p{margin:0; font-size:15px; line-height:1.55; color:var(--t70)}
.railcard .n{margin-top:auto; font:800 34px/1 var(--sans); letter-spacing:-.03em; color:var(--t100)}

/* ------------------------------------------------------------- READING SPREAD
   Where the site actually talks. Paper, two columns, nothing else on the screen. */
.spread{background:var(--paper); color:#141120; padding-block:clamp(56px,8vh,100px); position:relative; z-index:2}
.spread h2{color:#141120; max-width:20ch}
.spread__cols{margin-top:clamp(22px,3vh,38px)}
@media(min-width:900px){.spread__cols{column-count:2; column-gap:clamp(34px,4vw,72px)}}
.spread__cols p{margin:0 0 1.05em; font-size:19px; line-height:1.62; color:#3D3753; max-width:34em}
.spread__cols p:first-child::first-letter{
  float:left; font:900 3.1em/.82 var(--sans); padding:.06em .10em 0 0; color:var(--accent-solid);
}

/* --------------------------------------------------------------------- CLOSE
   One question and two ways to answer it. */
.close{background:var(--ink); position:relative; z-index:2; min-height:clamp(300px,52svh,520px);
  display:grid; align-content:center; padding-block:var(--beat-3)}
.close h2{max-width:15ch}
.close .actions{margin-top:clamp(24px,3.4vh,40px)}

/* ------------------------------------------------------------- shared quiet-down
   The reveal ran on every block on every page, so arrival itself became the sameness. Archetype
   sections arrive already there; only the artefacts still move. */
.statement .rise,.vfield .rise,.hinge .rise,.numwall .rise,.ledger-wall .rise,.spread .rise{
  opacity:1; transform:none;
}
@media(prefers-reduced-motion:reduce){
  .rail__track{scroll-behavior:auto}
}

/* ================================================================== V35 PLATES AND BEDS (2026-09-03)
   V34 gave the page a plate archetype and then starved it: 236px letterboxes on an ink ground, carrying
   nothing. Measured on the built page, two of them had zero pixels brighter than luminance 110. A picture
   that thin and that dark is not a picture, it is a gap, and five gaps is what "no imagery" looks like.

   Three sizes, and a rule for each:
     .plate         a photograph gets a screen of its own. Never under 52svh.
     .plate--full   the picture IS the section. Full viewport.
     .plate--band   the one thin form, and it must carry a caption, so it reads as deliberate.
     .bed           a full-screen photograph with type on it. The site had nothing like this.
   ================================================================================================== */

/* ---------------------------------------------------------------------- PLATE */
.plate{position:relative; margin:0; overflow:hidden; background:var(--ink); z-index:2}
.plate img{display:block; width:100%; height:clamp(340px,58svh,620px); object-fit:cover}
.plate--full img{height:100svh}
.plate--tall img{height:clamp(420px,78svh,780px)}
.plate--band{display:grid}
.plate--band img{height:clamp(170px,24svh,240px)}

/* A band is the only plate allowed to be thin, and it pays for it with a caption.
   The caption rides its own ink chip: a photograph has no fixed tone under any given corner, and the first
   attempt put dark type over a dark pleat and light type over a highlight. A chip is legible on all of them. */
.plate figcaption{
  position:absolute; left:var(--gut); bottom:clamp(14px,2.2vh,26px); z-index:3;
  max-width:min(52ch, calc(100% - var(--gut) * 2));
  padding:9px 16px; border-radius:13px;
  background:rgba(13,11,20,.82); border:1px solid rgba(240,237,245,.14);
  -webkit-backdrop-filter:blur(9px); backdrop-filter:blur(9px);
  font-family:var(--mono); font-size:var(--t-label); letter-spacing:.13em;
  text-transform:uppercase; color:rgba(240,237,245,.72);
}
.plate figcaption b{font-weight:700; color:var(--t100)}

/* the seam a plate needs against an ink section, so the photograph starts rather than fades in */
.plate::before{
  content:""; position:absolute; left:0; right:0; top:0; height:1px; z-index:3;
  background:linear-gradient(90deg, rgba(139,111,212,.55), rgba(139,111,212,.10) 52%, transparent 86%);
}

/* --------------------------------------------------------------------- THE BED
   A photograph fills the screen and one line of type sits on it. This is the move the site was missing
   entirely: every section was type on a flat ground. */
.bed{
  position:relative; min-height:100svh; display:grid; align-content:end;
  overflow:hidden; background:var(--ink); z-index:2; isolation:isolate;
}
.bed > img,.bed > picture > img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover; z-index:0;
}
.bed::after{
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(184deg, rgba(13,11,20,.72) 0%, rgba(13,11,20,.30) 34%,
                                     rgba(13,11,20,.62) 72%, rgba(13,11,20,.94) 100%);
}
.bed .wrap{position:relative; z-index:2; padding-block:clamp(48px,8vh,110px)}
.bed .label{color:rgba(240,237,245,.66)}
.bed h2{
  margin:14px 0 0; max-width:17ch;
  font:900 var(--t-statement)/1.02 var(--sans); letter-spacing:-.032em; color:#FFFFFF;
  text-wrap:balance; text-shadow:0 2px 40px rgba(13,11,20,.55);
}
.bed p{
  margin:clamp(16px,2.4vh,26px) 0 0; max-width:46ch; font-size:17px; line-height:1.6;
  color:rgba(244,241,250,.86);
}
.bed .actions{margin-top:clamp(22px,3vh,34px)}
.bed .lede{font-size:19px; line-height:1.55; color:rgba(244,241,250,.92)}
/* A bed on a light photograph flips to ink type. It needs a far heavier scrim than a dark one, because
   ink type over a bright convergence of creases is unreadable no matter how large it is set: the first
   version of the closing bed proved that. Anything using this must pick a CALM plate as well. */
.bed--light::after{
  background:linear-gradient(184deg, rgba(247,246,251,.50) 0%, rgba(247,246,251,.30) 22%,
                                     rgba(247,246,251,.88) 58%, rgba(247,246,251,.99) 100%);
}
.bed--light h2{color:#141120; text-shadow:none}
.bed--light p,.bed--light .lede{color:#3D3753}
.bed--light .label{color:#615B77}
/* the closing bed centres its column, so the scrim has to be strongest exactly where the type lands */
.bed--centre{align-content:center}
.bed--centre .wrap{text-align:center}
.bed--centre h2,.bed--centre p,.bed--centre .lede{margin-inline:auto}
.bed--centre .label{margin-inline:auto; display:block; width:fit-content}
.bed--centre .actions{justify-content:center}

/* S2c -- RE-MEASURED 2026-09-04: the closing bed's eyebrow measured 3.4-3.7:1 at every width tested
   (360 through 1440 - this one is not a width trap, the vertically-centred column always opens on the
   same weak point in the mask, 0-22% down the band, where the wash is only .30-.50 and the crumple
   photograph's own texture still shows through). #615B77 was tuned to read as quiet/secondary against a
   flat pale mat, not against the actual photograph. Reused #3D3753 - the body copy's own colour two
   lines down, already measuring 6.4-8.8:1 in the same band - rather than inventing a third shade. */
.bed--light .label{color:#3D3753}

/* ------------------------------------------------------------------- PORTRAIT
   One page in a set gets a tall picture beside its type instead of above it, so a run of case pages
   cannot be recognised by its silhouette alone. */
.duo{background:var(--ink); position:relative; z-index:2; padding-block:var(--beat-2)}
.duo__grid{display:grid; gap:clamp(22px,3vw,54px); align-items:center}
@media(min-width:900px){.duo__grid{grid-template-columns:minmax(0,1fr) minmax(0,.92fr)}}
.duo figure{margin:0; overflow:hidden; border-radius:var(--radius)}
.duo img{display:block; width:100%; height:clamp(320px,64svh,660px); object-fit:cover}

@media(max-width:760px){
  .plate img{height:clamp(280px,44svh,420px)}
  .plate--tall img{height:clamp(360px,62svh,560px)}
  /* the generic .plate img rule above is equal specificity and later in source than the base
     .plate--band img rule, so without this the one thin form rendered at 44svh (~375px) on the
     phone -- identical to a full plate, and the three plate sizes collapsed to one on the
     surface Danish reviews on. Kept proportional to the desktop band / plate ratio. */
  .plate--band img{height:clamp(140px,20svh,200px)}
  .bed h2{max-width:13ch}
}

/* =============================================================== V36 SCROLL EXPLAINERS (2026-09-03)
   Three drawings are scrubbed by scroll: the structure, the refused pages, the cadence. All three were
   built against a viewport that does not exist. Measured, not guessed:

     1  the nav is 77px of sticky translucent bar, and every pin was `top:0`, so the top 77px of each
        drawing sat behind it. On a phone the label row was simply gone.
     2  progress was measured against innerHeight/2 while the art is centred in (100svh - nav), so the
        copy and the drawing disagreed by half the nav all the way down.
     3  the nodes had a 600ms opacity transition AND a scrubbed opacity, so the drawing lagged the
        scroll by more than half a second. That lag is what reads as a broken parallax.
     4  the pile transforms sent three nodes up and left by similar amounts, so the "pile" was a jumble
        of crossing rectangles rather than a stack you could read.
     5  the step-04 class flipped on a bare `> .3`, so a slow scroll at the threshold strobed.
   ================================================================================================== */

:root{ --nav:77px; --nav-m:66px; }

/* 1 + 2 — the pin clears the nav, and its height is the space that is actually visible */
.silob__pin,.refb__pin,.cadb__pin,.portalb__pin{
  top:var(--nav); height:calc(100svh - var(--nav));
}

/* 3 — nothing that is scrubbed may also be transitioned */
.node{transition:none}
.tag{transition:opacity .35s ease}

/* 4 — the pile: a scatter that reads as a stack. Each node lands in its own quadrant with its own
   rotation, so no two overlap at k=0 and the settle is legible as six things finding one order. */
.n1{transform:translate(calc(-186px*(1 - var(--k))),calc(-104px*(1 - var(--k)))) rotate(calc(-9deg*(1 - var(--k))))}
.n2{transform:translate(calc( 158px*(1 - var(--k))),calc(-142px*(1 - var(--k)))) rotate(calc( 11deg*(1 - var(--k))))}
.n3{transform:translate(calc(-118px*(1 - var(--k))),calc( 128px*(1 - var(--k)))) rotate(calc( 14deg*(1 - var(--k))))}
.n4{transform:translate(calc( 196px*(1 - var(--k))),calc(  74px*(1 - var(--k)))) rotate(calc( -7deg*(1 - var(--k))))}
.n5{transform:translate(calc( -44px*(1 - var(--k))),calc(-186px*(1 - var(--k)))) rotate(calc(  5deg*(1 - var(--k))))}
.svc{transform:translate(calc(  22px*(1 - var(--k))),calc( 176px*(1 - var(--k)))) rotate(calc( -4deg*(1 - var(--k))))}
/* the pile starts dimmer and arrives solid, but it arrives by scrubbing, not by animating */
.node{opacity:calc(.52 + .48*var(--k))}

@media(max-width:900px){
  /* 1 on a phone — the pin sat under the nav and the top row of every drawing was invisible */
  .silob__pin,.refb__pin,.cadb__pin{
    top:var(--nav-m); height:auto; padding:18px 0 8px;
  }
  .silob__pin::after,.refb__pin::after,.cadb__pin::after{height:56px}
  /* the pile has less room, so it packs tighter */
  .silob{--pile:.55}
  .n1,.n2,.n3,.n4,.n5,.svc{transform:scale(1) translate(0,0)}
  .n1{transform:translate(calc(-96px*(1 - var(--k))),calc(-58px*(1 - var(--k)))) rotate(calc(-8deg*(1 - var(--k))))}
  .n2{transform:translate(calc( 88px*(1 - var(--k))),calc(-78px*(1 - var(--k)))) rotate(calc( 9deg*(1 - var(--k))))}
  .n3{transform:translate(calc(-66px*(1 - var(--k))),calc( 70px*(1 - var(--k)))) rotate(calc(12deg*(1 - var(--k))))}
  .n4{transform:translate(calc(104px*(1 - var(--k))),calc( 42px*(1 - var(--k)))) rotate(calc(-6deg*(1 - var(--k))))}
  .n5{transform:translate(calc(-26px*(1 - var(--k))),calc(-98px*(1 - var(--k)))) rotate(calc( 4deg*(1 - var(--k))))}
  .svc{transform:translate(calc( 14px*(1 - var(--k))),calc( 96px*(1 - var(--k)))) rotate(calc(-3deg*(1 - var(--k))))}
}


/* ============================================== V37 THE HERO FIELD AND REAL PARALLAX (2026-09-03)
   Two things a buyer reads in the first second: is this expensive, and is it true. The hero had the
   second (a real Google listing, read on a named day) and none of the first: type on flat black.

   So the hero gets a photographic field. Not a background image behind type, which is where legibility
   goes to die, but a large photograph anchored off the right edge and masked to nothing before it
   reaches the headline. The type never leaves the ink. The screen stops being flat.

   And the plates get parallax that actually works: one transform, on the GPU, driven by a single
   rAF-throttled scroll listener, off entirely under reduced motion. The previous attempt animated a
   transitioned property while scrubbing it, which is why it lagged and read as broken.
   ================================================================================================== */

/* --------------------------------------------------------------- THE HERO FIELD */
.hero--screen{position:relative; overflow:hidden; isolation:isolate}
.herofield{
  position:absolute; inset:0; z-index:0; pointer-events:none;
  /* the picture lives in the right two-thirds and is pulled off the edge, so what you see is the
     interior of the fold, not a photograph sitting in a box */
  --field-w:78%;
}
.herofield img{
  position:absolute; top:50%; right:-6%; width:var(--field-w); height:auto;
  min-height:118%; object-fit:cover; object-position:52% 42%;
  transform:translate3d(0,-50%,0) scale(1.04);
  opacity:.72; filter:saturate(.86) contrast(1.14);
  will-change:transform;
}
/* the mask does the work: the photograph is fully present at the right edge and gone by 46%, which is
   where the headline's measure ends */
.herofield::after{
  content:""; position:absolute; inset:0;
  background:
    linear-gradient(96deg, var(--ink) 0%, var(--ink) 30%, rgba(13,11,20,.88) 44%,
                           rgba(13,11,20,.44) 60%, rgba(13,11,20,.14) 100%),
    linear-gradient(180deg, var(--ink) 0%, rgba(13,11,20,0) 20%,
                            rgba(13,11,20,0) 76%, var(--ink) 100%);
}
.hero--screen > .wrap{position:relative; z-index:2}

@media(max-width:900px){
  /* on a phone the field moves behind and below the type, never across it */
  .herofield::after{
    background:linear-gradient(180deg, var(--ink) 0%, var(--ink) 30%, rgba(13,11,20,.62) 52%,
                                       rgba(13,11,20,.55) 78%, var(--ink) 100%);
  }
}

/* The proof card stops being a panel and becomes an object resting on the photograph: opaque enough to
   hold mono figures at full contrast, with a real shadow underneath. Without this the 20,400 washed out
   against the bright fold behind it, and the one piece of evidence above the fold was the thing that
   suffered. */
.hero--screen .verify{
  position:relative;
  background:rgba(13,11,20,.86);
  -webkit-backdrop-filter:blur(22px) saturate(150%); backdrop-filter:blur(22px) saturate(150%);
  border:1px solid rgba(240,237,245,.16);
  box-shadow:0 34px 90px -28px rgba(0,0,0,.92), inset 0 1px 0 rgba(255,255,255,.05);
}

/* ------------------------------------------------------------------- PARALLAX
   `--par` is set from JS between -1 and 1 as the plate crosses the viewport. The image is oversized by
   exactly the distance it will travel, so no edge is ever exposed. */
.plate{--par:0}
.plate img{
  transform:translate3d(0, calc(var(--par) * var(--par-range, 34px)), 0) scale(1.16);
  will-change:transform;
}
.plate--tall img{--par-range:52px}
.plate--band img{--par-range:20px; transform:translate3d(0, calc(var(--par) * 20px), 0) scale(1.10)}

/* a bed's photograph drifts more slowly than its type, which is what makes a full screen feel deep */
.bed{--par:0}
.bed > img,.bed > picture > img{transform:translate3d(0, calc(var(--par) * 46px), 0) scale(1.14); will-change:transform}

@media(prefers-reduced-motion:reduce){
  .plate img,.bed img,.herofield img{transform:none !important; scale:1 !important}
  .plate img,.bed img{transform:scale(1.02) !important}
}

/* ================================================== V38 THE CLIMB, ON THE HOMEPAGE (2026-09-03)
   All three scroll explainers sat on interior pages. A visitor who leaves in the first twenty seconds
   never saw one, which makes the best thing on the site the thing fewest people reach. This one is on
   the homepage, three screens in, immediately after the sentence it illustrates.

   `--k` is the climb, scrubbed across steps 02 and 03. `--g` lights the top three at step 04.
   Everything moves by transform only, and nothing that is scrubbed is also transitioned.
   ================================================================================================= */

.serpb{background:var(--ink); position:relative; z-index:2; padding-block:var(--beat-2); --k:0; --g:0}
.serpb__head{padding-bottom:clamp(16px,3vh,32px)}
.serpb__grid{display:grid; grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);
  gap:clamp(28px,5vw,80px); align-items:start}
.serpb__pin{position:sticky; top:var(--nav); height:calc(100svh - var(--nav));
  display:flex; align-items:center}
.serpb__draw{width:100%; aspect-ratio:720/480}
.serpb__draw svg{width:100%; height:100%; display:block; overflow:visible}
.serpb__steps{display:grid; max-width:500px}
.serpb__step{min-height:76svh; display:flex; flex-direction:column; justify-content:center; padding-block:8vh}
.serpb__step .num{display:block; font-family:var(--mono); font-size:13px; letter-spacing:.12em;
  color:var(--accent); margin-bottom:16px}
.serpb__step h3{font-size:var(--t-h2); font-weight:900; line-height:1.02; letter-spacing:-.02em;
  max-width:13ch; margin:0 0 18px}
.serpb__step p{font-size:22px; line-height:1.5; color:var(--t70); max-width:30em; text-wrap:pretty}
.serpb__step p b{color:var(--t100)}
.serpb__src{font-family:var(--mono); font-size:var(--t-label) !important; letter-spacing:.14em;
  text-transform:uppercase; color:var(--t45) !important; margin-top:14px}
@media(min-width:901px){.serpb__steps{padding-bottom:42svh}}

/* ---- the drawing */
.serp-box{fill:rgba(240,237,245,.05); stroke:rgba(240,237,245,.20); stroke-width:1}
.serp-mag{fill:none; stroke:var(--t45); stroke-width:1.6; stroke-linecap:round}
.serp-q{font-family:var(--mono); font-size:14px; fill:var(--t70)}
.serp-toplab,.serp-foldlab{font-family:var(--mono); font-size:10.5px; letter-spacing:.14em;
  text-transform:uppercase; fill:var(--t45)}
.serp-top{opacity:calc(.25 + .75*var(--g))}
.serp-toplab{opacity:calc(.35 + .65*var(--g))}

.rival rect{fill:rgba(240,237,245,.09)}
.rival rect.u{fill:rgba(240,237,245,.05)}
.rival{transform:translateY(calc(var(--drop, 0) * 40px))}

/* A rival steps down one slot at the moment the client's page passes it. The threshold per row is
   (9 - slot) / 7, because the climb runs from ninth to second across a --k of 0 to 1. The multiplier
   makes the step quick rather than a slow slide, so it reads as overtaking, not as drifting. */
.r2{--drop:clamp(0, (var(--k) - 0.99) * 60, 1)}
.r3{--drop:clamp(0, (var(--k) - 0.857) * 40, 1)}
.r4{--drop:clamp(0, (var(--k) - 0.714) * 40, 1)}
.r5{--drop:clamp(0, (var(--k) - 0.571) * 40, 1)}
.r6{--drop:clamp(0, (var(--k) - 0.428) * 40, 1)}
.r7{--drop:clamp(0, (var(--k) - 0.285) * 40, 1)}
.r8{--drop:clamp(0, (var(--k) - 0.142) * 40, 1)}

/* the client's page: ninth at --k 0, second at --k 1 */
/* ninth at --k 0 (y 424), second at --k 1 (y 126) */
.mine{transform:translateY(calc(var(--k) * -298px))}
.mine-card{
  fill:rgba(139,111,212,calc(.14 + .16*var(--k)));
  stroke:var(--accent); stroke-width:calc(1 + 0.6*var(--k));
}
.mine-title{fill:rgba(240,237,245,calc(.55 + .45*var(--k)))}
.mine-url{fill:rgba(139,111,212,.85)}
.mine-badge rect{fill:var(--accent-solid); opacity:calc(.55 + .45*var(--k))}
.mine-badge text{font-family:var(--mono); font-size:15px; font-weight:700; fill:#fff}
.serp-hash{opacity:.6}

@media(prefers-reduced-motion:reduce){
  .serpb{--k:1; --g:1}
}
@media(max-width:900px){
  .serpb__grid{grid-template-columns:1fr; gap:0}
  .serpb__pin{position:sticky; top:var(--nav-m); height:auto; display:block;
    background:var(--ink); padding:18px 0 8px; z-index:2}
  .serpb__pin::after{content:""; position:absolute; left:0; right:0; top:100%; height:56px;
    background:linear-gradient(180deg,var(--ink),transparent); pointer-events:none}
  .serpb__draw{max-height:44svh; margin-inline:auto}
  .serpb__steps{max-width:none; padding-top:52px}
  .serpb__step{min-height:0; padding-block:0; margin-top:48px}
  .serpb__step:first-child{margin-top:0}
  .serpb__step h3{max-width:none; font-size:30px}
  .serpb__step p{font-size:18px}
  .serp-q{font-size:16px}
}

/* On a phone the step column ends flush with the section, so the finished state of every explainer
   arrived on the very last frame of the scroll and was gone. Each one gets room to be looked at. */
@media(max-width:900px){
  .silob__steps,.refb__steps,.cadb__steps,.serpb__steps{padding-bottom:30svh}
}

/* `picture` is transparent to layout (display:contents below) but NOT to selectors, so every
   direct-child image rule has to allow the wrapper the WebP sources are served from. */
picture{display:contents}

/* ============================================ V39 THE CLIMB, WITH WORDS IN IT (2026-09-03)
   Six independent reviewers looked at the V38 explainer and FIVE of them called it the same thing: a
   skeleton loader. Nine featureless grey bars on near-black is pixel-for-pixel the shape browsers use to
   say "this page has not loaded yet", and the highlighted row sat about 1.1:1 against its neighbours, so
   the one thing the drawing existed to show was invisible at arm's length and gone entirely in greyscale.

   So every result now has a title, a domain and a snippet, the way a real result does, and the client's
   row carries three separate signals rather than one hue: a solid left rule, a filled card at roughly
   3:1 against its neighbours, and a chip that says "your page" in words.

   The rivals are generic by design. This is a drawing of how ranking works, not a claim about any named
   firm, so no real competitor is shown sitting in a position we invented for it.
   ========================================================================================== */

.serpb__draw{width:100%; aspect-ratio:720/520}

/* ---- rival rows: real result shape, deliberately quiet */
.rival .s-t{font:600 15px/1 var(--sans); fill:rgba(240,237,245,.50); letter-spacing:-.01em}
.rival .s-u{font:400 11.5px/1 var(--mono); fill:rgba(139,111,212,.46); letter-spacing:.01em}
.rival .s-s{font:400 12.5px/1 var(--sans); fill:rgba(240,237,245,.26)}
.rival{transform:translateY(calc(var(--drop, 0) * 50px))}

/* A rival steps down one slot the moment the client's page passes it. The thresholds are (9 - slot) / 7,
   because the climb runs ninth to second across a --k of 0 to 1. */
.r2{--drop:clamp(0, (var(--k) - 0.99) * 60, 1)}
.r3{--drop:clamp(0, (var(--k) - 0.857) * 40, 1)}
.r4{--drop:clamp(0, (var(--k) - 0.714) * 40, 1)}
.r5{--drop:clamp(0, (var(--k) - 0.571) * 40, 1)}
.r6{--drop:clamp(0, (var(--k) - 0.428) * 40, 1)}
.r7{--drop:clamp(0, (var(--k) - 0.285) * 40, 1)}
.r8{--drop:clamp(0, (var(--k) - 0.142) * 40, 1)}

/* ---- the client's page: ninth at --k 0 (y 490), second at --k 1 (y 140) */
.mine{transform:translateY(calc(var(--k) * -350px))}
.mine-card{
  fill:rgba(92,66,168,calc(.34 + .30*var(--k)));
  stroke:rgba(160,132,236,calc(.55 + .45*var(--k))); stroke-width:1.2;
}
.mine-rule{fill:#8B6BFF}
.m-t{font:700 15.5px/1 var(--sans); fill:#FFFFFF; letter-spacing:-.01em}
.m-u{font:400 12px/1 var(--mono); fill:#C9B6F5}
.m-s{font:400 12.5px/1 var(--sans); fill:rgba(255,255,255,.78)}
.mine-badge rect{fill:#6D3FE0}
.mine-badge text{font:700 12px/1 var(--mono); fill:#FFFFFF; letter-spacing:.06em}
.serp-hash{opacity:.62}

.serp-top{opacity:calc(.25 + .75*var(--g))}
.serp-toplab{opacity:calc(.4 + .6*var(--g))}

@media(prefers-reduced-motion:reduce){ .serpb{--k:1; --g:1} }

/* ------------------------------------------------------------------ the phone
   At 393px the desktop drawing scaled to a 230px strip: result rows about 4px tall and the caption a grey
   smudge at roughly 5px. Below 900px the drawing is redrawn, not shrunk. It keeps five rows instead of
   nine, at a size a thumb-height away from the eye can actually read. */
@media(max-width:900px){
  .serpb__draw{max-height:none; aspect-ratio:393/430}
  .serpb__draw svg{width:100%; height:100%}
  .rival.r6,.rival.r7,.rival.r8{display:none}
  .rival .s-t{font-size:19px; fill:rgba(240,237,245,.56)}
  .rival .s-u{font-size:15px}
  .rival .s-s{display:none}
  .m-t{font-size:20px}
  .m-u{font-size:15px}
  .m-s{display:none}
  .mine-badge text{font-size:15px}
  .serp-q{font-size:19px}
  .serp-toplab{font-size:14px}
}

/* The drawing was getting 1.1 of 2 columns, so at 1440 it rendered 480px tall inside an 823px pin and
   left ~170px of dead ground above and below it. It is the subject of the section; give it the room. */
@media(min-width:1100px){
  .serpb__grid{grid-template-columns:minmax(0,1.32fr) minmax(0,.68fr); gap:clamp(24px,3.4vw,56px)}
}
/* The one label that identifies this as a deliberate diagram rather than a broken page needed 8x
   magnification to resolve. It is now readable at 100%. */
.serp-toplab{font-size:11.5px; fill:rgba(240,237,245,.62); letter-spacing:.16em}
.serpb.lit .serp-toplab{fill:#C9B6F5}
.serp-top{opacity:calc(.45 + .55*var(--g))}

/* re-stated after the unconditional rule above, which would otherwise win on the phone */
@media(max-width:900px){
  .serp-toplab{font-size:14px; letter-spacing:.12em}
  .serpb__grid{grid-template-columns:1fr}
}

/* The panel measured the phone hero: the top 55% was one flat fill, and the photograph did not enter the
   frame until about y=465, behind the buttons. The headline change of the night had not shipped on the
   majority device. The field now starts at the top of the frame and keeps enough of itself to read as
   paper, with the scrim doing the legibility work instead of the opacity. */
@media(max-width:900px){
  /* max-width:100% in the global img reset CLAMPED this to the container, which is the whole bug:
     width:150% resolved to 393px on a 393px phone, and with right:-34% the image's own left edge landed
     at x=134 -- a hard vertical seam straight down the middle of the headline. Only visible by looking at
     a real phone; every layout measurement reported the box it had been given. */
  .herofield img{
    max-width:none;
    width:150%; right:-34%; top:-2%; bottom:auto; height:76svh;
    object-position:64% 34%; opacity:.58; transform:none; min-height:0;
  }
  .herofield::after{
    /* the vertical scrim carries legibility; the horizontal one hides the sheet's own left edge, which
       otherwise lands mid-screen as a hard seam behind the headline */
    background:
      linear-gradient(180deg, rgba(13,11,20,.82) 0%, rgba(13,11,20,.66) 26%,
                              rgba(13,11,20,.72) 52%, rgba(13,11,20,.92) 78%, var(--ink) 100%),
      linear-gradient(94deg, var(--ink) 0%, rgba(13,11,20,.72) 22%, rgba(13,11,20,.10) 54%,
                             rgba(13,11,20,0) 100%);
  }
}

/* The ledger's rail column now carries a unit and a source. Four of its nine values were bare integers,
   and down is good for a rank and bad for nearly everything else, so a buyer could not tell a win from a
   loss. And the site's whole claim is "read on a named day": the hero card carried a date and the ledger
   carried nine claims and not one. Rows whose value is a description rather than an instrument reading
   get no source line, because inventing one would be the exact thing this section exists to refuse. */
.lrow span{display:block; text-align:right; line-height:1.25}
.lrow span small{display:block; font-size:11px; font-weight:400; color:#615B77; letter-spacing:.02em;
  text-transform:none; margin-top:2px}
.lrow span .src{display:block; margin-top:5px; font-style:normal; font-size:10.5px; letter-spacing:.08em;
  text-transform:uppercase; color:#8079931f; color:rgba(97,91,119,.78)}
@media(max-width:640px){
  .lrow span{text-align:left}
  .lrow span .src{margin-top:3px}
}

/* ===================================================================== V40 THE 1.71.0 REPAIR (2026-09-03)
   Danish: "the most beautiful build yet, but tossed from the driveway to my door and my valuables broke
   inside." Fifteen pages audited at 1440 and 393 after 1.70.0 shipped. Every item below was proven on the
   rendered page, fixed here, and looked at again before it left. Appended, never spliced (F30). Numbers
   refer to ops/data/OD_1710_AUDIT_2026-09-03.md.
   ================================================================================================== */

/* F7 -- services 02/04/06 were dark type on a dark panel (h2 measured 1.05:1). The V35 PORTRAIT archetype
   bolted background:var(--ink) onto the .duo LAYOUT primitive; on a paper section the tokens are dark, so
   the copy vanished into the panel. On paper a duo is layout only. */
.plane--lit .duo{background:transparent}

/* S3 / M4 / M5 / P4 -- the turned planes differed from ink by 3-6 levels a channel, which no screen shows.
   Three dark sections in a row read as one flat ground and every rhythm job fell to the photographs.
   Flat fills still (V28), stepped so a turn is a turn: ink, +11 levels, +23 levels. */
.plane--turn{background:color-mix(in srgb, var(--paper) 5%, var(--ink))}
.plane--turn2{background:color-mix(in srgb, var(--paper) 10%, var(--ink))}

/* S1 -- the case-page steps sat in an equal-height grid: the one cell holding a drawing set the row height
   and the four beside it carried 250-370px of dead ink under a two-line paragraph, then 5 or 6 steps
   left a 4+1 orphan row. Steps now FLOW down columns like a set of notes: each keeps its own height, the
   drawing stays with the step it explains, and column balancing swallows the orphan. */
@media(min-width:640px){
  .steps--flow{display:block;columns:2;column-gap:clamp(24px,3vw,48px)}
  .steps--flow .step{break-inside:avoid;margin-bottom:clamp(22px,2.6vw,34px);padding-top:clamp(20px,2vw,28px)}
  .steps--flow .step p{max-width:46ch}
  .steps--flow .step__art{max-width:420px}
}
/* two columns at every width above the phone: with five or six steps and one drawing, two columns balance
   to within a line; three left the first column holding a single step over 330px of nothing. */

/* S2 -- the foundation hero caption measured 1.5-2.2:1 over the blown highlights of the sheen. The scrim
   was a symmetric top/bottom vignette that thinned to .12 exactly where the centred caption sits. It now
   also ramps in from the left, under the words, and the words carry their own thin shadow. The sheen
   photograph stays open on the right where it is the only thing you can see.

   RE-MEASURED 2026-09-04: that fix held on work-foundation's photo but not on the "crumple" material
   (contact, the-method, services) - its bright diagonal streak sits further right than this photo's,
   directly under a wide two-line caption (.sheen__cap p is up to 18ch), and the ramp had already faded
   to .10 by 68% width - proven by eye at 780 and 1280 on contact.html, "site" and "first" reading as
   grey-on-grey. The strong zone now reaches further right (still .10 by 78%, not 68%) and the text
   shadow is a full stop darker, without moving where the photograph opens up at the far right edge. */
.breaker--sheen::after{
  background:
    linear-gradient(90deg, rgba(13,11,20,.72) 0%, rgba(13,11,20,.56) 46%, rgba(13,11,20,.20) 78%, rgba(13,11,20,0) 100%),
    linear-gradient(180deg, rgba(13,11,20,.55) 0%, rgba(13,11,20,.22) 40%, rgba(13,11,20,.60) 100%);
}
.sheen__cap p:not(.label),.sheen__cap .label{text-shadow:0 1px 3px rgba(13,11,20,.75), 0 0 26px rgba(13,11,20,.6)}
/* the 11px eyebrow was the one part of the caption still measuring under 4.5:1 on every breaker--sheen
   page after the ramp fix above - it sits under the caption's own opacity (.62, dimmed for hierarchy)
   AND the general scrim, so it needed its own lift rather than a stronger site-wide scrim. */
.breaker--sheen .sheen__cap .label{color:rgba(240,237,245,.86); text-shadow:0 1px 2px rgba(13,11,20,.85), 0 0 14px rgba(13,11,20,.7)}
@media(max-width:640px){
  .breaker--sheen .sheen__cap{padding-inline:clamp(20px,6vw,28px)}
  .breaker--sheen.breaker--tall img,.breaker--sheen:not(.breaker--tall) img{height:clamp(270px,38vh,340px)}
}

/* S2b -- RE-MEASURED 2026-09-04: the live sweep above was re-run with a corrected probe (the eyebrow's
   readings had been inflated - it samples the label's own text glyphs now, not the full flex-stretched
   block that reached into the ramp's open right edge). With that fixed, S2's ramp genuinely holds from
   600px up (6.5-9.4:1 measured on both contact and the-method). Under 600px it does not: at 345-378px
   wide the band is nearly square (345x340 / 378x340), object-fit:cover shows a tighter, more central
   slice of the crumple photo than the wide crops the ramp was tuned against, and the bright streak lands
   earlier in the frame - measured 3.3-4.0:1 on contact's headline and the-method's eyebrow at 360/393.
   Strengthened for phone widths specifically, since 600px and up already pass on the ramp above. */
@media(max-width:640px){
  .breaker--sheen::after{
    background:
      linear-gradient(90deg, rgba(13,11,20,.84) 0%, rgba(13,11,20,.74) 55%, rgba(13,11,20,.42) 85%, rgba(13,11,20,.12) 100%),
      linear-gradient(180deg, rgba(13,11,20,.62) 0%, rgba(13,11,20,.36) 45%, rgba(13,11,20,.65) 100%);
  }
}

/* S6 -- on the phone the stat figures stacked with 200-260px of ink between them and a 250-500px void after
   the last one; the page looked as if it had run out of content. The beat tightens on the narrow surface. */
@media(max-width:640px){
  .plane{padding-block:clamp(48px,8vh,72px)}
  .plane--air{padding-block:clamp(64px,10vh,96px)}
  .figs{gap:22px}
  .fig{padding-block:6px}
}

/* S7 -- footer links were 23px rows on the phone, seventeen of them under the 40px target. */
@media(max-width:640px){
  .foot__links{gap:14px}
  .foot__links a{display:inline-block;padding-block:9px;margin-block:-9px}
}

/* S8 -- .tlink appends an arrow, which is right at the end of a card and wrong mid-sentence
   ("It is the content -> service."). The inline form keeps the drawn underline and drops the arrow. */
.tlink--inline::after{content:none}

/* S9 -- figures with a "from N" eyebrow sat 6px lower than figures without one, so a mixed row of values
   was visibly out of line. The reserved eyebrow row now includes the eyebrow's own margin. */
.fig > .fig__to:first-child{margin-top:28px}

/* S10 -- drawn-card body text sat at --t45 (about 3.9:1) at 10.5-11.5px. Lifted a step. The tick in a
   fixrow was wrapping onto a third line; it keeps its place at the end of the row now. */
.svcart__note,.step__proof,.fixrows>div{color:var(--t70)}
.fixrows>div{flex-wrap:nowrap}
.fixrows>div>span:not(.ok){flex:1 1 auto;min-width:0}
.fixrows .ok{flex:0 0 auto}

/* S11 -- in-page anchors (services #content etc.) landed under the fixed nav, and the footer email was
   clipped at max scroll. */
html{scroll-padding-top:calc(var(--nav) + 14px)}

/* M1 -- the "Drawn" closing line of all three explainers rendered at full body size (22px) because
   .silob__step p out-specifies .silob__note. It is a caption. */
.silob__steps p.silob__note,.cadb__steps p.cadb__note,.refb__steps p.refb__note{
  font-size:10.5px;line-height:1.6;letter-spacing:.02em;text-transform:none;color:var(--t45)
}

/* M3 -- the structure and cadence drawings had 1.15 of 2 columns and a fixed aspect ratio, and at 1440 sat
   small in the middle of an 823px pin with ~234px of dead ground above and below. Same remedy the climb
   got in V39: the drawing is the subject, it gets the room. */
@media(min-width:1100px){
  .silob__grid{grid-template-columns:minmax(0,1.42fr) minmax(0,.58fr);gap:clamp(24px,3.4vw,56px)}
  .silob__draw{aspect-ratio:auto}
  .silob__draw svg{height:auto}
  .cadb__grid{grid-template-columns:minmax(0,1.42fr) minmax(0,.58fr);gap:clamp(24px,3.4vw,56px)}
}

/* M2 -- on the phone the scattered pile bled out of the pinned drawing and landed on the step-01
   heading, and the left node was clipped past the edge. The pile packs to the room it has. */
@media(max-width:900px){
  .n1{transform:translate(calc(-46px*(1 - var(--k))),calc(-40px*(1 - var(--k)))) rotate(calc(-8deg*(1 - var(--k))))}
  .n2{transform:translate(calc( 54px*(1 - var(--k))),calc(-54px*(1 - var(--k)))) rotate(calc( 9deg*(1 - var(--k))))}
  .n3{transform:translate(calc(-40px*(1 - var(--k))),calc( 30px*(1 - var(--k)))) rotate(calc(12deg*(1 - var(--k))))}
  .n4{transform:translate(calc( 62px*(1 - var(--k))),calc( 20px*(1 - var(--k)))) rotate(calc(-6deg*(1 - var(--k))))}
  .n5{transform:translate(calc(-14px*(1 - var(--k))),calc(-62px*(1 - var(--k)))) rotate(calc( 4deg*(1 - var(--k))))}
  .svc{transform:translate(calc( 10px*(1 - var(--k))),calc( 38px*(1 - var(--k)))) rotate(calc(-3deg*(1 - var(--k))))}
  .silob__steps{padding-top:56px}
}

/* M6 -- the cadence drawing on the phone: every SVG label except the two big counts resolved at 5-7 screen
   pixels, because a 720-unit viewBox was drawn 350px wide. od.js now builds the narrow drawing in a
   380-unit box; these sizes are in those units and land at 11px or more on screen. */
@media(max-width:900px){
  .cad-day{font-size:12px}
  .cad-row{font-size:13px}
  .cad-note{font-size:11.5px}
  .cad-count{font-size:40px;letter-spacing:-1px}
  .cad-lab{font-size:12px;letter-spacing:.04em}
}
/* M7 -- step 04's payoff ("46 of 46 live") latched after its own words had scrolled off. Longer dwell. */
@media(min-width:901px){.cadb__steps{padding-bottom:64svh}}
/* minor -- weekend bands were imperceptible at .035; the method's step copy and its art card sat 560px apart */
.cad-wk{fill:rgba(240,237,245,.07)}
@media(min-width:900px){.method-steps .step{max-width:960px}}

/* W1 -- the work index shows Google's own AI answer as a receipt inside a browser frame. The V35 portrait
   rule (.duo img, height clamp + cover) cropped that 900x440 screenshot to a 585x576 slice and blew it up
   twice over, so the highlighted line the caption promises was half outside the frame. A receipt is shown
   whole, at its own proportions. The about-page portrait keeps its 4:5 by its own, later rule. */
.duo__art img{height:auto;object-fit:fill}

/* S7b -- the inline text links (the closing "It is the ... service." line, the mailto) measured 19-23px
   tall on the phone. The target grows without moving the text. */
@media(max-width:640px){
  .tlink{display:inline-block;padding-block:10px;margin-block:-10px}
}

/* R1 -- the refused-pages drawing on the phone (see od.js section 9, V40): 480-unit box drawn ~349px wide,
   so these sizes land at 11px or more on screen. */
@media(max-width:900px){
  .ref-legend text{font-size:17px;letter-spacing:.02em}
  .ref-legend rect{stroke-width:1.5}
  .ref-lab{font-size:16px;letter-spacing:.06em}
  .ref-note{font-size:14px}
  .ref-count{font-size:60px}
  .refb__draw{max-width:none}
}

/* P5 -- the authority and donation mid-page plates were two crumpled violet sheets at the same scale, and read
   as one picture reused. A plate can now carry its own crop and magnification, so the same material shows as
   fine texture on one page and as large folds on the next. The parallax travel is unchanged. */
.plate img{object-position:var(--op,50% 50%)}
.plate:not(.plate--band) img{transform:translate3d(0, calc(var(--par) * var(--par-range, 34px)), 0) scale(var(--zoom,1.16))}

/* T1 -- the drawn-card label and the wireframe margin labels sat at 10px and ~8.7px on screen. Floors. */
.step__art .svcart .cap{font-size:10.5px}
@media(max-width:900px){.wf2-lab{font-size:11.5px}}

/* M8 -- the structure drawing on the phone. The desktop drawing is a 720-unit box drawn 349px wide, so its
   node labels landed at 5 screen pixels and the sub-labels had to be hidden. The phone gets its own drawing:
   same six nodes, same classes (so the scroll scrub and the pile transforms drive both), laid out in a
   380-unit box as one service page over two rows of pages. Type sized for that box: 12px or more on screen. */
/* (.silob__draw svg is 0,1,1 and sets display:block; these toggles have to outrank it, not hope) */
.silob__draw svg.silob__svg--m{display:none}
@media(max-width:900px){
  .silob__draw svg.silob__svg--d{display:none}
  .silob__draw svg.silob__svg--m{display:block}
  .silob__draw{aspect-ratio:auto;max-height:none;max-width:360px}
  .silob__draw svg{height:auto}
  .silob__svg--m .node text{font-size:13px}
  .silob__svg--m .node text.sub{display:block;font-size:12px}
  .silob__svg--m .node.svc text{font-size:17px}
  .silob__svg--m .node.svc text.sub{font-size:13px}
  .silob__svg--m .tag text{font-size:12px}
  .silob__pin{padding-top:12px}
}
/* the browser-frame chrome tag ("AI MODE") sat at 9.5px */
.frame__tag{font-size:10.5px}

/* M9 -- the climb drawing on the phone: a 720-unit box drawn 349px wide put the result titles at 9px and the
   addresses at 7px on screen. Sized so a title lands at 11px and an address at 10px; the address drops 9 units
   so the larger lines do not touch. The snippets stay hidden under 900px as V39 left them. */
@media(max-width:900px){
  .rival .s-t{font-size:23px}
  .rival .s-u{font-size:21px;transform:translateY(9px)}
  .m-t{font-size:24px}
  .m-u{font-size:21px;transform:translateY(9px)}
  .serp-q{font-size:23px}
  .serp-toplab{font-size:20px;letter-spacing:.08em}
  .mine-badge text{font-size:19px;letter-spacing:.02em;transform:translateX(-22px)}
  /* the badge gets a phone-width rect and the marked title drops its tail, so the two never touch */
  .mine-badge .mb-d{display:none}
  .m-t .m-tail{display:none}
}
.mine-badge .mb-m{display:none}
@media(max-width:900px){.mine-badge .mb-m{display:inline}}

/* ===================================================================== V41 THE COLD-LOAD MARK (2026-09-04)
   Danish: "should we make a creative loading? brand specific? not mandatory on every single load, but for
   the real loads." Shown at most once per tab, and only when the page genuinely is not ready ~180ms after
   parse (od.js section 13 decides; nothing here decides visibility). The resting state is opacity:0 +
   pointer-events:none, set inline in <head> before this stylesheet has even arrived, so a slow CSS fetch
   can never be the cause of a flash - this block only ever gets ADDED to by the .is-on class. */
.odload{
  display:flex; align-items:center; justify-content:center;
  transition:opacity .32s ease;
}
.odload.is-on{opacity:1; pointer-events:auto}
.odload__mark{width:clamp(52px,9vw,72px); aspect-ratio:1}
.odload__mark svg{width:100%; height:100%; display:block; overflow:visible}
.odload__l,.odload__r{transform-origin:50% 88%; opacity:0}
.odload__l{fill:#6F49C0}
.odload__r{fill:#B49CE1}
.odload.is-on .odload__l{
  animation:odload-unfold .5s var(--ease) both, odload-breathe 1.7s ease-in-out .5s infinite;
}
.odload.is-on .odload__r{
  animation:odload-unfold .5s var(--ease) .1s both, odload-breathe 1.7s ease-in-out .6s infinite;
}
@keyframes odload-unfold{
  from{opacity:0; transform:scaleX(0) scaleY(.7)}
  to{opacity:1; transform:scaleX(1) scaleY(1)}
}
@keyframes odload-breathe{
  0%,100%{opacity:1}
  50%{opacity:.7}
}
@media(prefers-reduced-motion:reduce){
  .odload{display:none}
}

/* ===================================================================== V42 THE SHEET UNDER THE LAMP (2026-09-04)
   The photograph at full strength, the type never crossing it, a light that moves over the folds, and the sheet
   opening from its own centre on arrival. */
.hero--lamp{--ox:76%; --oy:52%; --lx:72vw; --ly:46vh}
.hero--lamp .herofield{--field-w:68%; overflow:hidden}
.hero--lamp .herofield picture{position:absolute; inset:0; display:block; transform-origin:var(--ox) var(--oy)}
.hero--lamp .herofield img{
  opacity:1; filter:saturate(.96) contrast(1.04);
  top:50%; right:-5%; width:var(--field-w); height:auto; min-height:126%;
  object-fit:cover; object-position:var(--px,56%) var(--py,66%);
  transform:translate3d(0, calc(-50% + var(--par,0) * 44px), 0) scale(1.04);
}
.hero--lamp .herofield::after{
  background:
    linear-gradient(94deg, var(--ink) 0%, var(--ink) 36%, rgba(13,11,20,.93) 42%, rgba(13,11,20,.60) 48%,
                           rgba(13,11,20,.18) 55%, rgba(13,11,20,0) 62%),
    linear-gradient(180deg, var(--ink) 0%, rgba(13,11,20,.55) 10%, rgba(13,11,20,0) 24%, rgba(13,11,20,0) 86%, var(--ink) 100%);
}
/* the lamp: a soft light that screens over the folds; it sits under the mask so the ink stays ink */
.hero__lampdrift{position:absolute; left:0; top:0; width:100%; height:100%; pointer-events:none;
  animation:lamp-drift 17s ease-in-out infinite alternate}
.hero__lamp{position:absolute; left:0; top:0; width:min(66vw,940px); aspect-ratio:1; border-radius:50%;
  pointer-events:none; mix-blend-mode:screen;
  background:radial-gradient(circle, rgba(255,251,255,.30) 0%, rgba(214,200,255,.15) 28%, rgba(120,90,200,0) 62%);
  transform:translate3d(var(--lx), var(--ly), 0) translate(-50%,-50%);
  transition:transform .55s cubic-bezier(.2,.7,.2,1);
  will-change:transform}
.hero--lamp.has-pointer .hero__lamp{transition-duration:.35s}
@keyframes lamp-drift{
  0%{transform:translate3d(-40px,-24px,0)} 50%{transform:translate3d(36px,30px,0)} 100%{transform:translate3d(-12px,44px,0)}
}
/* arrival: the sheet opens from its centre once the page is genuinely ready (od.js adds .is-in) */
html.js .hero--lamp:not(.is-in) .herofield picture{clip-path:circle(0% at var(--ox) var(--oy)); transform:scale(1.07)}
.hero--lamp.is-in .herofield picture{animation:hero-unfold 1.5s var(--ease) both}
@keyframes hero-unfold{
  from{clip-path:circle(0% at var(--ox) var(--oy)); transform:scale(1.07)}
  to{clip-path:circle(150% at var(--ox) var(--oy)); transform:scale(1)}
}
/* type: display steps up (6.1x body at 1440), the copy column widens so the three lines hold */
.hero--lamp .mega{font-size:clamp(44px, min(7.3vw, 11.6svh), 104px)}
@media(min-width:980px){
  .hero--lamp .herosplit{grid-template-columns:1.3fr .7fr; grid-template-areas:"copy verify" "actions verify"; row-gap:clamp(24px,3.2vh,36px)}
  .hero--lamp .hero__copy{grid-area:copy}
  .hero--lamp .hero__actions{grid-area:actions; margin-top:0}
  .hero--lamp .verify{grid-area:verify; max-width:440px}
}
@media(min-width:980px) and (max-width:1199px){ .hero--lamp .herosplit{grid-template-columns:1.15fr .85fr} }
/* the glass card shows the folds through it */
.hero--screen.hero--lamp .verify{background:rgba(13,11,20,.80)}
/* phone: the sheet is a full-width band between the sentence and the buttons, at full strength */
@media(max-width:899px){
  .hero--screen.hero--lamp{display:grid; grid-template-columns:100%; gap:0; padding-block:clamp(52px,7svh,80px) clamp(24px,4svh,48px); min-height:0}
  .hero--screen.hero--lamp > .wrap.herosplit{display:contents}
  .hero--lamp .hero__copy{order:1; padding-inline:var(--gut)}
  .hero--lamp .herofield{order:2; position:relative; inset:auto; height:clamp(250px,38svh,340px); margin-top:clamp(26px,4svh,40px); --ox:62%; --oy:44%; --lx:60vw; --ly:40%}
  .hero--lamp .herofield img{position:absolute; left:0; right:auto; top:-36%; width:100%; height:136%; min-height:0;
    object-position:var(--px,60%) 50%; transform:translate3d(0, calc(var(--par,0) * 26px), 0) scale(1.06)}
  .hero--lamp .herofield::after{background:linear-gradient(180deg, var(--ink) 0%, rgba(13,11,20,.6) 10%, rgba(13,11,20,0) 26%, rgba(13,11,20,0) 84%, var(--ink) 100%)}
  .hero__lamp{width:120vw}
  .hero--lamp .hero__actions{order:3; padding-inline:var(--gut); margin-top:clamp(20px,3svh,30px)}
  .hero--lamp .verify{order:4; margin-inline:var(--gut); margin-top:clamp(28px,4svh,40px); max-width:none; width:auto; justify-self:stretch}
}
@media(prefers-reduced-motion:reduce){
  .hero__lampdrift{animation:none}
  html.js .hero--lamp:not(.is-in) .herofield picture{clip-path:none; transform:none}
  .hero--lamp.is-in .herofield picture{animation:none}
}
@media(prefers-reduced-motion:reduce) and (min-width:900px){ .hero--lamp .herofield img{transform:translate3d(0,-50%,0) scale(1.04) !important} }
@media(prefers-reduced-motion:reduce) and (max-width:899px){ .hero--lamp .herofield img{transform:scale(1.06) !important} }

/* ===================================================================== V42-A THE HERO SHIP (variant A, panel-picked 2026-09-04, 4/4)
   The headline holds the ink panel in four lines so the folded sheet reads at full luminance (the panel
   rejected the type-over-photo variant as "folds smeared to grey mud"). The lede lifts for fast reading
   (the dyslexic-reader test). The ink->photo seam becomes a long multi-stop ramp so the sheet surfaces
   OUT of the ink instead of butting a hard vertical line (design-director note). Append-only; nothing here
   redefines a non-hero selector. */
@media(min-width:980px){
  .hero--lamp .herosplit{grid-template-columns:minmax(0,1.02fr) minmax(0,.98fr)}
  .hero--lamp .hero__copy{max-width:560px}
  .hero--lamp .mega{font-size:clamp(44px, min(6.0vw,9.6svh),84px); line-height:.99; letter-spacing:-.018em}
  .hero--lamp .verify{max-width:410px}
  .hero--lamp .herofield::after{
    background:
      linear-gradient(94deg, var(--ink) 0%, var(--ink) 34%, rgba(13,11,20,.94) 42%, rgba(13,11,20,.70) 48%,
                             rgba(13,11,20,.44) 54%, rgba(13,11,20,.22) 60%, rgba(13,11,20,.08) 66%, rgba(13,11,20,0) 73%),
      linear-gradient(180deg, var(--ink) 0%, rgba(13,11,20,.55) 10%, rgba(13,11,20,0) 24%, rgba(13,11,20,0) 86%, var(--ink) 100%);
  }
}
.hero--lamp .lede{color:rgba(240,237,245,.82)}

/* ===================================================================== V43 NUMWALL HIERARCHY (2026-09-04)
   The section already wins on proof (its source sits at the claim). It lacked ONE entry point: three
   equally-colossal numbers, the eye landing nowhere (Apple phone teardown, hierarchy dimension). Now the
   top-three-rankings figure is the hero across a full-width row (giant number left, its context and source
   to the right), and the other two sit paired and smaller beneath it. Copy and sources are unchanged.
   Append-only; scoped to .numwall__grid--hero so the old .numwall__grid is untouched. */
@media(min-width:820px){
  .numwall__grid--hero{grid-template-columns:1fr 1fr; column-gap:clamp(30px,4vw,64px); row-gap:clamp(44px,6vh,76px)}
  .numwall__grid--hero .fig--hero{grid-column:1 / -1; display:grid;
    grid-template-columns:minmax(0,auto) minmax(0,1fr); grid-template-rows:auto auto;
    column-gap:clamp(32px,4.5vw,72px); align-items:center}
  .numwall__grid--hero .fig--hero b{grid-row:1 / 3; align-self:center; font-size:clamp(96px,13.5vw,188px); line-height:.86}
  .numwall__grid--hero .fig--hero span{grid-column:2; grid-row:1; margin-top:0; align-self:end; font-size:20px; line-height:1.45; max-width:38ch}
  .numwall__grid--hero .fig--hero small{grid-column:2; grid-row:2; align-self:start; margin-top:8px}
  .numwall__grid--hero .fig:not(.fig--hero) b{font-size:clamp(52px,6.4vw,92px); line-height:.9}
}

/* ===================================================================== V44 REFUSALS HIERARCHY (2026-09-04)
   The five refusals read as an even grey wall (Apple phone teardown: hierarchy + negative space). Lifted
   WITHOUT hiding any reason - the reader is dyslexic and collapsing text behind a tap would cost her the
   content, which the doctrine forbids. The "no" gesture and the headline become the scan-line, the reason
   clearly supports, and each item gets more air. Append-only; copy unchanged. */
.refuse li{grid-template-columns:40px minmax(0,1fr); gap:clamp(16px,2vw,24px); padding:clamp(26px,3.4vh,40px) 0; align-items:baseline}
.refuse__x{font-size:30px; line-height:1; font-weight:700; opacity:.9}
.refuse b{font-weight:800; margin-bottom:10px}
.refuse p{max-width:48ch}

/* ===================================================================== V45 THE RECOVERY (2026-09-04, Danish live notes)
   1 THE PHOTO TILES ARE BACK, IN COLOUR. The four market tiles (.market) were greyed under a purple-to-ink scrim
   on 9/3 ("batman"), then replaced by text-only rail cards on 9/2-9/4 ("images ripped"). Restored as landscape
   photo cards: colour always, a light bottom-only scrim for legibility, a big outcome word on the photo, and
   FULL-WIDTH PHOTO CARDS ON THE PHONE (the old phone rule collapsed them to 96px thumbnails - overridden).
   2 The offer heading aligns to its card (34px sibling drift measured), the card gets presence.
   3 The statement's supporting line is a sentence, not a tiny all-caps label.  4 Plate captions clearer.
   5 The hero listing card reads crisp: rows in the sans, captions legible, same serious tone.
   Append-only; later-in-source wins over V19/M05 at equal specificity, no !important. */
.markets{grid-template-columns:repeat(2,minmax(0,1fr)); gap:clamp(14px,1.8vw,24px)}
@media(min-width:1180px){.markets{grid-template-columns:repeat(4,minmax(0,1fr))}}
.market{min-height:clamp(300px,38vh,440px); aspect-ratio:4/5; text-decoration:none}
@media(min-width:1180px){.market{aspect-ratio:auto}}
.market__img{filter:none; transition:transform .8s var(--ease)}
.market:hover .market__img{filter:none; transform:scale(1.045)}
.market::after{background:linear-gradient(180deg, rgba(13,11,20,.06) 0%, rgba(13,11,20,.18) 38%, rgba(13,11,20,.66) 76%, rgba(13,11,20,.88) 100%)}
.market:hover::after{opacity:1}
.market__n{color:var(--accent-2,#B49CE1)}
.market__k{display:block; margin-top:8px; font:800 clamp(30px,2.8vw,44px)/1 var(--sans); letter-spacing:-.03em; color:var(--t100);
  text-shadow:0 2px 18px rgba(13,11,20,.55)}
.market__t{text-shadow:0 1px 12px rgba(13,11,20,.5)}
@media(max-width:640px){
  .markets{grid-template-columns:1fr; gap:14px}
  .market{display:flex; flex-direction:column; justify-content:flex-end; min-height:0; aspect-ratio:16/10; padding:18px;
    background:none; border:0; border-radius:var(--radius)}
  .market__img{position:absolute; inset:0; width:100%; height:100%; border-radius:0; z-index:-2; object-fit:cover}
  .market::after{display:block}
  .market__t{margin-top:auto}
  .market__k{font-size:26px; margin-top:6px}
}
/* 2 the offer: heading alignment + card presence */
@media(min-width:901px){ .offer__grid > div:first-child{padding-top:clamp(22px,3vw,34px)} }
.offer__how{border:1px solid rgba(240,237,245,.12); box-shadow:inset 0 2px 0 var(--accent), 0 22px 60px rgba(0,0,0,.30)}
/* 3 the statement's supporting line: a sentence a person can read */
.statement .after{font-family:var(--sans); font-size:clamp(17px,1.7vw,21px); line-height:1.5; letter-spacing:0;
  text-transform:none; color:var(--t70); max-width:38ch; margin-top:clamp(24px,3.6vh,44px)}
/* 4 plate captions: clearer, a step larger, still a chip */
.plate figcaption{font-size:13px; letter-spacing:.10em; color:rgba(240,237,245,.88); padding:11px 18px}
/* 5 the hero listing card: crisp, legible, serious */
.hero--lamp .svcart{background:rgba(13,11,20,.74); border-color:rgba(240,237,245,.18)}
.hero--lamp .svcart .cap{font-size:12px; letter-spacing:.12em; color:var(--t70); margin-bottom:14px}
.hero--lamp .gbpcard{gap:10px}
.hero--lamp .gbpcard .gbp-name{font-size:17px}
.hero--lamp .gbpcard .gbp-stars{font-size:13px}
.hero--lamp .gbpcard .gbp-row{font-family:var(--sans); font-size:14.5px; letter-spacing:0; color:var(--t70); padding-top:10px}
.hero--lamp .gbpcard .gbp-row b{font-weight:700}
.hero--lamp .verify__cap{font-size:14.5px; color:var(--t70)}
.hero--lamp .verify{box-shadow:0 22px 70px rgba(0,0,0,.5), inset 0 1px 0 rgba(240,237,245,.08)}

/* V45.1 the supporting line under the statement sits beneath the headline, not beside it (weight) */
.statement .after{font-weight:500}

/* ============================================================ V43 — 2026-09-06
   THE PILE WAS SCATTERING OFF THE PAGE, AND THE PILE WAS NOT A PILE.

   Danish, tonight: "this section seems wrongly cropped and I have seen similar
   instances on other pages too." He was right on both counts, and a new gate
   (gates/od-qa/collide.mjs) now measures the whole class rather than one report:
   it hit-tests every text element's real glyph boxes and reports text that is
   clipped by an ancestor or painted over by something above it.

   WHAT IT FOUND, measured on the live site at 393 / 820 / 1440:

   1. CLIPPED. `.n1` translated -186 user units at k=0. Its rect starts at x=14,
      so the pile state put it at x=-172 in a 0..720 viewBox. At 1440 the drawing
      starts 100px from the left edge and renders at 1.175 px/unit, so the node
      landed at CSS x=-102 and `body{overflow-x:hidden}` cut it away. "Stockport"
      and "the town" were sliced off the left of the screen on /the-method/ and
      /services/. The phone version of this exact bug was fixed on 2026-09-03
      (see M2); the desktop values were never bounded.

   2. COVERED. In the pile the cards overlap, and `.node rect{fill:none}` meant
      the card on top hid nothing: two labels sat on each other as mush. At 393
      the probe found "how often to" and "deep clean" with a third of their
      glyphs under another node's text.

   THE FIX IS ALSO THE BETTER DESIGN. Every offset below is computed so the
   node's ROTATED half-extent still lands inside the viewBox, and the pile is
   laid out so no card's label falls under another card. The cards also get a
   ground fill, so they read as objects on the dark plane instead of outlines,
   and so that any overlap that does occur reads as paper rather than as mush.
   ------------------------------------------------------------------------- */

/* cards occlude, like paper. This is what makes an overlapping pile legible. */
.silob .node rect{fill:#100E18;stroke:rgba(240,237,245,.30)}
.silob .node.svc rect{fill:#171426;stroke:rgba(240,237,245,.46)}
.silob.s3 .svc rect{stroke:var(--accent);fill:#1E1733}

/* desktop pile: viewBox 720x380, node 124x66, svc 264x80.
   Offsets are pile-centre minus settled-centre, in user units.
   Worst rotated half-extent for a node at 14deg is 68 x 47, so a centre inside
   x[76,644] y[55,325] cannot leave the frame. Every centre below is inside it. */
@media(min-width:901px){
  .n1 {transform:translate(calc(  52px*(1 - var(--k))),calc(-175px*(1 - var(--k)))) rotate(calc(-11deg*(1 - var(--k))))}
  .n2 {transform:translate(calc(  82px*(1 - var(--k))),calc(-187px*(1 - var(--k)))) rotate(calc(  9deg*(1 - var(--k))))}
  .n3 {transform:translate(calc( 110px*(1 - var(--k))),calc(-191px*(1 - var(--k)))) rotate(calc( 13deg*(1 - var(--k))))}
  .n4 {transform:translate(calc( 110px*(1 - var(--k))),calc(-115px*(1 - var(--k)))) rotate(calc( -7deg*(1 - var(--k))))}
  .n5 {transform:translate(calc(-494px*(1 - var(--k))),calc( -33px*(1 - var(--k)))) rotate(calc(  5deg*(1 - var(--k))))}
  .svc{transform:translate(calc( -24px*(1 - var(--k))),calc( 226px*(1 - var(--k)))) rotate(calc( -4deg*(1 - var(--k))))}
}

/* phone pile: viewBox 380x430, node 116x56, svc 240x76.
   Worst rotated half-extent 63 x 40, so a centre inside x[71,309] y[48,382] is
   safe. These replace the two earlier phone sets, which were bounded for the
   frame but still let two nodes land glyph-on-glyph. */
@media(max-width:900px){
  .n1 {transform:translate(calc(  43px*(1 - var(--k))),calc(-140px*(1 - var(--k)))) rotate(calc( -8deg*(1 - var(--k))))}
  .n2 {transform:translate(calc(  78px*(1 - var(--k))),calc(-122px*(1 - var(--k)))) rotate(calc(  9deg*(1 - var(--k))))}
  .n3 {transform:translate(calc(-208px*(1 - var(--k))),calc( -28px*(1 - var(--k)))) rotate(calc( 12deg*(1 - var(--k))))}
  .n4 {transform:translate(calc( 146px*(1 - var(--k))),calc( -90px*(1 - var(--k)))) rotate(calc( -6deg*(1 - var(--k))))}
  .n5 {transform:translate(calc(-134px*(1 - var(--k))),calc(   2px*(1 - var(--k)))) rotate(calc(  4deg*(1 - var(--k))))}
  .svc{transform:translate(calc(  50px*(1 - var(--k))),calc( 310px*(1 - var(--k)))) rotate(calc( -3deg*(1 - var(--k))))}
}

/* V43b — the big count and its caption shared 20 user units of baseline gap. At
   60px the comma's descender reaches ~13 below the baseline and the caption's
   cap-height reaches ~12 above its own, so on the phone they touched. Measured
   by the collide gate on /work/engine-at-scale/ at 393 and 820.

   Fixed in the GEOMETRY (y 424 -> 436 in work-scale.html), not with a CSS
   translate on the text. A CSS transform on an SVG <text> is not reflected in
   getScreenCTM(), so the probe kept reading the pre-transform position and the
   finding never cleared however far the caption was pushed. Moving the actual
   baseline makes the render and the measurement agree. */

/* V43e — A SCREENSHOT IS NOT A PHOTOGRAPH, AND .plate CROPS IT.
   The two real portal screenshots went into `.plate--tall`, which is a full-bleed
   photographic device: `object-fit:cover` at a fixed height. On a 1440x862 UI
   capture shown at 1670x814 that cropped the product's own header, nav and axis
   labels off, and the caption chip sat over the chart. Checked by looking at the
   rendered element, not by trusting the image-density number that had just gone up.

   A screenshot gets its own component: contained, whole, at its own aspect ratio,
   framed, with the caption underneath rather than on top of the interface. */
.shotfig{margin:0;position:relative;z-index:2;background:var(--ink);
  padding-block:clamp(30px,6vh,72px)}
.shotfig__in{max-width:1180px;margin-inline:auto;padding-inline:var(--gut)}
.shotfig img{
  display:block;width:100%;height:auto;border-radius:14px;
  border:1px solid rgba(240,237,245,.16);
  box-shadow:0 34px 90px -34px rgba(0,0,0,.8), 0 2px 0 rgba(240,237,245,.05) inset;
}
.shotfig--phone .shotfig__in{max-width:430px}
.shotfig--phone img{border-radius:26px}
.shotfig figcaption{
  margin-top:16px;font-family:var(--mono);font-size:var(--t-label);letter-spacing:.13em;
  text-transform:uppercase;color:var(--t70);
}
.shotfig figcaption b{color:var(--t100);font-weight:700}
/* the seam a plate gets, so a screenshot band also starts rather than fades in */
.shotfig::before{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,rgba(139,111,212,.55),rgba(139,111,212,.10) 52%,transparent 86%);
}
@media(max-width:640px){.shotfig--phone .shotfig__in{max-width:320px}}

/* ============================================================ V44 — 2026-09-06
   THE DRAWN MOCKS ARE GONE. Nineteen "Drawn ·" cards standing in for evidence
   (a drawn Google listing with numbers in the FIRST SCREEN, a drawn monthly
   report, a drawn technical pass, a drawn wireframe, a drawn card per case
   study) were removed by structure in one pass. Danish had ruled it on 8/23:
   the metaphor survives as motion, never as literal illustration; a real
   screenshot beats anything drawn. The four scrubbed explainers stay: they
   show method, they are not fake evidence.

   What the layout does without them, so nothing collapses oddly:            */
/* the hero split had a "verify" column; with the card gone the copy takes the
   panel, capped at a reading measure so the headline never runs to the edge */
@media(min-width:980px){
  .hero--lamp .herosplit{grid-template-columns:minmax(0,1fr); grid-template-areas:"copy" "actions"}
  .hero--lamp .hero__copy{max-width:min(680px, 62ch)}
}
/* a duo whose art was a drawn card becomes a single reading column, not a grid
   with an empty cell; the ink band and its rhythm are unchanged */
.duo--solo{grid-template-columns:minmax(0,1fr)}
.duo--solo > .stack--wide,.duo--solo > .duo__copy,.duo--solo > div:first-child{max-width:62ch}


/* ============================================================ V45 — 2026-09-06
   THE SYSTEM CHANGE UNDER THE CORE (ops/gates/OD_CORE.md), not a patch.

   Danish, tonight, on what he loathes: "that sharp cut black solid container in
   the grey" and "that dumb caption starting with 'drawn' like a trophy in
   minecraft fonts". And on what he loves: the sections where "you forget if you
   were on Apple's brochure". The core reads both the same way: quiet, physical,
   one idea per screen, nothing that announces itself.

   Three mechanisms produced the hated things, and each is REDEFINED here (value
   substitution on the existing components, so every page changes at once and
   nothing is layered on top):

   1. `.duo{background:var(--ink)}` painted a pure-ink rectangle with hard edges
      inside the grey `.plane--turn` planes. A duo is now an open plane: the
      section's own ground carries it, there is no inner box.
   2. `.plate figcaption` was a blurred, bordered, radiused chip in tracked mono
      uppercase. A caption is now one quiet sentence-case line of Satoshi on the
      plate's lower edge, with no box, and most plates carry none.
   3. `.label`, `.note`, `.artcap`, `.step__n` and the explainer notes were
      tracked mono uppercase: labels doing the work of trophies. They are now
      small sentence-case sans in the quiet tone; mono survives only where a
      figure names its source, and never in capitals.
   ------------------------------------------------------------------------- */

/* 1. no ink box inside a plane. The duo takes the plane it sits on. */
.duo,.plane--turn .duo,.plane--turn2 .duo{background:transparent}
.duo{padding-block:var(--beat-1)}
.duo figure{border-radius:6px}

/* 2. the caption is a quiet line, not a chip */
.plate figcaption,.plate figcaption b{
  font-family:var(--sans);font-size:14px;letter-spacing:0;text-transform:none;font-weight:500;
}
.plate figcaption{
  padding:0;border:0;border-radius:0;background:none;
  -webkit-backdrop-filter:none;backdrop-filter:none;
  color:rgba(240,237,245,.86);text-shadow:0 1px 22px rgba(13,11,20,.85),0 0 2px rgba(13,11,20,.9);
  max-width:min(44ch, calc(100% - var(--gut) * 2));
}
.plate figcaption b{color:#FFFFFF;font-weight:600}
.plate figcaption b::after{content:" "}

/* 3. eyebrows and notes stop being trophies */
.label,.label--accent{
  font-family:var(--sans);font-size:14px;letter-spacing:0;text-transform:none;font-weight:500;
  color:var(--t45);
}
.label--accent{color:#9778D8}
.plane--lit .label{color:#615B77}
.note,.artcap,.serpb__src,.silob__note,.refb__note,.cadb__note,.small.mono{
  font-family:var(--sans);font-size:13px;letter-spacing:0;text-transform:none;line-height:1.55;
  color:var(--t45);
}
.note b{font-weight:600;color:#9778D8}
.step__n{font-family:var(--sans);font-size:13px;letter-spacing:0;font-weight:600;color:var(--accent)}
.flag .stat span,.figures .cap,.stat__cap{font-family:var(--sans)}


/* V45b — the same decision, at the specificity the originals used.
   The mono-hunt (a DOM probe listing every text element whose computed family
   is Space Mono) found the labels that outranked the V45 redefinition:
   `.breaker figcaption p.label` (0,2,1), `figcaption.artcap`, `.foot h4`,
   `.shotfig figcaption`, and a family of tags and ghosts. One rule, each at or
   above the original's specificity, no !important except where the original
   already used it. Mono survives ONLY for: SVG text inside the scroll
   explainers, a URL, and a figure's source line in sentence case. */
.breaker figcaption p.label,.sheen__cap .label,.breaker--sheen .sheen__cap .label,
.bed .label,.bed--light .label,.numwall .label,.ledger-wall .label,.card .label,
figcaption.artcap,.duo__art figcaption,.shotfig figcaption,
.foot h3,.foot h4,.casehero__meta i,.ladder__head,.rung__was,.stat small,.sheen__stat,
.frame__tag,.portalb__open,.hinge p,.numwall small,.vfield .sub,.railcard .k,
.serp-toplab,.serp-foldlab,.lrow span .src,.market__tag,.market__n,.ledger__tag,
.fig__was,.statement .after,.crumb,.crumb a{
  font-family:var(--sans);letter-spacing:0;text-transform:none;
}
.foot h3,.foot h4,.ledger__tag,.market__tag,.frame__tag,.portalb__open,.railcard .k,.sheen__stat,
.rung__was,.fig__was,.stat small,.numwall small,.vfield .sub,.casehero__meta i,.ladder__head{
  font-size:13px;font-weight:500;
}
.foot h3,.foot h4{font-size:14px;font-weight:600;color:var(--t70)}
.crumb,.crumb a{font-size:13px}
.serpb__src{font-family:var(--sans) !important;letter-spacing:0 !important;text-transform:none !important;font-size:13px !important}
/* source lines stay mono, but as a quiet sentence, never capitals */
.fig__src,.step__proof,.frame__url,.ledger__num{text-transform:none;letter-spacing:0}


/* V45c — the caption comes OFF the photograph.
   The compositor gate measured the quiet caption at 1.0 to 1.6:1 on the bright
   parts of the plates, which is the exact reason the old chip existed. The core
   answer is not the chip back; it is that nothing is written ON a photograph
   that is meant to be looked at. A plate is now a printed figure: the picture,
   then one quiet line under it on the ink ground. The scroll explainers and the
   beds (one statement over a calm picture, with their own heavy scrim) are
   unchanged. */
.plate{display:flex;flex-direction:column}
.plate figcaption{
  position:static;margin:0;padding:12px var(--gut) 14px;max-width:none;
  color:var(--t45);text-shadow:none;font-size:13px;line-height:1.5;
}
.plate figcaption b{color:var(--t70);font-weight:600}
.plate--band{display:flex}

/* the ledger tags and arrows were one step short of AA on their ground (4.48
   and 3.98 at #242229); one step lighter clears it without changing the family */
.ledger__tag,.duo .label--accent,.label--accent{color:#A98DE3}
.ledger__go{color:#A98DE3}

/* the market tiles: photography with one line on it, which the core allows,
   but the V38 scrim let the type sit on the bright band of the picture at
   1.6:1. The ramp darkens before the copy begins (doctrine section 4.2). */
.market::after{background:linear-gradient(180deg, rgba(13,11,20,.10) 0%, rgba(13,11,20,.28) 34%, rgba(13,11,20,.80) 62%, rgba(13,11,20,.94) 100%)}
.market__n{color:#C9B7EE}
.market__tag{color:rgba(240,237,245,.84)}


/* V45d — two things V45c introduced, measured by the gate and fixed at source:
   1. the lighter accent label also fired on the LIGHT planes, where the original
      scoped it to the solid accent; on white it read 2.6:1. Re-scoped.
   2. .frame__tag kept the pale accent on the frame bar at 3.3:1. */
.plane--lit .label--accent,.plane--lit .duo .label--accent,.plane--lit .duo--solo .label--accent{color:var(--accent-solid)}
.frame__tag{color:#C9B7EE}


/* V45e — THE MARKETS ARE IN COLOUR. Danish, twice ("also said last night but
   forgotten"): the four market tiles under "Four markets. Different rivals every
   time." were greyscale at rest with colour only on hover. They are graded
   photographs of real places; they are shown in colour, at rest, always. The
   hover keeps its lift and scale only. */
.market__img{filter:none}
.market:hover .market__img{filter:none;transform:scale(1.04)}


/* ============================================================ V46 — 2026-09-06
   THE MARKETS ARE PRINTED FIGURES. The core (ops/gates/OD_CORE.md, "In"): a photograph
   is a thing you could touch, and real places are shown in colour, at rest. V45e put the
   colour back and the compositor gate then measured the copy on the photographs at
   1.4 to 2.9 : 1 (the sky over Vancouver, the pale grid of the valley). The V38 answer
   was a scrim, which is a filter on a photograph the core says to leave alone. So the
   composition changes instead of the scrim: the picture on top, whole and untouched, and
   the outcome, the place and the sentence under it on the ink ground, the same way every
   plate now carries its line beneath it. Nothing is written on the photograph.
   Value substitution at the specificity the V45 recovery used; later in source wins. */
.market{display:flex;flex-direction:column;justify-content:flex-start;min-height:0;aspect-ratio:auto;
  padding:0 0 22px;background:none;border:0;border-radius:6px;overflow:hidden;
  transition:transform .6s var(--ease)}
.market:hover{transform:translateY(-4px)}
.market__img{position:static;inset:auto;width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;
  display:block;border-radius:6px;z-index:auto;filter:none;transform:none}
.market:hover .market__img{transform:none}
.market::after{display:none}
.market__n{margin-top:18px;padding-inline:2px;color:#C9B7EE}
.market__k{margin-top:6px;padding-inline:2px;text-shadow:none;font-size:clamp(28px,2.4vw,38px)}
.market__t{margin-top:4px;padding-inline:2px;text-shadow:none}
.market__tag{padding-inline:2px;color:rgba(240,237,245,.84)}
.market__b{padding-inline:2px;color:rgba(240,237,245,.80)}
@media(max-width:640px){
  .market{display:flex;flex-direction:column;justify-content:flex-start;min-height:0;aspect-ratio:auto;padding:0 0 22px}
  .market__img{position:static;inset:auto;width:100%;height:auto;aspect-ratio:16/10;border-radius:6px;z-index:auto}
  .market::after{display:none}
  .market__t{margin-top:4px}
  .market__k{font-size:28px;margin-top:6px}
}
/* the one-step-short accent on a figure note (4.48 : 1 measured over the proof card) */
.note b{color:#A98DE3}


/* V46b — THE CAPTION IS CLEAR OF THE PICTURE. Measured in a real viewport at 393 and 820:
   the parallax scale(1.16) on the plate image paints 8% past its own box, and a transformed
   element paints after static content, so the scaled photograph was covering the quiet caption
   V45c placed beneath it (white type on the bright edge of white paper: the "invisible" figcaption
   findings). collide could not see it because the coverer precedes the text in document order.
   The picture element now clips the scale inside its own box; the caption sits after it on the ink
   ground and above anything the plate paints. No markup change: every plate carries a <picture>. */
.plate picture{display:block;position:relative;overflow:hidden;flex:none;line-height:0}
.plate figcaption{position:relative;z-index:2;background:var(--ink)}
.plate--band picture{display:block}

/* V46c — the chip rule at 1615 still carries left/right/bottom offsets; V45c neutralised them with
   position:static, V46b's position:relative turned them back into a relative shift (collide: every
   caption cut right by the gutter at 393). The offsets are cleared at the same specificity. */
.plate figcaption{inset:auto;left:auto;right:auto;top:auto;bottom:auto;width:auto;transform:none}


/* ============================================================ V48 — 2026-09-06, the panel's six
   Four personas read the rendered sheets (data/OD_V46_PANEL_2026-09-06.md) and ranked what still broke
   the core. Each is a value substitution on the existing component; nothing is layered on top.
   1 THE OFFER IS ONE PLANE. The right column was an ink card (bg, 18px radius, border, shadow, tracked
     caps title, hairline rows, mono lines, a full-width pill) inset in the paper plane: the exact object
     he described. The card is gone; the four steps sit on the paper in the page's own type beside the
     five things you get, separated by space.
   3 THE PROOF LINES SPEAK IN THE PAGE'S TYPE. Mono carried the claim on the site's strongest numbers;
     now the claim is Satoshi and the source is a small quiet line under it.
   8 LAMPLIGHT DARKENS. The primary button cast a violet bloom (rgb 29,17,53 on rgb 13,11,20 ground,
     lighter and more saturated than the ground = emission). The shadow is now a shadow. */
.offer__how{background:none;border:0;border-radius:0;box-shadow:none;padding:0}
@media(min-width:901px){ .offer__grid > div:first-child{padding-top:0} }
.offer__h,.offer__how .offer__h{font-family:var(--sans);font-size:18px;letter-spacing:0;text-transform:none;font-weight:600;color:var(--t100);margin:0 0 16px}
.hows{margin:0 0 16px}
.hows li{border-top:0;padding:7px 0;gap:14px}
.hows i{font-family:var(--sans);font-size:13px;font-weight:600;color:var(--accent-solid)}
.hows b{font-size:16.5px}
.hows span{font-family:var(--sans);font-size:14px;color:var(--t70);margin-top:1px}
.offer__note{font-size:14px;color:var(--t70);margin:0 0 20px;max-width:40ch}
.offer__how .btn{width:auto}
.step__proof{font-family:var(--sans);font-size:15.5px;line-height:1.55;color:var(--t70);
  background:none;border:0;border-left:0;border-radius:0;padding:0;margin:14px 0 0}
.step__proof b{font-weight:600;color:var(--t100)}
.step__proof small{display:block;font-size:13px;color:var(--t45);margin-top:4px}
.btn--solid{box-shadow:0 14px 34px -18px rgba(0,0,0,.70)}
.btn--solid:hover{box-shadow:0 22px 44px -18px rgba(0,0,0,.75)}

/* V48b — the card carried its own light token set (1037-1039) for its ink ground; on the paper plane
   the column now takes the lit plane's tokens (161-165), the same ones the left column reads by. */
.offer__how{--t100:#141120;--t70:#3D3753;--t45:#615B77;--line:rgba(20,17,32,.14);--accent:var(--accent-solid)}
.offer__how .offer__h{color:var(--t100)}


/* ============================================================ X1-A — 2026-09-06, the last screen
   Thirteen inner pages ended on the same object: a heading and two pills on flat ink, no image (the
   panel's item 7, Danish's "every section looks same" in the last screen every visitor sees). Each
   page now closes the way the homepage already does: one photograph from the library, a different one
   on every page and never one already on that page, carrying the page's own last statement, one line,
   one action and a quiet next-case line. Left-aligned and bottom-anchored (the panel: a case close is a
   paragraph of reading, and the whole page is left-aligned). Light closes use the calm plates with a
   fold or an edge; dark closes the crumples and the veined slate; light and dark alternate along the
   work index. Nothing announces itself: no eyebrow on the bed. The greys are re-picked for paper. */
.bed--close .wrap{padding-block:clamp(64px,11vh,140px) clamp(96px,18vh,200px)}
.bed--close h2{max-width:16ch}
.bed--close .actions{display:flex;justify-content:flex-start}
.bed--close .actions .btn{width:auto;min-width:0}
.bed--close .note{margin-top:18px;max-width:52ch}
.bed--close .note .tlink{display:block;margin-top:8px}
.bed--close.bed--light p,.bed--close.bed--light .lede{color:#33303F}
.bed--close.bed--light .note{color:#3A3540}
.bed--close.bed--light .tlink{color:#141120}
.bed--close:not(.bed--light) .note{color:rgba(244,241,250,.80)}
.bed--close:not(.bed--light) .tlink{color:#FFFFFF}

/* X1-A(b) — the phone pill: the 640px rule gives every .actions .btn flex:1 1 auto, which is what stretched
   the closing button to 89% of a 393 viewport (the panel's change 3). On the closing bed it keeps its own width. */
@media(max-width:640px){ .bed--close .actions .btn{flex:0 0 auto;justify-content:center} }


/* ============================================================ V49 — 2026-09-06, the send gesture
   STANDING_ORDERS 2026-09-03, round 5 of the mark: "D (the keeled dart) approved as a brand element,
   not a logo, use with restraint — the send gesture in CTAs." Never built until tonight. It replaces
   the plain arrow ONLY on the button that performs the site's one action, "Send me your site" — every
   other arrow (the .tlink next-case links, the .btn--line "Read it" case previews) stays the plain
   character, because the mark is the send gesture specifically, not a house arrow. Painted with
   currentColor via mask, so it inherits the button's own ink or paper colour with no second rule
   needed for .plane--lit or .bed--light. The lean-into-flight is the hover behaviour the mark was
   designed with (_logospec5.html candidate D). Shape unchanged: the pill stays the pill. */
.btn--solid .ar{
  width:15px;height:15px;display:inline-block;flex:none;font-size:0;line-height:0;color:transparent;
  background-color:currentColor;color:#fff;
  -webkit-mask:url("data:image/svg+xml,<svg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 100 100%27><polygon points=%2790,10 10,50 42,56%27/><polygon points=%2790,10 42,56 40,86%27 opacity=%27.62%27/><polygon points=%2742,56 40,86 30,64%27 opacity=%27.38%27/></svg>") center/contain no-repeat;
  mask:url("data:image/svg+xml,<svg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 100 100%27><polygon points=%2790,10 10,50 42,56%27/><polygon points=%2790,10 42,56 40,86%27 opacity=%27.62%27/><polygon points=%2742,56 40,86 30,64%27 opacity=%27.38%27/></svg>") center/contain no-repeat;
  transition:transform .35s var(--ease);
}
.btn--solid:hover .ar{transform:translate(3px,-2px) rotate(6deg)}
@media (prefers-reduced-motion: reduce){ .btn--solid:hover .ar{transform:none} }

/* ---------------------------------------------------------------- X1 LEDGER ON PAPER (1.90.0)
   A record that belongs to somebody else (a hospital's own price list, the year's verdicts) sits on
   paper, in the ledger-wall register. The source line under it inherits the ink-plane colour and
   vanished on paper; give it the paper's own muted ink. */
.ledger-wall .fig__src{color:#615B77}
.x1-ledger .lrows{margin-top:clamp(20px,3vh,32px)}

/* ------------------------------------------------------------ THE METHOD'S ORDER, READ (1.90.0)
   The four steps kept the two-column grid that held the drawings after the drawings were cut: a
   34ch strip of prose beside 360px of nothing, and the heading sitting on the first rule. Danish:
   "what happened here". The order is a reading, one column at the reading measure; the heading
   gets its beat above the first rule. */
.method-steps{max-width:var(--read);margin-top:clamp(18px,2.6vh,30px)}
.method-steps .step p{max-width:none}
.method-steps .step .lede{max-width:none}
@media (min-width:900px){
  .method-steps .step{grid-template-columns:1fr;max-width:none}
}

/* X1 exemplar panel (2026-09-07): the price rows and the record rows are <div>s, not links, so they
   take no hover; the price column stops drifting away from its line at 1440; the record variant
   stacks verb / clause / verdict on the phone instead of baseline-aligning a verdict to line one. */
.x1-ledger .lrows{max-width:920px}
.x1-ledger .lrow:hover{background:none}
.x1-ledger .lrow:hover b{text-decoration:none}
.x1-record .lrow{grid-template-columns:170px minmax(0,1fr) 180px}
.x1-record .lrow span{color:#3D3753}
@media(max-width:640px){
  .x1-record .lrow{grid-template-columns:1fr;gap:4px}
  .x1-record .lrow i{order:1;grid-column:auto}
  .x1-record .lrow b{order:2}
  .x1-record .lrow span{order:3;text-align:left;white-space:normal}
}

/* ------------------------------------------------------------- X1 PROPER, THE SEVEN (1.92.0)
   Composition per story. A numeral wall on a case page keeps the homepage's register (its source
   line in the page's own mono); a paired before/after for the one story that is a correction; a
   drawn flow for the one story that is a machine; the product capture that fits the screen it is
   on. No new colour, type or photograph. */
.x1-numwall{padding-block:clamp(56px,8vh,96px)}
.x1-numwall small{font-family:var(--mono);letter-spacing:0;text-transform:none}
@media(min-width:820px){.x1-numwall--pair .numwall__grid--hero .fig--hero{grid-column:1 / -1}}
.x1-pair__grid{margin-top:clamp(22px,3vh,36px)}
.x1-pair__heads{display:none}
.x1-pair__row{display:grid;gap:8px 0;padding:16px 0;border-top:1px solid var(--line)}
.x1-pair__row:last-child{border-bottom:1px solid var(--line)}
.x1-pair__row p{margin:0;font-size:var(--t-body);line-height:1.5;max-width:34em}
.x1-pair__had{color:var(--t45)}
.x1-pair__now{color:var(--t100)}
.x1-pair__had::before,.x1-pair__now::before{display:block;font-size:13px;font-weight:600;letter-spacing:0;margin-bottom:3px}
.x1-pair__had::before{content:"Google had";color:var(--t45)}
.x1-pair__now::before{content:"It is";color:#9778D8}
@media(min-width:820px){
  .x1-pair__heads{display:grid;grid-template-columns:1fr 1fr;gap:0 clamp(28px,4vw,64px);padding-bottom:12px}
  .x1-pair__row{grid-template-columns:1fr 1fr;gap:0 clamp(28px,4vw,64px);padding:18px 0;align-items:start}
  .x1-pair__had::before,.x1-pair__now::before{display:none}
}
.x1-sys__flow{list-style:none;margin:clamp(24px,3vh,40px) 0 0;padding:0;display:grid;gap:0;position:relative}
.x1-sys__flow li{position:relative;display:grid;grid-template-columns:44px 1fr;gap:6px 18px;padding:22px 0 26px 0;border-top:1px solid var(--line)}
.x1-sys__flow li:last-child{border-bottom:1px solid var(--line)}
.x1-sys__flow i{font-style:normal;font-family:var(--sans);font-size:13px;font-weight:600;color:var(--accent);grid-row:1 / span 2;padding-top:5px}
.x1-sys__flow b{font-size:var(--t-h3);font-weight:700;letter-spacing:var(--track);color:var(--t100);line-height:1.25}
.x1-sys__flow span{font-size:var(--t-small);color:var(--t70);max-width:48ch;line-height:1.5}
.x1-sys__flow li::after{content:"";position:absolute;left:14px;bottom:-1px;width:1px;height:14px;background:var(--accent);opacity:.7}
.x1-sys__flow li:last-child::after{display:none}
@media(min-width:900px){
  .x1-sys__flow{grid-template-columns:repeat(5,1fr);grid-template-rows:auto auto 1fr;gap:0 clamp(18px,2vw,34px);border-top:1px solid var(--line)}
  .x1-sys__flow li{display:grid;grid-template-columns:1fr;grid-template-rows:subgrid;grid-row:1 / span 3;border:0;padding:22px 0 0}
  .x1-sys__flow i{grid-row:auto;padding-top:0;margin-bottom:12px}
  .x1-sys__flow b{margin-bottom:10px;display:block}
  .x1-sys__flow li::after{display:none}
  .x1-sys__flow li:last-child{border-bottom:0}
}
.x1-shot--phone{display:none}
@media(max-width:640px){.x1-shot--desk{display:none}.x1-shot--phone{display:block}}

/* ------------------------------------------------------------- THE NAV MARK, 46px (1.94.0)
   Doctrine's "nav mark slightly bigger". The geometry is untouched; four crease re-cuts were rejected
   at true 16px and the crease loop is closed (data/OD_ASCENT_R6_PANEL_2026-09-07.md). */
.nav__mark svg{width:46px}

/* ------------------------------------------------------------- THE EVIDENCE FRAME (1.95.0)
   The captures of Search Console, Ahrefs and Google's AI answer sat inside a drawn browser: three
   traffic-light dots and a URL bar. The Core: real captures framed like printed evidence, not like
   UI. The drawn chrome goes; what stays is a caption strip naming the instrument and the window, in
   the page's own mono, sentence case, and the capture itself. */
.frame__bar i{display:none}
.frame__bar{padding:10px 14px;border-bottom:1px solid rgba(240,237,245,.08)}
.frame__url{font-size:12px;letter-spacing:0;color:var(--t70)}
.frame__tag{letter-spacing:0;text-transform:none;font-size:12px}
.frame__url{background:none;padding:0;border:0;border-radius:0;overflow:visible;white-space:normal;text-overflow:clip;flex:1 1 auto;line-height:1.45}
.frame__tag{background:none;border:0;padding:0;color:var(--t45)}

/* ============================================================================
   2026-09-08 · THE CINEMATIC PAGE HEAD
   Danish: "add cinematic full hd images to the heros of OD inner pages ... no
   one has listened to me about this yet." The six inner sheets opened on type
   alone. Now each opens on one full-bleed photograph, graded into the house
   night, with the headline low in the frame the way a film title sits. One
   photograph, one line, one sub. Nothing else on the screen.
   The reference he sent: a cloud of lit paper cranes in a dark gallery.
   ============================================================================ */
.pagehead--cine{
  position:relative;isolation:isolate;overflow:hidden;
  min-height:clamp(560px, 84svh, 920px);
  display:flex;flex-direction:column;justify-content:flex-end;
  padding-top:calc(var(--beat-3) + 60px);padding-bottom:var(--beat-2);
}
main > .plane.pagehead--cine:first-child{padding-top:calc(var(--beat-3) + 60px)}
.cinefield{position:absolute;inset:0;z-index:0;pointer-events:none;background:var(--ink)}
.cinefield picture{position:absolute;inset:0;display:block}
.cinefield img{
  position:absolute;inset:0;width:100%;height:100%;display:block;
  object-fit:cover;object-position:var(--px,50%) var(--py,50%);
  filter:saturate(.92) contrast(1.05);
  transform:scale(1.02);will-change:transform;
}
/* the scrim is the photograph's own dark, deepened where the words sit: a
   vertical ramp that leaves the upper two thirds open and closes over the
   bottom, and a left ramp under the measure. No panel, no card, no edge.
   This is atmosphere, not the contrast guarantee -- see the text-shadow
   note below for why the words stay legible regardless of what is under
   them, on any of the six photographs, at any width. */
.cinefield::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(180deg, rgba(13,11,20,.55) 0%, rgba(13,11,20,.10) 26%, rgba(13,11,20,.30) 58%,
                            rgba(13,11,20,.82) 84%, var(--ink) 100%),
    linear-gradient(90deg, rgba(13,11,20,.60) 0%, rgba(13,11,20,.28) 38%, rgba(13,11,20,0) 66%);
}
.pagehead--cine .wrap{position:relative;z-index:2}
/* 2026-09-08, the decisive fix, replacing three rounds of chasing the gradient stops
   per photo per breakpoint (six photographs, unlimited widths -- that never converges).
   A soft dark glow behind the glyphs reads correctly against ANY pixel underneath, the
   way a film title card does over any frame of the picture. This is the technique the
   skill's own text-over-photography section names as the right fix when colour alone
   cannot save it: reshape what sits behind the words, once, structurally. */
.pagehead--cine .label--accent,.pagehead--cine h1,.pagehead--cine .lede{
  text-shadow:0 2px 20px rgba(13,11,20,.85),0 1px 3px rgba(13,11,20,.9);
}
.pagehead--cine h1{color:var(--paper);max-width:15ch}
.pagehead--cine .lede{color:#D9D4E4;max-width:52ch}
.pagehead--cine .label--accent{color:var(--paper)}
/* arrival: the photograph settles from a slow push-in once it has decoded. With no JS the
   resting state is the finished state, so the picture can never be hidden. */
html.js .pagehead--cine:not(.is-in) .cinefield img{transform:scale(1.07);opacity:0}
.pagehead--cine.is-in .cinefield img{transition:transform 2.2s var(--ease),opacity 1.1s ease}
/* the breadcrumb is emitted before <main>. On a cinematic sheet it sits on the
   photograph, top-left, instead of holding a band of nothing above it. */
.crumb:has(+ main > .pagehead--cine){
  position:relative;z-index:5;padding-top:20px;line-height:18px;margin-bottom:-38px;
}
.crumb:has(+ main > .pagehead--cine) a,.crumb:has(+ main > .pagehead--cine) .csep{color:rgba(240,237,245,.74)}
.crumb:has(+ main > .pagehead--cine) [aria-current]{color:var(--paper)}
@media(max-width:640px){
  .pagehead--cine{min-height:clamp(560px, 88svh, 800px);padding-top:calc(var(--beat-2) + 48px)}
  /* one clean deepen for the taller phone frame; the text-shadow above is what actually
     guarantees legibility now, so this stays simple atmosphere, not a per-photo chase. */
  .cinefield::after{
    background:
      linear-gradient(180deg, rgba(13,11,20,.70) 0%, rgba(13,11,20,.20) 20%, rgba(13,11,20,.40) 52%,
                              rgba(13,11,20,.88) 82%, var(--ink) 100%);
  }
}
@media (prefers-reduced-motion:reduce){
  html.js .pagehead--cine:not(.is-in) .cinefield img{transform:scale(1.02);opacity:1}
}

/* ============================================================================
   2.0 THE OPEN INVITATION
   The hero's action is now completed in the hero. The form is a sheet resting
   on the photographed folds, with a clipped turned corner and ink fields. It
   keeps the one-person promise visible at the moment the visitor writes.
   ============================================================================ */
.hero--lamp .heroform{
  box-sizing:border-box;position:relative;z-index:3;width:100%;max-width:390px;
  color:#141120;background-color:#ECE6F0;
  background-image:
    linear-gradient(112deg,rgba(255,255,255,.36),rgba(255,255,255,0) 42%),
    repeating-linear-gradient(0deg,rgba(20,17,32,.015) 0 1px,transparent 1px 4px);
  padding:clamp(24px,2.2vw,30px) clamp(22px,2.4vw,30px) 23px;
  box-shadow:0 38px 92px -22px rgba(0,0,0,.78),0 1px 0 rgba(255,255,255,.52) inset;
  transform:rotate(-1deg);transform-origin:50% 100%;
  clip-path:polygon(0 0,94% 0,100% 7%,100% 100%,0 100%);
}
.hero--lamp .heroform::before{
  content:"";position:absolute;right:0;top:0;width:25px;height:25px;
  background:linear-gradient(225deg,rgba(13,11,20,.16) 0 48%,#D4CCDF 50%);
  box-shadow:-5px 5px 14px rgba(13,11,20,.12);
}
.heroform__head{margin-bottom:17px;padding-bottom:15px;border-bottom:1px solid rgba(20,17,32,.16)}
.heroform__head span{display:block;font:650 13px/1.2 var(--sans);color:#6735C3;margin-bottom:7px}
.heroform__head strong{display:block;color:#141120;font:850 clamp(23px,2vw,27px)/1.06 var(--sans);letter-spacing:-.026em}
.heroform__field{display:block;margin-top:12px}
.heroform__field > span{display:block;font:650 12.5px/1.2 var(--sans);color:#514A62;margin-bottom:5px}
.heroform__field input{
  box-sizing:border-box;width:100%;height:47px;border:0;border-bottom:1px solid rgba(20,17,32,.24);
  border-radius:0;background:rgba(255,255,255,.42);padding:10px 11px;
  font:500 15.5px/1.2 var(--sans);color:#141120;outline:0;
  transition:border-color .2s ease,background-color .2s ease,box-shadow .2s ease;
}
.heroform__field input::placeholder{color:#746D80;opacity:1}
.heroform__field input:focus-visible{
  border-bottom-color:#6735C3;background:#FFFFFF;box-shadow:0 3px 0 -1px #6735C3;
}
.heroform .btn{width:100%;min-height:52px;margin-top:19px;justify-content:center;border:0}
.heroform > small{display:block;margin-top:11px;color:#514A62;font:500 12px/1.45 var(--sans);text-align:center}
.heroform--sent p{color:#3D3753;font-size:17px;line-height:1.5;max-width:28ch}

@media(min-width:980px){
  .hero--lamp .herosplit{
    grid-template-columns:minmax(0,1.12fr) minmax(340px,.72fr);
    grid-template-areas:"copy form" "actions form";
    column-gap:clamp(48px,5.2vw,82px);row-gap:clamp(22px,3vh,32px);
  }
  .hero--lamp .hero__copy{grid-area:copy;max-width:650px}
  .hero--lamp .hero__actions{grid-area:actions}
  .hero--lamp .heroform{grid-area:form;justify-self:end;align-self:center}
  .hero--lamp .mega{font-size:clamp(46px,min(5.4vw,8.8svh),78px)}
}

@media(max-width:979px){
  .hero--screen.hero--lamp{
    display:grid;grid-template-columns:100%;gap:0;min-height:0;
    padding-block:clamp(52px,7svh,80px) clamp(30px,5svh,54px);
  }
  .hero--screen.hero--lamp > .wrap.herosplit{display:contents}
  .hero--lamp .hero__copy{order:1;padding-inline:var(--gut)}
  .hero--lamp .herofield{
    order:2;position:relative;inset:auto;height:clamp(215px,31svh,286px);
    margin-top:clamp(20px,3svh,30px);--ox:62%;--oy:44%;--lx:60vw;--ly:40%;
  }
  .hero--lamp .herofield img{
    position:absolute;left:0;right:auto;top:-36%;width:100%;height:136%;min-height:0;
    object-position:var(--px,60%) 50%;transform:translate3d(0,calc(var(--par,0) * 26px),0) scale(1.06);
  }
  .hero--lamp .herofield::after{
    background:linear-gradient(180deg,var(--ink) 0%,rgba(13,11,20,.56) 10%,rgba(13,11,20,0) 28%,rgba(13,11,20,0) 82%,var(--ink) 100%);
  }
  .hero__lamp{width:120vw}
  .hero--lamp .heroform{
    order:3;margin:clamp(-82px,-9svh,-62px) var(--gut) 0;width:auto;max-width:none;
    justify-self:stretch;padding:24px 22px 21px;transform:rotate(-.35deg);
  }
  .hero--lamp .hero__actions{order:4;padding-inline:var(--gut);margin-top:20px}
  .hero--lamp .hero__actions .btn{min-width:0}
}

@media(min-width:720px) and (max-width:979px){
  .hero--lamp .heroform{display:grid;grid-template-columns:1fr 1fr;column-gap:18px}
  .heroform__head,.heroform__field:last-of-type,.heroform .btn,.heroform > small{grid-column:1 / -1}
}
.hero--lamp .heroform--sent{display:block}
.hero--lamp .heroform[hidden]{display:none !important}

@media(max-width:420px){
  .hero--lamp .heroform{margin-inline:16px}
  .heroform__head strong{font-size:23px}
}

/* ============================================================================
   2.1 THE DIRECTOR'S CUT
   The homepage now carries one scroll explainer. Search keeps the movement;
   the portal becomes one composed product reveal made only from real screens.
   Decorative interludes and repeated trust sections were removed in markup.
   ============================================================================ */
main{overflow:clip}
.home .statement{padding-block:clamp(82px,12vw,170px)}

.portalb.magic-static{padding-block:clamp(80px,10vw,148px);overflow:hidden}
.portalb.magic-static .portalb__head{
  grid-template-columns:minmax(0,.9fr) minmax(360px,1.1fr);
  align-items:end;gap:clamp(44px,7vw,100px)
}
.portalb.magic-static .portalb__lines{display:none}
.portalb.magic-static .portalb__grid{
  min-height:0;height:auto;margin-top:clamp(50px,7vw,96px);
  grid-template-columns:minmax(300px,.8fr) minmax(0,1.2fr);
  gap:clamp(48px,8vw,120px);align-items:center
}
.portalb.magic-static .portalb__pin{
  position:relative;top:auto;height:auto;min-height:680px;display:block
}
.portalb.magic-static .phoneb{
  position:absolute;left:8%;top:4%;width:min(310px,70%);
  transform:rotate(-4deg);box-shadow:0 46px 100px rgba(0,0,0,.55)
}
.portalb.magic-static .phoneb::before,.portalb.magic-static .phoneb::after{display:none}
.portalb.magic-static .phoneb.magic-phone2{left:25%;top:10%;transform:rotate(4deg);z-index:2;opacity:.92}
.portalb.magic-static .phoneb.magic-phone3{left:43%;top:20%;transform:rotate(10deg);z-index:1;opacity:.78}
.portalb.magic-static .phoneb:not(.magic-phone2):not(.magic-phone3){z-index:3}
.portalb.magic-static .portalb__steps{display:grid;gap:0;height:auto;max-width:none}
.portalb.magic-static .portalb__step{
  min-height:0;padding:clamp(25px,3vw,38px) 0;margin:0;
  border-top:1px solid rgba(240,237,245,.15)
}
.portalb.magic-static .portalb__step:last-child{border-bottom:1px solid rgba(240,237,245,.15)}
.portalb.magic-static .portalb__step p{max-width:56ch}
.portalb.magic-static .portalb__cta{margin-top:22px}

.magic-trust{padding-block:clamp(72px,10vw,144px)}
.magic-trust .wrap{max-width:1240px}
.magic-trust .magic-trust__head{
  display:grid;grid-template-columns:minmax(0,.75fr) minmax(0,1.25fr);
  gap:clamp(36px,6vw,100px);align-items:end;margin-bottom:clamp(44px,6vw,84px)
}
.magic-trust .magic-trust__head h2{margin:0;max-width:13ch}
.magic-trust .magic-qa{
  display:grid;grid-template-columns:repeat(3,1fr);gap:1px;
  background:rgba(20,17,32,.14);border:1px solid rgba(20,17,32,.14);
  margin-bottom:clamp(52px,7vw,92px)
}
.magic-trust .magic-qa .qa{background:#ece6f0;padding:clamp(24px,3vw,38px)}
.magic-trust .refuse{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:0 clamp(40px,7vw,96px);max-width:none
}
.magic-trust .refuse li{padding-block:24px;border-top:1px solid rgba(20,17,32,.14)}
.magic-trust .refuse li:last-child{border-bottom:1px solid rgba(20,17,32,.14)}

@media(min-width:901px){
  .home .serpb__step{min-height:64svh}
  .home .serpb__steps{padding-bottom:24svh}
}

@media(max-width:800px){
  .magic-trust .magic-trust__head{grid-template-columns:1fr;gap:14px}
  .magic-trust .magic-qa,.magic-trust .refuse{grid-template-columns:1fr}
  .magic-trust .magic-qa .qa{padding:25px 22px}
  .portalb.magic-static .portalb__head{grid-template-columns:1fr}
  .portalb.magic-static .portalb__grid{grid-template-columns:1fr;gap:42px}
  .portalb.magic-static .portalb__pin{min-height:515px}
  .portalb.magic-static .phoneb{left:2%;width:59%;max-width:254px}
  .portalb.magic-static .phoneb.magic-phone2{left:19%;top:7%}
  .portalb.magic-static .phoneb.magic-phone3{left:36%;top:15%}
  .portalb.magic-static .portalb__step{padding:26px 0}

  .home .rail{overflow:hidden}
  .home .markets{
    display:flex;gap:18px;overflow-x:auto;overscroll-behavior-inline:contain;
    scroll-snap-type:x mandatory;scrollbar-width:none;
    margin-right:calc(var(--gut) * -1);padding-right:var(--gut);padding-bottom:12px
  }
  .home .markets::-webkit-scrollbar{display:none}
  .home .market{flex:0 0 min(82vw,330px);scroll-snap-align:start}
}
