@font-face{font-family:Anton;src:url(a1/fonts/Anton.woff2) format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:Departure;src:url(a1/fonts/DepartureMono-Regular.woff2) format('woff2');font-weight:400;font-style:normal;font-display:swap}

:root{
  /* read off his plates */
  --lot:#06070c; --ink:#e9e6df; --dim:#8b8f9c;
  --grape:#8b4ce8; --lime:#c8f24a; --amber:#ffb42e;
  font-synthesis:none;
}

*{box-sizing:border-box}
/* a selector with its own display beats the UA rules for these, so say it once */
[hidden]{display:none!important}
dialog:not([open]){display:none!important}

html,body{height:100%}
body{
  margin:0;background:var(--lot);color:var(--ink);
  font-family:Departure,ui-monospace,SFMono-Regular,Menlo,monospace;
  overflow:hidden;overscroll-behavior:none;-webkit-tap-highlight-color:transparent;
}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
:where(button,a,[tabindex]):focus-visible{outline:3px solid var(--lime);outline-offset:2px;border-radius:2px}

/* ---------- the world: one render, one light ---------- */
#world{position:fixed;inset:0;z-index:1;background:#04050a}
/* more of the same world, blurred, so no edge of the frame is ever empty */
#bgblur{position:absolute;inset:-8%;width:116%;height:116%;object-fit:cover;z-index:0;
  filter:blur(46px) brightness(.24) saturate(.65)}
#plate{position:absolute;z-index:1;box-shadow:0 0 140px 60px rgba(3,4,9,.9)}
#bg{position:absolute;inset:0;width:100%;height:100%;object-fit:fill;z-index:0}

body.shaking #world{animation:quake .11s linear infinite}
@keyframes quake{
  0%{transform:translate(0,0)}25%{transform:translate(-6px,2px)}
  50%{transform:translate(5px,-3px)}75%{transform:translate(-4px,1px)}
  100%{transform:translate(0,0)}
}

/* ---------- the 24 cans behind the glass ---------- */
#slots{position:absolute;inset:0}
.slot{position:absolute;padding:0;border:0;background:none;cursor:pointer;display:block}
/* graded down into the machine's own green light, or a full brightness can reads as a
   sticker sitting on top of the picture rather than a thing behind the glass */
.slot .can{position:absolute;left:50%;bottom:0;transform:translateX(-50%);
  width:var(--can-w,60%);height:100%;object-fit:fill;
  image-rendering:pixelated;
  filter:brightness(.70) saturate(.88) contrast(1.03)
         drop-shadow(0 2px 2px rgba(0,0,0,.8));
  transition:transform .16s ease-out,filter .16s}
.slot .code{position:absolute;left:0;right:0;bottom:-1.15em;text-align:center;
  font-size:clamp(6px,.62vw,11px);line-height:1;color:#cfe0b4;opacity:0;
  text-shadow:0 1px 2px #000,0 0 5px #000;pointer-events:none;transition:opacity .15s}
.slot:hover .code,.slot:focus-visible .code{opacity:.95}
.slot:hover .can,.slot:focus-visible .can{transform:translateX(-50%) translateY(-4%) scale(1.06);
  filter:brightness(.95) saturate(1) drop-shadow(0 3px 5px rgba(0,0,0,.8))}
.slot[data-state=gone]{cursor:default}
.slot[data-state=gone] .can{display:none}
.slot.turning .can{animation:turn .5s ease-in-out}
@keyframes turn{0%,100%{transform:translateX(-50%)}50%{transform:translateX(-38%) rotate(4deg)}}
.slot[data-state=stuck] .can{transform:translate(-24%,-6%) rotate(-22deg);
  filter:brightness(1.1) drop-shadow(0 4px 5px rgba(0,0,0,.7));animation:none}
body.dead .slot .can{filter:brightness(.25) saturate(.3)}

/* the falling can */
#fall{position:absolute;inset:0;pointer-events:none;z-index:4;overflow:visible}
.faller{position:absolute;image-rendering:pixelated;filter:drop-shadow(0 3px 5px rgba(0,0,0,.7))}

/* ---------- stickers: real surfaces, with the type PRINTED onto them ----------
   A flat CSS rectangle is not a sticker. Each of these is a rendered object with its own
   worn edge, curled corner, tape or rivets, nine-sliced so it holds its edge at any size;
   the words go on with multiply so they sink into the grain instead of floating over it. */
.sticker{position:absolute;z-index:5;text-decoration:none;border:0;padding:0;background:none;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  line-height:1;text-align:center;cursor:pointer;isolation:isolate;
  filter:brightness(.86) saturate(.92) drop-shadow(0 3px 5px rgba(0,0,0,.75));
  transition:transform .13s,filter .13s}
.sticker::before{content:"";position:absolute;inset:0;z-index:-1;
  background-image:var(--surface);background-size:100% 100%;background-repeat:no-repeat}
.sticker > *{mix-blend-mode:multiply}
.sticker:hover,.sticker:focus-visible{transform:scale(1.045);filter:brightness(1.02) saturate(1)}

#st-buy{--surface:url(a1/sticker-buy.webp);transform:rotate(-2deg);color:#14200a}
#st-buy .st-l1{font-family:Anton;font-size:clamp(7px,.95vw,18px);letter-spacing:.1em;opacity:.72}
#st-buy .st-l2{font-family:Anton;font-size:clamp(13px,1.85vw,35px);letter-spacing:.015em;margin-top:-.04em}

#st-who{--surface:url(a1/sticker-who.webp);transform:rotate(1.6deg);color:#231d12;
  font-family:Departure}
#st-who .st-w1{font-size:clamp(5px,.66vw,12px);letter-spacing:.14em;opacity:.62}
#st-who .st-w2{font-family:Anton;font-size:clamp(13px,1.75vw,33px);margin-top:.12em}

#st-x{--surface:url(a1/sticker-x.webp);transform:rotate(3deg);color:#15140f}
#st-x svg{width:46%;height:auto;display:block;flex:none;mix-blend-mode:multiply}

.sticker[aria-disabled=true]{filter:grayscale(.55) brightness(.62);cursor:not-allowed}
.sticker[aria-disabled=true]:hover{transform:none;filter:grayscale(.55) brightness(.68)}

/* ---------- the tray ---------- */
#tray{position:absolute;z-index:3;padding:0;border:0;background:transparent;cursor:pointer;
  overflow:visible}
#tray[disabled]{cursor:default}
#tray.full{background:radial-gradient(60% 90% at 50% 80%,rgba(200,242,74,.20),transparent 72%)}
#trayitem{position:absolute;left:50%;bottom:6%;height:64%;width:auto;
  transform:translateX(-50%) rotate(-80deg);image-rendering:pixelated;
  filter:brightness(.6) saturate(.85) drop-shadow(0 2px 4px rgba(0,0,0,.85));transition:transform .14s}
#tray:hover #trayitem{transform:translateX(-50%) rotate(-80deg) translateY(-4px)}

/* ---------- the contract: a riveted service plate bolted to the machine ----------
   Real brushed aluminium with four rivets, nine-sliced so the rivets stay round however
   wide it gets. The address is ENGRAVED into it: dark ink multiplied into the brush
   scratches, with a hairline of light under each stroke, the way a stamped plate reads. */
#label{position:absolute;z-index:5;display:flex;flex-direction:column;justify-content:center;
  isolation:isolate;transform:rotate(-.4deg);padding:0 4.6%;
  filter:brightness(.78) saturate(.88) drop-shadow(0 4px 7px rgba(0,0,0,.85))}
#label::before{content:"";position:absolute;inset:0;z-index:-1;
  background-image:url(a1/plate.webp);background-size:100% 100%;background-repeat:no-repeat}
#label-k{font-size:clamp(7px,.72vw,14px);letter-spacing:.24em;color:#26271f;opacity:.78;
  mix-blend-mode:multiply;text-shadow:0 1px 0 rgba(255,255,255,.4)}
#label-copy{display:flex;align-items:baseline;gap:.7em;width:100%;margin:.15em 0 0;padding:0;
  border:0;background:none;text-align:left;cursor:pointer;color:inherit;font-family:Departure}
#label-copy[disabled]{cursor:default}
#label-ca{flex:1 1 auto;font-size:clamp(9px,1.12vw,20px);line-height:1.15;letter-spacing:.02em;
  color:#1b1c17;word-break:break-all;user-select:all;mix-blend-mode:multiply;
  text-shadow:0 1px 0 rgba(255,255,255,.45)}
#label-hint{flex:none;font-size:clamp(6px,.66vw,12px);letter-spacing:.18em;color:#2b2d24;
  opacity:.7;mix-blend-mode:multiply;text-shadow:0 1px 0 rgba(255,255,255,.4)}
#label-copy:hover #label-hint{opacity:1;color:#1d3a12}
#label.ok #label-hint{opacity:1;color:#1b4a10}
#label.err #label-hint{opacity:1;color:#6b1a12}

/* ---------- shake: you grab the machine, the camera feels it ---------- */
/* fixed to the viewport, not to the plate: the plate runs off the sides of the window and
   its centre is not where the reader is looking */
#shake{position:fixed;inset:0;z-index:9;border:0;background:rgba(4,6,10,.30);cursor:grab;
  display:grid;place-content:center;align-content:center;
  font-family:Anton;color:#fff;letter-spacing:.01em}
#shake span{font-size:clamp(30px,7vw,96px);text-transform:uppercase;
  paint-order:stroke fill;-webkit-text-stroke:clamp(5px,1vw,12px) #000;
  animation:pulse 1.1s ease-in-out infinite}
@keyframes pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
#shake:active{cursor:grabbing}

/* ---------- what the machine shouts ---------- */
#shout{position:fixed;z-index:8;left:50%;top:16svh;transform:translateX(-50%) scale(.92);
  margin:0;width:max-content;max-width:92vw;text-align:center;pointer-events:none;
  font-family:Anton;text-transform:uppercase;color:#fff;line-height:.95;
  font-size:clamp(26px,5.4vw,74px);opacity:0;transition:opacity .16s,transform .16s;
  paint-order:stroke fill;-webkit-text-stroke:clamp(4px,.85vw,10px) #000}
#shout.on{opacity:1;transform:translateX(-50%) scale(1)}

#hint{position:fixed;z-index:7;left:0;right:0;bottom:calc(1.8svh + env(safe-area-inset-bottom));
  margin:0;text-align:center;font-size:clamp(9px,1.4vw,13px);letter-spacing:.34em;
  color:#a7aebf;text-transform:uppercase;pointer-events:none;opacity:0;transition:opacity .5s;
  text-shadow:0 1px 4px #000,0 0 8px #000}
body.started #hint{opacity:.9}
body.picked #hint,body.busy #hint{opacity:0}

/* ---------- lightbox ---------- */
#lightbox{border:0;padding:0;max-width:100vw;max-height:100svh;width:100vw;height:100svh;
  background:rgba(4,5,9,.95);color:var(--ink);overflow:hidden}
#lightbox::backdrop{background:rgba(2,3,6,.8)}
#lb-fig{margin:0;position:absolute;inset:0;display:grid;place-items:center;padding:7svh 2vw 9svh}
#lb-media{position:relative;display:flex;max-width:96vw;max-height:84svh}
#lb-img,#lb-vid{max-width:96vw;max-height:84svh;width:auto;height:auto;display:block;
  box-shadow:0 18px 60px rgba(0,0,0,.75)}
/* the caption sits ON the picture, Impact style, the way a meme is set */
#lb-cap{position:absolute;left:0;right:0;bottom:.35em;padding:0 .3em;
  text-align:center;font-family:Anton,Impact,sans-serif;text-transform:uppercase;color:#fff;
  line-height:.95;font-size:clamp(19px,3.6vw,46px);text-wrap:balance;
  paint-order:stroke fill;-webkit-text-stroke:clamp(4px,.62vw,9px) #000;
  text-shadow:0 .05em .05em rgba(0,0,0,.75)}
#lb-close{position:absolute;top:1.2svh;right:2vw;z-index:3;width:44px;height:44px;border:0;
  background:rgba(255,255,255,.08);color:var(--ink);font-size:24px;line-height:1;cursor:pointer}
#lb-close:hover{background:var(--lime);color:#101010}
#lb-nav{position:absolute;left:50%;transform:translateX(-50%);bottom:2.4svh;display:flex;
  gap:14px;align-items:center;font-size:13px;letter-spacing:.16em;color:var(--dim)}
#lb-nav button{min-width:88px;min-height:44px;border:1px solid #3a3f4d;background:rgba(255,255,255,.05);
  color:var(--ink);font-family:Departure;letter-spacing:.16em;cursor:pointer}
#lb-nav button:hover{background:var(--lime);color:#101010;border-color:var(--lime)}

/* ---------- the receipt the machine prints ---------- */
#roll{border:0;padding:0;background:transparent;max-width:100vw;max-height:100svh;
  width:100vw;height:100svh;overflow:hidden;display:grid;place-items:center}
#roll::backdrop{background:rgba(2,3,6,.88)}
#roll-paper{position:relative;width:min(92vw,430px);max-height:82svh;overflow:auto;
  background:
    repeating-linear-gradient(180deg,rgba(0,0,0,.022) 0 2px,transparent 2px 4px),
    linear-gradient(#fbf7ec,#efe8d6 60%,#e6dcc6);
  color:#1b1c18;padding:2.4em 1.1em 2.6em;
  box-shadow:0 22px 50px rgba(0,0,0,.7),inset 0 0 40px rgba(150,140,110,.18);
  clip-path:polygon(0% 7px,3% 0,6% 7px,9% 0,12% 7px,15% 0,18% 7px,21% 0,24% 7px,27% 0,30% 7px,
    33% 0,36% 7px,39% 0,42% 7px,45% 0,48% 7px,51% 0,54% 7px,57% 0,60% 7px,63% 0,66% 7px,69% 0,
    72% 7px,75% 0,78% 7px,81% 0,84% 7px,87% 0,90% 7px,93% 0,96% 7px,99% 0,100% 7px,
    100% calc(100% - 7px),97% 100%,94% calc(100% - 7px),91% 100%,88% calc(100% - 7px),85% 100%,
    82% calc(100% - 7px),79% 100%,76% calc(100% - 7px),73% 100%,70% calc(100% - 7px),67% 100%,
    64% calc(100% - 7px),61% 100%,58% calc(100% - 7px),55% 100%,52% calc(100% - 7px),49% 100%,
    46% calc(100% - 7px),43% 100%,40% calc(100% - 7px),37% 100%,34% calc(100% - 7px),31% 100%,
    28% calc(100% - 7px),25% 100%,22% calc(100% - 7px),19% 100%,16% calc(100% - 7px),13% 100%,
    10% calc(100% - 7px),7% 100%,4% calc(100% - 7px),1% 100%,0 calc(100% - 7px));
  scrollbar-width:thin;scrollbar-color:#b3a98d transparent}
#roll-paper::-webkit-scrollbar{width:8px}
#roll-paper::-webkit-scrollbar-track{background:transparent}
#roll-paper::-webkit-scrollbar-button{display:none}
#roll-paper::-webkit-scrollbar-thumb{background:#b3a98d}
#roll-text{margin:0;font-family:Departure,ui-monospace,monospace;
  font-size:clamp(11px,2.9vw,14px);line-height:1.5;white-space:pre-wrap;letter-spacing:.02em;
  min-height:22em}
#roll-close{position:absolute;top:1.4svh;right:2vw;z-index:3;width:44px;height:44px;border:0;
  background:rgba(255,255,255,.1);color:var(--ink);font-size:24px;line-height:1;cursor:pointer}
#roll-close:hover{background:var(--lime);color:#101010}

/* ---------- intro film ---------- */
#intro{position:fixed;inset:0;z-index:40;background:#000;display:grid;place-items:center}
#introvid{width:100%;height:100%;object-fit:cover}
#introcap{position:absolute;left:50%;transform:translateX(-50%);bottom:9svh;width:min(92vw,1100px);
  text-align:center;font-family:Anton;text-transform:uppercase;color:#fff;line-height:.98;
  font-size:clamp(22px,5.2vw,64px);
  paint-order:stroke fill;-webkit-text-stroke:clamp(3px,.8vw,9px) #000}
#introline{display:inline-block;opacity:0}
#introline.on{opacity:1;animation:pop .18s ease-out}
@keyframes pop{from{transform:scale(.94)}to{transform:scale(1)}}
#introskip{position:absolute;right:2.4vw;top:2.4svh;min-height:44px;padding:0 18px;border:1px solid #4a4f5d;
  background:rgba(0,0,0,.5);color:var(--ink);font-family:Departure;letter-spacing:.2em;cursor:pointer}
#introskip:hover{background:var(--lime);color:#101010}

/* ---------- boot ---------- */
#boot{position:fixed;inset:0;z-index:60;border:0;cursor:pointer;color:var(--ink);
  background:radial-gradient(90% 70% at 50% 55%,#141826,#05060a 72%);
  display:grid;align-content:center;justify-items:center;gap:.5em;padding:6vw;font-family:Departure}
.boot-l1{font-family:Anton;font-size:clamp(58px,17vw,190px);line-height:.82;
  color:var(--grape);text-shadow:0 0 26px rgba(139,76,232,.5),4px 4px 0 #0a0b11}
.boot-l2{font-size:clamp(11px,2.1vw,17px);letter-spacing:.26em;color:#9aa0b0;text-transform:uppercase}
.boot-l3{margin-top:1.4em;font-size:clamp(10px,1.7vw,14px);letter-spacing:.22em;color:var(--lime)}
#boot:hover .boot-l3{color:#fff}
body.booted #boot{display:none}

@media (prefers-reduced-motion:reduce){
  body.shaking #world{animation:none}
  .slot.turning .can{animation:none}
  #shake span{animation:none}
  #introline.on{animation:none}
  .slot .can,.sticker,#trayitem{transition:none}
}

@media (max-width:760px){
  /* a phone leaves slack above and below the machine, so let more of the lot show through */
  #bgblur{filter:blur(40px) brightness(.34) saturate(.7)}
  /* the address gets two comfortable lines on a phone instead of one unreadable one */
  #label-copy{flex-wrap:wrap}
  #label-ca{flex:1 1 100%;font-size:clamp(9px,2.7vw,15px);line-height:1.25}
  #label-hint{flex:0 0 auto;margin-left:auto}
  #label-k{font-size:clamp(6px,1.9vw,11px);letter-spacing:.16em}
}
