/* the page declares the Haffer faces (the prototype from web3d/fonts, the website from /fonts) */
:root{
  --black:#17181C; --orange:#FF581C; --white:#FFFFFF; --grey:#F7F7F7;
  --ink:rgba(255,255,255,.96); --ink-2:rgba(247,247,247,.74); --ink-3:rgba(247,247,247,.46); --ink-4:rgba(247,247,247,.2);
  --night:#070b12;
  --f:"Haffer",Arial,Helvetica,sans-serif;
  --gutter:clamp(22px,3.4vw,56px);
  --ease:cubic-bezier(.2,.75,.15,1); --ease-in:cubic-bezier(.55,0,.8,.3);
}
*{box-sizing:border-box}
html{background:var(--night);color:var(--ink);scrollbar-width:none}
html::-webkit-scrollbar{display:none}
body{margin:0;font-family:var(--f);-webkit-font-smoothing:antialiased;overflow-x:hidden}
button,a{font:inherit;color:inherit}
button{background:none;border:0;padding:0;cursor:pointer}
:focus-visible{outline:2px solid var(--orange);outline-offset:4px}
.instant *,.instant *::before,.instant *::after{transition:none!important}

/* ---------------------------------------------------------------- stage */
/* the largest viewport: a phone's address bar sliding away never resizes or re-crops the film */
#stage{position:fixed;left:0;top:0;width:100%;height:100vh;height:100lvh;overflow:hidden;background:var(--night);transition:transform 2.8s var(--ease)}
body:not(.live) #stage{transform:scale(1.045)}
#film{position:absolute;inset:0;width:100%;height:100%;display:block}
#fx{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}
.scrim{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,rgba(6,9,14,.82) 0%,rgba(6,9,14,.58) 24%,rgba(6,9,14,.14) 44%,rgba(6,9,14,0) 56%),
             linear-gradient(0deg,rgba(6,9,14,.7) 0%,rgba(6,9,14,0) 22%),
             linear-gradient(180deg,rgba(6,9,14,.55) 0%,rgba(6,9,14,0) 16%)}
.vignette{position:absolute;inset:0;pointer-events:none;background:radial-gradient(120% 100% at 62% 48%,transparent 55%,rgba(3,5,9,.55) 100%)}
.grain{position:absolute;inset:-60px;pointer-events:none;opacity:.07;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .5  0 0 0 0 .5  0 0 0 0 .5  0 0 0 1.4 -.2'/></filter><rect width='220' height='220' filter='url(%23n)'/></svg>");
  animation:grain 1s steps(6) infinite}
@keyframes grain{0%{transform:translate(0,0)}20%{transform:translate(-22px,14px)}40%{transform:translate(18px,-26px)}60%{transform:translate(-30px,-8px)}80%{transform:translate(26px,22px)}100%{transform:translate(0,0)}}

/* ---------------------------------------------------------------- chrome */
header{position:fixed;left:var(--gutter);right:var(--gutter);top:clamp(18px,3.2vh,34px);display:flex;align-items:center;justify-content:space-between;z-index:6;pointer-events:none}
.brand{display:flex;align-items:center;gap:16px;pointer-events:auto;text-decoration:none}
.brand img{height:clamp(30px,3.4vw,42px);width:auto;display:block}
.brand span{font-size:13px;color:var(--ink-3);padding-left:16px;border-left:1px solid var(--ink-4);line-height:20px;align-self:center}
.count{font-size:13px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--ink-2);display:flex;align-items:center;gap:10px}
.count b{display:inline-block;min-width:1.4em;text-align:right;color:var(--ink)}
.count i{width:26px;height:1px;background:var(--ink-4)}

/* ---------------------------------------------------------------- copy */
#copy{position:fixed;left:var(--gutter);top:50%;width:min(31vw,430px);z-index:5}
.panel{position:absolute;left:0;top:0;width:100%;pointer-events:none;transform:translateY(-50%) scale(var(--fit,1));transform-origin:0 50%}
.panel.on{pointer-events:auto}
.eyebrow{display:flex;align-items:center;gap:12px;font-size:13px;font-weight:600;color:var(--ink-2);margin:0 0 18px}
/* chapter swaps are sequential: the old copy is gone (about .3 s) before the new copy starts, so
   titles, numbers and notes never sit on top of each other mid-swap */
.eyebrow b{color:var(--orange);font-weight:600;font-variant-numeric:tabular-nums;opacity:0;transition:opacity .16s linear}
.panel.on .eyebrow b{opacity:1;transition:opacity .45s var(--ease) .3s}
.eyebrow i{display:block;height:1px;width:28px;background:var(--ink-3);transform-origin:left;transform:scaleX(0);transition:transform .7s var(--ease) .3s}
.eyebrow span{opacity:0;transform:translateY(8px);transition:opacity .5s var(--ease) .34s,transform .6s var(--ease) .34s}
.panel h2{font-weight:600;font-size:clamp(30px,3.05vw,50px);line-height:1.06;letter-spacing:-.022em;margin:0 0 22px;color:var(--ink)}
.panel h2 .w{display:inline-block;overflow:hidden;vertical-align:top;padding:.04em 0 .16em;margin:-.04em 0 -.16em}
.panel h2 .w>span{display:inline-block;transform:translateY(135%);transition:transform .9s var(--ease)}
.panel[data-ch="0"] h2{font-size:clamp(46px,5.4vw,92px);letter-spacing:-.035em;line-height:.98;margin-bottom:26px}
.panel[data-ch="0"] p{max-width:36ch}
.panel p{font-size:clamp(15px,1.06vw,17px);line-height:1.56;color:var(--ink-2);margin:0;max-width:32ch;opacity:0;transform:translateY(12px);transition:opacity .7s var(--ease) .44s,transform .8s var(--ease) .44s}
.panel p em{font-style:normal;color:var(--ink);font-weight:600}
.panel.on .eyebrow i{transform:scaleX(1)}
.panel.on .eyebrow span{opacity:1;transform:none}
.panel.on h2 .w>span{transform:none}
.panel.on p{opacity:1;transform:none}
.panel.out .eyebrow i{transform:scaleX(0);transition:transform .24s var(--ease-in)}
.panel.out .eyebrow span{opacity:0;transform:translateY(-6px);transition:opacity .16s linear,transform .24s var(--ease-in)}
.panel.out h2 .w>span{transform:translateY(-135%);transition:transform .3s cubic-bezier(.55,0,.85,.35)}
.panel.reset,.panel.reset *{transition:none!important}
.panel.out p{opacity:0;transform:translateY(-8px);transition:opacity .16s linear,transform .24s var(--ease-in)}
.panel.out .note,.panel.out .plan,.panel.out .cta{opacity:0;transition:opacity .16s linear}
.cta{display:inline-flex;align-items:center;gap:14px;margin-top:28px;padding:15px 22px 15px 24px;border:1px solid rgba(255,255,255,.34);border-radius:999px;font-size:15px;font-weight:600;color:var(--ink);text-decoration:none;position:relative;overflow:hidden;opacity:0;transform:translateY(10px);transition:opacity .6s var(--ease) .6s,transform .7s var(--ease) .6s,border-color .3s}
.cta::before{content:"";position:absolute;inset:0;background:var(--orange);transform:translateX(-101%);transition:transform .5s var(--ease);z-index:-1}
.cta:hover{border-color:var(--orange)}
.cta:hover::before{transform:none}
.cta svg{width:14px;height:14px;transition:transform .35s var(--ease)}
.cta:hover svg{transform:translateX(3px)}
.panel.on .cta{opacity:1;transform:none}

/* hit and miss plan, chapter 3 only */
.note{display:flex;align-items:center;gap:10px;margin:22px 0 0;font-size:12.5px;color:var(--ink-3);opacity:0;transition:opacity .6s var(--ease) .62s}
.note i{width:6px;height:6px;border-radius:50%;background:var(--orange);flex:none}
.panel.on .note{opacity:1}
.plan{margin-top:26px;opacity:0;transform:translateY(10px);transition:opacity .6s var(--ease) .55s,transform .7s var(--ease) .55s}
.panel.on .plan{opacity:1;transform:none}
.plan svg{width:100%;max-width:236px;height:auto;display:block;overflow:visible}
.plan figcaption{font-size:12px;color:var(--ink-3);margin-top:10px}
.plan .wall{fill:rgba(247,247,247,.07);stroke:rgba(247,247,247,.3);stroke-width:1}
.plan .bay rect{fill:transparent;stroke:rgba(247,247,247,.28);stroke-width:1;transition:fill .25s,stroke .25s}
.plan .bay text{font-size:9px;font-weight:600;fill:rgba(247,247,247,.42);text-anchor:middle;dominant-baseline:central;transition:fill .25s}
.plan .bay.dug rect{fill:rgba(0,0,0,.55);stroke:rgba(247,247,247,.8)}
.plan .bay.dug text{fill:var(--white)}
.plan .bay.shut rect{stroke:var(--orange);stroke-width:2}
.plan .bay.cast rect{fill:#aebccb;stroke:#d9e2ea}
.plan .bay.cast text{fill:var(--black)}
.plan .bay.now rect{animation:pulse 1.1s var(--ease) infinite}
@keyframes pulse{50%{stroke-opacity:.35}}

/* ---------------------------------------------------------------- callouts */
/* a pin on the thing named, a short elbow leader, a small glass tag in clear film space;
   white for the permanent works, orange for temporary works (the word says so too) */
#callouts{position:fixed;inset:0;z-index:4;pointer-events:none;overflow:hidden}
.callout{position:absolute;left:0;top:0;width:0;height:0;visibility:hidden;transition:visibility 0s linear .62s;--c:var(--white);--c-line:rgba(255,255,255,.9)}
.callout.on{visibility:visible;transition-delay:0s}
.callout .lead{position:absolute;left:0;top:0;overflow:visible;filter:drop-shadow(0 0 1.5px rgba(4,6,10,.7))}
.callout .lead path{fill:none;stroke:var(--c-line);stroke-width:1.15;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1;stroke-dashoffset:1;transition:stroke-dashoffset .26s var(--ease-in) .1s}
.callout.on .lead path{stroke-dashoffset:0;transition:stroke-dashoffset .5s var(--ease) .16s}
.callout .pin{position:absolute;left:-4px;top:-4px;width:8px;height:8px;border-radius:50%;background:var(--c);box-shadow:0 0 0 2px rgba(6,9,14,.3),0 0 14px rgba(6,9,14,.55);transform:scale(0);transition:transform .22s var(--ease-in) .3s}
.callout.on .pin{transform:scale(1);transition:transform .55s cubic-bezier(.34,1.56,.64,1) 0s}
.callout .pin::before,.callout .pin::after{content:"";position:absolute;inset:-7px;border-radius:50%;border:1px solid var(--c);opacity:0}
.callout .pin::before{transition:opacity .2s}
.callout.on .pin::before{opacity:.45;transition:opacity .6s var(--ease) .3s}
.callout.on .pin::after{animation:ping 1.15s var(--ease) .06s 1 both}
@keyframes ping{0%{opacity:.85;transform:scale(.4)}100%{opacity:0;transform:scale(2.7)}}
.callout .tag{position:absolute;left:0;top:0;width:max-content;white-space:nowrap;text-wrap:balance;padding:8px 12px 9px;font-size:13.5px;line-height:1.25;font-weight:600;letter-spacing:-.004em;color:var(--ink);
  background:rgba(10,13,18,.58);-webkit-backdrop-filter:blur(14px) saturate(1.25);backdrop-filter:blur(14px) saturate(1.25);
  border:1px solid rgba(255,255,255,.17);border-radius:3px;box-shadow:0 12px 30px rgba(0,0,0,.24);
  clip-path:inset(0 100% 0 0 round 3px);transition:clip-path .24s cubic-bezier(.4,0,.2,1) 0s}
.callout.temp .tag{border-color:rgba(255,88,28,.5)}
.callout .tag i{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--orange);margin:0 8px 0 0;vertical-align:.12em}
.callout.left .tag{clip-path:inset(0 0 0 100% round 3px)}
.callout.on .tag{clip-path:inset(0 0 0 0 round 3px);transition:clip-path .58s var(--ease) .4s}
/* on the way out the text stays and is wiped away with the tag, then resets unseen */
.callout .tag span{display:block;opacity:0;transform:translateX(-12px);transition:opacity 0s linear .26s,transform 0s linear .26s}
.callout.left .tag span{transform:translateX(12px)}
.callout.on .tag span{opacity:1;transform:none;transition:opacity .45s var(--ease) .46s,transform .6s var(--ease) .44s}
#fx #planeg{transition:opacity .35s var(--ease)}
#fx .plane{fill:url(#sheet);stroke:rgba(255,255,255,.42);stroke-width:1;stroke-dasharray:5 5}
#fx .plane-edge{fill:none;stroke:rgba(255,255,255,.95);stroke-width:1.5}
#fx .plane-corners{fill:none;stroke:#fff;stroke-width:2;stroke-linecap:square}

/* ---------------------------------------------------------------- depth gauge */
#gauge{position:fixed;right:calc(var(--gutter) + 4px);top:50%;height:min(44vh,400px);transform:translateY(-50%);z-index:5;width:132px;opacity:0;transition:opacity .6s var(--ease);pointer-events:none}
#gauge.on{opacity:1}
#gauge .t{position:absolute;right:0;top:-34px;font-size:12px;color:var(--ink-3);text-align:right;white-space:nowrap}
#gauge .axis{position:absolute;right:0;top:0;bottom:0;width:1px;background:var(--ink-4)}
#gauge .tick{position:absolute;right:0;height:1px;width:8px;background:var(--ink-3)}
#gauge .tick span{position:absolute;right:14px;top:-7px;font-size:11px;color:var(--ink-3);font-variant-numeric:tabular-nums;white-space:nowrap}
#gauge .mark{position:absolute;right:0;height:1px;width:26px;background:var(--white);transition:opacity .4s}
#gauge .mark span{position:absolute;right:34px;top:-9px;font-size:13px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
#gauge .fill{position:absolute;right:0;top:0;width:3px;background:linear-gradient(rgba(255,255,255,.08),rgba(255,255,255,.45));transform:translateX(1px)}
/* the gauge crosses the lit party wall in later chapters; a soft halo keeps its small type legible */
#gauge .t,#gauge .tick span,#gauge .mark span{text-shadow:0 0 10px rgba(6,9,14,.9),0 0 3px rgba(6,9,14,.75)}
#gauge .floor{opacity:0}
#gauge .floor.on{opacity:1}

/* ---------------------------------------------------------------- footer */
footer{position:fixed;left:var(--gutter);right:var(--gutter);bottom:clamp(18px,3.6vh,34px);display:flex;align-items:center;gap:22px;z-index:6}
#play{position:relative;width:44px;height:44px;flex:none;border-radius:50%}
#play svg{position:absolute;inset:0}
#play .bg{fill:rgba(255,255,255,.06);stroke:rgba(255,255,255,.22);stroke-width:1}
#play .prog{fill:none;stroke:var(--orange);stroke-width:1.5;stroke-linecap:round;transform:rotate(-90deg);transform-origin:22px 22px}
#play .icon{fill:var(--white)}
#rail{display:flex;flex:1;gap:4px;align-items:flex-end}
#rail button{position:relative;text-align:left;padding:0 0 12px;font-size:12px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .3s}
#rail button::after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--ink-4)}
#rail button b{position:absolute;left:0;bottom:0;height:2px;width:100%;background:var(--white);transform-origin:left;transform:scaleX(0);z-index:1;font-weight:400}
#rail button.on{color:var(--ink)}
#rail button.on b{background:var(--orange)}
#rail button.done b{background:rgba(255,255,255,.55)}
#rail button:hover{color:var(--ink)}
#buffer{position:absolute;left:0;bottom:-6px;height:1px;background:rgba(255,255,255,.18);width:0;transition:width .4s linear,opacity .6s}
#hint{position:fixed;left:50%;bottom:92px;transform:translateX(-50%);z-index:5;display:flex;flex-direction:column;align-items:center;gap:12px;font-size:12px;color:var(--ink-3);transition:opacity .5s;pointer-events:none}
#hint i{display:block;width:1px;height:38px;background:linear-gradient(var(--ink-3),transparent);animation:cue 1.9s var(--ease) infinite;transform-origin:top}
@keyframes cue{0%{transform:scaleY(0)}55%{transform:scaleY(1);opacity:1}100%{transform:scaleY(1);opacity:0}}

/* ---------------------------------------------------------------- loader */
#loader{position:fixed;inset:0;z-index:20;background:var(--night);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:26px;transition:opacity 1s var(--ease),visibility 1s}
#loader img{height:30px;width:auto;opacity:.95}
#loader .bar{width:180px;height:1px;background:var(--ink-4);overflow:hidden}
#loader .bar i{display:block;height:100%;width:100%;background:var(--orange);transform-origin:left;transform:scaleX(0);transition:transform .25s linear}
#loader p{margin:0;font-size:12px;color:var(--ink-3)}
#loader.done{opacity:0;visibility:hidden}
#err{position:fixed;left:var(--gutter);bottom:100px;z-index:30;color:#ffb38f;font-size:13px}
#scroll{height:calc(var(--units,18) * var(--vh-unit,68vh) + 100vh)}

/* ---------------------------------------------------------------- portrait */
/* short laptop windows: the mark stays bigger than before (26 px, was 20) but the header keeps
   the height the label planner was tuned for; at 1100 x 700 the full-size mark cost the stair label */
@media (max-height:760px) and (min-width:761px) and (min-aspect-ratio:9/10){header{top:14px}.brand img{height:26px}}
@media (max-aspect-ratio:9/10),(max-width:760px){
  .scrim{background:linear-gradient(0deg,rgba(6,9,14,.94) 0%,rgba(6,9,14,.8) 26%,rgba(6,9,14,.2) 46%,rgba(6,9,14,0) 58%),linear-gradient(180deg,rgba(6,9,14,.6) 0%,rgba(6,9,14,0) 14%)}
  .brand img{height:32px}.brand span{display:none}
  #copy{top:auto;bottom:108px;transform:none;width:auto;right:var(--gutter)}
  .panel{top:auto;bottom:0;transform:none}
  .panel h2{font-size:28px;margin-bottom:12px}
  .panel[data-ch="0"] h2{font-size:44px}
  .panel p{font-size:14.5px;line-height:1.5;max-width:none}
  .eyebrow{margin-bottom:12px}
  .plan{display:none}
  #gauge{display:none}
  .callout .tag{font-size:12.5px;line-height:1.3;padding:7px 10px 8px}
  #rail button{font-size:0;padding-bottom:10px}
  footer{gap:14px}
  #hint{display:none}
}
@media (prefers-reduced-motion:reduce){
  .grain{animation:none}
  #hint i,.callout.on .pin::after,.plan .bay.now rect{animation:none}
  .callout .tag,.callout.on .tag,.callout.left .tag{clip-path:none}
  .callout .tag{opacity:0;transition:opacity .2s}
  .callout.on .tag{opacity:1;transition:opacity .3s .1s}
  .panel h2 .w>span{transform:none!important}
}
