/* Vortex — Navier–Stokes. A single guided story over a WebGPU scene.
   Text and mathematics share the canvas: the left column is a reading lane
   the camera framing deliberately leaves empty. */

@font-face{font-family:Inter;src:url('./fonts/inter-latin.woff2') format('woff2');font-style:normal;font-weight:100 900;font-display:swap}
@font-face{font-family:'Latin Modern Math';src:url('./fonts/latinmodern-math.otf') format('opentype');font-style:normal;font-weight:400;font-display:block}

:root{
  color-scheme:dark;
  --fg:#eef6f3;--muted:#adc7ce;--line:#91b9c52e;--cyan:#6ce5df;
  font:15px/1.4 Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
}

/* ---- Reset and shell ---- */
*{box-sizing:border-box}
[hidden]{display:none!important}
body{margin:0;background:#01070b;color:var(--fg);overflow:hidden}
button,input{font:inherit}
button{color:inherit;border:0;background:none;cursor:pointer}
button,a,input{-webkit-tap-highlight-color:transparent}
button:focus-visible,a:focus-visible,summary:focus-visible,input:focus-visible{outline:2px solid var(--cyan);outline-offset:5px}
a{color:inherit;text-decoration:none}
a:hover,button:hover{color:#fff}
svg{width:23px;height:23px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0;pointer-events:none}

#view{position:fixed;inset:0;width:100%;height:100%;touch-action:none;cursor:grab}
#view.dragging{cursor:grabbing}
.shell{position:fixed;inset:0;pointer-events:none}
.shell button,.shell input{pointer-events:auto}

/* A single quiet affordance for the model, scope and sources. */
.about-link{position:fixed;right:28px;top:18px;z-index:8;display:flex;align-items:center;gap:8px;padding:6px 2px;min-height:36px;font-size:14px;color:#a4c4d6;opacity:.7;transition:opacity .15s}
.about-link:hover{opacity:1}
.about-link svg{width:15px;height:15px}

/* ---- The story scene ---- */
/* Shared sizes for the left reading column: labels, values, support text. */
.story-overlay{position:absolute;inset:0;pointer-events:none;
  --story-label-size:24px;--story-value-size:48px;--story-note-size:20px;--story-formula-gap:26px}

.story-copy{position:absolute;z-index:3}
.story-copy h1{font:400 clamp(36px,3vw,56px)/1.15 Georgia,serif;letter-spacing:-.035em;max-width:100%;margin:0;color:#f4fafc;text-shadow:0 2px 24px #000}
.story-copy[data-placement=above] h1{font-size:32px}
.story-copy .story-scope{margin:12px 0 0;font-size:var(--story-note-size);line-height:1.35;color:var(--muted);pointer-events:auto}

.story-equation{position:absolute;text-align:left;z-index:3;pointer-events:none}
.story-formula{display:flex;flex-direction:column;align-items:flex-start;gap:var(--story-formula-gap)}
.story-formula math{font-family:'Latin Modern Math',math;color:#e4eeec;margin:0;overflow:visible;font-variant-numeric:tabular-nums}
.story-formula math mn{color:#f0ce94}
.story-formula math mi{color:#c7e8e3}
.story-formula p{margin:0;line-height:1.45}
.story-formula p math{font-size:1.15em;color:inherit}
.story-formula .formula-heading{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 14px;margin-bottom:8px}
.story-formula .formula-heading math mi,.story-formula .formula-heading math mn{color:inherit}
.story-formula p,.story-key-heading,.story-scale{font-size:var(--story-label-size);color:#bed6db}
.story-formula>math:not(.story-energy-law),.story-scale math{font-size:var(--story-value-size)}
.story-key-heading span:last-child,.story-key-ticks,.story-formula .formula-condition{font-size:var(--story-note-size)}
.story-formula math.story-energy-law{font-size:calc(var(--story-value-size)*.72);margin-top:12px}
/* Narrow scenes stack the equation below the viewport instead of beside it. */
.story-equation[data-placement=below] .story-formula{align-items:center;gap:8px}
.story-equation[data-placement=below] .story-formula p{display:none}
.story-equation[data-placement=below] .story-formula math{font-size:28px}
.story-equation[data-placement=below] #story-formula-aspect p{display:block;margin:0;font-size:var(--story-label-size);max-width:100%;line-height:1.2}
.story-equation[data-placement=below] #story-formula-aspect p span{display:none}
.story-equation[data-placement=below] .story-energy-law{display:none}

/* A quiet key and physical scale sit in the unused lower-left scene margin. */
.story-legends{position:fixed;left:56px;bottom:156px;width:350px;display:flex;flex-direction:column;gap:32px;z-index:3}
.story-speed-key{order:0;color:#c7dcdf;pointer-events:auto}
.story-key-heading,.story-key-ticks{display:flex;justify-content:space-between;align-items:baseline;gap:12px}
.story-key-heading{margin-bottom:14px}
.story-key-heading span:last-child{color:#aec9ce}
/* Painted from the shared rotation palette at startup, so the key and the
   shaders can never drift apart. */
.story-key-gradient{height:9px;border-radius:5px}
.story-key-ticks{margin-top:10px;color:#b2cdd2}
.story-scale{order:1;color:#bed6db;pointer-events:auto;line-height:1.4}
.story-scale>div{display:flex;flex-direction:column;align-items:flex-start;gap:14px;margin-top:14px}
.story-scale math{font-family:'Latin Modern Math',math;font-variant-numeric:tabular-nums;color:#d7e9e6}
.story-scale math mn{color:#eed19d}

/* The main view gets the height; the rail keeps the other cameras in place. */
.story-panel{position:absolute;border:1px solid #86b6c621;border-radius:14px;background:linear-gradient(140deg,#779eae04,transparent 65%);overflow:hidden}
.story-panel[data-featured=true]{border-color:#8caab810;background:transparent}
.story-panel>button{position:absolute;inset:0;display:flex;align-items:flex-start;justify-content:space-between;gap:10px;padding:14px 16px;text-align:left;pointer-events:auto;border-radius:14px;transition:background .15s,box-shadow .15s}
.story-panel>button:hover{background:#7cbbb610;box-shadow:inset 0 0 0 1px #82c4c23d}
.story-panel>button[aria-pressed=true]{background:linear-gradient(140deg,#7cbbb611,transparent 60%);box-shadow:inset 0 0 0 1px #88d8d36b}
.story-panel>button[aria-pressed=true] .pane-expand{color:#b0eee6}
.story-panel>button:focus-visible{outline:2px solid #a0e8df;outline-offset:-3px}
.story-panel[data-featured=true]>button{visibility:hidden;pointer-events:none}  /* hides .pane-expand with it */
.story-panel>button b{font-size:clamp(20px,1.2vw,24px);font-weight:500;display:block;line-height:1.2;color:#e1ecee}
.pane-expand{font-size:23px;color:#89b7ba}

/* ---- Mechanism captions, drawn beside the flow ---- */
.story-diagram-layer{position:absolute;inset:0;pointer-events:none;z-index:4}
#story-diagram-guides{position:fixed;inset:0;width:100%;height:100%;overflow:hidden}
#story-diagram-guides path{fill:none;stroke:#b4d6d1;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
#story-direction-guide{stroke:#d6f5ec!important;stroke-width:2.5!important;filter:drop-shadow(0 0 3px #020909)}
#story-width-guide{stroke:#c4e5df!important;stroke-width:2!important;opacity:.8}
.story-diagram-note{position:fixed;padding:0;background:radial-gradient(ellipse at center,#020909e8 25%,#0209098c 66%,transparent 100%);text-shadow:0 1px 8px #000}
.story-diagram-note[data-zone=rotation]{text-align:center}
.story-diagram-note h2{font-family:inherit;font-weight:500;font-size:clamp(22px,1.5vw,28px);line-height:1.25;color:#e2eee8;margin:0 0 12px;text-wrap:pretty}
.story-diagram-note .story-description{font-size:clamp(20px,1.35vw,25px);line-height:1.4;margin:0;min-height:2.8em;max-width:100%;color:#c3dbde;text-wrap:pretty}
.story-plane-label{position:fixed;font-size:20px;color:#bdd3d8;text-shadow:0 1px 8px #000;padding:4px 10px;background:#020909c9;border-radius:4px;white-space:nowrap}

.story-ending{position:fixed;z-index:5;transform:translate(-50%,-50%);text-align:center;pointer-events:none;text-shadow:0 2px 18px #020909;background:#020606f5;box-shadow:0 0 48px 28px #020606d9}
.story-ending .ending-kicker{font-size:24px;color:#a8d8d2;margin:0 0 20px}
.story-ending h2{font:clamp(32px,3.2vw,54px)/1.13 Georgia,serif;letter-spacing:-.025em;margin:0 0 28px;color:#f0eee6;text-wrap:balance}
.story-ending h2 span{display:block;white-space:nowrap}
.story-ending p{font-size:clamp(20px,1.45vw,26px);line-height:1.45;margin:0 0 18px;color:#d0e2e1;text-wrap:pretty}
.story-ending small{display:block;font-size:20px;line-height:1.4;color:#aac4c8;margin-top:28px}

/* ---- Chapters, scrubber and transport ---- */
.chapter-nav{position:fixed;left:32px;right:32px;bottom:78px;display:grid;grid-template-columns:repeat(5,1fr);gap:16px;height:36px}
.chapter-nav button{font-size:18px;display:flex;align-items:center;gap:10px;text-align:left;padding:9px 0;color:#94b2bc;border-top:1px solid #779aaa3d;transition:color .35s,border-color .35s}
.chapter-nav button span{font-size:16px;color:#89b5b6}
.chapter-nav button[aria-current=step]{color:#edf5ef;border-color:#84e0d7}
.chapter-nav button[aria-current=step] span{color:#84e0d7}

.story-progress{position:fixed;left:160px;right:32px;bottom:40px;display:flex;align-items:center;gap:22px;height:24px;pointer-events:auto}
#story-progress{--fill:0%;appearance:none;flex:1;width:100%;min-width:0;height:24px;margin:0;border:0;cursor:pointer;accent-color:var(--cyan);
  background:linear-gradient(to right,var(--cyan) 0 var(--fill),#325465 var(--fill) 100%);background-size:100% 2px;background-position:center;background-repeat:no-repeat}
#story-progress::-webkit-slider-thumb{appearance:none;width:14px;height:14px;border:0;border-radius:50%;background:var(--cyan);box-shadow:0 0 16px #00dce973}
#story-progress::-moz-range-thumb{width:14px;height:14px;border:0;border-radius:50%;background:var(--cyan);box-shadow:0 0 16px #00dce973}
.story-progress output{font-size:16px;font-variant-numeric:tabular-nums;white-space:nowrap;color:#a1bfc6}
.story-timeline-label{font-size:18px;white-space:nowrap;color:#b9d1d5}
/* Tick marks share the slider's thumb-centre interval. The presentation-time
   counter stays separate from these physical remaining-time ratios. */
.story-time-track{position:relative;display:flex;flex:1;min-width:0;align-items:center}
.story-time-ticks{position:absolute;left:7px;right:7px;top:28px;height:22px;pointer-events:none;font-size:16px;line-height:20px;color:#b9d1d5;font-variant-numeric:tabular-nums}
.story-time-ticks>span{position:absolute;left:calc(var(--position)*100%);transform:translateX(-50%);white-space:nowrap}
.story-time-ticks>span:first-child{transform:none}
.story-time-ticks>span:last-child{transform:translateX(-100%)}
.story-time-ticks>span:before{content:'';position:absolute;left:50%;top:-7px;height:4px;border-left:1px solid #769a9e}
.story-time-ticks>span:first-child:before{left:0}
.story-time-ticks>span:last-child:before{left:100%}
.story-time-ticks sup{font-size:.75em}

footer{position:absolute;left:32px;bottom:29px;width:108px;height:46px;display:flex;align-items:center;gap:12px}
.play{width:40px;min-width:40px;height:40px;display:flex;align-items:center;justify-content:center;padding:0;border:1px solid #87d9d19c;border-radius:30px;background:#102726;transition:background .2s,box-shadow .2s}
.play:hover{background:#07516077;box-shadow:0 0 26px #00d9f333}
.play svg{width:18px;height:18px}
.restart{display:flex;align-items:center;justify-content:center;min-width:40px;min-height:40px;padding:3px;color:#a9cde4}
.restart svg{width:23px;height:23px}

/* ---- Loading and failure ---- */
#loading{position:fixed;inset:0;background:#020a12ec;backdrop-filter:blur(18px);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:15px;z-index:50}
#loading strong{font:27px Georgia,serif}
#loading p{font-size:14px;color:#94b2c2;margin:0;max-width:360px;text-align:center;line-height:1.6}
#retry{margin-top:10px;border:1px solid #69c7e366;border-radius:7px;padding:9px 18px}
.spinner{width:28px;height:28px;border:1px solid #2c586f;border-top-color:var(--cyan);border-radius:50%;animation:spin 1.1s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---- Model & sources dialog ---- */
dialog{color:var(--fg);background:#071520;border:1px solid #76b3d144;border-radius:15px;padding:30px;width:min(730px,calc(100vw - 30px));max-height:85dvh;line-height:1.7;box-shadow:0 25px 130px #000;scrollbar-width:thin}
dialog::backdrop{background:#01050bbe;backdrop-filter:blur(8px)}
.dialog-header{display:flex;align-items:center;justify-content:space-between;gap:20px;position:sticky;top:-30px;background:#071520;padding:12px 0;z-index:2}
.dialog-header h2{font:31px Georgia,serif;margin:0}
.dialog-header button{padding:7px;display:flex}
dialog h3{color:#cce5ef;font-size:17px;font-weight:500;margin-top:27px}
dialog p{color:#9cb7c8;font-size:16px}
dialog code{font:.9em ui-monospace,SFMono-Regular,Consolas,monospace;color:#bad9e4}
dialog p a{color:#81d7df;text-decoration:underline;text-underline-offset:3px}
.model-lede{color:#d3e8ee;font-size:16px}
.science{margin:24px 0;padding:16px 0;border-block:1px solid var(--line)}
.science summary{font-size:16px;color:#cbe5ed;cursor:pointer}
.science p{font-size:14px;line-height:1.75}
.figure-audit{overflow-x:auto}
.figure-audit table{width:100%;border-collapse:collapse;font-size:14px;line-height:1.6;text-align:left}
.figure-audit th,.figure-audit td{padding:12px 8px;border-bottom:1px solid #82b6d026;vertical-align:top}
.figure-audit tbody th{width:64px;white-space:nowrap;font-weight:500}
.figure-audit td{color:#b4ccda}
.figure-audit a{color:#5cdbdf;text-decoration:underline;text-underline-offset:3px}
.equation{background:#0c2535;border:1px solid #70adc32b;padding:16px;border-radius:8px;font-size:14px;line-height:2;color:#c2e0ec}
.scope{border-left:2px solid #dfa96b;padding-left:16px}
.source-links{display:flex;gap:9px 20px;flex-wrap:wrap;border-top:1px solid var(--line);padding-top:20px;margin-top:24px;font-size:14px;color:#89d5e3}

/* ---- Responsive ---- */
@media(min-width:760px) and (max-height:1100px){
 .story-overlay{--story-label-size:22px;--story-value-size:42px;--story-note-size:18px;--story-formula-gap:22px}
}
@media(min-width:760px) and (max-height:799px){
 .story-overlay{--story-label-size:20px;--story-value-size:34px;--story-note-size:18px;--story-formula-gap:18px}
 .story-copy[data-placement=above] h1{font-size:36px}
 .story-panel:not([data-featured=true])>button{padding:10px 16px}
 .story-diagram-note h2{font-size:20px;margin-bottom:8px}
 .story-diagram-note .story-description{font-size:18px}
 .story-ending .ending-kicker{font-size:20px;margin-bottom:12px}
 .story-ending h2{font-size:36px;margin-bottom:20px}
 .story-ending p{font-size:18px;line-height:1.4;margin-bottom:12px}
 .story-ending small{font-size:16px;margin-top:18px}
}
@media(max-width:1200px),(max-height:799px){
 .story-plane-label{font-size:18px}
}
/* Short recording windows keep the two length ratios on one line. */
@media(min-width:760px) and (max-height:1000px){
 .story-key-heading{margin-bottom:10px}
 .story-key-ticks{margin-top:8px}
 .story-scale>div{flex-direction:row;gap:12px;margin-top:8px}
}
/* Below the desktop reading-column breakpoint, retain room for the plot. */
@media(min-width:760px) and (max-width:1200px),(min-width:760px) and (max-height:799px){
 .story-legends{width:auto;max-width:calc(100vw - 112px);flex-direction:row;align-items:flex-end;gap:32px;bottom:116px}
 .story-speed-key{width:240px}
 .story-key-heading{margin-bottom:9px;column-gap:6px}
 .story-key-ticks{margin-top:7px}
 .story-scale>div{flex-direction:row;gap:10px;margin-top:8px}
}
@media(min-width:760px) and (max-width:1200px){
 .chapter-nav{gap:10px}
 .chapter-nav button{gap:8px}
}
@media(max-width:759px){
 .story-overlay{--story-label-size:16px;--story-value-size:26px;--story-note-size:15px;--story-formula-gap:12px}
 .story-copy h1,.story-copy[data-placement=above] h1{font-size:28px}
 .story-copy .story-scope{margin-top:8px;font-size:14px}
 .story-formula{gap:8px;align-items:center}
 .story-formula p{display:none}
 #story-formula-energy math{font-size:21px}
 .story-panel>button{padding:12px 12px}
 .story-diagram-note h2{font-size:18px;margin-bottom:8px}
 .story-diagram-note .story-description{font-size:16px}
 .story-plane-label{font-size:14px}
 .story-legends{left:28px;right:28px;bottom:140px;width:auto;flex-direction:row;align-items:flex-end;gap:22px}
 .story-speed-key{flex:1;min-width:0}
 .story-key-heading{margin-bottom:8px}
 .story-key-heading span:last-child{display:none}
 .story-key-ticks{margin-top:6px}
 .story-key-gradient{height:7px}
 .story-scale{max-width:165px}
 .story-scale>div{gap:3px;margin-top:5px}
 .story-ending .ending-kicker{font-size:18px;margin-bottom:12px}
 .story-ending h2{font-size:30px;margin-bottom:18px}
 .story-ending p{font-size:18px;margin-bottom:12px}
 .story-ending small{font-size:14px;margin-top:18px}
 .chapter-nav{left:16px;right:16px;bottom:82px;gap:7px}
 .chapter-nav button{font-size:14px;gap:0;justify-content:center;line-height:1.2;padding:5px 0;text-align:center}
 .chapter-nav button span{display:none}
 .chapter-nav button:nth-child(4){font-size:0}
 .chapter-nav button:nth-child(4):after{content:'Shrink';font-size:14px}
 .story-progress{left:112px;right:16px;bottom:40px;gap:7px}
 .story-timeline-label{display:none}
 .story-time-ticks{font-size:14px}
 .story-time-ticks .intermediate-tick{display:none}
 footer{left:16px;height:44px}
 .play{height:44px}
 .about-link{right:16px;top:14px;font-size:14px;gap:5px}
 dialog{padding:22px}
}
@media(prefers-reduced-motion:reduce){
 *,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}
}
