/* hero.css — outside → the turn → inside the phone. 2026-10-01.
   Sits on top of site.css (v3.2 tokens). The dark field of the opening is the design
   system's dark mode: the screen showcase, never printed. The canvas is drawn by
   js/hero/phone.js; `.inside` is the HTML that takes over when the screen fills. */

:root{
  --dk:#04101C; --dk-fg:#F5F1EA; --dk-dim:#8E97A3; --dk-panel:#0B1622; --dk-rule:#243445;
  --phone-w:390; --phone-h:844;
  --p:0;
}
html{scroll-behavior:auto}
body{padding:0;background:var(--dk);overscroll-behavior-y:none;transition:background .35s}
body.is-paper{background:var(--bg)}   /* once the field has turned, the page behind the canvas is paper too */
/* inside, the page itself does not scroll: the wheel and the finger belong to the phone, and a stray scroll up cannot start the walk out */
body.is-locked{overflow:hidden}
html:has(body.is-locked){overflow:hidden}
.track{height:460vh}

/* ── the scene ─────────────────────────────────────────────────────────────── */
/* 100lvh, not 100%: when Safari tucks its bar away the canvas must not resize mid-gesture (the Fusion lesson) */
.phone{position:fixed;left:0;top:0;width:100%;height:100vh;height:100lvh;z-index:0;display:block;transition:opacity .3s}
.is-inside .phone{opacity:0;pointer-events:none;transition:opacity .55s var(--ease)}   /* the way in is a fade: the phone and its reel dissolve, the inside is there */
.no-gl .phone,.no-gl .track{display:none}
#reel,#pickVideo,#pickVideo2{position:fixed;left:0;top:0;width:2px;height:2px;opacity:0;pointer-events:none}   /* hidden with opacity, never display:none: a hidden video stops decoding */

/* a vertical pan is the page's; a horizontal one is the hand's (it turns the phone) */
.phone{touch-action:pan-y;cursor:grab}
.phone:active{cursor:grabbing}

/* ── the loader ────────────────────────────────────────────────────────────── */
.loader,.outside,.bar{user-select:none;-webkit-user-select:none}   /* a drag turns the phone; it never selects the words */
.loader{position:fixed;inset:0;z-index:60;background:var(--dk);color:var(--dk-fg);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:22px;
  transition:opacity .55s var(--ease),transform .55s var(--ease)}
.is-ready .loader{opacity:0;transform:translateY(-14px);pointer-events:none}
.loader__mark{display:flex;align-items:center;gap:12px;font:500 22px/1 var(--display);letter-spacing:-.02em}
.loader__mark i{font-style:normal;font-weight:400;opacity:.7}
.loader__bar{width:168px;height:1px;background:var(--dk-rule);overflow:hidden}
.loader__bar i{display:block;height:100%;width:100%;background:var(--accent);transform:scaleX(0);transform-origin:left}
.loader__t{font:500 11px/1 var(--mono);letter-spacing:.08em;color:var(--dk-dim)}
.loader__t span:last-child{font-family:var(--body);letter-spacing:.06em;text-transform:lowercase}
/* the words wait behind the door (visibility, so the scroll-driven opacity below keeps its say) */
.outside{visibility:hidden}
.is-ready .outside,.no-gl .outside{visibility:visible}
.no-gl .outside h1 .w > span{opacity:1}
.no-gl .loader{display:none}
@media (prefers-reduced-motion:reduce){.loader{transition:none}.outside h1,.outside p{transition:none}}

/* ── chrome ────────────────────────────────────────────────────────────────── */
.bar{position:fixed;left:0;right:0;z-index:30;height:var(--bar);display:flex;align-items:center;gap:18px;padding:0 var(--pad);
  font:500 11.5px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--dk-dim);transition:color .35s;
  pointer-events:none;background:none;backdrop-filter:none;-webkit-backdrop-filter:none}   /* site.css tints the bars with the page's paper: not over the dark field */
.bar>*{pointer-events:auto}
.bar .spacer{pointer-events:none}   /* the empty middle of a bar must not catch what is under it (the tab bar inside) */
.bar--top{top:0}.bar--bot{bottom:0}
.is-paper .bar{color:var(--chrome)}
.wordmark{display:flex;align-items:center;gap:9px;font:500 15px/1 var(--display);letter-spacing:-.02em;text-transform:none;color:var(--dk-fg);transition:color .35s}
.is-paper .wordmark{color:var(--fg)}
.bar .wordmark:hover{color:var(--dk-fg)}   /* on the dark field the hover keeps the letters light (site.css darkens every bar link on hover) */
.is-paper .bar .wordmark:hover{color:var(--fg)}
.wordmark i{font-style:normal;font-weight:400;opacity:.75}
.wordmark svg path{stroke:currentColor}
/* the mark, built in depth: two arcs on their own planes and the block as a real solid. At rest it is the flat logo;
   on hover it turns once — the arcs pass like a wave towards the block, the block spins a full turn showing its sides,
   and the wave carries on through the letters. One pass, it finishes even if the pointer leaves. */
.wordmark .mark{position:relative;flex:none;width:20px;height:19px;perspective:90px}
.wordmark .mark>*{transform-style:preserve-3d}
.wordmark .arc{position:absolute;left:0;top:0;overflow:visible}
.wordmark .blk{position:absolute;left:12.5px;top:3.45px;width:3.34px;height:12.1px;--d:1.67px}
.wordmark .blk b{position:absolute;inset:0;background:#00E0C6;backface-visibility:hidden}
.wordmark .blk b:nth-child(1){transform:translateZ(var(--d))}
.wordmark .blk b:nth-child(2){transform:rotateY(180deg) translateZ(var(--d))}
.wordmark .blk b:nth-child(3){transform:rotateY(90deg) translateZ(var(--d));background:#00A896}
.wordmark .blk b:nth-child(4){transform:rotateY(-90deg) translateZ(var(--d));background:#00A896}
.wordmark .blk b:nth-child(5){height:3.34px;transform:translateY(-1.67px) rotateX(90deg);background:#7FF3E6}
.wordmark .blk b:nth-child(6){height:3.34px;top:auto;bottom:0;transform:translateY(1.67px) rotateX(-90deg);background:#008577}
.wordmark .w,.wordmark i{display:inline-flex;perspective:120px}
.wordmark .c{display:inline-block;transform-origin:50% 60%}
.wordmark.is-turn .mark{animation:wm-mark 1.05s cubic-bezier(.3,.7,.2,1) both}
.wordmark.is-turn .arc--1{animation:wm-arc .7s cubic-bezier(.3,.7,.2,1) both}
.wordmark.is-turn .arc--2{animation:wm-arc .7s .09s cubic-bezier(.3,.7,.2,1) both}
.wordmark.is-turn .blk{animation:wm-blk .95s .1s cubic-bezier(.45,.05,.2,1) both}
.wordmark.is-turn .c{animation:wm-c .52s calc(.26s + var(--i) * 26ms) cubic-bezier(.3,.7,.2,1) both}
@keyframes wm-mark{0%,100%{transform:none}30%,70%{transform:scale(1.22)}}
@keyframes wm-arc{0%,100%{transform:none}45%{transform:translateZ(14px) rotateY(-38deg)}}
@keyframes wm-blk{0%{transform:none}25%{transform:rotateX(-22deg) rotateY(90deg)}75%{transform:rotateX(-22deg) rotateY(300deg)}100%{transform:rotateY(360deg)}}
@keyframes wm-c{0%,100%{transform:none}45%{transform:translateY(-2.5px) rotateX(-55deg)}}
@media (prefers-reduced-motion:reduce){.wordmark.is-turn .mark,.wordmark.is-turn .arc,.wordmark.is-turn .blk,.wordmark.is-turn .c{animation:none}}
.spacer{flex:1}
.menu{display:flex;align-items:center;padding:14px 12px;margin:-14px -12px}
.menu i{display:block;width:16px;height:1.2px;background:currentColor;margin:3px 0}
.clock{font:500 11px/1 var(--mono);letter-spacing:.08em}
@keyframes beat{to{transform:scale(1.6)}}

/* ── the menu sheet (nav.sheet: the panels inside the phone have their own .sheet) ── */
nav.sheet{position:fixed;inset:0;z-index:50;background:var(--dk);color:var(--dk-fg);padding:calc(var(--bar) + 30px) var(--pad) 40px;
  display:flex;flex-direction:column}
nav.sheet[hidden]{display:none}
.sheet__close{position:absolute;top:0;right:var(--pad);height:var(--bar);font:300 28px/1 var(--display);color:var(--dk-fg)}
.sheet__list{list-style:none;flex:1;display:flex;flex-direction:column;justify-content:center;gap:4px;max-width:720px}
.sheet__list a{display:flex;align-items:baseline;gap:18px;padding:14px 0;border-top:1px solid var(--dk-rule)}
.sheet__list li:first-child a{border-top:0}
.sheet__list span{font:500 clamp(34px,5vw,64px)/1 var(--display);letter-spacing:-.035em}
.sheet__list em{font:500 11.5px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--dk-dim);font-style:normal}
.sheet__list a:hover span{color:var(--accent)}
.sheet__foot{display:flex;flex-wrap:wrap;gap:10px 28px;font:500 11.5px/1.6 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--dk-dim)}
.sheet__foot a:hover{color:var(--dk-fg)}
.menu-open .bar--top .menu{opacity:0}

/* ── outside: the headline ─────────────────────────────────────────────────── */
.outside{position:fixed;left:var(--pad);bottom:calc(var(--bar) + 34px);z-index:5;max-width:min(560px,70vw);color:var(--dk-fg);pointer-events:none}
.outside>*{pointer-events:auto}
.outside h1{font:500 clamp(40px,6vw,88px)/.98 var(--display);letter-spacing:-.04em;text-wrap:balance}
.outside h1 .w{white-space:nowrap}
/* each letter is its own body: typed in with a pop, then carried off by the wave (hero.js sets the transforms) */
.outside h1 .w > span{display:inline-block;will-change:transform,opacity}
.outside h1 .w > span.is-off{opacity:0}
.outside h1 .w > span.is-pop{animation:keypop .18s var(--ease)}
@keyframes keypop{from{transform:translateY(.12em) scale(1.22);opacity:.2}to{transform:none;opacity:1}}
.outside h1 .caret{display:inline-block;width:.06em;height:.82em;margin-left:.08em;vertical-align:-.06em;background:var(--accent);animation:blink 1s steps(1) infinite}
.outside h1 .caret.is-done{opacity:0;transition:opacity .5s;animation:none}
@keyframes blink{50%{opacity:0}}
@media (prefers-reduced-motion:reduce){.outside h1 .w > span.is-pop{animation:none}.outside h1 .caret{display:none}}
/* the letters unwrite themselves in hero.js; the small line goes first, with the very first scroll */
.outside p{margin-top:18px;font:500 12.5px/1.6 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--dk-dim);
  opacity:clamp(0, 1 - var(--p) * 14, 1);transform:translateY(calc(var(--p) * 60px));transition:opacity .5s .1s}
.outside:not(.is-in) p{opacity:0}   /* it fades in after the headline has written itself */
.outside p b{color:var(--accent);font-weight:500}
/* while reduced motion is on, the whole block simply fades */
@media (prefers-reduced-motion:reduce){.outside{opacity:clamp(0, 1 - var(--p) * 5, 1)}}
@media (max-width:720px){
  /* the page's own bars give way on the way in: the foot with the first scroll, the head in the last stretch. Nothing of the page is left at the cut */
  .bar--bot{opacity:clamp(0, 1 - (var(--p) - .04) * 10, 1)}
  .bar--top{opacity:clamp(0, 1 - (var(--p) - .62) * 8, 1)}
}
.no-gl .outside{position:relative;left:auto;bottom:auto;padding:calc(var(--bar) + 40px) var(--pad) 40px;max-width:none;opacity:1;transform:none;background:var(--dk)}
.no-gl .outside p{opacity:1;transform:none}

/* ── inside: the HTML that takes over the screen ───────────────────────────── */
/* The rectangle matches the 3D screen at the end of the dolly: full height, the
   phone's aspect, centred. On a phone it covers the viewport. Three states:
   hidden (outside) · chrome (on the way in: laid over the 3D screen and scaled to its
   projection by hero.js, but UNSEEN — nothing of the inside shows until you are in) ·
   live (after the cut: paper behind, the archive, the hand). On the way out it fades
   over the phone coming back. */
.inside{position:fixed;z-index:10;left:50%;top:50%;transform:translate(-50%,-50%);
  --ih:100dvh;--iw:calc(var(--ih) * var(--phone-w) / var(--phone-h));
  height:var(--ih);width:var(--iw);overflow:hidden;
  color:var(--fg);
  opacity:0;pointer-events:none;visibility:hidden;background:transparent;transition:opacity .24s,visibility 0s .24s}   /* hidden for hit-testing too: a child with pointer-events:auto would still catch the hand */
.is-chrome .inside{will-change:transform}
.is-inside .inside{opacity:1;visibility:visible;pointer-events:auto;background:var(--bg);transition:transform .6s var(--ease),opacity .55s var(--ease)}   /* the last 1 % of scale eases off after the cut */
/* on a desktop the phone's edges stay at the sides of the screen after the cut, so nothing jumps */
@media (min-width:721px){
  .inside{--iw:calc(var(--ih) * .56)}   /* on a desktop the column is a little wider than the phone's screen (Juan, 6-oct: too skinny); the arrival is a fade, so nothing has to match */
  .inside::before,.inside::after{content:"";position:absolute;top:0;bottom:0;width:18px;background:var(--dk-panel);pointer-events:none;opacity:0}   /* 18px: the body's pad plus its bevel at the final distance */
  .inside::before{right:100%;box-shadow:inset -1px 0 0 var(--dk-rule)}
  .inside::after{left:100%;box-shadow:inset 1px 0 0 var(--dk-rule)}
  /* the edges no longer stay after the cut: the way in is a fade now, the phone dissolves whole */
}
.no-gl .inside{position:relative;left:auto;top:auto;transform:none;width:100%;height:auto;min-height:100vh;opacity:1;visibility:visible;pointer-events:auto;margin:0 auto;max-width:520px;background:var(--bg);overflow:visible}

/* the status bar: ← out · where you are · the time. It floats over the top of whatever is open and comes down once you are in */
.status{position:absolute;left:0;right:0;top:0;height:44px;z-index:5;display:flex;align-items:center;padding:0 18px;gap:10px;font:500 11px/1 var(--mono);letter-spacing:.08em;color:var(--chrome);
  background:linear-gradient(rgba(var(--bg-rgb),.96) 50%,rgba(var(--bg-rgb),0));pointer-events:none;
  transform:translateY(-100%);opacity:0;transition:transform .45s var(--ease),opacity .3s}
.status>*{pointer-events:auto}
.status .spacer{pointer-events:none}
.is-arrived .status{transform:none;opacity:1}
.status .out{font:500 11.5px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--accent-text);background:none;border:0;padding:16px 12px;margin-left:-12px;cursor:pointer}
.status .out:hover{color:var(--fg)}
.status .who{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font:500 11.5px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--fg);display:flex;align-items:center;gap:7px;white-space:nowrap}
.status .who svg path{stroke:var(--fg)}
/* a piece held up: the clock gives its place to the way back */
.status .close{display:none;font:500 11.5px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--accent-text);background:none;border:0;padding:16px 12px;margin-right:-12px;cursor:pointer}
.status .close:hover{color:var(--fg)}
.is-held .status .close{display:inline-flex}
.is-held .status #osClock{display:none}
/* the speaker: sound on or off, remembered (sound.js). While it is on but nothing has been touched yet, the waves breathe: the browser is waiting for a tap */
.status .snd{display:inline-flex;align-items:center;gap:6px;font:500 11.5px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--accent-text);background:none;border:0;padding:15px 10px;cursor:pointer;transition:color .2s}
.status .snd:hover{color:var(--fg)}
.status .snd svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.status .snd .sp{fill:currentColor;stroke:none}
.status .snd .x{display:none}
.status .snd[aria-pressed=false] .w1,.status .snd[aria-pressed=false] .w2{display:none}
.status .snd[aria-pressed=false] .x{display:block}
.status .snd.is-wait .w1,.status .snd.is-wait .w2{animation:sndwait 1.5s ease-in-out infinite}
.status .snd.is-wait .w2{animation-delay:.2s}
@keyframes sndwait{50%{opacity:.2}}

/* the panels: four screens side by side; a tab is a selection, a swipe is a scroll */
.panels{position:absolute;inset:0;display:flex;overflow:hidden;scroll-snap-type:x mandatory;overscroll-behavior-x:contain;scrollbar-width:none}
.panels::-webkit-scrollbar{display:none}
.is-inside .panels{overflow-x:auto;overflow-y:hidden}
/* a panel's scroll stays its own: pulling past its top never reaches the page (the way out is the button) */
.panel{position:relative;flex:0 0 100%;height:100%;scroll-snap-align:start;scroll-snap-stop:always;overflow:hidden;overscroll-behavior-y:contain}
.is-inside .panel{overflow-y:auto;overflow-x:hidden}
.is-inside .panel--archive{overflow:hidden}   /* the archive takes the hand itself */
.panel .sheet{padding:62px 20px 132px;min-height:100%}   /* under the floating status bar, over the floating slabs */

/* ── work: the archive. The canvas (js/hero/archive.js) is the whole panel; the words float over it ── */
.archive{position:absolute;inset:0;width:100%;height:100%;display:block;touch-action:none;cursor:grab;outline:none}
.archive:active{cursor:grabbing}
/* a desktop: the archive lies under the phone's column, the whole page wide */
.archive--out{position:fixed;inset:0;width:100vw;height:100dvh;z-index:9;opacity:0;pointer-events:none;transition:opacity .5s var(--ease);-webkit-mask-image:linear-gradient(#000 calc(100% - 170px),transparent calc(100% - 70px)),linear-gradient(90deg,transparent calc(var(--capl) + var(--capw) + 36px),#000 calc(var(--capl) + var(--capw) + 140px));mask-image:linear-gradient(#000 calc(100% - 170px),transparent calc(100% - 70px)),linear-gradient(90deg,transparent calc(var(--capl) + var(--capw) + 36px),#000 calc(var(--capl) + var(--capw) + 140px));-webkit-mask-composite:source-in;mask-composite:intersect}   /* the next group dissolves before it reaches the slabs */
.is-inside .archive--out.is-on{opacity:1;pointer-events:auto}
@media (min-width:721px){
  .is-inside .inside.on-work{background:none;pointer-events:none}
  .is-inside .inside.on-work .status>*,.is-inside .inside.on-work .tabs,.is-inside .inside.on-work .racks{pointer-events:auto}
  .inside.on-work .panels,.inside.on-work .panel{pointer-events:none}
  .inside.on-work .panels{clip-path:inset(0 2px 0 0)}   /* no sliver of the next panel at the column's edge */
  .inside.on-work .status,.inside.on-work .dock{background:none}
  .panel:not(.panel--archive){background:var(--bg)}
  .aside--l{pointer-events:none!important}
}
.archive-ui{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .5s .3s}
.is-arrived .archive-ui{opacity:1}
/* the groups, as a row of words under the status bar: the one you are at is ink with a rule under it (the status bar carries the count) */
.racks{position:absolute;left:18px;right:18px;top:54px;display:flex;gap:16px;pointer-events:auto;transition:opacity .3s}
.racks button{padding:6px 0 5px;position:relative;border-bottom:1px solid transparent;font:500 11px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--chrome);transition:color .2s,border-color .2s}
.racks button::before{content:'';position:absolute;left:-6px;right:-6px;top:-12px;bottom:-12px}   /* the hit area, 44 px tall, without moving the row */
.racks button[aria-pressed=true]{color:var(--fg);border-bottom-color:var(--fg)}
.racks button:hover{color:var(--fg)}
.archive-ui .hint{position:absolute;left:18px;right:40px;top:88px;font:500 10.5px/1.5 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--chrome);transition:opacity .5s}
.is-touched .hint{opacity:0}
/* the caption of the piece in front: index, what it is, the title, the facts. Held up, it grows the line and sits on paper at the foot, as the feed had it */
.pick{position:absolute;left:18px;right:18px;top:69%;transition:opacity .28s,transform .28s var(--ease)}   /* just under the sheet in front */
.pick.is-off{opacity:0;transform:translateY(6px)}
.pick h2{font:var(--w-display) 19px/1.1 var(--display);letter-spacing:-.025em;margin-top:8px}
.pick .l,.pick .go{display:none}
.pick .go{margin-top:12px;font:500 11.5px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--accent-text);pointer-events:auto}
.pick .go:hover{color:var(--fg)}
.is-open .racks,.is-open .hint,.is-open .soon{opacity:0;pointer-events:none}
.is-open .pick{left:0;right:0;top:auto;bottom:0;padding:16px 18px 112px;background:var(--bg-alt)}
.is-open .pick .l{display:block}
.is-open .pick .go:not([hidden]){display:inline-flex}
.is-open .status{background:none}
.soon{position:absolute;left:18px;right:40px;top:44%;transform:translateY(-50%);pointer-events:auto}
.soon h2{font:var(--w-display) 26px/1.04 var(--display);letter-spacing:-.03em;margin-top:10px}
.soon .lede{color:var(--dim);font-size:14px;line-height:1.55;margin-top:12px;max-width:30ch}
.is-empty .pick{display:none}
/* on a desktop the words of the piece in front stand at the left of the page, level with it (Juan, 3-oct: under the sheet
   they ran into the next group and the slabs); the sheets already passed dissolve before they reach the words. Held up,
   only the way to the piece stays under it. */
@media (min-width:721px){
  .aside.aside--l{top:42%;z-index:10;left:var(--capl);width:var(--capw)}
  .aside--l p.l{text-wrap:pretty}
  .aside--l.is-empty{display:none}
  .aside--l>*{transition:opacity .2s}
  .aside--l.is-swap>*{opacity:0}
  .pick{top:auto;bottom:0;text-align:center}
  .pick .k,.pick h2,.pick .disc,.pick .l,.is-open .pick .l{display:none}
  .is-open .pick{background:none;padding:0 18px 118px}
  .is-inside .bar--bot{opacity:0;pointer-events:none;transition:opacity .3s}   /* inside, the foot of the page belongs to the slabs */
  .is-inside .bar--bot>*{pointer-events:none}
}

/* the shelf: the pieces as data, and as the page when there is no WebGL */
.shelf{display:none}
.no-gl .shelf{display:block;padding-top:52px}
.no-gl .archive,.no-gl .archive-ui,.no-gl .dock{display:none}
.no-gl .item{padding:0 0 26px}
.no-gl .item img{width:100%;height:auto;background:var(--panel)}
.no-gl .item .cap{padding:14px 18px 0}

/* ── what i do: Juan presents. His photo fills the panel for a beat, then goes to the corner (is-pip) and what he
   names appears on the paper under it (js/hero/call.js); the chapter's words are the headline ── */
.panel--call{background:var(--bg)}
.is-inside .panel--call{overflow:hidden}
.panel--call .stage{position:absolute;left:0;top:236px;width:100%;height:calc(100% - 236px - 152px);display:block;touch-action:none;clip-path:inset(0 0 4px 0)}   /* the band between the chapter's words and the link at the foot */
.callv{position:absolute;left:0;top:0;width:100%;height:100%;object-fit:cover;object-position:50% 32%;background:var(--panel);z-index:2;
  transition:left .6s var(--ease),top .6s var(--ease),width .6s var(--ease),height .6s var(--ease),border-radius .6s var(--ease),box-shadow .6s}
.is-pip .callv{left:calc(100% - 84px - 16px);top:52px;width:84px;height:auto;aspect-ratio:3/4;border-radius:6px;box-shadow:0 10px 24px rgba(28,25,21,.18)}
.call-ui{position:absolute;inset:0;z-index:3;pointer-events:none}
.call-ui>*{pointer-events:auto}
.call-ui::before{content:"";position:absolute;left:0;right:0;top:0;height:150px;background:linear-gradient(rgba(var(--bg-rgb),.94) 38%,rgba(var(--bg-rgb),0));pointer-events:none}   /* the paper comes down over the top of his photo: the name is ink on it */
.call-ui .who{position:absolute;left:18px;top:54px;color:var(--fg)}
.call-ui .who b{display:block;font:500 15px/1.1 var(--display);letter-spacing:-.02em}
.call-ui .who span{display:block;margin-top:5px;font:500 11px/1 var(--mono);letter-spacing:.06em;color:var(--chrome)}
.call-ui .chapter{position:absolute;left:18px;right:calc(84px + 40px);top:100px;opacity:0;transform:translateY(8px);transition:opacity .35s,transform .35s var(--ease)}
.is-pip .call-ui .chapter{opacity:1;transform:none}
.call-ui .who b{transition:font-size .3s}
@media (max-width:720px){
  .is-pip .call-ui .who{left:auto;right:16px;top:172px;text-align:right}   /* under his photo: only the name, small */
  .is-pip .call-ui .who b{font:500 11px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--chrome)}
  .is-pip .call-ui .who span,.is-pip .call-ui .chapter span{display:none}
  .is-pip .call-ui .chapter{top:60px}
}
.call-ui .chapter b{display:block;font:500 clamp(23px,6.6vw,28px)/1.05 var(--display);letter-spacing:-.025em;color:var(--fg);text-wrap:balance}
.call-ui .chapter span{display:block;margin-top:6px;font:500 10.5px/1.5 var(--mono);letter-spacing:.08em;color:var(--dim)}
.call-ui .chapter em{display:block;margin-top:12px;font:400 15px/1.5 var(--body);font-style:normal;color:var(--dim);max-width:26ch}   /* the sentence he would say */
.call-ui .next{position:absolute;left:20px;right:20px;bottom:132px;margin-top:0;opacity:0;transition:opacity .35s .3s}   /* at the foot, as in the other panels, over the floating slabs */
.is-pip.is-last .call-ui .next{opacity:1}
/* a desktop: his photo keeps the whole phone; what he shows is on the page at the right of it */
/* a desktop, once you answer: he goes to the left with the whole phone, and the page at his right is one thing to read —
   the chapter's words on top, what he shows under them, on the same left edge (Juan's sketch, 3-oct: two places, not three) */
:root{--capl:max(var(--pad),calc(50vw - 640px));--capw:min(300px,22vw)}   /* the archive's caption on a desktop: it leaves the page's edge once the window is wide, to stay near the sheet */
:root{--iwd:calc(100dvh * .56);--cs:max(0px,min(20vw,calc(50vw - var(--iwd) / 2 - 230px)));--cl:calc(50vw - var(--cs) + var(--iwd) / 2 + clamp(32px,4vw,72px))}
.stage--out{--st:calc(var(--bar) + 9vh + clamp(150px,8.4vw + 70px,215px) + 44px);position:fixed;z-index:6;left:var(--cl);top:var(--st);display:block;width:calc(100vw - var(--cl) - var(--pad));height:calc(100dvh - var(--st) - 104px);clip-path:inset(0 0 6px 0);opacity:0;pointer-events:none;transition:opacity .45s}
.stage--out.is-on{opacity:1}
@media (min-width:721px){
  .is-presenting .inside{transform:translate(calc(-50% - var(--cs)),-50%)}
  .aside.call-head{left:var(--cl);right:var(--pad);top:calc(var(--bar) + 9vh);transform:none;width:auto;z-index:7}
  .aside.call-head h2{font-size:clamp(34px,4.2vw,64px);line-height:1;max-width:14ch;text-wrap:balance}
  .aside.call-head .disc{margin-top:14px}
  .aside.call-head p.l{font-size:clamp(15px,1.3vw,19px);max-width:36ch;margin-top:14px}
  .is-pip .callv{left:0;top:0;width:100%;height:100%;aspect-ratio:auto;border-radius:0;box-shadow:none}
  .call-ui .chapter,.call-ui .next{display:none}   /* on the page: the chapter's words and the link live in the aside */
  .aside.call-head .next{position:fixed;left:var(--cl);bottom:44px;width:min(360px,calc(100vw - var(--cl) - var(--pad)));margin:0;opacity:0;transition:opacity .4s}
  .aside.call-head.is-last .next{opacity:1}
  .aside.call-head .disc{display:none}
  .is-pip .call-ui .who{top:56px;left:18px}   /* only the name, small, on the paper that comes down over the top of his photo */
  .is-pip .call-ui .who b{font:500 11.5px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--dim)}
  .is-pip .call-ui .who span{display:none}
}
#callPiece{position:fixed;left:0;top:0;width:2px;height:2px;opacity:0;pointer-events:none}
.no-gl .panel--call .stage{display:none}
.no-gl .callv{position:relative;height:auto;aspect-ratio:9/16}
/* ── offer and talk, in the language of the call: flat things on the paper, hairlines, no boxes ── */
/* offer: a month. Four pieces land on their days, the replies go out, one day gets booked; then it starts again. */
.month{margin:22px 0 4px;perspective:900px}
.month__sheet{display:grid;grid-template-columns:repeat(7,1fr);transform:rotateX(16deg) rotateZ(-2.5deg);transform-origin:50% 60%;transform-style:preserve-3d;animation:monthfloat 9s ease-in-out infinite alternate}
@keyframes monthfloat{from{transform:rotateX(16deg) rotateZ(-2.5deg)}to{transform:rotateX(11deg) rotateY(5deg) rotateZ(-1deg)}}
.month .wd{padding:0 0 8px;font:500 9.5px/1 var(--mono);letter-spacing:.08em;color:var(--chrome);text-align:center}
.month .d{position:relative;aspect-ratio:1;box-shadow:0 0 0 .5px var(--rule);transform-style:preserve-3d}
.month .d>span{position:absolute;left:11%;top:11%;font:500 clamp(8px,16cqw,11px)/1 var(--mono);letter-spacing:.04em;color:var(--chrome)}
.month .d{container-type:inline-size}
.month .d.is-void{background:none}.month .d.is-void>span{display:none}
.month .pc{position:absolute;left:50%;top:50%;height:104%;aspect-ratio:9/16;object-fit:cover;border:1.5px solid #fff;border-radius:3px;box-shadow:0 5px 12px rgba(28,25,21,.22);transform:translate(-50%,-50%) translateZ(8px) rotate(var(--rz,3deg));opacity:0}
.month .rp{position:absolute;right:12%;bottom:14%;width:38%;height:26%;border-radius:40% 40% 40% 8%;background:var(--fg);transform:translateZ(4px) scale(0);transform-origin:0 100%}
.month .rp::after{content:"";position:absolute;left:22%;right:22%;top:46%;height:12%;border-radius:2px;background:#fff;opacity:.85}
.month .bk{position:absolute;inset:9%;border:1.5px solid var(--accent-text);border-radius:50%;transform:translateZ(4px) scale(.4);opacity:0}
.month .bk+b{position:absolute;left:0;right:0;top:50%;margin-top:-.5em;text-align:center;font:500 clamp(7px,15cqw,10px)/1 var(--mono);letter-spacing:.06em;color:var(--accent-text);opacity:0}
.month.is-run .pc{animation:pcland .7s calc(var(--at) * 1s) cubic-bezier(.2,.8,.2,1) both}
.month.is-run .rp{animation:rppop .4s calc(var(--at) * 1s) cubic-bezier(.3,1.4,.5,1) both}
.month.is-run .bk{animation:bkring .5s calc(var(--at) * 1s) cubic-bezier(.3,1.4,.5,1) both}
.month.is-run .bk+b{animation:fadein .4s calc(var(--at) * 1s + .2s) both}
.month.is-out .pc,.month.is-out .rp,.month.is-out .bk,.month.is-out .bk+b{transition:opacity .5s;opacity:0!important}
@keyframes pcland{from{opacity:0;transform:translate(-50%,-90%) translateZ(150px) rotate(calc(var(--rz,3deg) * -3))}to{opacity:1;transform:translate(-50%,-50%) translateZ(8px) rotate(var(--rz,3deg))}}
@keyframes rppop{from{transform:translateZ(4px) scale(0)}to{transform:translateZ(4px) scale(1)}}
@keyframes bkring{from{opacity:0;transform:translateZ(4px) scale(.4)}to{opacity:1;transform:translateZ(4px) scale(1)}}
@keyframes fadein{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){.month__sheet{animation:none}.month .pc,.month .bk,.month .bk+b{opacity:1;animation:none!important}.month .rp{transform:translateZ(4px) scale(1);animation:none!important}}
.panel--offer .sheet{display:flex;flex-direction:column;align-items:flex-start}
.panel--offer .sheet>*{width:100%}
.panel--offer .sheet>.k{order:1}.panel--offer .sheet>h2{order:2}.panel--offer .sheet>.lede{order:3}.panel--offer .sheet>.pill{order:4;width:auto}.panel--offer .sheet>.month{order:5}.panel--offer .sheet>.list{order:6}.panel--offer .sheet>.price{order:7}.panel--offer .sheet>.next{order:8}
.panel--offer .month{padding:18px 6px 0}
.panel--offer .list{margin-top:18px}
.price{margin-top:4px;padding-top:16px;border-top:1px solid var(--rule);font-size:13px;color:var(--dim);line-height:1.5}
.price b{color:var(--fg);font-weight:600}
.pill{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 22px;border-radius:22px;background:var(--fg);color:#fff;font:500 14px/1 var(--body);margin-top:18px}
.pill.ghost{background:none;color:var(--accent-text);padding:0 4px}
/* talk: a conversation. He types, it arrives; you answer; he answers. The field under it is the way to WhatsApp. */
.who2{display:flex;gap:12px;align-items:center;margin-top:20px;padding-bottom:14px;border-bottom:1px solid var(--rule);font-size:12.5px;line-height:1.45;color:var(--dim)}
.who2 img{width:40px;height:40px;border-radius:50%;object-fit:cover}
.who2 b{color:var(--fg);font-weight:600;font-size:14px}
.chat{margin-top:18px;display:flex;flex-direction:column;gap:10px}
.turn{position:relative;display:flex}
.turn.me{justify-content:flex-end}
.msg{max-width:84%;padding:11px 15px;font-size:14.5px;line-height:1.4;border:1px solid var(--rule);border-radius:18px 18px 18px 5px;background:#fff;transform-origin:0 100%}
.turn.me .msg{border-color:var(--fg);background:var(--fg);color:#fff;border-radius:18px 18px 5px 18px;transform-origin:100% 100%}
.chat.is-play .msg{opacity:0;transform:scale(.6) translateY(10px)}
.chat.is-play .is-in .msg{opacity:1;transform:none;transition:opacity .25s,transform .38s cubic-bezier(.3,1.3,.5,1)}
.turn::before{content:"";position:absolute;left:0;top:0;width:54px;height:34px;border:1px solid var(--rule);border-radius:17px 17px 17px 5px;background:#fff radial-gradient(circle,var(--chrome) 2.6px,transparent 3.2px) 50% 50%/12px 12px repeat-x;background-clip:content-box;padding:0 9px;box-sizing:border-box;opacity:0;transition:opacity .2s;pointer-events:none}
.chat.is-play .is-typing::before{opacity:1;animation:typing 1s ease-in-out infinite}
@keyframes typing{50%{background-position-y:35%}}
.pill.write{display:flex;justify-content:space-between;height:48px;margin-top:22px;padding:0 8px 0 20px;border-radius:24px;background:#fff;border:1px solid var(--fg);color:var(--fg)}
.pill.write i{font-style:normal;display:flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:50%;background:var(--fg);color:#fff}
.panel--talk .pill.ghost{margin-top:8px;font-size:13px}
/* on a desktop the column is phone-sized on a big screen: the small labels go up a step */
@media (min-width:721px){.racks button,.archive-ui .hint,.k,.next,.status .out,.status .close,.status .who,.sheet__list em,.disc,.call-ui .chapter span,.call-ui .who span{font-size:12px}}
/* on a desktop the column's bar is two words: the way out at the left, where you are at the right; no clock, no mark (the page's own bar is right above) */
@media (min-width:721px){
  .status #osClock,.status .who svg{display:none}
  .status .who{left:auto;right:18px;transform:translateY(-50%);color:var(--chrome)}
  .status .out{order:-2}.status .snd{order:-1;margin-left:2px}   /* on a desktop the speaker sits by the way out; the right of the bar is where you are */
  .is-held .status .who{display:none}
}
/* on a desktop the phone steps to the left (like the call once answered) and the headline and what it shows take the page */
.beside{display:none}
@media (min-width:721px){
  .is-beside .inside{transform:translate(calc(-50% - var(--cs)),-50%)}
  .beside{display:block;position:fixed;z-index:7;left:var(--cl);right:var(--pad);top:calc(var(--bar) + 9vh);opacity:0;visibility:hidden;transition:opacity .3s,visibility 0s .3s}
  .on-offer #besideOffer,.on-talk #besideTalk{opacity:1;visibility:visible;transition:opacity .5s .25s}
  .beside .k{margin-bottom:12px}
  .beside h2{font:var(--w-display) clamp(34px,4.2vw,64px)/1 var(--display);letter-spacing:-.03em;max-width:14ch;text-wrap:balance}
  .beside__slot{margin-top:clamp(40px,7vh,72px)}
  .beside .month{margin:0;padding:0;width:min(100%,640px,calc((100dvh - var(--bar) - 9vh - clamp(150px,8.4vw + 70px,215px) - 130px) * 1.3))}
  .reach{margin-top:clamp(32px,6vh,60px);max-width:620px;border-bottom:1px solid var(--rule)}
  .reach>*{display:grid;grid-template-columns:clamp(92px,10vw,150px) minmax(0,1fr) auto;align-items:baseline;gap:12px;padding:20px 0;border-top:1px solid var(--rule)}
  .reach span{font:500 11.5px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--chrome)}
  .reach b{overflow-wrap:anywhere;font:var(--w-display) clamp(16px,1.9vw,28px)/1.1 var(--display);letter-spacing:-.02em;color:var(--fg)}
  .reach i{font-style:normal;color:var(--accent-text);transition:transform .25s var(--ease)}
  .reach a:hover b{color:var(--accent-text)}.reach a:hover i{transform:translateX(5px)}
  .panel .in-phone{display:none}
  .panel--offer .sheet,.panel--talk .sheet{padding-top:calc(var(--bar) + 9vh - 6px)}   /* the column starts on the page's kicker line */
  .panel--offer .sheet>.lede{margin-top:0;font-size:15px;color:var(--fg)}
  .panel--talk .who2{margin-top:0}
  .panel--offer .sheet>.month{order:4}.panel--offer .sheet>.list{order:5}.panel--offer .sheet>.price{order:6}.panel--offer .sheet>.pill{order:7}   /* on a desktop the button closes the column, under the price */
}
.no-gl .beside{display:none}
.next{display:flex;align-items:baseline;gap:10px;margin-top:28px;padding:16px 0 14px;min-height:44px;border-top:1px solid var(--rule);font:500 11.5px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--chrome)}
.next b{font-weight:500;color:var(--accent-text)}
.next i{font-style:normal;color:var(--accent-text);margin-left:auto}
.next:hover b,.next:hover i{color:var(--fg)}
.k{font:500 11px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--chrome);display:flex;gap:10px;align-items:center}
.k .n{font-family:var(--mono);letter-spacing:.08em}
.k .client{color:var(--fg)}
.item h2{font:var(--w-display) 20px/1.08 var(--display);letter-spacing:-.025em;margin-top:9px}
.disc{font:500 10.5px/1.5 var(--mono);letter-spacing:.08em;color:var(--dim);margin-top:7px}
.item p.l,.pick .l{color:var(--dim);font-size:13.5px;line-height:1.5;margin-top:8px;max-width:38ch}
.sheet h2{font:var(--w-display) 30px/1.02 var(--display);letter-spacing:-.03em;text-wrap:balance}
.sheet .lede{color:var(--dim);font-size:14px;line-height:1.55;margin-top:12px;max-width:34ch}
.list{margin-top:26px}
.row{display:grid;grid-template-columns:30px 1fr;gap:10px;padding:16px 0;border-top:1px solid var(--rule)}
.row .n{font:500 11px/1.6 var(--mono);letter-spacing:.08em;color:var(--chrome)}
.row h3{font:var(--w-display) 17px/1.15 var(--display);letter-spacing:-.02em}
.row p{color:var(--dim);font-size:13px;line-height:1.5;margin-top:5px}
.row.extra h3{color:var(--dim)}
.voice{font:italic 400 16px/1.35 var(--voice);color:var(--fg);border-top:1px solid var(--rule);margin-top:22px;padding-top:14px}

/* ── the tab bar: four slabs (js/hero/dock.js) under four buttons. The slabs are drawn; the icons
   and the words are these, laid over them, and they arrive with them: the icons ride up with the
   slabs, the words type themselves once the slabs are up ── */
.dock{position:absolute;left:0;right:0;bottom:env(safe-area-inset-bottom,0px);height:124px;z-index:6;pointer-events:none;display:block;width:100%;
  background:linear-gradient(rgba(var(--bg-rgb),0),rgba(var(--bg-rgb),.9) 42%,rgba(var(--bg-rgb),.97));opacity:0;transition:opacity .4s}   /* the page dissolves under the slabs: paper, not glass */
.is-arrived .dock{opacity:1}   /* it comes with the arrival: at the cut itself the reel still fills the screen, edge to edge */
.tabs{position:absolute;left:0;right:0;bottom:env(safe-area-inset-bottom,0px);height:88px;z-index:7;display:grid;grid-template-columns:repeat(4,1fr)}
.tab{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;padding-top:14px;gap:17px;font:500 10.5px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--chrome);transition:color .2s}
.tab svg .f{fill:currentColor;stroke:none}
/* the icon rides up with its slab (.ic), and lies on the slab's face: the same lean the slab has (dock.js: 24° back, 10° once it lifts), seen from the same camera */
.tab .ic{display:block;width:22px;height:22px;opacity:0;transform:translateY(64px);transition:transform .65s cubic-bezier(.34,1.56,.64,1),opacity .2s}
.is-arrived .tab .ic{opacity:1;transform:none}
.tab:nth-child(2) .ic{transition-delay:.07s}.tab:nth-child(3) .ic{transition-delay:.14s}.tab:nth-child(4) .ic{transition-delay:.21s}
.tab svg{display:block;width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;transform:perspective(230px) rotateX(24deg);transition:transform .32s var(--ease)}
.tab[aria-selected=true] svg{transform:perspective(230px) rotateX(10deg)}
.tab[aria-selected=true]{color:var(--fg)}
.tab>span{min-height:11px;white-space:nowrap}
.tab>span i{display:inline-block;font-style:normal}
.tab>span i.is-off{opacity:0}
.tab>span i.is-pop{animation:keypop .18s var(--ease)}
.no-gl .status{position:sticky;transform:none;opacity:1;pointer-events:auto;background:var(--bg);border-bottom:1px solid var(--rule)}
.no-gl .panels{position:relative;display:block;overflow:visible}
.no-gl .panel{height:auto;overflow:visible}
.no-gl .panel .sheet{padding-bottom:40px}
.no-gl .tabs{position:sticky;bottom:0;height:62px;background:var(--bg);border-top:1px solid var(--rule)}
.no-gl .tab{padding-top:10px;gap:6px}
.no-gl .tab .ic,.no-gl .tab svg{opacity:1;transform:none;transition:none}

/* ── inside, on a desktop: the captions beside the phone ───────────────────── */
.aside{position:fixed;top:50%;transform:translateY(-50%);z-index:6;width:min(300px,26vw);opacity:0;transition:opacity .4s;pointer-events:none}
.is-inside .aside{opacity:1;pointer-events:auto}
.is-inside .aside.is-off{opacity:0;pointer-events:none}
.aside--l{left:var(--pad)}.aside--r{right:var(--pad);text-align:right}
.aside .k{margin-bottom:12px}
.aside h2{font:var(--w-display) clamp(22px,2.4vw,34px)/1.04 var(--display);letter-spacing:-.03em}
.aside .disc{margin-top:10px}
.aside p.l{color:var(--dim);font-size:14px;line-height:1.5;margin-top:12px}
.aside .hint{font:500 11.5px/1.6 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--chrome);margin-top:14px}
.aside .pill{margin-top:0}
.aside .back{display:block;margin-top:16px;font:500 11.5px/1 var(--body);letter-spacing:.06em;text-transform:lowercase;color:var(--accent-text)}
.no-gl .aside{display:none}

@media (max-width:720px){
  .outside{bottom:calc(var(--bar) + 18px);max-width:calc(100vw - 32px)}
  .outside h1{font-size:clamp(34px,11vw,48px)}
  .inside{--iw:100vw;--ih:100dvh;width:var(--iw);height:var(--ih)}
  .aside,.bar .hide-sm{display:none}
  .status .snd span{display:none}   /* on a phone the speaker is the icon alone, by the clock */
  .is-inside .bar,.is-inside .bar>*{opacity:0;pointer-events:none;transition:opacity .3s}
}
