/* ═══════════════════════════════════════════════════════════
   WORLDS — tab anatomy + one machine per subsection.
   ═══════════════════════════════════════════════════════════ */

body[data-world="science"].tab{background:#04121A}
body[data-world="career"].tab{background:#080F18}
body[data-world="coaching"].tab{background:#120608}
body[data-world="humanity"].tab{background:#17120A;--ink:#F4EFE4;--ink-dim:#A89F8C}

/* back-to-journey button */
.bar__home{display:inline-flex;align-items:center;gap:.5rem;margin-left:1rem;
  font-family:var(--mono);font-size:.58rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-dim);transition:color .35s var(--ease)}
.bar__home:hover{color:var(--accent)}
.bar__home i{display:inline-block;transition:transform .35s var(--ease)}
.bar__home:hover i{transform:translateX(-5px)}
.bar__left{display:flex;align-items:center}

/* ── tab hero ──
   The image is 16:9 and must NEVER be cropped, so the media block owns a
   real 16:9 box and the copy sits BELOW it rather than on top of it. The
   old version overlaid a 3-line headline on a cover-cropped image, which
   collided with the top bar and cut Darya out of frame. */
.thero{position:relative;padding-top:5.5rem}
/* width is capped by the height budget so the box stays exactly 16:9 —
   no pillarboxing, and still never cropped */
.thero__media{position:relative;width:min(100%, calc(74vh * 16 / 9));
  aspect-ratio:16/9;margin-inline:auto;overflow:hidden;background:#04060A}
.thero__media img{width:100%;height:100%;object-fit:contain;background:#04060A}
.thero__media::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to top,color-mix(in srgb,var(--accent) 6%,#04060A) 2%,transparent 40%)}
.thero__inner{position:relative;z-index:1;width:100%;
  padding-top:clamp(1.8rem,4vh,3rem);padding-bottom:clamp(2rem,5vh,3.5rem)}
.thero h1{font-size:clamp(1.9rem,4.4vw,3.6rem);max-width:22ch;line-height:1.04}
.thero .lede{color:var(--ink-dim);max-width:54ch;margin-top:1.1rem;font-size:1.02rem}
@media(min-width:1100px){
  /* on wide screens the copy can sit beside the frame instead of under it */
  .thero__inner{display:grid;grid-template-columns:1.15fr .85fr;
    gap:clamp(1.5rem,3vw,3rem);align-items:end}
  .thero .lede{margin-top:0;padding-bottom:.3rem}
}

.chap{padding-block:clamp(4.5rem,9vw,8rem);position:relative}
.chap--alt{background:rgba(255,255,255,.022)}
.chap h2{font-size:clamp(1.9rem,4.4vw,3.4rem);margin-block:1.2rem 1.4rem;max-width:18ch}
.chap .lede{color:var(--ink-dim);max-width:56ch}
.split{display:grid;gap:clamp(2rem,4vw,4rem);grid-template-columns:1fr}
@media(min-width:960px){.split{grid-template-columns:1fr 1.15fr;align-items:start}}
.crosslinks{display:flex;flex-wrap:wrap;gap:.8rem;margin-top:2.4rem}
.hint{font-family:var(--mono);font-size:.56rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--ink-dim);text-align:center;margin-top:1.2rem}

/* shared lightbox */
.lbox{position:fixed;inset:0;z-index:180;background:rgba(4,6,8,.95);display:grid;
  place-items:center;opacity:0;visibility:hidden;transition:opacity .4s,visibility .4s;
  backdrop-filter:blur(10px)}
.lbox.on{opacity:1;visibility:visible}
.lbox figure{max-width:88vw;max-height:86vh;text-align:center}
.lbox img{max-width:100%;max-height:80vh;border-radius:10px;box-shadow:0 30px 90px rgba(0,0,0,.6)}
.lbox figcaption{font-family:var(--mono);font-size:.62rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--ink-dim);margin-top:1rem}

/* generic placeholder */
.ph{position:absolute;inset:0;display:grid;place-items:center;text-align:center;padding:1rem;
  font-family:var(--mono);font-size:.5rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-dim);background:linear-gradient(155deg,#12181F,#080B10)}
.ph b{display:block;color:var(--accent);font-size:.66rem;margin-bottom:.35rem}
/* A placeholder whose container already names it beneath: a quiet frame
   mark instead of the title said twice. An empty box reads as broken; a
   mark reads as a picture that has not arrived yet. */
.ph--quiet::after{content:'';width:20px;height:20px;border:1px solid var(--hair);
  border-radius:3px;opacity:.55}

/* ══════════ SCIENCE · fiber-drawn digits ══════════ */
.fstats{display:flex;flex-wrap:wrap;gap:clamp(1.5rem,4vw,3.5rem);
  border-top:1px solid var(--hair);padding-top:1.8rem;margin-top:2.4rem}
.fstat .n{font-family:var(--serif);font-size:clamp(2rem,4vw,3.2rem);color:var(--accent);
  position:relative;display:inline-block}
.fstat .n.drawing{text-shadow:0 0 18px var(--accent),0 0 40px color-mix(in srgb,var(--accent) 50%,transparent)}
.fstat .n.drawing::after{content:"";position:absolute;left:-6%;right:-6%;top:50%;height:1px;
  background:linear-gradient(90deg,transparent,var(--accent),transparent);
  animation:fdraw .5s linear infinite}
@keyframes fdraw{0%{transform:translateY(-140%)}100%{transform:translateY(140%)}}
.fstat .l{font-family:var(--mono);font-size:.56rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--ink-dim);margin-top:.35rem}

/* ══════════ SCIENCE · woven loom ══════════ */
.loom{position:relative;margin-top:2rem;display:grid;
  grid-template-columns:1fr;gap:0}
@media(min-width:900px){.loom{grid-template-columns:1.15fr 1fr}}
.loom__svg{width:100%;height:100%;min-height:26rem;overflow:visible}
.loom__thread{fill:none;stroke:var(--w-science);stroke-width:1.4;opacity:.28;
  stroke-dasharray:2400;stroke-dashoffset:2400;
  transition:opacity .5s var(--ease),stroke-width .5s var(--ease),d .6s var(--ease)}
.loom.woven .loom__thread{animation:weave 2.2s var(--ease) forwards;
  animation-delay:calc(var(--i) * .13s)}
@keyframes weave{to{stroke-dashoffset:0}}
.loom__thread.taut{opacity:1;stroke-width:2.6;
  filter:drop-shadow(0 0 8px var(--w-science))}
.loom.pulling .loom__thread:not(.taut){opacity:.1}
.loom__labels{display:flex;flex-direction:column;justify-content:center;gap:.2rem}
.loom__label{text-align:left;padding:.9rem 1.1rem;border-left:2px solid transparent;
  transition:all .45s var(--ease);background:none}
.loom__label:hover{border-left-color:var(--w-science);
  background:color-mix(in srgb,var(--w-science) 6%,transparent);padding-left:1.5rem}
.loom__label.dim{opacity:.3}
.loom__label .k{font-family:var(--mono);font-size:.52rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--w-science);display:block}
.loom__label b{font-family:var(--serif);font-weight:400;font-size:1.3rem;display:block;margin:.25rem 0}
.loom__label em{font-style:normal;color:var(--ink-dim);font-size:.86rem}

/* ══════════ SCIENCE · double helix ══════════ */
.helix{position:relative;height:clamp(32rem,84vh,46rem);overflow:hidden;
  border:1px solid var(--hair);border-radius:14px;cursor:grab;touch-action:pan-y;
  perspective:1400px;background:#040E14}
.helix:active{cursor:grabbing}
.helix__bg{position:absolute;inset:0;background:var(--helix-bg,radial-gradient(70% 90% at 50% 50%,rgba(15,223,208,.07),transparent));
  background-size:cover;background-position:center;opacity:.5;filter:blur(1px)}
.helix__bg::after{content:"";position:absolute;inset:0;
  background:radial-gradient(60% 70% at 50% 50%,transparent,#040E14 92%)}
/* the real 3D model canvas sits between the background and the cards */
.helix__gl{position:absolute;inset:0;width:100%!important;height:100%!important;
  z-index:1;opacity:0;transition:opacity 1.2s var(--ease)}
.helix.gl-ready .helix__gl{opacity:1}
.helix.gl-ready .helix__bg{opacity:.25}
.helix__world{z-index:2}
.helix__world{position:absolute;inset:0;transform-style:preserve-3d}
.hcard{position:absolute;left:0;top:0;width:clamp(6rem,11vw,9.5rem);aspect-ratio:16/10;
  border-radius:7px;overflow:hidden;border:1px solid var(--hair);background:#0A141B;
  will-change:transform,opacity,filter;cursor:pointer}
.hcard img{width:100%;height:100%;object-fit:cover}
.hcard--b{border-color:color-mix(in srgb,var(--w-science) 40%,transparent)}
.hcard__cap{position:absolute;left:0;right:0;bottom:0;padding:.4rem .5rem;
  font-family:var(--mono);font-size:.42rem;letter-spacing:.1em;text-transform:uppercase;
  background:linear-gradient(transparent,rgba(4,14,20,.95));color:var(--ink)}
.hrung{position:absolute;left:0;top:0;height:1px;transform-origin:0 50%;
  background:linear-gradient(90deg,var(--w-science),color-mix(in srgb,var(--w-science) 30%,transparent));
  pointer-events:none}

/* ══════════ SCIENCE · stats over living tissue ══════════ */
#statsChap.stats3d{position:relative;overflow:hidden}
.stats__gl{position:absolute;inset:0;width:100%!important;height:100%!important;
  z-index:0;opacity:0;transition:opacity 1.2s var(--ease)}
#statsChap.gl-ready .stats__gl{opacity:1}
#statsChap.stats3d .wrap{position:relative;z-index:1}
#statsChap.gl-ready{background:#030B10}
.stats__specimen{position:absolute;right:1.4rem;bottom:1rem;z-index:1;
  max-width:min(30rem,72%);text-align:right;line-height:1.9;
  font-family:var(--mono);font-size:.52rem;letter-spacing:.14em;color:var(--ink-dim);
  text-transform:uppercase;opacity:0;transition:opacity 1.4s var(--ease) .6s}
#statsChap.gl-ready .fstat .n,#statsChap.gl-ready .fstat .l{
  text-shadow:0 2px 14px rgba(3,11,16,.85)}
.stats__specimen em{font-style:normal;color:var(--w-science)}
#statsChap.gl-ready .stats__specimen{opacity:.85}
body.read .stats__specimen{display:none}

/* ══════════ SCIENCE · citation gravity well ══════════ */
.gwell{position:relative;height:clamp(30rem,78vh,42rem);margin-top:2rem;overflow:hidden;
  border:1px solid var(--hair);border-radius:14px;cursor:grab;touch-action:pan-y;
  background:radial-gradient(50% 60% at 50% 50%,rgba(15,223,208,.09),transparent 70%)}
.gwell:active{cursor:grabbing}
.gwell__core{position:absolute;left:50%;top:50%;width:16px;height:16px;border-radius:50%;
  transform:translate(-50%,-50%);background:var(--w-science);
  box-shadow:0 0 30px var(--w-science),0 0 80px color-mix(in srgb,var(--w-science) 60%,transparent)}
/* real 3D scene behind the DOM bodies */
.gwell__gl{position:absolute;inset:0;width:100%!important;height:100%!important;
  z-index:0;opacity:0;transition:opacity 1.2s var(--ease)}
.gwell.gl-ready .gwell__gl{opacity:1}
.gwell.gl-ready .gwell__core{opacity:0}          /* the model replaces the CSS glow dot */
.gwell.gl-ready{background:#030A10}
/* Portrait: the system is a wide ring, so fitting it to a narrow width
   leaves the tall box mostly empty. Shorten the box to meet the
   composition instead of padding it with void. */
@media(orientation:portrait) and (max-width:900px){
  .gwell{height:clamp(22rem,52vh,30rem)}
}
.gwell .gbody,.gwell__info{z-index:2}
.gbody{position:absolute;left:0;top:0;border-radius:50%;border:1px solid var(--hair);
  background:radial-gradient(circle at 35% 30%,#123,#050B10);
  display:grid;place-items:center;color:var(--ink-dim);
  font-family:var(--mono);font-size:.5rem;will-change:transform;
  transition:box-shadow .35s,border-color .35s,color .35s}
.gbody:hover,.gbody.hot{border-color:var(--w-science);color:var(--ink);
  box-shadow:0 0 24px color-mix(in srgb,var(--w-science) 60%,transparent)}
.gwell__info{position:absolute;left:50%;bottom:1.2rem;transform:translateX(-50%) translateY(10px);
  width:min(30rem,88%);text-align:center;opacity:0;transition:all .4s var(--ease);
  background:rgba(4,14,20,.9);border:1px solid var(--hair);border-radius:10px;
  padding:.9rem 1.1rem;backdrop-filter:blur(8px);pointer-events:none}
.gwell__info.on{opacity:1;transform:translateX(-50%)}
.gwell__info .y{font-family:var(--mono);font-size:.55rem;color:var(--w-science);letter-spacing:.14em}
.gwell__info .t{font-size:.92rem;margin:.3rem 0;line-height:1.4}
.gwell__info .j{font-size:.78rem;color:var(--ink-dim);font-style:italic}
.gwell__info .c{font-family:var(--mono);font-size:.6rem;color:var(--w-science);margin-top:.3rem}

/* ══════════ SCIENCE · blueprint unfold ══════════ */
.bprint{display:grid;gap:1rem;margin-top:2rem;grid-template-columns:1fr}
/* patents 3D: one canvas over the grid, molecules scissored per card */
.bprint.bp3d{position:relative}
.bp__gl{position:absolute;inset:0;width:100%!important;height:100%!important;
  z-index:4;pointer-events:none;opacity:0;transition:opacity 1.2s var(--ease)}
.bprint.gl-ready .bp__gl{opacity:1}
body.read .bp__gl{display:none!important}
@media(min-width:800px){.bprint{grid-template-columns:1fr 1fr}}
.bp{position:relative;border:1px solid var(--hair);border-radius:10px;overflow:hidden;
  background:linear-gradient(160deg,#071A24,#040C12);cursor:pointer;
  display:grid;grid-template-columns:auto 1fr;gap:1.2rem;padding:1.2rem;align-items:center}
.bp__fold{position:relative;width:clamp(6rem,12vw,9rem);aspect-ratio:5/3;
  border:1px solid color-mix(in srgb,var(--w-science) 35%,transparent);
  border-radius:5px;overflow:hidden;background:#03212E;
  transform:perspective(600px) rotateY(58deg);transform-origin:left center;
  transition:transform .7s var(--ease)}
.bp.open .bp__fold{transform:perspective(600px) rotateY(0)}
.bp__draw{position:absolute;inset:0;width:100%;height:100%}
.bp__draw path,.bp__draw line,.bp__draw circle,.bp__draw rect{
  fill:none;stroke:var(--w-science);stroke-width:1.4;
  stroke-dasharray:400;stroke-dashoffset:400;opacity:.85}
.bp.open .bp__draw path,.bp.open .bp__draw line,
.bp.open .bp__draw circle,.bp.open .bp__draw rect{
  animation:bpdraw 1.1s var(--ease) forwards}
@keyframes bpdraw{to{stroke-dashoffset:0}}
.bp__seal{position:absolute;right:.4rem;bottom:.4rem;font-family:var(--mono);
  font-size:.42rem;letter-spacing:.14em;border:1px solid var(--w-science);color:var(--w-science);
  padding:.15rem .35rem;border-radius:3px;opacity:0;transform:scale(1.6) rotate(-12deg);
  transition:all .5s var(--ease) .6s}
.bp.open .bp__seal{opacity:1;transform:scale(1) rotate(-12deg)}
.bp__seal--p{border-color:var(--ink-dim);color:var(--ink-dim)}
.bp__no{font-family:var(--mono);font-size:.58rem;letter-spacing:.1em;color:var(--w-science)}
.bp__meta h3{font-family:var(--serif);font-weight:400;font-size:1.2rem;margin:.35rem 0 .3rem}
.bp__meta p{color:var(--ink-dim);font-size:.84rem;line-height:1.5}

/* ══════════ CAREER · gauge cluster ══════════ */
/* career journey — desk + notebook behind the boarding passes */
#passChap.j3d{position:relative;overflow:hidden}
.journey__gl{position:absolute;inset:0;width:100%!important;height:100%!important;
  z-index:0;opacity:0;transition:opacity 1.2s var(--ease)}
#passChap.gl-ready .journey__gl{opacity:1}
#passChap.j3d .wrap{position:relative;z-index:1}
#passChap.gl-ready{background:#05090D}

/* career process flow — real plant ceiling overhead */
#flowChap.flow3d{position:relative;overflow:hidden}
.flow__gl{position:absolute;inset:0;width:100%!important;height:100%!important;
  z-index:0;opacity:0;transition:opacity 1.2s var(--ease)}
#flowChap.gl-ready .flow__gl{opacity:1}
#flowChap.flow3d .wrap{position:relative;z-index:1}
#flowChap.gl-ready{background:#05090D}

/* career gauges — 3D instrument bench replaces the SVG dials */
.gauges.g3d{position:relative;display:block;height:clamp(26rem,60vh,34rem);cursor:grab}
.gauges.g3d:active{cursor:grabbing}
.gauges.g3d .gauge{display:none}                 /* SVG dials yield to the bench */
.gauges__gl{position:absolute;inset:0;width:100%!important;height:100%!important;
  z-index:0;opacity:0;transition:opacity 1.2s var(--ease)}
.gauges.gl-ready .gauges__gl{opacity:1}
.gauges__lane{position:absolute;left:0;right:0;bottom:3.2rem;z-index:1;display:flex;
  justify-content:space-around;pointer-events:none}
/* equal thirds with breathing room: space-around alone let the three
   captions butt together and pushed the last one past the section edge,
   so the row read as one run-on sentence instead of three readings */
.glab{flex:1 1 0;min-width:0;padding:0 .5rem;
  text-align:center;transition:all .4s var(--ease);opacity:.75}
.glab span{display:block;line-height:1.4;text-wrap:balance}
.glab b{font-family:var(--serif);font-weight:400;display:block;
  font-size:clamp(1.4rem,2.4vw,2rem)}
.glab span{font-family:var(--mono);font-size:.5rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-dim)}
.glab.hot{opacity:1;transform:translateY(-6px)}
.glab.hot b{color:var(--w-career);text-shadow:0 0 24px color-mix(in srgb,var(--w-career) 50%,transparent)}
.gauges__chips{position:absolute;left:0;right:0;bottom:.9rem;z-index:1;display:flex;
  justify-content:center;gap:2rem;pointer-events:none}
.gauges__chips span{font-family:var(--mono);font-size:.55rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-dim)}
.gauges__chips b{color:var(--ink);font-weight:500}
body.read .gauges.g3d{height:auto;cursor:auto}
body.read .gauges.g3d .gauge{display:block}
body.read .gauges__lane,body.read .gauges__chips{display:none}

.gauges{display:flex;flex-wrap:wrap;gap:clamp(1.5rem,4vw,3rem);margin-top:2.4rem;
  border-top:1px solid var(--hair);padding-top:2rem}
.gauge{text-align:center;width:clamp(7rem,13vw,10rem)}
.gauge svg{width:100%;overflow:visible}
.gauge__arc{fill:none;stroke:var(--hair);stroke-width:3;stroke-linecap:round}
.gauge__val{fill:none;stroke:var(--w-career);stroke-width:3;stroke-linecap:round;
  stroke-dasharray:132;stroke-dashoffset:132;transition:stroke-dashoffset 1.4s var(--ease)}
.gauge__needle{stroke:var(--ink);stroke-width:1.6;stroke-linecap:round;
  transform-origin:50px 56px;transform:rotate(-90deg);
  transition:transform 1.4s cubic-bezier(.34,1.4,.5,1)}
.gauge__hub{fill:var(--ink)}
.gauge.live .gauge__needle{stroke:var(--w-career)}
.gauge__n{font-family:var(--serif);font-size:clamp(1.5rem,2.6vw,2.2rem);margin-top:.3rem}
.gauge__l{font-family:var(--mono);font-size:.52rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-dim);margin-top:.25rem}

/* ══════════ CAREER · process flow ══════════ */
.flow{position:relative;margin-top:2.5rem;overflow-x:auto;padding-bottom:1rem;
  /* The pipeline is 44rem of process line, so on a narrow screen it has
     to scroll sideways. Left alone that puts a chunky OS scrollbar
     across the middle of the composition, on top of a plant ceiling —
     so it gets the world's own colour and a hairline profile. */
  scrollbar-width:thin;
  scrollbar-color:color-mix(in srgb,var(--w-career) 55%,transparent) transparent}
.flow::-webkit-scrollbar{height:4px}
.flow::-webkit-scrollbar-track{background:transparent}
.flow::-webkit-scrollbar-thumb{border-radius:2px;
  background:color-mix(in srgb,var(--w-career) 45%,transparent)}
.flow::-webkit-scrollbar-thumb:hover{background:var(--w-career)}
.flow__pipes{width:100%;height:6rem;min-width:44rem}
.flow__pipe{fill:none;stroke:var(--hair);stroke-width:6;stroke-linecap:round}
.flow__pulse{fill:none;stroke:var(--w-career);stroke-width:6;stroke-linecap:round;
  stroke-dasharray:1000;stroke-dashoffset:1000;filter:drop-shadow(0 0 8px var(--w-career))}
.flow__nodes{display:flex;gap:1rem;min-width:44rem;margin-top:-3.4rem;position:relative;z-index:1}
.flow__node{flex:1;text-align:center;opacity:.35;transition:opacity .5s var(--ease),transform .5s var(--ease)}
.flow__node.lit{opacity:1;transform:translateY(-4px)}
.flow__node i{display:block;width:14px;height:14px;border-radius:50%;margin:0 auto .6rem;
  background:#0A1622;border:2px solid var(--hair);transition:all .5s var(--ease)}
.flow__node.lit i{background:var(--w-career);border-color:var(--w-career);
  box-shadow:0 0 16px var(--w-career)}
.flow__node b{display:block;font-family:var(--mono);font-size:.58rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink)}
.flow__node span{display:block;font-size:.72rem;color:var(--ink-dim);margin-top:.2rem}

/* ══════════ CAREER · boarding-pass stack ══════════ */
.pstack{position:relative;height:clamp(25rem,54vh,31rem);margin-top:2.5rem;
  perspective:1200px}
.pass{position:absolute;left:50%;top:50%;width:min(34rem,92%);
  transform:translate(-50%,-50%) translateY(calc(var(--i) * 8px)) rotate(calc((var(--i) - 3) * 1.1deg)) scale(calc(1 - var(--i) * .012));
  display:grid;grid-template-columns:1fr auto auto;gap:1rem;align-items:center;
  padding:1.1rem 1.3rem;border-radius:10px;
  background:linear-gradient(120deg,#0E1A28,#08111C);
  border:1px solid var(--hair);box-shadow:0 12px 40px rgba(0,0,0,.5);
  opacity:0;transition:transform .8s var(--ease),opacity .8s var(--ease),box-shadow .5s;
  z-index:calc(10 - var(--i))}
.pstack.dealt .pass{opacity:1}
/* Two numbers here were wrong together, which is why the fault looked like
   a rendering glitch rather than arithmetic.

   STEP. A pass is 79px tall and the fan stepped 46px, so 33px of every card
   sat under the next one — and 33px from the bottom is exactly where the
   year and the route line live. The result was a deck whose every row but
   the hovered one was sliced through the middle of its own letters. The
   step now clears the text: 62px leaves only the 17.6px of bottom padding
   covered.

   CENTRE. `--i - 3` over six cards (i = 0..5) fans three steps upward and
   only two downward. The deck hung above its own container, crowding the
   line of copy above it, and every extra pixel of step made it worse.
   2.5 is the middle of 0..5. */
.pstack.fanned .pass{
  transform:translate(-50%,-50%) translateY(calc((var(--i) - 2.5) * 62px)) rotate(calc((var(--i) - 2.5) * 1.6deg)) scale(1)}
.pass.front{box-shadow:0 20px 60px rgba(0,0,0,.65),0 0 30px color-mix(in srgb,var(--w-career) 30%,transparent);
  border-color:color-mix(in srgb,var(--w-career) 50%,transparent);z-index:20}
.pass__l{display:flex;align-items:center;gap:.9rem}
.pass__from,.pass__to{font-family:var(--mono);font-size:.72rem;letter-spacing:.12em;color:var(--ink)}
.pass__arrow{color:var(--w-career)}
.pass__r{text-align:right}
.pass__role{font-family:var(--serif);font-size:1.05rem}
.pass__yr{font-family:var(--mono);font-size:.56rem;color:var(--ink-dim);letter-spacing:.12em}
.pass__stub{font-family:var(--mono);font-size:.62rem;color:var(--w-career);
  border-left:1px dashed var(--hair);padding-left:1rem}

/* ══════════ CAREER · cleanroom window wall ══════════ */
/* corridor 3D: real ceiling recedes behind/above the windows */
.wwall__gl{position:absolute;inset:0;width:100%!important;height:100%!important;
  z-index:0;opacity:0;transition:opacity 1.2s var(--ease)}
.wwall.gl-ready .wwall__gl{opacity:1}
.wwall.w3d .wwall__track{position:relative;z-index:1;padding-top:clamp(6rem,14vh,9rem)}
.wwall.gl-ready{background:#05090D}

.wwall{position:relative;overflow:hidden;margin-top:2.5rem;
  border-block:1px solid var(--hair);padding-block:2rem}
.wwall__track{display:flex;gap:clamp(1rem,2.5vw,2rem);width:max-content;will-change:transform}
.wwin{position:relative;flex:0 0 clamp(16rem,28vw,24rem);aspect-ratio:4/3;
  border-radius:6px;overflow:hidden;border:1px solid var(--hair);
  background:#0A1420;cursor:pointer;
  transition:transform .5s var(--ease),box-shadow .5s var(--ease)}
.wwin:hover{transform:translateY(-8px);box-shadow:0 24px 60px rgba(0,0,0,.6)}
.wwin img{width:100%;height:100%;object-fit:cover}
.wwin__glass{position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(125deg,rgba(255,255,255,.14) 0%,transparent 30%,transparent 70%,rgba(255,255,255,.05) 100%)}
.wwin figcaption{position:absolute;left:0;right:0;bottom:0;z-index:3;padding:.8rem 1rem;
  font-family:var(--mono);font-size:.55rem;letter-spacing:.14em;text-transform:uppercase;
  background:linear-gradient(transparent,rgba(5,10,16,.92))}

/* ══════════ HUMANITY · 3D canvases ══════════ */
.roots__gl,.murm__gl{position:absolute;inset:0;width:100%!important;height:100%!important;
  z-index:0;opacity:0;transition:opacity 1.2s var(--ease)}
.roots.gl-ready .roots__gl,.murm.gl-ready .murm__gl{opacity:1}
.roots.r3d{position:relative;min-height:34rem}
.roots.r3d .roots__svg{display:none}
.roots.r3d .roots__cards,.roots.r3d .roots__svg{position:relative;z-index:1}
.roots.r3d .rootcard{background:color-mix(in srgb,#0E0A06 76%,transparent);
  backdrop-filter:blur(8px);border:1px solid color-mix(in srgb,var(--w-humanity) 18%,transparent);
  border-radius:12px;padding:1.2rem 1.4rem}
.murm.m3d .murmcard{z-index:2}
.quill3d{position:relative;float:right;width:clamp(9rem,16vw,13rem);aspect-ratio:1;
  margin:0 0 .5rem 1.2rem;opacity:0;transition:opacity 1.2s var(--ease)}
.quill3d.gl-ready{opacity:1}
.quill3d canvas{width:100%!important;height:100%!important}
body.read .quill3d{display:none}

/* ══════════ HOME · album cover + contact plane ══════════ */
.album{position:relative}                      /* anchor for the 3D cover */
.album__cover3d{position:absolute;inset:0;z-index:40;cursor:pointer;outline:none;
  display:grid;place-items:center;background:radial-gradient(60% 70% at 50% 45%,rgba(20,16,10,.4),rgba(4,7,10,.92));
  opacity:0;transition:opacity .9s var(--ease)}
.album__cover3d.gl-ready{opacity:1}
.album__cover3d.opening{opacity:0;pointer-events:none}
.album__cover3d canvas{position:absolute;inset:0;width:100%!important;height:100%!important}
.album__coverhint{position:absolute;bottom:1.6rem;left:50%;transform:translateX(-50%);
  font-family:var(--mono);font-size:.55rem;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ink-dim);animation:coverpulse 2.4s ease-in-out infinite}
@keyframes coverpulse{50%{opacity:.4}}
body.read .album__cover3d{display:none}
.contact__gl{position:absolute;inset:0;width:100%!important;height:100%!important;
  z-index:0;opacity:0;transition:opacity 1.2s var(--ease);pointer-events:none}
#contact.gl-ready .contact__gl{opacity:1}
#contact.p3d>*:not(.contact__gl){position:relative;z-index:1}

/* ══════════ COACHING · shared 3D canvases ══════════ */
.belt__gl,.split__gl,.steps__gl{position:absolute;inset:0;
  width:100%!important;height:100%!important;z-index:0;opacity:0;
  transition:opacity 1.2s var(--ease)}
.belt.gl-ready .belt__gl,.split2.gl-ready .split__gl,
.cubewrap.gl-ready .steps__gl{opacity:1}
/* THE WALL. The section is a tall runway — scrolling through it is the
   hand that nails the plates on — and the stage inside stays sticky and
   viewport-high while the story plays.
   The runway height keys on .belt--wall, which initBelt applies WHEN IT
   BUILDS THE DOM, not on .b3d, which arrives at lazy 3D-init: the
   ScrollTrigger measures the section at creation, and a trigger measured
   40px tall snaps progress 0→1 the moment it scrolls past — the whole
   story then plays itself before the visitor has nailed anything. */
.belt.belt--wall{display:block;height:260vh;padding:0}
.belt.belt--wall .belt__stage{position:sticky;top:0;height:100vh;overflow:hidden}
/* invisible hit areas the 3D module keeps aligned over its slabs:
   hover/focus tilts the belt, screen readers get the cert names */
.belt.belt--wall .plate{position:absolute;z-index:2;opacity:1;transform:none;
  background:transparent;cursor:pointer}
.belt.belt--wall .plate:focus-visible{outline:2px solid
  color-mix(in srgb,var(--w-coaching) 70%,white);outline-offset:4px;border-radius:8px}
.belt .hint{position:absolute;left:0;right:0;bottom:1.6rem;z-index:2;
  transition:opacity .8s var(--ease)}
.belt.belt--live .hint{opacity:0}   /* the wall is down; the hint's job is done */
/* instant path (reduced motion / no ScrollTrigger): no runway, one frame */
.belt.belt--wall.belt--instant{height:auto;min-height:37rem}
.belt.belt--wall.belt--instant .belt__stage{position:relative;height:min(100vh,44rem)}
/* drag is only offered once the belt is the one on stage */
.belt.belt--live .belt__gl{cursor:grab}
.belt.belt--live .belt__gl:active{cursor:grabbing}
.split2.s3d{position:relative}
.split2.s3d .sp{position:relative;z-index:1}
.cubewrap.st3d{position:relative;min-height:34rem}
/* The caption used to sit dead centre, directly on top of the hypercube
   it describes — the subject read as a dark mass behind a box. Given
   room, move the card to one side and let coaching3d slide the object
   to the other, so the two sit beside each other instead of fighting
   for the same middle. */
@media(min-width:900px){
  .cubewrap.st3d{align-items:flex-end;padding-right:clamp(1rem,5vw,5rem)}
}
.cubewrap.st3d .cube,.cubewrap.st3d .cube__dots{position:relative;z-index:1}
/* the hypercube is the subject; the card is a caption laid over it */
.cubewrap.gl-ready .cface{background:color-mix(in srgb,#0B0507 74%,transparent);
  backdrop-filter:blur(10px);border:1px solid color-mix(in srgb,var(--w-coaching) 22%,transparent)}
/* (the .bagrow 3D variants left with the inline gym — see ring.html) */

/* ══════════ COACHING · championship belt (base + read mode) ══════════ */
.belt{position:relative;margin-top:2.5rem}
/* read mode: the certifications printed as text, nothing else */
.belt--read{display:block}
.certs{list-style:none;margin:2.5rem 0 0;padding:0;display:grid;gap:.9rem}
.certs b{font-family:var(--mono);font-size:.85rem;letter-spacing:.16em;color:#DDBE72}
.certs span{display:block;font-family:var(--mono);font-size:.6rem;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-dim);margin-top:.25rem}

/* ══════════ COACHING · split screen ══════════ */
.split2{margin-top:2.5rem;display:flex;flex-direction:column;gap:1px;
  background:var(--hair);border:1px solid var(--hair);border-radius:12px;overflow:hidden}
.sp{display:grid;grid-template-columns:1fr auto 1fr;align-items:stretch;
  background:#0C0508;transition:background .5s var(--ease)}
.sp.sync{background:#140609}
.sp__side{padding:clamp(1.2rem,2.6vw,2rem);transition:all .5s var(--ease)}
.sp__side--lab{text-align:right;border-right:0}
.sp.sync .sp__side{transform:scale(1.015)}
.sp__tag{font-family:var(--mono);font-size:.5rem;letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink-dim);margin-bottom:.5rem}
.sp.sync .sp__side--lab .sp__tag{color:var(--w-science)}
.sp.sync .sp__side--gym .sp__tag{color:var(--w-coaching)}
.sp__t{font-family:var(--serif);font-size:clamp(1rem,1.9vw,1.45rem);line-height:1.25}
.sp__divider{width:1px;background:var(--hair);position:relative}
.sp__divider i{position:absolute;left:50%;top:50%;width:9px;height:9px;border-radius:50%;
  transform:translate(-50%,-50%) scale(.6);background:var(--ink-dim);
  transition:all .5s var(--ease)}
.sp.sync .sp__divider i{transform:translate(-50%,-50%) scale(1);
  background:var(--w-coaching);box-shadow:0 0 14px var(--w-coaching)}

/* ══════════ COACHING · rotating cube ══════════ */
.cubewrap{margin-top:3rem;perspective:1400px;display:flex;flex-direction:column;
  align-items:center;gap:1.6rem}
.cube{position:relative;width:min(24rem,84vw);height:15rem;transform-style:preserve-3d;
  transition:transform 1s cubic-bezier(.4,0,.2,1);transform:translateZ(-11rem)}
.cface{position:absolute;inset:0;padding:1.6rem 1.8rem;border-radius:12px;
  background:linear-gradient(160deg,#1B0A0E,#0C0507);border:1px solid var(--hair);
  backface-visibility:hidden;display:flex;flex-direction:column;justify-content:center}
.cface:nth-child(1){transform:rotateY(0) translateZ(11rem)}
.cface:nth-child(2){transform:rotateY(90deg) translateZ(11rem)}
.cface:nth-child(3){transform:rotateY(180deg) translateZ(11rem)}
.cface:nth-child(4){transform:rotateY(270deg) translateZ(11rem)}
.cface__k{font-family:var(--mono);font-size:.52rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--w-coaching)}
.cface h3{font-family:var(--serif);font-weight:400;font-size:1.5rem;margin:.5rem 0 .5rem}
.cface p{color:var(--ink-dim);font-size:.88rem;line-height:1.55}
.cube__dots{display:flex;gap:.5rem}
.cube__dots i{width:7px;height:7px;border-radius:50%;background:var(--hair);cursor:pointer;
  transition:all .35s var(--ease)}
.cube__dots i.on{background:var(--w-coaching);box-shadow:0 0 10px var(--w-coaching);width:20px;border-radius:4px}

/* (COACHING · heavy bags — the DOM bag row is gone with the inline gym) */

/* ══════════ HUMANITY · root system ══════════ */
.roots{position:relative;margin-top:2.5rem}
.roots__svg{width:100%;height:clamp(12rem,24vh,16rem);display:block}
.roots .rt{fill:none;stroke:var(--w-humanity);stroke-width:1.6;opacity:.6;
  stroke-dasharray:600;stroke-dashoffset:600}
.roots.grow .rt{animation:rootgrow 1.6s var(--ease) forwards}
.roots.grow .rt:nth-child(2){animation-delay:.5s}
.roots.grow .rt:nth-child(3){animation-delay:.62s}
.roots.grow .rt:nth-child(4){animation-delay:.74s}
@keyframes rootgrow{to{stroke-dashoffset:0}}
.roots__cards{display:grid;gap:1.2rem;grid-template-columns:1fr;margin-top:-1rem}
@media(min-width:820px){.roots__cards{grid-template-columns:repeat(3,1fr)}}
.rootcard{padding:1.5rem 1.6rem;border:1px solid var(--hair);border-radius:12px;
  background:linear-gradient(160deg,rgba(232,180,74,.05),rgba(23,18,10,.6));
  opacity:0;transform:translateY(22px);transition:all .8s var(--ease)}
.rootcard.in{opacity:1;transform:none}
.rootcard__k{font-family:var(--mono);font-size:.55rem;letter-spacing:.18em;color:var(--w-humanity)}
.rootcard h3{font-family:var(--serif);font-weight:400;font-size:1.35rem;margin:.5rem 0 .5rem}
.rootcard p{color:var(--ink-dim);font-size:.9rem;line-height:1.6}

/* ══════════ HUMANITY · handwritten ink ══════════ */
.inkwrite{font-family:var(--serif);font-size:clamp(1.5rem,3.4vw,2.6rem);line-height:1.3;
  max-width:24ch;margin:3rem 0;padding-left:1.6rem;border-left:2px solid var(--accent)}
/* Until initInk splits the quote into per-character spans there are no
   spans to hide, so the raw sentence paints at full opacity and is then
   wiped when the script runs — a flash of the whole quote, then nothing,
   because preload.js is deferred and the curtain is not up yet to mask
   it. Hold the text transparent until the split has happened. Scoped to
   (scripting: enabled) so a reader without JS still gets the quote
   instead of an empty space. The text still occupies its box, so nothing
   reflows when it appears. */
@media (scripting: enabled){
  .inkwrite:not(.inked){color:transparent}
}
.inkwrite span{opacity:0;filter:blur(3px);transition:opacity .18s linear,filter .18s linear}
.inkwrite span.on{opacity:1;filter:none}

/* ══════════ HUMANITY · murmuration ══════════ */
.murm{position:relative;height:clamp(30rem,80vh,44rem);overflow:hidden;margin-top:2rem;
  border:1px solid var(--hair);border-radius:14px;
  background:radial-gradient(70% 80% at 50% 40%,rgba(232,180,74,.06),transparent)}
.murmcard{position:absolute;left:0;top:0;width:clamp(6.5rem,11vw,9.5rem);aspect-ratio:9/16;
  border-radius:8px;overflow:hidden;border:1px solid var(--hair);cursor:pointer;
  box-shadow:0 14px 40px rgba(0,0,0,.45);will-change:transform}
.murmcard img{width:100%;height:100%;object-fit:cover}
.murmcard.calm{box-shadow:0 30px 70px rgba(0,0,0,.7),0 0 40px color-mix(in srgb,var(--w-humanity) 40%,transparent);
  border-color:var(--w-humanity)}
.murmcard .tcard__cap{position:absolute;left:0;right:0;bottom:0;padding:.6rem .7rem;
  font-family:var(--mono);font-size:.45rem;letter-spacing:.12em;text-transform:uppercase;
  background:linear-gradient(transparent,rgba(23,18,10,.95));color:var(--ink);
  transform:translateY(100%);transition:transform .4s var(--ease)}
.murmcard.calm .tcard__cap{transform:none}

/* read mode neutralises every machine */
body.read .helix,body.read .gwell,body.read .murm,
body.read .pstack,body.read .cube,body.read .album{height:auto!important;
  perspective:none!important;display:block!important}
body.read .hcard,body.read .gbody,body.read .murmcard,body.read .pass,
body.read .cface,body.read .leaf{position:relative!important;transform:none!important;
  opacity:1!important;filter:none!important;inset:auto!important;width:auto!important;
  margin-bottom:1rem;visibility:visible!important}
/* Every hint on the site instructs the hand — "drag to orbit", "hover the
   stack", "pinch or ctrl+scroll to zoom". In read mode the machine those
   sentences describe is not running and its canvas is hidden, so they are
   directions to a room the reader is not standing in. */
body.read .hint{display:none}

/* the flat publication list that replaces the gravity well — see initGwell */
.pubs{list-style:none;padding:0;margin:1.5rem 0 0;display:flex;flex-direction:column;gap:.1rem}
.pubs li{display:grid;gap:.15rem;padding:.85rem 0;border-top:1px solid var(--hair)}
.pubs li:last-child{border-bottom:1px solid var(--hair)}
.pubs a{font-family:var(--serif);font-size:1.02rem;line-height:1.35;color:var(--ink);
  text-decoration:none;border-bottom:1px solid transparent;justify-self:start;
  transition:border-color .3s var(--ease)}
.pubs a:hover,.pubs a:focus-visible{border-bottom-color:var(--w-science)}
.pubs__j{font-size:.86rem;color:var(--ink-dim)}
.pubs__c{font-family:var(--mono);font-size:.56rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--w-science)}

body.read .hrung,body.read .gwell__core,body.read .album__spine,
body.read .belt__strap{display:none!important}
body.read canvas[class*="__gl"]{display:none!important}  /* every 3D machine canvas */
body.read .inkwrite span{opacity:1!important;filter:none!important}
body.read .rootcard,body.read .plate,body.read .flow__node{opacity:1!important;transform:none!important}

/* (COACHING · the gym round — deleted with the inline gym; the game is
   its own page now, ring.html, with its own stylesheet) */

/* ══════════ HUMANITY · the murmuration ══════════ */
/* the flock is the subject; empty photo slots must not litter the sky */
.murm.gl-ready .murmcard--empty{display:none}
.murm.m3d{min-height:clamp(30rem,76vh,42rem);border:1px solid var(--hair);
  border-radius:14px;overflow:hidden;background:#0E0A06}
.murm.gl-ready .murmcard{box-shadow:0 30px 70px rgba(0,0,0,.55)}

/* the lanterns need a band of dark air above the commitments to hang in */
.roots.r3d{min-height:46rem}
.roots.gl-ready .roots__cards{margin-top:clamp(13rem,26vh,20rem)}

/* ══════════ HOME · the real album ══════════ */
.album.a3d{position:relative;min-height:clamp(30rem,74vh,42rem);
  border:1px solid var(--hair);border-radius:14px;overflow:hidden;background:#0B0906;
  cursor:grab;touch-action:pan-y}
.album.a3d:active{cursor:grabbing}
.album__gl{position:absolute;inset:0;width:100%!important;height:100%!important;
  z-index:1;opacity:0;transition:opacity 1.2s var(--ease)}
.album.gl-ready .album__gl{opacity:1}
/* the flat DOM leaves are the read-mode fallback once real pages exist */
.album.gl-ready .leaf{display:none}
.album.gl-ready .album__spine{display:none}
body.read .album.a3d{min-height:0;border:0;cursor:auto}
body.read .album__gl{display:none}
body.read .album.gl-ready .leaf{display:block}

/* the balance needs room above the rows to swing in */
.split2.s3d{min-height:44rem}
.split2.gl-ready .sp{background:color-mix(in srgb,#120608 72%,transparent);
  backdrop-filter:blur(9px);border-radius:10px}
.split2.gl-ready{padding-top:clamp(11rem,22vh,17rem)}

/* a slot waiting for a photograph shows its title, never its filename */
.ph__hint{display:none}
