/* Three roles, three self-hosted faces, no external font request (W4.2). Display is Plex 600 rather than Neue
Montreal: spec 3.1 makes that the fallback unless the Fontshare licence is verified to permit self-hosting, and it
could not be (their licence page serves a script shell). Mono is Geist Mono 400, SIL OFL, from the geist package. */
:root{--bg:#070c10;--panel:#04090c;--accent:#72e8de;--text:#e4e9e9;--nav-bg:#070c10f5;--font-display:Plex,Arial,sans-serif;--font-text:Plex,Arial,sans-serif;--font-ui:Plex,Arial,sans-serif;--font-mono:'Geist Mono',ui-monospace,monospace}
@font-face{font-family:Plex;src:url('/assets/vendor/plex-400.ttf');font-weight:400;font-display:swap}
@font-face{font-family:Plex;src:url('/assets/vendor/plex-600.ttf');font-weight:600;font-display:swap}
@font-face{font-family:'Geist Mono';src:url('/assets/vendor/geist-mono-400.ttf');font-weight:400;font-display:swap}

*{box-sizing:border-box}
html{color-scheme:dark;scrollbar-color:#3b4c55 #070c10;scroll-behavior:auto;scroll-padding-top:125px;overflow-y:scroll}
body{margin:0;background:var(--bg);color:var(--text);font-family:var(--font-text);line-height:1.6;overflow-x:clip}
a{color:inherit;text-decoration:none}
a:hover{color:#b1d3cd}
button{font:inherit;cursor:pointer}
a:focus-visible,button:focus-visible,summary:focus-visible{outline:2px solid #b8d7d5;outline-offset:5px}
code{font-family:var(--font-mono);font-size:.85em;color:#c4d7d4;overflow-wrap:anywhere}

/* Site navigation */
.site-nav,.chapter-nav,.site-footer{font-family:var(--font-ui)}
.site-nav{position:fixed;inset:0 0 auto;z-index:10;height:70px;padding:0 clamp(24px,5vw,96px);display:flex;align-items:center;justify-content:space-between;background:var(--nav-bg);border-bottom:1px solid #9fc5cb20}
.brand{font-family:var(--font-ui);font-weight:600;font-size:22px;letter-spacing:-.04em}
.brand-ai{color:var(--accent)}
.site-nav .brand{font-size:23px;line-height:1;white-space:nowrap}
.site-nav>div{display:flex;align-items:center;gap:28px;font-size:13px}
.site-nav>div>a{line-height:20px;font-size:13px;color:#bdc9cc}
.site-nav>div>a:first-child{color:#e8f4f2;background:#12221f;border:1px solid #72e8de55;padding:7px 14px;border-radius:5px}
.site-nav>div>a:hover{color:white}
.chapter-nav{position:fixed;inset:70px 0 auto;z-index:9;display:flex;align-items:stretch;gap:clamp(18px,2.4vw,34px);height:48px;padding:0 clamp(24px,5vw,96px);background:#080f13f5;border-bottom:1px solid #ffffff0d;overflow-x:auto;white-space:nowrap;scrollbar-width:thin;opacity:0;visibility:hidden;transform:translateY(-6px);transition:opacity .25s,transform .25s,visibility .25s;pointer-events:none}
.content-entered .chapter-nav{opacity:1;visibility:visible;transform:none;pointer-events:auto}
.chapter-nav a{display:inline-flex;align-items:center;position:relative;padding:0;font-size:12px;color:#91a4aa}
.chapter-rail-label{display:none}
.chapter-nav a[aria-current]{color:#d9f7f1;border-color:#9fd9e1}
.chapter-nav a[aria-current]::after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--accent)}
.chapter-nav a:hover{color:white}

/* Hero room and the approach to the desk */
#living-room{position:fixed;inset:0;width:100%;height:100%;pointer-events:none;z-index:0}
#living-room{opacity:0;transition:opacity 1.6s ease-out}.scene-ready #living-room{opacity:1}
@media (prefers-reduced-motion:reduce){#living-room{transition:none}}
.cipher-journey{position:relative;height:135svh}
.cipher-stage{position:sticky;top:0;height:100svh;pointer-events:none}
/* The intro holds the left 40 percent so the figure, monitor and lamp own the right of the frame (W3.1). */
.room-intro{position:absolute;left:6vw;bottom:9vh;max-width:min(530px,40vw);pointer-events:auto;text-shadow:0 2px 20px #000}
.room-intro h1{font-family:var(--font-display);font-size:clamp(32px,4vw,55px);font-weight:600;letter-spacing:-.045em;line-height:1.1;margin:0 0 18px}
.room-intro p{font-size:19px;max-width:420px;color:#c3cecf;margin:0 0 20px}
.room-intro .text-link{margin-right:22px}
.text-link{display:inline-block;font-size:14px;border-bottom:1px solid #8caaa773;padding:8px 0}
#scene-status{display:block;font-size:12px;color:#9fb7b9;margin:0 0 8px}
#scene-status:empty{display:none}
/* Phase 6 D intro: the load is shown by the room fading up, so the bar stays only for assistive technology. */
.scene-progress{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%)}
.scene-progress span{display:block;height:100%;width:0;background:var(--accent);transition:width .2s linear}
.scene-progress[hidden]{display:none}
.device-tour{position:relative;height:90svh;z-index:1;pointer-events:none}
.device-tour-stage{position:sticky;top:120px;height:calc(100svh - 120px)}
.tour-caption{position:absolute;left:6vw;bottom:11vh;font-size:15px;color:#aec1c5;letter-spacing:.015em;margin:0;text-shadow:0 2px 15px #000}
.tour-skip{position:absolute;right:6vw;bottom:11vh;font-size:12px;color:#b9d0ce;pointer-events:auto;border-bottom:1px solid #90b2ae55}

/* Chapters: the copy is typeset onto the objects; the DOM copy stays as the source */
.object-story{position:relative;z-index:1}
.object-chapter{position:relative;display:block;min-height:180svh;padding:0 7vw;scroll-margin-top:0}
.art-space{display:none}
.inspect-art{position:absolute;bottom:0;left:50%;transform:translateX(-50%);padding:7px 12px;background:#0b151cc9;border:1px solid #89aaa633;color:#adc9c7;font-size:11px;z-index:2}
.inspect-art[aria-pressed="true"]{border-color:#86b6af}
.object-copy{position:sticky;top:145px;margin:0 auto;max-width:780px;padding:30px 34px 45px;background:transparent;transform-origin:50% 40%;will-change:transform,opacity;visibility:hidden}
.object-copy h2{font-family:var(--font-display);font-size:clamp(34px,4vw,60px);font-weight:600;line-height:1.08;letter-spacing:-.04em;margin:0 0 25px;max-width:none}
.object-copy h3{font-size:19px;color:#e9f2f3;margin:22px 0 8px}
.object-copy p{font-size:18px;line-height:1.7;color:#b3c1c6;margin:0 0 20px}
.object-copy p.aside{font-size:14px;color:#879ca5}
.plain-list{padding-left:18px;margin:20px 0 25px;font-size:15px;color:#bdc9cd}
.plain-list li{margin:8px 0}
.object-copy .plain-list{columns:2;column-gap:34px}
.code-block{position:relative;margin:26px 0 18px;padding:20px 65px 20px 20px;background:#101a20dc;border-left:2px solid #668c88}
.copy-command{position:absolute;right:12px;top:14px;background:transparent;border:0;color:#a4bbb9;font-size:11px;padding:8px}
.object-copy details{border-top:1px solid #ffffff20;margin:24px 0 10px;padding:15px 0}
.object-copy summary{cursor:pointer;font-size:14px;color:#d0dcdf;list-style-position:outside;margin-left:15px}
.object-copy details p{margin:16px 0;font-size:15px}
.measurements{margin:24px 0}
.measurements>div{border-top:1px solid #ffffff1a;padding:14px 0}
.measurements dt{font-size:18px}
.measurements dd{margin:5px 0 0;color:#a6b7bd;font-size:15px}
.source-copy{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;visibility:visible}
.skip-link{position:fixed;left:16px;top:-100px;z-index:20;padding:10px 14px;background:var(--panel);color:var(--text);border:1px solid var(--accent)}
.skip-link:focus-visible{top:12px;outline:2px solid var(--accent)}

/* Projected controls over the 3D text */
#spatial-actions{position:fixed;inset:0;z-index:5;pointer-events:none}
#spatial-actions .spatial-action{position:absolute;pointer-events:auto;opacity:1;font-size:0;padding:0;border:0;background:transparent;color:transparent;cursor:pointer;transition:background .16s,border-color .16s}
#spatial-actions a.spatial-action{border-bottom:1px solid var(--accent)}
#spatial-actions button.spatial-action{border:1px solid #72e8de80;border-radius:4px}
#spatial-actions .spatial-action:hover{background:#72e8de14;border-color:#d7fffb}
#spatial-actions .spatial-action:focus-visible{outline:2px solid #d7fffb;outline-offset:4px;background:#72e8de14}

/* Fixed film grain: one finish over canvas and footer alike (spec W1.5b). Stepped, 12 fps, frozen for reduced motion. */
.grain{position:fixed;inset:0;z-index:4;pointer-events:none;opacity:.05;mix-blend-mode:soft-light;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5 0 0 0 0 .5 0 0 0 0 .5 0 0 0 1 0'/%3E%3C/filter%3E%3Crect width='256' height='256' filter='url(%23n)'/%3E%3C/svg%3E");background-size:256px 256px;animation:grain-step .5s steps(6) infinite}
@keyframes grain-step{0%{background-position:0 0}100%{background-position:96px -64px}}
.no-webgl .grain,.tier-b .grain,.tier-c .grain{display:none}
.idle-paused .grain{animation:none}
/* Motion control */


/* The toggle lives in the nav as a small icon-sized control (W4.4); the floating box that sat over the phone
   copy is gone, so there is nothing left to hide when the footer arrives. */
.motion-toggle{width:20px;height:20px;padding:0;border:0;border-radius:4px;background:#1b2a2e;color:transparent;cursor:pointer;position:relative;overflow:hidden;text-indent:-200px;flex:0 0 auto}
.motion-toggle::before{content:"";position:absolute;left:6px;top:5px;width:3px;height:10px;border-left:3px solid #9fd9e1;border-right:3px solid #9fd9e1;text-indent:0}
.motion-toggle[aria-pressed="false"]::before{left:7px;width:0;height:0;border:5px solid transparent;border-left:8px solid #9fd9e1;top:5px}
.motion-toggle:hover{background:#24383d}
.motion-toggle:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* Footer */
/* The top 240px fade in from the scene so the last fixture darkens behind the footer instead of meeting a black band (W3.6). */
.site-footer{position:relative;z-index:2;padding:0 clamp(24px,6vw,110px) 26px;background:linear-gradient(to bottom,#080e1200 0,#080e12 240px)}
.site-footer>div{display:grid;gap:32px;margin:0;font-size:13px;color:#a4b6bd}
.site-footer p{font-size:15px;line-height:1.65;color:#9fadb3;margin:0 0 24px}
.footer-start{display:grid;grid-template-columns:1.3fr 1fr;gap:70px;align-items:center;padding:72px 0 64px;border-bottom:1px solid #243238}
.site-footer .footer-eyebrow{font-size:13px;color:var(--accent);margin:0 0 12px}
.footer-start h2{font-size:clamp(32px,4vw,52px);letter-spacing:-.035em;line-height:1.1;margin:0 0 20px;font-weight:600}
.footer-primary{display:inline-flex;align-items:center;background:#c7eee5;color:#10211d;padding:12px 18px;border-radius:5px;font-size:14px;font-weight:600}
.footer-primary:hover{background:#e0fff7;color:#10211d}
.footer-command{border-left:1px solid #3f6b66;padding:14px 0 14px 32px}
.footer-command>span{font-size:12px;color:#8d9fa6}
.footer-command pre{margin:18px 0;white-space:pre-wrap}
.footer-command code{font-size:19px;line-height:1.9;color:#e3eeeb}
.site-footer .footer-command p{font-size:12px;margin:0}
.site-footer .footer-directory{grid-template-columns:2fr 1fr 1fr;padding:44px 0}
.footer-directory nav{display:flex;flex-direction:column;align-items:flex-start;gap:10px}
.footer-directory h3{font-size:13px;color:#edf4f3;margin:0 0 7px;font-weight:600}
.footer-directory nav a{font-size:13px;color:#96a8ae}
.footer-directory nav a:hover{color:#b9f1e4;text-decoration:underline;text-underline-offset:4px}
.footer-identity .brand{display:inline-block;margin-bottom:15px}
.site-footer .footer-identity p{font-size:13px;margin:0}
.site-footer .footer-bottom{display:flex;justify-content:space-between;border-top:1px solid #243238;padding-top:22px;font-size:12px;color:#82959d}
.footer-bottom a{color:#b0c2c7}

/* Text-only fallback when WebGL is unavailable or ?view=text is set */
.no-webgl .art-space,.no-webgl #living-room,.no-webgl .device-tour,.no-webgl .motion-toggle,.no-webgl #spatial-actions,.no-webgl #scene-status,.no-webgl .scene-progress{display:none}
.no-webgl .cipher-journey,.no-webgl .cipher-stage{height:85svh}
.no-webgl .object-chapter{display:block;min-height:0!important;padding:50px 6vw;scroll-margin-top:90px}
/* Tier C: no usable WebGL. The hero shows a still of the real scene; the chapters read as text. */
.tier-c .cipher-stage{background:url(/assets/hero-poster.webp?v=1) center/cover no-repeat}
.no-webgl .object-copy{position:relative!important;top:auto;width:auto;height:auto;max-width:750px;margin:0 auto;padding:0;overflow:visible;white-space:normal;background:none!important;opacity:1!important;visibility:visible!important;transform:none!important;clip-path:none!important}

@media(max-width:760px){
html{scroll-padding-top:112px}
.site-nav{height:60px;padding:0 22px}
.site-nav .brand{font-size:20px}
.site-nav>div{gap:18px;font-size:12px}
.site-nav>div a:last-child{display:none}
/* Phones get a dot rail with the current chapter named, instead of a row that scrolls sideways (W4.3).
   The link text stays in the DOM so every dot keeps its accessible name; only its rendering changes. */
.chapter-nav{top:60px;height:44px;gap:0;padding:0 14px;overflow-x:hidden;justify-content:flex-start}
.chapter-nav a{width:24px;min-width:24px;height:44px;overflow:hidden;white-space:nowrap;text-indent:-200px;color:transparent}
.chapter-nav a::before{content:"";position:absolute;left:8px;top:50%;width:8px;height:8px;margin-top:-4px;border-radius:50%;background:#44585f;text-indent:0}
.chapter-nav a[aria-current]::before{background:var(--accent)}
.chapter-nav a[aria-current]::after{display:none}
.chapter-rail-label{display:block;margin:0 0 0 10px;font-size:12px;line-height:44px;color:#b3c1c6;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cipher-journey{height:125svh}
.room-intro{bottom:12vh;max-width:87vw}
.room-intro p{font-size:17px;max-width:330px}
.room-intro .text-link{font-size:12px}
.device-tour{height:85svh}
.device-tour-stage{top:105px;height:calc(100svh - 105px)}
.tour-caption{bottom:9vh;max-width:50vw;font-size:13px}
.tour-skip{bottom:9vh;font-size:11px}
.object-chapter{padding:0 6vw}
.object-copy{top:112px;padding:22px 0 40px}
.object-copy h2{font-size:34px;margin-bottom:20px}
.object-copy p{font-size:16px}
.object-copy p.aside{font-size:13px}
.object-copy .plain-list{columns:1}
.object-copy details{margin-top:18px}


.footer-start{grid-template-columns:1fr;gap:30px;padding:46px 0}
.footer-command{padding-left:20px}
.site-footer .footer-directory{grid-template-columns:1fr 1fr;gap:30px}
.footer-identity{grid-column:1/-1}
.site-footer .footer-bottom{gap:20px}
.footer-primary{font-size:13px}
}
@media(prefers-reduced-motion:reduce){
.chapter-nav{transition:none}
.grain{animation:none}
}
/* W5.4: the scene is held at a static pose and the chapter copy is read from the document, so it has to be
   visible and in flow. Same layout the no-WebGL path uses, with the canvas kept behind it. */
.static-scene .object-copy{position:relative!important;top:auto;width:auto;height:auto;max-width:750px;margin:0 auto;padding:34px 38px 40px;overflow:visible;white-space:normal;background:#04090cf2!important;border:1px solid #ffffff14;border-radius:10px;opacity:1!important;visibility:visible!important;transform:none!important;clip-path:none!important}
.static-scene .object-chapter{display:block;min-height:100svh;padding:150px 6vw 90px;scroll-margin-top:90px}
.static-scene .object-copy .visually-hidden{position:static;width:auto;height:auto;clip:auto;clip-path:none;white-space:normal;overflow:visible}
