/* The Excuse Generator. One machine, the new site's night city: violet, deep blue, pink, cyan, yellow.
   Nothing here depends on the height of the window, so the page that frames it can size the box safely. */
@font-face{font-family:"Bebas Neue";src:url(assets/bebas-neue.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Albert Sans";src:url(assets/albert-sans.woff2) format("woff2");font-weight:100 900;font-style:normal;font-display:swap}

:root{
  --violet:#2a1a74;--night:#150d45;--ink:#0c0728;--panel:#120a3a;
  --pink:#ff7df0;--cyan:#36dff2;--yellow:#fbc146;--yellow2:#ffd370;
  --text:#f3efff;--muted:#cfc8f5;--paper:#fff6df;--inkd:#1a1033;--stamp:#c4175f;
  --accent:var(--cyan);--needle:-78deg;
  color-scheme:dark;
}
*,*::before,*::after{box-sizing:border-box}
html{background:var(--night);-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{
  margin:0;color:var(--text);
  font-family:"Albert Sans",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;font-size:16px;line-height:1.4;
  background:
    url(assets/skyline.svg) center bottom/auto 118px repeat-x,
    radial-gradient(1.5px 1.5px at 12% 9%,rgba(255,255,255,.8),transparent 60%),
    radial-gradient(1.5px 1.5px at 81% 6%,rgba(255,255,255,.7),transparent 60%),
    radial-gradient(1px 1px at 44% 15%,rgba(255,255,255,.7),transparent 60%),
    radial-gradient(1px 1px at 93% 31%,rgba(255,255,255,.6),transparent 60%),
    radial-gradient(1.5px 1.5px at 5% 43%,rgba(255,255,255,.55),transparent 60%),
    radial-gradient(60% 34% at 100% 0,rgba(255,125,240,.17),transparent 70%),
    radial-gradient(55% 36% at 0 100%,rgba(54,223,242,.13),transparent 70%),
    linear-gradient(180deg,#2a1a74 0,#1c1260 55%,#150d45 100%);
  overflow-x:hidden;
}
html.solo body{min-height:100vh;min-height:100svh;display:grid;align-items:center}
img{max-width:100%;height:auto}
[hidden]{display:none!important}
.sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
:focus-visible{outline:3px solid var(--cyan);outline-offset:3px}

/* ---------- the layout: one column on a phone, the machine and Alfred side by side on a laptop ---------- */
.app{
  position:relative;display:grid;grid-template-columns:minmax(0,1fr);row-gap:8px;
  width:100%;max-width:520px;margin:0 auto;padding:42px 10px 16px;
}
.app::before{ /* the cabinet */
  content:"";grid-column:1;grid-row:1/6;z-index:-1;border-radius:26px;
  background:linear-gradient(180deg,#4330b0 0,#2f1f8d 26%,#1e1366 100%);
  box-shadow:0 0 0 3px var(--panel),0 0 0 5px var(--accent),0 0 30px -2px var(--accent),0 22px 44px rgba(5,2,20,.6),inset 0 2px 0 rgba(255,255,255,.22);
  transition:box-shadow .5s;
}
.sign{grid-column:1;grid-row:1;margin:12px 12px 0}
.app>noscript{grid-column:1;grid-row:2}
.dash{grid-column:1;grid-row:2;margin:0 14px}
.win{grid-column:1;grid-row:3;margin:0 12px}
.heckle{grid-column:1;grid-row:4;margin:0 12px}
.big{grid-column:1;grid-row:5;margin:0 auto 16px}
.wayon{grid-column:1;grid-row:6;margin-top:6px}
.foot{grid-column:1;grid-row:7}

/* ---------- the sign ---------- */
.sign{position:relative;padding:15px 8px 10px;border-radius:16px;background:var(--panel);text-align:center;overflow:hidden;
  box-shadow:inset 0 0 0 2px rgba(255,255,255,.09),0 0 0 2px var(--ink)}
.sign::before,.sign::after{content:"";position:absolute;left:9px;right:9px;height:8px;
  background:radial-gradient(circle,#ffd370 0 2.4px,rgba(255,211,112,.28) 3px,transparent 4.4px) 0 0/18px 8px repeat-x}
.sign::before{top:4px;animation:bulbs 1s steps(2,jump-none) infinite}
.sign::after{bottom:3px;animation:bulbs 1s steps(2,jump-none) infinite reverse}
@keyframes bulbs{from{background-position:0 0}to{background-position:9px 0}}
.title{margin:0;font-family:"Bebas Neue","Arial Narrow",Impact,sans-serif;font-weight:400;letter-spacing:.03em;line-height:.9;
  font-size:clamp(38px,11.8vw,56px);text-transform:uppercase}
.title span{display:block}
.t1{color:var(--text);text-shadow:0 0 18px rgba(255,125,240,.75),0 2px 0 #0c0728}
.t2{color:var(--yellow);text-shadow:0 0 20px rgba(251,193,70,.6),0 2px 0 #0c0728}

/* ---------- the dashboard: a dial and a counter ---------- */
.dash{display:flex;align-items:center;justify-content:space-between;gap:10px}
.gauge{display:flex;flex-direction:column;align-items:center;gap:1px}
.gauge svg{display:block;width:104px;height:auto;overflow:visible}
.arc{fill:none;stroke-width:9;stroke-dasharray:18.4 81.6}
.a1{stroke:#36dff2;stroke-dashoffset:0}
.a2{stroke:#6fe0b0;stroke-dashoffset:-20.4}
.a3{stroke:#fbc146;stroke-dashoffset:-40.8}
.a4{stroke:#ff9a6b;stroke-dashoffset:-61.2}
.a5{stroke:#ff7df0;stroke-dashoffset:-81.6}
.needle{transform-origin:60px 62px;transform:rotate(var(--needle));transition:transform .55s cubic-bezier(.3,1.6,.5,1)}
.needle line{stroke:#f3efff;stroke-width:3.5;stroke-linecap:round}
.needle circle{fill:#f3efff}
.glabel,.clabel{font-size:11px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.counter{display:flex;flex-direction:column;align-items:flex-end;gap:5px}
.digits{display:flex;gap:4px}
.digits i{display:block;min-width:26px;padding:5px 0 2px;border-radius:6px;background:var(--ink);color:var(--yellow);
  font:400 28px/1 "Bebas Neue","Arial Narrow",Impact,sans-serif;font-style:normal;text-align:center;
  box-shadow:inset 0 2px 4px rgba(0,0,0,.7),0 1px 0 rgba(255,255,255,.14)}
.digits i.roll{animation:roll .25s ease-out}
@keyframes roll{from{transform:translateY(-45%);opacity:.2}to{transform:none;opacity:1}}

/* ---------- the window: the excuse prints here ---------- */
.win{position:relative;min-height:206px;display:flex;flex-direction:column;justify-content:center;border-radius:16px;overflow:hidden;
  background:linear-gradient(180deg,#0a0626,#120a3a);
  box-shadow:inset 0 0 0 2px rgba(54,223,242,.28),inset 0 6px 22px rgba(0,0,0,.75),0 1px 0 rgba(255,255,255,.14)}
.intro{margin:0;padding:14px 16px;text-align:center;font-size:16.5px;line-height:1.42;font-weight:600;color:var(--text)}
[data-state="spinning"] .intro{visibility:hidden}

.reel{position:absolute;inset:0;display:none;overflow:hidden;
  -webkit-mask-image:linear-gradient(transparent,#000 28%,#000 72%,transparent);mask-image:linear-gradient(transparent,#000 28%,#000 72%,transparent)}
[data-state="spinning"] .reel{display:block}
.strip{position:absolute;left:0;right:0;top:0;display:flex;flex-direction:column;align-items:center;gap:12px;padding-top:30px;
  font:400 36px/1 "Bebas Neue","Arial Narrow",Impact,sans-serif;letter-spacing:.04em;text-transform:uppercase;color:var(--cyan);
  filter:blur(1.2px);opacity:.9;animation:reel 1.5s cubic-bezier(.3,0,.6,1) both;will-change:transform}
.strip span{white-space:nowrap}
.strip span:nth-child(3n+2){color:var(--pink)}
.strip span:nth-child(3n){color:var(--yellow)}
@keyframes reel{from{transform:translateY(0)}to{transform:translateY(-80%)}}

.banner{display:none;position:absolute;left:0;right:0;top:0;z-index:3;margin:0;padding:8px 6px 6px;text-align:center;
  background:var(--pink);color:var(--inkd);font:400 20px/1 "Bebas Neue","Arial Narrow",Impact,sans-serif;letter-spacing:.08em;text-transform:uppercase}
[data-emergency] .banner{display:block;animation:blink .5s steps(2,jump-none) 4}
@keyframes blink{from{opacity:1}to{opacity:.35}}

.ticket{margin:12px;padding:13px 14px 52px;border-radius:3px;background:var(--paper);color:var(--inkd);
  transform:rotate(-1.2deg);box-shadow:0 10px 22px rgba(0,0,0,.5)}
.ticket::before,.ticket::after{content:"";position:absolute;left:0;right:0;height:7px;
  background:radial-gradient(circle at 6px 0,#0e0830 3.6px,transparent 4.2px) 0 0/12px 7px repeat-x}
.ticket::before{top:-1px}
.ticket::after{bottom:-1px;transform:scaleY(-1)}
.ticket.print{animation:print .44s steps(8,end) both}
@keyframes print{from{transform:translateY(-112%) rotate(-1.2deg)}to{transform:translateY(0) rotate(-1.2deg)}}
.tk-head{display:flex;justify-content:space-between;align-items:baseline;gap:10px;padding:3px 0 7px;border-bottom:2px dashed rgba(26,16,51,.35);
  font-size:11.5px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:#4a3a78}
.tk-no{white-space:nowrap}
.tk-grade{text-align:right}
@media (max-width:359px){.tk-head{font-size:10.5px;letter-spacing:.05em}.stamp{font-size:22px}}
.tk-text{margin:11px 0 0;font-weight:800;font-size:clamp(19px,5.5vw,24px);line-height:1.2;text-wrap:balance;overflow-wrap:break-word}
.tk-small{margin:8px 0 0;font-size:15px;font-weight:600;color:#3d2f66}
.stamp{position:absolute;right:11px;bottom:10px;padding:6px 10px 3px;border:3px solid currentColor;border-radius:6px;color:var(--stamp);
  font:400 24px/1 "Bebas Neue","Arial Narrow",Impact,sans-serif;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;
  transform:rotate(-7deg);box-shadow:inset 0 0 0 1px rgba(196,23,95,.35)}
.ticket.print .stamp{animation:slam .2s cubic-bezier(.5,0,1,.6) .4s both}
@keyframes slam{from{transform:rotate(-7deg) scale(2.7);opacity:0}to{transform:rotate(-7deg) scale(1);opacity:1}}
.app.thump .win,.app.thump .dash,.app.thump .sign,.app.thump::before{animation:thump .24s linear}
@keyframes thump{0%{transform:translateY(0)}25%{transform:translateY(5px)}55%{transform:translateY(-2px)}100%{transform:translateY(0)}}

.smoke{position:absolute;inset:0;z-index:4;pointer-events:none}
.smoke i{position:absolute;bottom:18%;width:54px;height:54px;border-radius:50%;background:rgba(226,220,255,.55);filter:blur(9px);opacity:0}
.smoke i:nth-child(1){left:14%}.smoke i:nth-child(2){left:44%}.smoke i:nth-child(3){left:72%}
[data-broken] .smoke i{animation:smoke 2.2s ease-out 2 both}
[data-broken] .smoke i:nth-child(2){animation-delay:.35s}
[data-broken] .smoke i:nth-child(3){animation-delay:.7s}
@keyframes smoke{0%{transform:translateY(20px) scale(.5);opacity:0}25%{opacity:.75}100%{transform:translateY(-150px) scale(1.9);opacity:0}}

/* ---------- Alfred and his comeback ---------- */
.heckle{display:grid;grid-template-columns:104px minmax(0,1fr);align-items:center;column-gap:4px;min-height:104px}
.alf{display:block;width:124px;max-width:none;height:auto;margin:-10px 0 -8px -14px}
.bubble{margin:0;padding:11px 13px;border-radius:16px;background:var(--text);color:var(--inkd);
  font-size:15.5px;line-height:1.3;font-weight:700;overflow-wrap:anywhere;box-shadow:0 6px 16px rgba(0,0,0,.35)}
.bubble::after{content:"";position:absolute;left:-9px;top:50%;margin-top:-9px;border:9px solid transparent;border-left:0;border-right-color:var(--text)}
.bubble:empty{visibility:hidden;min-height:44px}
.bubble.pop{animation:pop .22s cubic-bezier(.3,1.7,.5,1) both}
@keyframes pop{from{transform:scale(.6);opacity:0}to{transform:none;opacity:1}}
.alf.bob{animation:bob .3s ease-out}
@keyframes bob{0%{transform:translateY(8px)}60%{transform:translateY(-4px)}100%{transform:none}}

/* ---------- the button worth pressing ---------- */
.big{appearance:none;-webkit-appearance:none;display:block;width:calc(100% - 28px);max-width:400px;padding:0 0 11px;border:0;background:none;
  font:inherit;color:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent;touch-action:manipulation}
.cap{display:block;padding:20px 14px 18px;border-radius:999px;
  background:linear-gradient(180deg,#ffe596 0,#fbc146 46%,#f2a91c 100%);color:var(--inkd);
  font-weight:900;font-size:clamp(20px,5.8vw,25px);line-height:1;text-align:center;
  box-shadow:0 11px 0 #9c6200,0 11px 0 4px var(--panel),0 22px 26px rgba(0,0,0,.5),inset 0 3px 0 rgba(255,255,255,.65),inset 0 -4px 0 rgba(156,98,0,.35);
  transition:transform .07s,box-shadow .07s}
.big:hover .cap{background:linear-gradient(180deg,#fff0b8 0,#ffd370 46%,#f7b530 100%)}
.big:active .cap,.big[aria-disabled="true"] .cap{transform:translateY(9px);
  box-shadow:0 2px 0 #9c6200,0 2px 0 4px var(--panel),0 8px 12px rgba(0,0,0,.5),inset 0 3px 0 rgba(255,255,255,.65),inset 0 -4px 0 rgba(156,98,0,.35)}
.big[aria-disabled="true"]{cursor:progress}
.big:focus-visible{outline:none}
.big:focus-visible .cap{outline:4px solid var(--cyan);outline-offset:4px}
[data-state="idle"] .cap{animation:beckon 1.7s ease-in-out infinite}
@keyframes beckon{0%,100%{filter:brightness(1)}50%{filter:brightness(1.13) drop-shadow(0 0 12px rgba(251,193,70,.75))}}

/* ---------- the way on: one calm line, one button ---------- */
.wayon{display:flex;flex-wrap:wrap;align-items:center;gap:6px 14px;padding:14px 16px;border-radius:18px;
  background:rgba(12,7,40,.72);border:1px solid rgba(243,239,255,.24)}
.wayline{flex:1 1 200px;margin:0;font-size:16.5px;line-height:1.4;font-weight:600}
.waybtn{display:inline-flex;align-items:center;justify-content:center;min-height:48px;padding:0 22px;border-radius:999px;
  border:2px solid rgba(255,255,255,.78);color:var(--text);font-weight:800;font-size:16px;text-decoration:none;white-space:nowrap;
  transition:background .3s,color .3s,border-color .3s,box-shadow .3s}
.waybtn:hover{background:rgba(255,255,255,.12)}
[data-lit] .waybtn{background:var(--yellow);border-color:var(--yellow);color:var(--inkd);box-shadow:0 0 0 4px rgba(251,193,70,.28)}
[data-lit] .waybtn:hover{background:var(--yellow2)}
.waylink{display:inline-flex;align-items:center;min-height:44px;padding:0 4px;color:var(--muted);font-size:15px;font-weight:600;text-underline-offset:3px}
.waylink:hover{color:var(--text)}

/* ---------- the small print ---------- */
.foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:6px 10px;padding-top:2px}
.mini{appearance:none;-webkit-appearance:none;min-height:44px;padding:0 16px;border-radius:999px;border:1px solid rgba(243,239,255,.34);
  background:rgba(12,7,40,.6);color:var(--muted);font:700 14px/1 "Albert Sans",system-ui,sans-serif;cursor:pointer}
.mini:hover{color:var(--text);border-color:rgba(243,239,255,.6)}
.credit{display:inline-flex;align-items:center;min-height:44px;padding:0 8px;color:var(--muted);font-size:14px;font-weight:600;text-underline-offset:3px}
html.framed .credit{display:none}
.noscript{margin:0 14px 16px;padding:14px 16px;border-radius:14px;background:var(--ink);font-size:17px;font-weight:600;text-align:center}

/* ---------- the machine's moods ---------- */
[data-level="1"]{--needle:-56deg}
[data-level="2"]{--needle:-28deg}
[data-level="3"]{--needle:0deg;--accent:var(--yellow)}
[data-level="4"]{--needle:29deg;--accent:#ff9a6b}
[data-level="5"]{--needle:62deg;--accent:var(--pink)}
[data-state="spinning"] .needle{animation:jitter .16s linear infinite}
@keyframes jitter{0%{transform:rotate(calc(var(--needle) - 7deg))}50%{transform:rotate(calc(var(--needle) + 9deg))}100%{transform:rotate(calc(var(--needle) - 7deg))}}
[data-level="4"] .sign::before,[data-level="4"] .sign::after{animation-duration:.55s}
[data-level="5"] .sign::before,[data-level="5"] .sign::after{animation-duration:.3s}
[data-level="5"][data-state="result"] .needle{animation:jitter .22s linear infinite}
[data-level="5"] .t2{animation:wonky 2.4s ease-in-out infinite}
@keyframes wonky{0%,100%{transform:rotate(0)}30%{transform:rotate(-2.2deg)}65%{transform:rotate(1.6deg)}}
/* it gives up: lights out, needle flat, a red glow */
[data-broken]{--needle:-88deg;--accent:#ff4d6d}
[data-broken] .sign::before,[data-broken] .sign::after{opacity:.18;animation:none}
[data-broken] .title{animation:flicker 1.6s steps(1) 2}
@keyframes flicker{0%,100%{opacity:1}8%{opacity:.25}14%{opacity:1}42%{opacity:.4}47%{opacity:1}}
[data-broken] .ticket{transform:rotate(2.4deg)}
[data-broken] .ticket.print{animation-name:printb}
@keyframes printb{from{transform:translateY(-112%) rotate(2.4deg)}to{transform:translateY(0) rotate(2.4deg)}}
[data-broken] .stamp{color:#3d2f66;box-shadow:inset 0 0 0 1px rgba(61,47,102,.35)}

/* ---------- the works: painted parts that peek out from behind the cabinet and never stop moving ---------- */
.mech{grid-column:1;grid-row:1/6;position:relative;z-index:-2;pointer-events:none}
.m{position:absolute;display:block;height:auto;max-width:none}
.m-horn{left:3%;top:-35px;width:58px;transform-origin:22% 92%;transition:transform .5s cubic-bezier(.3,1.6,.5,1)}
.m-antenna{left:24%;top:-37px;width:22px;transform-origin:50% 100%;transition:transform .5s cubic-bezier(.3,1.6,.5,1)}
.m-lamp{left:calc(24% - 4px);top:-43px;width:30px;height:30px;border-radius:50%;background:radial-gradient(circle,rgba(255,120,120,.95) 0,rgba(255,70,70,.55) 34%,rgba(255,60,60,0) 70%);animation:lamp 1.6s steps(2,jump-none) infinite}
@keyframes lamp{from{opacity:1}to{opacity:.08}}
.m-cog1{left:37%;top:-29px;width:78px;animation:cog 9s linear infinite}
.m-cog2{left:calc(37% + 66px);top:-13px;width:46px;animation:cog 5.4s linear infinite reverse}
@keyframes cog{to{transform:rotate(360deg)}}
.m-glove{left:calc(37% + 14px);top:2px;width:44px;transform-origin:50% 100%;transform:translateY(70px);opacity:0}
.m-whistle{right:25%;top:-27px;width:26px}
.m-jet{right:calc(25% + 1px);top:-44px;width:24px;height:24px;border-radius:50%;background:rgba(240,238,255,.95);filter:blur(4px);opacity:0}
.m-chimney{right:5%;top:-33px;width:50px}
.m-puff{right:calc(5% + 11px);top:-44px;width:28px;height:28px;border-radius:50%;background:rgba(226,220,255,.8);filter:blur(5px);opacity:0;animation:puff 4.5s ease-out var(--pd,0s) infinite}
.p2{--pd:1.5s}.p3{--pd:3s}
@keyframes puff{0%{transform:translateY(18px) scale(.4);opacity:0}7%{opacity:.85}30%{transform:translate(9px,-22px) scale(1.25);opacity:0}100%{transform:translate(9px,-22px) scale(1.25);opacity:0}}
.m-cog3,.m-lever,.m-key{display:none}
.valve{display:block;width:42px;height:auto;flex:none;filter:drop-shadow(0 2px 3px rgba(0,0,0,.5))}
.roller{position:absolute;left:12px;right:12px;top:0;height:11px;z-index:11;border-radius:0 0 7px 7px;
  background:repeating-linear-gradient(115deg,#aab4e6 0 8px,#5c68ad 8px 16px);box-shadow:0 3px 6px rgba(0,0,0,.6),inset 0 2px 0 rgba(255,255,255,.4),inset 0 -2px 0 rgba(0,0,0,.3)}
@keyframes rollx{to{background-position:-17.65px 0}}
.bolt{position:absolute;z-index:1;width:13px;height:auto;opacity:.92}
.b1{left:5px;top:14px}.b2{right:5px;top:14px}.b3{left:5px;bottom:5px}.b4{right:5px;bottom:5px}
/* running: everything speeds up and the whole cabinet rumbles */
[data-state="spinning"] .m-cog1{animation-duration:1.3s}
[data-state="spinning"] .m-cog2{animation-duration:.8s}
[data-state="spinning"] .m-cog3{animation-duration:1s}
[data-state="spinning"] .m-lamp{animation-duration:.22s}
[data-state="spinning"] .m-puff{animation-duration:.75s}
[data-state="spinning"] .p2{--pd:.25s}
[data-state="spinning"] .p3{--pd:.5s}
[data-state="spinning"] .valve{animation:cog .6s linear infinite}
[data-state="spinning"] .roller,.win:has(.ticket.print) .roller{animation:rollx .3s linear infinite}
[data-state="spinning"] .sign,[data-state="spinning"] .dash,[data-state="spinning"] .win,[data-state="spinning"] .mech,.app[data-state="spinning"]::before{animation:rumble .13s linear infinite}
@keyframes rumble{0%,100%{transform:translate(0,0)}25%{transform:translate(1px,-1px)}50%{transform:translate(-1px,1px)}75%{transform:translate(1px,1px)}}
.app.thump .m-jet{animation:jet .55s ease-out}
@keyframes jet{0%{transform:scale(.3);opacity:.95}100%{transform:translateY(-16px) scale(1.9);opacity:0}}
.app.toot .m-horn{animation:toot .4s ease-out}
@keyframes toot{0%,100%{transform:scale(1)}40%{transform:scale(1.28) rotate(7deg)}}
/* it gives up: the works stop, things droop, and a boxing glove on a spring pops out of the top */
[data-broken] .m-cog,[data-broken] .m-puff{animation-play-state:paused}
[data-broken] .m-lamp{animation:none;opacity:1}
[data-broken] .m-horn{transform:rotate(-26deg)}
[data-broken] .m-antenna{transform:rotate(26deg)}
[data-broken] .m-lamp{transform:translate(14px,6px)}
[data-broken] .m-glove{opacity:1;animation:boing .8s cubic-bezier(.3,1.9,.4,1) both,sway 1.1s ease-in-out .8s infinite alternate}
@keyframes boing{from{transform:translateY(70px) scaleY(.4)}to{transform:translateY(-30px) scaleY(1)}}
@keyframes sway{from{transform:translateY(-30px) rotate(-10deg)}to{transform:translateY(-30px) rotate(10deg)}}

/* ---------- special effects: a layer that cannot be pressed and changes no heights ---------- */
/* READABILITY RULE (Sy, 12 Nov 2026: "people will still be able to read the text even with effects going"):
   the effects layer sits at level 5. Every piece of text a visitor needs (the ticket, Alfred's reply, the buttons, the way on) sits at level 10, above it.
   So an effect can pass over the cabinet, the sign and the dials, and always passes BEHIND the words. */
body{position:relative;isolation:isolate}
.fx{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:5}
.ticket,.bubble,.intro,.big,.wayon,.foot{position:relative;z-index:10}
.fxi{position:absolute;left:var(--x,0);top:var(--y,0);width:var(--s,48px);pointer-events:none;will-change:transform,opacity;
  animation-duration:var(--d,2s);animation-delay:var(--w,0s);animation-timing-function:var(--e,linear);animation-fill-mode:both}
.fxin{width:100%}
.fxi img,.fxi svg{display:block;width:100%;height:auto;max-width:none}
.fxclip{position:absolute;overflow:hidden;pointer-events:none}
.fxclip .fxi{left:0;top:0}
.fx-across{animation-name:fx-across}
@keyframes fx-across{from{transform:translate(0,0)}to{transform:translate(var(--tx),var(--ty,0))}}
.fx-visit{animation-name:fx-visit;animation-timing-function:ease-in-out}
@keyframes fx-visit{0%{transform:translate(0,0)}32%,68%{transform:translate(calc(var(--tx)*.5),var(--ty))}100%{transform:translate(var(--tx),calc(var(--ty)*-2))}}
.fx-fall{animation-name:fx-fall}
@keyframes fx-fall{from{transform:translate(0,0)}to{transform:translate(var(--dx,0),var(--ty))}}
.fx-rise{animation-name:fx-rise;animation-timing-function:ease-out}
@keyframes fx-rise{0%{transform:translate(0,0) scale(.4);opacity:0}15%{opacity:.92}100%{transform:translate(var(--tx,0),var(--ty)) scale(1.7);opacity:0}}
.fx-pop{animation-name:fx-pop;animation-timing-function:ease-out}
@keyframes fx-pop{0%{transform:scale(.2) rotate(var(--r,0deg));opacity:0}12%{transform:scale(1.14) rotate(var(--r,0deg));opacity:1}20%{transform:scale(1) rotate(var(--r,0deg))}82%{transform:scale(1) rotate(var(--r,0deg));opacity:1}100%{transform:scale(.9) rotate(var(--r,0deg));opacity:0}}
.fx-peek{animation-name:fx-peek;animation-timing-function:ease-in-out}
@keyframes fx-peek{0%{transform:translateY(102%)}22%,78%{transform:translateY(0)}100%{transform:translateY(102%)}}
.fx-drop{animation-name:fx-drop}
@keyframes fx-drop{0%{transform:translateY(var(--from))}18%{transform:translateY(0)}23%{transform:translateY(-12%)}28%{transform:translateY(0)}86%{transform:translateY(0);opacity:1}100%{transform:translateY(0);opacity:0}}
.fx-spark{animation-name:fx-spark;animation-timing-function:cubic-bezier(.1,.7,.3,1)}
@keyframes fx-spark{0%{transform:rotate(var(--a)) translateX(0) scale(1);opacity:0}5%,70%{opacity:1}100%{transform:rotate(var(--a)) translateX(var(--dist)) scale(.3);opacity:0}}
.fx-shoot{animation-name:fx-shoot;animation-timing-function:ease-out}
@keyframes fx-shoot{0%{transform:translateY(var(--from));opacity:1}85%{opacity:1}100%{transform:translateY(0);opacity:0}}
.fx-ring{animation-name:fx-ring;animation-timing-function:ease-out}
@keyframes fx-ring{0%{transform:scale(.05);opacity:0}15%{opacity:1}100%{transform:scale(1);opacity:0}}
.fx-ring .fxin{aspect-ratio:1;border:5px solid var(--c);border-radius:50%}
.fx-veil{left:0;top:0;width:100%;height:100%;background:#05021a;animation-name:fx-veil;animation-timing-function:ease-in-out}
@keyframes fx-veil{0%,100%{opacity:0}30%,70%{opacity:.78}}
.fx-arc{animation-name:fx-arc;animation-timing-function:ease-in-out}
@keyframes fx-arc{0%{transform:translateY(120px) scale(.8);opacity:0}25%,75%{transform:none;opacity:1}100%{transform:translateY(120px) scale(.8);opacity:0}}
.fx-tide{animation-name:fx-tide;animation-timing-function:ease-in-out}
@keyframes fx-tide{0%{transform:translate(0,60px);opacity:0}20%{transform:translate(-30px,0);opacity:1}50%{transform:translate(-80px,6px)}80%{transform:translate(-40px,0);opacity:1}100%{transform:translate(0,60px);opacity:0}}
.fx-tide svg{height:60px}
.fx-fadeend{animation-name:fx-across,fx-fadeio}
@keyframes fx-fadeio{0%,100%{opacity:0}8%,90%{opacity:1}}
/* how a thing wobbles while it travels */
.fx-bob{animation:fxw-bob .5s ease-in-out infinite alternate}
@keyframes fxw-bob{from{transform:translateY(-7px) rotate(-5deg)}to{transform:translateY(7px) rotate(5deg)}}
.fx-rock{animation:fxw-rock 1.1s ease-in-out infinite alternate}
@keyframes fxw-rock{from{transform:rotate(-5deg)}to{transform:rotate(5deg)}}
.fx-float{animation:fxw-float 1.3s ease-in-out infinite alternate}
@keyframes fxw-float{from{transform:translateY(-4px) rotate(-6deg)}to{transform:translateY(5px) rotate(7deg)}}
.fx-waddle{transform-origin:50% 100%;animation:fxw-waddle .42s ease-in-out infinite alternate}
@keyframes fxw-waddle{from{transform:rotate(-6deg)}to{transform:rotate(6deg)}}
.fx-hop{animation:fxw-hop .26s ease-out infinite alternate}
@keyframes fxw-hop{from{transform:translateY(0)}to{transform:translateY(-16px)}}
.fx-roll{animation:fxw-roll 1.1s linear infinite}
@keyframes fxw-roll{to{transform:rotate(360deg)}}
.fx-shake{animation:fxw-shake .09s linear infinite alternate}
@keyframes fxw-shake{from{transform:translateY(-2px)}to{transform:translateY(2px)}}
.fx-leap{animation:fxw-leap var(--d,2.2s) ease-in-out var(--w,0s) both}
@keyframes fxw-leap{0%{transform:translateY(30px) rotate(-28deg)}50%{transform:translateY(-150px) rotate(0)}100%{transform:translateY(30px) rotate(30deg)}}
.fx-tumble{animation:fxw-tumble var(--d,2s) linear var(--w,0s) both}
@keyframes fxw-tumble{to{transform:rotate(var(--r,360deg))}}
.fx-glow{animation:fxw-glow .8s ease-in-out infinite alternate}
@keyframes fxw-glow{from{filter:drop-shadow(0 0 6px #ff7df0)}to{filter:drop-shadow(0 0 26px #ff7df0)}}
/* the things drawn here, not painted */
.fx-bit{height:calc(var(--s)*.6);background:var(--c);border-radius:2px}
.fx-coin{aspect-ratio:1;border-radius:50%;background:var(--c);box-shadow:inset 0 -3px 0 rgba(0,0,0,.22),inset 0 2px 0 rgba(255,255,255,.5)}
.fx-sheet{aspect-ratio:.75;border-radius:2px;box-shadow:0 2px 6px rgba(0,0,0,.3);background-color:var(--c);
  background-image:linear-gradient(transparent 20%,rgba(26,16,51,.25) 20% 24%,transparent 24% 40%,rgba(26,16,51,.25) 40% 44%,transparent 44% 60%,rgba(26,16,51,.25) 60% 64%,transparent 64%)}
.fx-rain{height:24px;border-radius:2px;background:linear-gradient(transparent,#9feaf6)}
.fx-letter{font:400 34px/1 "Bebas Neue","Arial Narrow",Impact,sans-serif;color:var(--c);text-shadow:0 2px 0 #0c0728}
.fx-puff{aspect-ratio:1;border-radius:50%;background:rgba(232,228,255,.84);filter:blur(6px)}
.fx-note{font:700 var(--fs,40px)/1 "Albert Sans",system-ui,sans-serif;color:var(--c);text-shadow:0 2px 0 #0c0728}
.fx-dot{aspect-ratio:1;border-radius:50%;background:var(--c);box-shadow:0 0 10px var(--c)}
.fx-big{box-shadow:0 0 26px var(--c)}
.fx-flame{aspect-ratio:1;border-radius:50%;background:radial-gradient(circle,#fff3b0 0,#fbc146 38%,#ff7a3d 66%,rgba(255,122,61,0) 72%);filter:blur(2px)}
.fx-moon{aspect-ratio:1;border-radius:50%;background:radial-gradient(circle at 35% 30%,#fffdf2,#f3e7b8 60%,#d9cc98);box-shadow:0 0 40px rgba(255,246,223,.55),inset -10px -8px 0 rgba(120,105,60,.18)}
.fxt{width:auto}
.fxt .fxin{font:400 var(--fs,46px)/1 "Bebas Neue","Arial Narrow",Impact,sans-serif;letter-spacing:.04em;color:var(--c);white-space:nowrap;text-shadow:0 3px 0 #0c0728,0 0 18px rgba(12,7,40,.8)}
.fx-slip{display:inline-block;padding:7px 16px 4px;border-radius:3px;background:#fff6df;color:#1a1033;font:400 26px/1 "Bebas Neue","Arial Narrow",Impact,sans-serif;letter-spacing:.08em;white-space:nowrap;box-shadow:0 4px 10px rgba(0,0,0,.4)}
.fx-trail{position:relative}
.fx-trail::before{content:"";position:absolute;right:86%;top:44%;width:70vw;height:12px;border-radius:6px;background:linear-gradient(90deg,rgba(243,239,255,0),rgba(243,239,255,.85));filter:blur(4px)}
/* effects that take hold of the whole machine for a moment */
html.fx-hue .sign,html.fx-hue .dash,html.fx-hue .mech,html.fx-hue .app::before{animation:fx-hue 2.2s linear}
@keyframes fx-hue{from{filter:hue-rotate(0deg)}to{filter:hue-rotate(360deg)}}
html.fx-glitch .sign,html.fx-glitch .dash,html.fx-glitch .mech,html.fx-glitch .app::before{animation:fx-glitch .9s steps(1)}
@keyframes fx-glitch{0%,100%{transform:none;filter:none}10%{transform:translate(-6px,2px) skewX(-4deg);filter:hue-rotate(90deg)}25%{transform:translate(5px,-3px) skewX(3deg);filter:invert(.15)}40%{transform:translate(-3px,0);filter:hue-rotate(-60deg)}55%{transform:translate(7px,3px) skewX(-2deg)}70%{transform:translate(-4px,-2px);filter:hue-rotate(40deg)}85%{transform:translate(2px,1px)}}
html.fx-dance .alf{animation:fx-dance 2.8s ease-in-out}
@keyframes fx-dance{0%,100%{transform:none}10%{transform:rotate(-14deg) translateY(-10px)}22%{transform:rotate(12deg)}34%{transform:rotate(-12deg) translateY(-14px)}46%{transform:rotate(14deg)}58%{transform:rotate(-10deg) translateY(-10px)}70%{transform:rotate(360deg)}82%{transform:rotate(366deg) translateY(-8px)}92%{transform:rotate(360deg)}}

/* ---------- laptop and wider: the machine on the left, Alfred on the right ---------- */
@media (min-width:860px){
  .app{max-width:1120px;grid-template-columns:minmax(0,500px) minmax(0,1fr);column-gap:52px;row-gap:10px;padding:52px 34px 12px}
  .app::before{grid-column:1;grid-row:1/5}
  .sign{grid-column:1;grid-row:1;margin:16px 16px 0;padding:18px 10px 12px}
  .app>noscript{grid-column:1;grid-row:2}
  .dash{grid-column:1;grid-row:2;margin:2px 22px}
  .win{grid-column:1;grid-row:3;margin:0 16px;min-height:246px}
  .big{grid-column:1;grid-row:4;margin:4px auto 20px}
  .heckle{grid-column:2;grid-row:1/4;margin:0;display:flex;flex-direction:column-reverse;align-items:center;justify-content:center;gap:18px;min-height:0}
  .wayon{grid-column:2;grid-row:4;margin:0;align-self:center}
  .foot{grid-column:1/3;grid-row:5;padding-top:6px}
  .mech{grid-column:1;grid-row:1/5}
  .m-horn{width:70px;top:-43px}
  .m-antenna{width:26px;top:-44px}
  .m-lamp{left:calc(24% - 5px);top:-51px;width:36px;height:36px}
  .m-cog1{width:96px;top:-36px}
  .m-cog2{left:calc(37% + 82px);width:56px;top:-16px}
  .m-glove{width:52px;left:calc(37% + 20px)}
  .m-whistle{width:32px;top:-33px}
  .m-jet{top:-52px}
  .m-chimney{width:60px;top:-40px}
  .m-puff{right:calc(5% + 15px);top:-52px;width:32px;height:32px}
  .m-cog3{display:block;left:-27px;top:41%;width:64px;animation:cog 6s linear infinite}
  .m-lever{display:block;right:-22px;top:26%;width:42px;transform-origin:50% 86%;transform:rotate(38deg);transition:transform .22s cubic-bezier(.3,1.5,.5,1)}
  [data-state="spinning"] .m-lever{transform:rotate(104deg)}
  .m-key{display:block;right:-44px;bottom:15%;width:60px;animation:wind 2.6s ease-in-out infinite alternate}
  @keyframes wind{from{transform:rotate(90deg) scaleX(1)}to{transform:rotate(90deg) scaleX(-1)}}
  [data-state="spinning"] .m-key{animation-duration:.35s}
  [data-broken] .m-key{animation-play-state:paused}
  .valve{width:52px}
  .roller{left:16px;right:16px;height:13px}
  .title{font-size:60px}
  .title span{display:inline}
  .gauge svg{width:124px}
  .digits i{min-width:32px;font-size:34px}
  .intro{font-size:19px;padding:22px 26px}
  .tk-text{font-size:27px}
  .ticket{margin:16px;padding:15px 18px 56px}
  .stamp{font-size:28px;right:14px;bottom:11px}
  .alf{width:min(330px,34vw);margin:-26px 0 0}
  .bubble{max-width:430px;min-width:200px;padding:16px 20px;font-size:21px;border-radius:22px;text-align:center}
  .bubble::after{left:50%;top:auto;bottom:-12px;margin:0 0 0 -12px;border:12px solid transparent;border-bottom:0;border-top-color:var(--text)}
  .bubble:empty{min-height:62px}
  .cap{font-size:27px;padding:24px 16px 22px}
  .wayline{font-size:18px}
}

/* ---------- reduced motion: everything still works and nothing moves ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  .smoke,.fx,.m-puff,.m-jet{display:none}
  [data-broken] .m-glove{transform:translateY(-30px)}
}
