/* PY: the landing page's own styles, shared by / and /pt/. Interior pages use
   styles.css instead; the rules the two have in common (nav, buttons, footer, hero
   entrance) are repeated in both. Keep them in step. */
@font-face{font-family:"Satoshi";font-weight:400;font-display:swap;src:url("/assets/fonts/satoshi-400.woff2") format("woff2")}
@font-face{font-family:"Satoshi";font-weight:500;font-display:swap;src:url("/assets/fonts/satoshi-500.woff2") format("woff2")}
@font-face{font-family:"Fragment Mono";font-weight:400;font-display:swap;src:url("/assets/fonts/fragment-mono-latin.woff2") format("woff2")}

:root{
  --bg:#08090A;--surface:#0E0F12;
  --border:rgba(255,255,255,0.08);--border-2:rgba(255,255,255,0.14);
  --text:#F5F6F7;--dim:#8A8F98;--mute:#757A82;--amber:#E3A72C;
  --sans:"Satoshi",-apple-system,"Segoe UI",system-ui,sans-serif;
  --mono:"Fragment Mono","SFMono-Regular",Menlo,monospace;
  --maxw:1120px;--ease:cubic-bezier(.16,1,.3,1)}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{background:var(--bg);color:var(--dim);font-family:var(--sans);font-size:1rem;line-height:1.6;font-weight:400;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;overflow-x:hidden}
/* A large monitor should get the same page at its own scale, not the same page
   stranded small in a corner. Every size here is capped in rem, so moving the root
   grows type, spacing and drawings together; the column widens with it. The biggest
   step also asks for height: a pinned panel gets one screen and cannot scroll inside
   itself, and on a wide but short window 20px leaves the boards only 20px of air. */
@media(min-width:1700px){:root{--maxw:1240px}html{font-size:18px}}
@media(min-width:2200px){:root{--maxw:1400px}}
@media(min-width:2200px) and (min-height:900px){html{font-size:20px}}
a{color:inherit;text-decoration:none}
img,svg{display:block;max-width:100%}
::selection{background:var(--amber);color:#0a0a0a}
:focus-visible{outline:2px solid var(--amber);outline-offset:3px;border-radius:2px}

.skip-link{position:absolute;left:-9999px;top:0;z-index:100;background:var(--amber);color:#0a0a0a;
  font-family:var(--mono);font-size:.8rem;padding:.7rem 1rem;border-radius:0 0 4px 0}
.skip-link:focus{left:0}

/* scroll progress rail */
.progress{position:fixed;top:0;left:0;right:0;height:2px;background:var(--amber);
  transform:scaleX(0);transform-origin:0 50%;z-index:70;pointer-events:none}
@supports (animation-timeline: scroll()){
  .progress{animation:prog linear both;animation-timeline:scroll(root block)}
}
@keyframes prog{to{transform:scaleX(1)}}
/* phones: the scroll-timeline bar remaps when Safari's URL bar resizes the viewport,
   and the fixed mix-blend grain is a scroll-repaint cost. Drop both. */
@media(max-width:900px){.progress{display:none}.grain{display:none}}

/* nav */
.nav{position:sticky;top:0;z-index:50;background:rgba(8,9,10,0.7);
  backdrop-filter:blur(12px) saturate(1.4);-webkit-backdrop-filter:blur(12px) saturate(1.4);border-bottom:1px solid var(--border)}
.nav-in{max-width:var(--maxw);margin-inline:auto;height:60px;padding-inline:clamp(1.1rem,4vw,2rem);
  display:flex;align-items:center;justify-content:space-between}
.brand{display:inline-flex;align-items:center}.brand img{width:30px;height:23px}
.nav-links{display:flex;align-items:center;gap:clamp(1rem,3vw,2rem)}
.nav-links a{font-size:.92rem;font-weight:400;color:var(--dim);transition:color .18s}
.nav-links a:hover{color:var(--text)}

/* the other language: quiet, set in the mono like the page's other labels */
.nav-links a.lang-switch{font-family:var(--mono);font-size:.74rem;letter-spacing:.12em;color:var(--mute)}
.nav-links a.lang-switch:hover{color:var(--text)}
.btn{display:inline-flex;align-items:center;gap:.4em;font-family:var(--sans);font-size:.92rem;
  font-weight:500;line-height:1;border-radius:3px;cursor:pointer;
  transition:transform .18s var(--ease),background .18s,border-color .18s,color .18s}
.btn-primary{background:var(--amber);color:#0a0a0a;padding:.6rem 1rem;border:1px solid var(--amber)}
.btn-primary:hover{background:#f0b53c;transform:translateY(-1px)}
.btn-ghost{background:rgba(255,255,255,0.02);color:var(--text);padding:.58rem 1rem;border:1px solid var(--border-2)}
.btn-ghost:hover{background:rgba(255,255,255,0.06);transform:translateY(-1px)}
.btn-amber,.nav-links a.btn-amber{background:transparent;color:var(--amber);padding:.6rem 1rem;border:1px solid var(--amber)}
.btn-amber:hover,.nav-links a.btn-amber:hover{background:var(--amber);color:#0a0a0a;transform:translateY(-1px)}

.wrap{position:relative;z-index:1;max-width:var(--maxw);margin-inline:auto;padding-inline:clamp(1.1rem,4vw,2rem)}

/* scroll deck: panels cross-fade one at a time (JS adds .live) */
.panel{position:relative;padding-block:clamp(3rem,7vw,5rem)}
#pnl-hero{padding-block:0}
.deck.live{height:1208vh}
.deck.live .deck-pin{position:sticky;top:0;height:100svh;overflow:hidden}
.deck.live .panel{position:absolute;inset:0;padding:64px 0 20px;display:flex;flex-direction:column;
  justify-content:center;opacity:0;pointer-events:none;will-change:opacity,transform}
.deck.live #pnl-hero{padding:0}
/* the two arms sit higher than dead centre: the block is tall, and centring it
   leaves the cards' footers grazing the bottom edge of the pin. The lift is only
   as much as the spare height allows, or on a short window it drives the eyebrow
   up under the nav. Padding of 20 + 2L lifts the centred block by L. */
.deck.live #pnl-arms{padding-bottom:clamp(20px,calc((100svh - 700px) * .55),100px)}
.deck.live .panel.on{pointer-events:auto}
.deck.live .panel>.wrap{width:100%}
.deck.live #pnl-hero .hero{height:100%;min-height:0}
.deck.live .reveal{opacity:1!important;transform:none!important;animation:none!important}

/* hero: left aligned, fills the first screen */
.hero{text-align:left;display:flex;flex-direction:column;justify-content:center;
  min-height:calc(100vh - 60px);min-height:calc(100svh - 60px);
  padding-top:clamp(3.5rem,13vh,8rem);padding-bottom:clamp(1.5rem,4vw,2.5rem)}
h1{font-family:var(--sans);font-weight:500;color:var(--dim);
  font-size:clamp(2.2rem,5.2vw,4rem);line-height:1.06;letter-spacing:-.02em;max-width:18ch}
h1 em{font-style:normal;color:var(--text)}
/* every heading lands on an amber full stop. Listed under h1 em too, which would
   otherwise outrank a bare `h1 .dot` and paint the period white again. */
h1 .dot,h2 .dot,h3 .dot,h1 em .dot{color:var(--amber)}
h1 em .ul{text-decoration:underline;text-decoration-color:var(--amber);text-decoration-thickness:.055em;text-underline-offset:.18em;text-decoration-skip-ink:none}
.sub{font-size:clamp(1.05rem,1.55vw,1.24rem);color:var(--dim);line-height:1.55;
  max-width:38rem;margin-top:clamp(1.4rem,3vw,1.8rem);font-weight:400}
.cta{display:flex;gap:.8rem;justify-content:flex-start;flex-wrap:wrap;margin-top:clamp(1.8rem,4vw,2.4rem)}
.cta .btn{font-size:.98rem;padding:.82rem 1.4rem}
.sig-text .cta{margin-top:1.9rem}

/* statement: typed by scroll inside the deck, static in normal flow */
.statement{padding-block:clamp(2.5rem,6vw,4.5rem)}
.statement p{font-family:var(--sans);font-weight:500;font-size:clamp(1.55rem,3.5vw,2.6rem);
  line-height:1.24;letter-spacing:-.02em;color:var(--dim);max-width:26ch}
.statement b{font-weight:500;color:var(--text)}
.statement.center{text-align:center}.statement.center p{margin-inline:auto}
.statement .w{white-space:nowrap}
.statement .c{opacity:0;color:var(--dim)}
.statement .c.hl{color:var(--text)}
.statement .c.dot{color:var(--amber)}   /* the full stop the phrase lands on */
.statement .c.caret{position:relative}
.statement .c.caret::after{content:"";position:absolute;right:-.06em;top:.08em;bottom:.08em;width:2px;
  background:var(--amber);animation:caretblink 1.05s steps(1) infinite}
@keyframes caretblink{50%{opacity:0}}

/* hero load entrance */
/* The hero's entrance. styles.css carries the same rule for the other pages. Keep the two in step. */
.h-anim{opacity:0;animation:heroIn .9s var(--ease) forwards}
h1.h-anim{animation-delay:.04s}.sub.h-anim{animation-delay:.14s}.cta.h-anim{animation-delay:.24s}
@keyframes heroIn{from{opacity:0;transform:translateY(22px)}to{opacity:1;transform:none}}
.hero-copy{will-change:transform,opacity}

/* section shell */
.sec-head{max-width:36rem}.sec-head.center{margin-inline:auto;text-align:center}
.eyebrow{font-family:var(--mono);font-size:.74rem;letter-spacing:.16em;text-transform:uppercase;color:var(--amber);margin-bottom:1rem}
h2{font-family:var(--sans);font-weight:500;color:var(--text);font-size:clamp(1.8rem,3.8vw,2.7rem);
  letter-spacing:-.018em;line-height:1.1}
.lead{color:var(--dim);margin-top:.95rem;font-size:1.06rem;line-height:1.55}

/* two arms: figure columns */
/* The pair sits in a block of its own, narrower than the page and centred in it, rather than
   stretching to both margins. The heading above shares the block's left edge, so the two read
   as one composition instead of a title at the page edge above a pair of far-flung columns. */
#pnl-arms .wrap{max-width:56rem}
.arms{margin-top:clamp(1.5rem,3vw,2.2rem);display:grid;grid-template-columns:1fr 1fr}
.armcol{display:flex;flex-direction:column;padding:0 clamp(1.6rem,3vw,3rem);border-left:1px solid var(--border)}
.armcol:first-child{border-left:0;padding-left:0}
/* Below 900 the two arms stack. The same 900 as the deck's phone trims below: a tablet
   that gets phone spacing must get the phone layout too, or it lands on neither. */
@media(max-width:899px){
  .arms{grid-template-columns:1fr}
  .armcol{border-left:0;padding-left:0;padding-top:1.6rem}
  .armcol:first-child{padding-top:0}
  /* stacked, the column is the full width: a centred drawing would float away from
     the words it belongs to, so it lines up with them instead */
  .armcol .art{justify-content:flex-start}
}
.armcol .fig{font-family:var(--mono);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--mute)}
.armcol .art{height:clamp(92px,10vw,128px);display:flex;align-items:center;justify-content:center;color:var(--text);margin:clamp(.7rem,1.5vw,1rem) 0}
.armcol .art svg{width:auto;height:100%;max-width:100%;overflow:visible}
.armcol .k{display:flex;align-items:center;gap:.6rem}
.armcol .k img{width:30px;height:23px}
.armcol .k b{font-family:var(--sans);font-weight:500;font-size:clamp(1.4rem,2.2vw,1.9rem);color:var(--text);letter-spacing:-.02em}
.armcol p{color:var(--dim);font-size:1rem;line-height:1.55;margin-top:.7rem;max-width:34ch}
.armcol .armfoot{margin-top:auto;padding-top:1.4rem;display:flex;gap:1.3rem;align-items:center;flex-wrap:wrap}
.armcol .go{font-family:var(--mono);font-size:.74rem;letter-spacing:.05em;text-transform:uppercase;color:var(--amber);
  display:inline-flex;gap:.4em;align-items:center;transition:gap .2s}
.armcol:hover .go{gap:.75em}
.armcol .tag{font-family:var(--mono);font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;color:var(--mute)}

/* Seven marks under the heading: how many there are, and which one you are on. Without it
   a reader has no idea whether this is seven things or seventy. */
/* Each mark is an empty track with a fill inside it. The fill is not switched on when the
   board changes: it is drawn by the scroll, so the current mark writes itself across as you
   move through its board and is full at the moment the next one starts. Nothing jumps. */
.ticks{display:flex;justify-content:center;gap:.6rem;margin-top:clamp(1.1rem,2.4vw,1.6rem);list-style:none}
.ticks li{position:relative;width:20px;height:2px;border-radius:2px;background:var(--border-2);
  transition:transform .45s var(--ease)}
.ticks li span{position:absolute;inset:0;border-radius:2px;background:var(--amber);
  transform:scaleX(0);transform-origin:0 50%;will-change:transform;
  transition:background .45s var(--ease)}
.ticks li.done span{background:rgba(245,246,247,.34)}   /* behind you: lit, but out of the way */
.ticks li.now{transform:scaleY(2.2)}
@media(max-width:720px){.ticks{gap:.45rem}.ticks li{width:15px}}
.deck:not(.live) .ticks{display:none}   /* stacked, every one of them is already on the page */

/* how-we-work: fixed header, one board at a time. Each fades out completely before the
   next arrives, and nothing travels: they appear and leave on the spot. */
.boards{position:relative;height:clamp(340px,50vh,460px);margin-top:clamp(1.8rem,4vw,2.6rem)}
.board-stage{position:absolute;inset:0}
/* drawing and words form one block of a fixed width, centred in the page. The columns are
   not fractions of the wrap: if they were, the pair would stretch to the far edges and the
   board would read as two things pinned to opposite margins rather than one composition. */
.board{position:absolute;inset:0;display:grid;
  grid-template-columns:auto minmax(0,34rem);grid-template-rows:auto auto auto;
  align-content:center;justify-content:center;column-gap:clamp(2rem,4.6vw,4.2rem);
  opacity:0;will-change:opacity}
/* the drawing sits at the inner edge of its column, so it reads as a pair with the words
   rather than as two things at opposite ends of the page */
.board .art{grid-column:1;grid-row:1/4;align-self:center;justify-self:end;margin:0;
  height:clamp(190px,25vw,290px);display:flex;align-items:center;justify-content:center;color:var(--text)}
.board .art svg{width:auto;height:100%;max-width:100%;overflow:visible}
.board .fig{grid-column:2;grid-row:1;align-self:end;
  font-family:var(--mono);font-size:.78rem;letter-spacing:.14em;text-transform:uppercase;color:var(--mute)}
.board h3{grid-column:2;grid-row:2;font-family:var(--sans);font-weight:500;
  font-size:clamp(1.6rem,2.9vw,2.25rem);color:var(--text);letter-spacing:-.02em;margin:.8rem 0}   /* stays under the h2 above it at every width */
.board .desc{grid-column:2;grid-row:3;align-self:start;margin:0;max-width:44ch;
  color:var(--dim);font-size:clamp(1.06rem,1.55vw,1.24rem);line-height:1.6}
/* every other one turns around: the drawing crosses to the right, the words to the left */
@media(min-width:900px){
  .board:nth-child(even){grid-template-columns:minmax(0,34rem) auto}
  .board:nth-child(even) .art{grid-column:2;justify-self:start}
  .board:nth-child(even) .fig,.board:nth-child(even) h3,.board:nth-child(even) .desc{grid-column:1}
}
@media(max-width:899px){
  .boards{height:clamp(340px,64vh,440px)}
  .board{grid-template-columns:1fr;grid-template-rows:auto auto auto auto;
    justify-items:center;text-align:center;padding:clamp(1.6rem,6vw,2.4rem) 0}
  .board .art{grid-column:1;grid-row:1;height:clamp(110px,26vw,150px);justify-self:center}
  .board .fig{grid-column:1;grid-row:2}.board h3{grid-column:1;grid-row:3}
  .board .desc{grid-column:1;grid-row:4;max-width:38ch;margin-inline:auto}
}
/* fallback when the deck isn't scroll-driven (mobile / reduced motion / no-JS): stack every board */
.deck:not(.live) .boards{height:auto;padding:0}
.deck:not(.live) .board-stage{position:relative;inset:auto}
.deck:not(.live) .board{position:relative;inset:auto;opacity:1;transform:none;
  border-top:1px solid var(--border)}
.deck:not(.live) .board:first-of-type{border-top:0}
.deck:not(.live) .statement .c{opacity:1}   /* phrase is JS-typed in the deck; show it statically in normal flow */

/* signature + portrait */
.sig-wrap{display:grid;gap:clamp(2rem,5vw,3.5rem);align-items:center;margin-top:clamp(2rem,4vw,2.6rem)}
/* Desktop: portrait on the left spanning both rows, the argument and then its CTA on
   the right. The CTA is a sibling of the copy, not a child, so phones can put it after
   the photo. Grid areas make the source order irrelevant here. */
@media(min-width:820px){
  .sig-wrap{grid-template-columns:.82fr 1fr;grid-template-areas:"pic text" "pic cta";row-gap:0}
  #sig-portrait{grid-area:pic}
  #sig-copy{grid-area:text;align-self:end}
  #sig-cta{grid-area:cta;align-self:start;margin-top:1.9rem}
}
/* the figure is the frame plus its legend; the framed box is the inner div */
.portrait-fig{display:flex;flex-direction:column;align-items:flex-start;justify-self:center;width:100%;max-width:17rem}
.portrait{position:relative;border:1px solid var(--border-2);border-radius:12px;overflow:hidden;
  width:100%;aspect-ratio:4/5;box-shadow:0 30px 80px -30px rgba(0,0,0,.8)}
.portrait img{width:100%;height:100%;object-fit:cover}
.portrait-fig figcaption{margin-top:1.1rem;padding-left:.1rem}
.sig-text .eyebrow{color:var(--amber)}
.sig-text h2{font-size:clamp(1.7rem,3.6vw,2.4rem)}
.sig-text h2 .py-inline{height:.72em;width:auto;display:inline-block;vertical-align:-0.02em;margin-right:.06em}
.sig-text p{color:var(--dim);margin-top:1rem;line-height:1.6;max-width:46ch;font-size:1.05rem}
.sig-name{font-weight:500;color:var(--text);font-size:1.05rem;line-height:1.3}
.sig-name span{display:block;font-family:var(--mono);font-weight:400;font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;color:var(--mute);margin-top:.35rem}
/* phones: read the words first, then meet the man, then act. The portrait is centered
   and its legend sits centered underneath, so it closes the section as one block. */
@media(max-width:819px){
  .sig-wrap{gap:clamp(1.8rem,6vw,2.4rem);justify-items:start}
  #sig-portrait{justify-self:center;align-items:center}
  #sig-portrait figcaption{text-align:center;padding-left:0}
}

/* PHONES, DECK LIVE. A pinned panel gets exactly one screen, and a phone screen is short.
   Every panel here is trimmed to fit the smallest one we support (360x640) without a
   scrollbar inside the pin: the arms lose their drawings, the signature shrinks its
   portrait. Nothing is cut that carries meaning, only decoration and air. */
@media(max-width:899px){
  .deck.live .panel{padding:64px 0 12px}   /* 64 clears the 60px nav when a panel fills the screen */
  .deck.live .sec-head h2{font-size:clamp(1.4rem,3.6svh,1.9rem);line-height:1.2}
  .deck.live .sec-head .eyebrow{margin-bottom:clamp(.5rem,1.5svh,.8rem)}
  /* the two arms */
  .deck.live .arms{margin-top:clamp(.9rem,2.2svh,1.3rem)}
  .deck.live .armcol{padding-top:clamp(.9rem,2.2svh,1.3rem)}
  .deck.live .armcol .art{display:none}
  .deck.live .armcol .k img{width:26px;height:20px}
  .deck.live .armcol .k b{font-size:clamp(1.15rem,2.9svh,1.4rem)}
  .deck.live .armcol p{margin-top:clamp(.45rem,1.4svh,.7rem);font-size:clamp(.9rem,2.1svh,1rem);line-height:1.5}
  .deck.live .armcol .armfoot{padding-top:clamp(.75rem,1.9svh,.95rem);gap:1rem}
  .deck.live #pnl-arms .lead{font-size:clamp(.9rem,2.1svh,1rem);line-height:1.5;margin-top:.65rem}
  /* the seven things */
  .deck.live .boards{height:clamp(250px,42svh,340px);margin-top:clamp(.5rem,1.6svh,.9rem)}
  .deck.live .board{padding:0}
  .deck.live .board .art{height:clamp(72px,13svh,112px)}
  .deck.live .board h3{font-size:clamp(1.15rem,2.9svh,1.3rem);margin:clamp(.3rem,1svh,.5rem) 0}
  .deck.live .board .desc{font-size:clamp(.86rem,2svh,.95rem)}
  /* the signature */
  .deck.live .sig-wrap{gap:clamp(.8rem,2.2svh,1.3rem);margin-top:clamp(.6rem,1.8svh,1rem)}
  .deck.live .portrait-fig{max-width:clamp(7.5rem,25svh,15rem)}
  .deck.live .portrait-fig figcaption{margin-top:clamp(.5rem,1.4svh,.8rem)}
  .deck.live .sig-text h2{font-size:clamp(1.25rem,3.2svh,1.6rem)}
  .deck.live .sig-text p{margin-top:clamp(.4rem,1.3svh,.6rem);font-size:clamp(.88rem,2.05svh,1rem)}
  /* the portrait is spaced by the grid's row gap alone, so the air above it and the air
     below it are the same. The CTA is a grid sibling, not a child of the copy, so its own
     top margin would otherwise be added to the gap under the photograph. */
  .deck.live #sig-cta{margin-top:0}
}
/* Only a tall phone has room to keep the two drawings as well as the words, and how
   much room depends on the width too: a narrow 412px phone wraps the copy onto more
   lines than a 430px one, which is why the drawing is sized against both. */
@media(max-width:899px) and (min-height:900px){
  .deck.live .armcol .art{display:flex;height:min(clamp(56px,8svh,76px),14vw);margin:.4rem 0}
}

/* touch targets: on phones the nav, footer and brand links are only 19px to 24px
   tall as text. Grow the hit area to 44px without moving anything visually. */
@media(pointer:coarse),(max-width:900px){
  .brand{min-width:44px;min-height:44px}
  .nav-links a{display:inline-flex;align-items:center;justify-content:center;min-height:44px;min-width:44px}
  .nav-links a.btn{padding-block:.78rem}
  .btn{padding-block:.84rem}
  .foot-col li{margin-top:0}
  .foot-col a{display:inline-flex;align-items:center;min-height:44px;min-width:44px}
  .foot-id .foot-mail{min-height:44px}
  .skip-link{padding:.85rem 1rem}
}

/* footer */
.foot{border-top:1px solid var(--border);margin-top:1rem}
.foot-in{max-width:var(--maxw);margin-inline:auto;padding:clamp(2rem,5vw,3rem) clamp(1.1rem,4vw,2rem) 2rem}
.foot-top{display:flex;justify-content:space-between;gap:2.5rem;flex-wrap:wrap}
.foot-top .brand img{width:34px;height:26px}
.foot-id{max-width:22rem}
.foot-id .foot-tag{margin-top:1rem;color:var(--text);font-weight:500;font-size:1.02rem;letter-spacing:-.01em}
.foot-id .foot-sub{margin-top:.4rem;color:var(--dim);font-size:.92rem;line-height:1.5}
.foot-id .foot-mail{display:inline-flex;align-items:center;margin-top:.9rem;font-family:var(--mono);font-size:.78rem;
  color:var(--amber);border-bottom:1px solid transparent;transition:border-color .18s}
.foot-id .foot-mail:hover{border-color:var(--amber)}
.foot-cols{display:flex;gap:clamp(2.5rem,7vw,5.5rem);flex-wrap:wrap}
.foot-col p{font-family:var(--mono);font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;color:var(--mute);margin-bottom:.85rem}
.foot-col ul{list-style:none}
.foot-col li{margin-top:.45rem}
.foot-col a{font-size:.92rem;color:var(--dim);transition:color .18s}
.foot-col a:hover{color:var(--text)}
.foot-legal{margin-top:clamp(2rem,5vw,2.8rem);padding-top:1.4rem;border-top:1px solid var(--border);
  display:flex;justify-content:space-between;gap:.8rem;flex-wrap:wrap;
  font-family:var(--mono);font-size:.72rem;color:var(--mute);line-height:1.7}

/* ---- ambient texture ---- */
.grain{position:fixed;inset:0;z-index:60;pointer-events:none;opacity:.035;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}

/* dot wave: hero centerpiece */
.hero{position:relative}
.field{position:absolute;top:0;left:50%;transform:translateX(-50%);width:100vw;height:100%;
  z-index:0;pointer-events:none;
  -webkit-mask-image:linear-gradient(90deg,transparent 0%,transparent 34%,#000 58%,#000 76%,transparent 100%),
                     linear-gradient(180deg,transparent 0%,#000 24%,#000 62%,transparent 100%);
  -webkit-mask-composite:source-in;
          mask-image:linear-gradient(90deg,transparent 0%,transparent 34%,#000 58%,#000 76%,transparent 100%),
                     linear-gradient(180deg,transparent 0%,#000 24%,#000 62%,transparent 100%);
          mask-composite:intersect}
.hero>*:not(.field){position:relative;z-index:1}
/* phones and small tablets: the reading column runs the full width, so hold the field to
   the top right and lighten it, exactly as the interior pages do */
@media(max-width:899px){
  .field{opacity:.5;
    -webkit-mask-image:linear-gradient(90deg,transparent 0%,transparent 46%,#000 74%,#000 90%,transparent 100%),
                       linear-gradient(180deg,#000 0%,#000 34%,transparent 66%);
            mask-image:linear-gradient(90deg,transparent 0%,transparent 46%,#000 74%,#000 90%,transparent 100%),
                       linear-gradient(180deg,#000 0%,#000 34%,transparent 66%)}
}

/* Reveal on enter. Time-based, not scroll-linked: a view() timeline ties the fade to
   scroll position, so text resting near the fold can sit half-faded indefinitely. */
.reveal{opacity:1;transform:none}                 /* no-JS: visible */
html.js .reveal{opacity:0;transform:translateY(28px);
  transition:opacity .75s var(--ease),transform .75s var(--ease)}
html.js .reveal.in{opacity:1;transform:none}

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .reveal,html.js .reveal,.h-anim{opacity:1!important;transform:none!important;animation:none!important;transition:none!important}
  .hero{animation:none!important}
  .progress{display:none}
  .field{-webkit-mask-image:linear-gradient(90deg,transparent 0%,transparent 34%,#000 60%,#000 76%,transparent 100%),
                     linear-gradient(180deg,transparent 0%,#000 24%,#000 62%,transparent 100%);
          mask-image:linear-gradient(90deg,transparent 0%,transparent 34%,#000 60%,#000 76%,transparent 100%),
                     linear-gradient(180deg,transparent 0%,#000 24%,#000 62%,transparent 100%)}
}
