/* ===========================================================================
   ad6mski · BOOT

   The door. An 8-bit boot screen that counts the manifest in, resolves the
   campaign out of blocks, and hands over to the plate underneath it.

   THE BLUR RULE, IN PIXELS. The campaign does not cross-fade in. It resolves
   in resolution steps, 8px blocks up to sharp, because unexamined-to-examined
   is the rule the whole site runs on and a dissolve is the 8-bit spelling of
   it. Every motion in here moves on steps(), never on a tween. Smoothness is
   what breaks the medium.

   IT LOADS ONCE. sessionStorage gates it. A 2.6s wall in front of a shop is a
   cost, and it is only worth paying on the first arrival.

   IT NEVER BLOCKS. Hidden unless html.booting is set, and only the inline
   script in the head sets it. JS off, storage full, script blocked: the
   screen never appears and the shop is simply there.
   ========================================================================= */

.boot{display:none}

html.booting,html.booting body{overflow:hidden;height:100%}
html.booting .boot{
  display:grid;place-items:center;
  position:fixed;inset:0;z-index:9999;
  background:var(--plate);color:var(--paper);
  font-family:'Silkscreen',ui-monospace,'Courier New',monospace;
  font-size:14px;line-height:1.6;
  -webkit-font-smoothing:none;   /* pixel type must not antialias */
  animation:boot-flick .1s steps(2) 3;
  /* a boot screen is a display, not a document. dragging a thumb across it
     must never select the terminal type or flash a tap highlight. */
  -webkit-user-select:none;user-select:none;
  -webkit-tap-highlight-color:transparent;
  touch-action:manipulation;
}
@keyframes boot-flick{from{opacity:.35}to{opacity:1}}

/* the overlay leaves on steps too, and it leaves onto the same photograph
   it just resolved, so the handover is a chrome removal, not a transition. */
html.booting .boot.out{animation:boot-out .24s steps(4) forwards}
@keyframes boot-out{to{opacity:0}}

/* ---------- the tube. scanlines and a vignette, both cheap, both required.
   without them the pixel type reads as a font choice instead of a display. */
.boot-tube{position:absolute;inset:0;z-index:80;pointer-events:none}
.boot-tube::before{content:"";position:absolute;inset:0;
  background:repeating-linear-gradient(to bottom,
    rgba(0,0,0,0) 0 2px,rgba(0,0,0,.34) 2px 4px);
  mix-blend-mode:multiply;opacity:.55}
.boot-tube::after{content:"";position:absolute;inset:0;
  background:radial-gradient(120% 90% at 50% 50%,transparent 42%,rgba(0,0,0,.62) 100%)}
/* once the campaign is sharp the tube stands down. the boot is a display,
   the photograph is the garment, and scanlines on a garment are a filter. */
.boot.sharp .boot-tube::before{opacity:.1}

/* ---------- 1 · the terminal ---------- */
.boot-panel{position:relative;z-index:20;width:min(560px,86vw);display:grid;gap:26px}
.boot.sharp .boot-panel{display:none}

.boot-mark{font-weight:700;font-size:clamp(26px,6.4vw,44px);line-height:1;
  letter-spacing:.02em;text-transform:lowercase;color:var(--paper)}
.boot-mark .six{color:var(--cut)}
.boot-sub{color:var(--ash);font-size:10px;letter-spacing:.22em;
  text-transform:uppercase;margin-top:12px}

/* the log. lines are suddenly there. nothing fades in on a terminal. */
.boot-log{display:grid;gap:5px;font-size:10.5px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ash);min-height:98px}
.boot-log li{list-style:none;display:none;justify-content:space-between;gap:12px}
.boot-log li.on{display:flex}
.boot-log b{color:var(--paper);font-weight:400}

/* the bar. 28 discrete cells, because a continuous bar is a different century. */
.boot-bar{display:flex;gap:3px;height:16px}
.boot-cell{flex:1;background:rgba(240,238,233,.11)}
.boot-cell.on{background:var(--paper)}
.boot-cell.hot{background:var(--cut)}   /* the leading edge only */

.boot-read{display:flex;justify-content:space-between;margin-top:10px;
  font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ash)}
.boot-read .pct{color:var(--paper)}

/* ---------- 2 · the campaign, resolving out of blocks ---------- */
.boot-shot{position:absolute;inset:0;z-index:10;visibility:hidden}
.boot-shot canvas,.boot-shot img{position:absolute;inset:0;
  width:100%;height:100%;object-fit:cover;image-rendering:pixelated}
.boot-shot img{image-rendering:auto;opacity:0}
.boot.live .boot-shot{visibility:visible}
.boot.sharp .boot-shot img{opacity:1}

/* ---------- 3 · the gate ---------- */
.boot-gate{position:absolute;left:0;right:0;bottom:0;z-index:60;
  display:grid;place-items:center;
  /* clear of the home indicator, so the last control on the page is never
     the one sitting under the gesture bar */
  padding:0 var(--pad) calc(64px + env(safe-area-inset-bottom,0px));
  opacity:0;pointer-events:none}
.boot.sharp .boot-gate{opacity:1;pointer-events:auto}
/* type on a photograph gets a ground. the blur rule, again. */
.boot-gate::before{content:"";position:absolute;inset:auto 0 0 0;height:200px;z-index:-1;
  background:linear-gradient(to top,rgba(11,11,10,.86),transparent)}
.boot-gate .cap{font-size:10px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--paper);padding-bottom:18px;text-shadow:0 1px 0 rgba(0,0,0,.9)}

.boot-enter{font:inherit;font-weight:700;font-size:16px;
  letter-spacing:.22em;text-transform:uppercase;
  color:var(--plate);background:var(--paper);
  padding:18px 40px;border:0;cursor:pointer;
  /* four blinks to get seen, then it holds. a permanently blinking button is
     a nag, and this one is the last thing between a person and the shop. */
  animation:boot-blink .58s steps(1,end) 4 both}
@keyframes boot-blink{0%,54%{opacity:1}55%,99%{opacity:.28}100%{opacity:1}}

/* hover is a pointer idea. on a touch screen it latches after a tap and the
   button stays lit for as long as the page lives, which reads as broken. */
@media (hover:hover) and (pointer:fine){
  .boot-enter:hover{background:var(--cut);color:var(--paper);animation:none;opacity:1}
  .boot-skip:hover{color:var(--paper)}
}
/* a thumb gets the press state instead, and only while it is down */
.boot-enter:active{background:var(--cut);color:var(--paper);animation:none;opacity:1}

.boot-skip{position:absolute;right:var(--pad);z-index:70;
  top:calc(var(--pad) + env(safe-area-inset-top,0px));
  font:inherit;font-size:9.5px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ash);background:none;border:0;cursor:pointer;
  /* 44px of thumb, whatever the type measures */
  padding:12px;margin:-4px}
.boot-skip:active{color:var(--paper)}
.boot.sharp .boot-skip{display:none}

@media (prefers-reduced-motion:reduce){
  html.booting .boot{animation:none}
  html.booting .boot.out{animation:none;opacity:0}
  .boot-enter{animation:none}
  .boot-tube::before{opacity:.28}
}
