:root{
  --void:#0b0713;
  --bg:#150e1f;
  --panel:#1d1428;
  --panel2:#281b36;
  --line:#4a3560;
  --ink:#f7efe6;
  --dim:#a396b4;
  --pink:#ffb3d1;
  --pink-hot:#ff6fae;
  --cyan:#8fe3ff;
  --gold:#ffd98a;
  --grey:#b9b2c4;
  --mono: ui-monospace, "SFMono-Regular", "Cascadia Mono", "DejaVu Sans Mono", "Courier New", monospace;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  background:
    radial-gradient(120% 90% at 50% 0%, #241634 0%, var(--bg) 45%, var(--void) 100%);
  color:var(--ink);
  font-family:var(--mono);
  font-size:13px;
  letter-spacing:.3px;
  overflow:hidden;
  -webkit-tap-highlight-color:transparent;
  -webkit-font-smoothing:none;
}
button,input,textarea,select{font:inherit;color:inherit}
button{cursor:pointer;background:none;border:0}
.hidden{display:none!important}

/* ---------- shared pixel chrome ---------- */
.pxbox{
  background:var(--panel);
  box-shadow:0 0 0 2px var(--line), 0 0 0 4px var(--void), 0 8px 0 4px rgba(0,0,0,.35);
}
.btn{
  background:var(--panel2);
  color:var(--ink);
  padding:8px 14px;
  box-shadow:0 0 0 2px var(--line), 0 3px 0 0 var(--void);
  transition:transform .06s, box-shadow .06s, background .12s;
  text-transform:lowercase;
}
.btn:hover{background:#33244a}
.btn:active{transform:translateY(3px);box-shadow:0 0 0 2px var(--line)}
.btn:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}
.btn.pink{background:#3a1e30;box-shadow:0 0 0 2px var(--pink-hot),0 3px 0 0 var(--void);color:var(--pink)}
.btn.pink:hover{background:#4c2740}
.btn.sm{padding:5px 9px;font-size:11px}
.btn[disabled]{opacity:.4;cursor:not-allowed}
input[type=text],input[type=password],input[type=date],textarea,select{
  background:#120c1b;border:0;box-shadow:0 0 0 2px var(--line);
  padding:9px 10px;width:100%;color:var(--ink);
}
input:focus,textarea:focus,select:focus{outline:none;box-shadow:0 0 0 2px var(--cyan)}
::placeholder{color:#6b5d7d}

/* ---------- stage ---------- */
#app{position:fixed;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:10px}
#stagewrap{position:relative}
#stage{position:relative;line-height:0;
  box-shadow:0 0 0 3px #2c1f3d, 0 0 0 6px var(--void), 0 0 60px 6px rgba(255,140,190,.10), 0 14px 0 6px rgba(0,0,0,.4);}
canvas{display:block;image-rendering:pixelated;image-rendering:crisp-edges;touch-action:none}
#scan{position:absolute;inset:0;pointer-events:none;
  background:repeating-linear-gradient(180deg, rgba(0,0,0,.18) 0 1px, rgba(0,0,0,0) 1px 3px);
  mix-blend-mode:multiply}
#vig{position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 110% at 50% 45%, rgba(0,0,0,0) 45%, rgba(6,3,12,.55) 100%)}
#tags{position:absolute;inset:0;pointer-events:none;overflow:hidden}
#slider{position:absolute;left:6px;top:6px;z-index:6;display:flex;gap:4px;align-items:flex-start}
#slider button{background:rgba(11,7,19,.72);box-shadow:0 0 0 2px var(--line);padding:3px;display:block;line-height:0}
#slider button.on{box-shadow:0 0 0 2px var(--pink-hot);background:rgba(58,30,48,.85)}
#slider button:hover{background:rgba(51,36,74,.9)}
#slider canvas{image-rendering:pixelated;display:block}
#slLab{align-self:center;margin-left:4px;background:rgba(11,7,19,.72);box-shadow:0 0 0 1px var(--line);
  padding:3px 6px;font-size:10px;color:var(--ink);white-space:nowrap;letter-spacing:.4px}
#slLab i{font-style:normal;color:var(--pc, var(--pink))}
#keys{position:absolute;right:10px;bottom:8px;z-index:6;background:none;box-shadow:none;padding:0;
  font-size:19px;line-height:1;color:var(--gold);letter-spacing:3px;pointer-events:none;
  text-shadow:1px 0 0 #0b0713,-1px 0 0 #0b0713,0 1px 0 #0b0713,0 -1px 0 #0b0713,0 0 8px rgba(11,7,19,.9)}
#keys b{color:#fff;font-weight:400}
@media (max-width:560px){ #keys{font-size:15px;right:7px;bottom:6px} }
#hint{position:absolute;left:50%;bottom:10px;transform:translateX(-50%);
  background:rgba(11,7,19,.85);box-shadow:0 0 0 2px var(--line);
  padding:5px 10px;font-size:11px;color:var(--ink);white-space:nowrap;opacity:0;transition:opacity .15s}
#hint.on{opacity:1}

/* ---------- name tags ---------- */
.tag{position:absolute;transform:translate(-50%,-100%);white-space:nowrap;font-size:10px;letter-spacing:1.5px;pointer-events:none;text-transform:lowercase}
.tag i{font-style:normal;position:absolute;font-size:8px;opacity:0}
.tag.zz{opacity:.55}
/* josh — monochrome sparkle */
.tag.josh{color:#fff;text-shadow:1px 0 0 #000,-1px 0 0 #000,0 1px 0 #000,0 -1px 0 #000,0 0 8px rgba(255,255,255,.75);animation:joshpulse 2.6s ease-in-out infinite}
.tag.josh i:nth-child(1){left:-9px;top:-2px;color:#fff;animation:spark 1.9s infinite}
.tag.josh i:nth-child(2){right:-9px;top:3px;color:#cfcfe6;animation:spark 1.9s infinite .95s}
.tag.josh i:nth-child(3){left:50%;top:-9px;color:#fff;animation:spark 2.6s infinite .45s}
@keyframes joshpulse{0%,100%{text-shadow:1px 0 0 #000,-1px 0 0 #000,0 1px 0 #000,0 -1px 0 #000,0 0 6px rgba(255,255,255,.55)}50%{text-shadow:1px 0 0 #000,-1px 0 0 #000,0 1px 0 #000,0 -1px 0 #000,0 0 12px rgba(255,255,255,.95)}}
@keyframes spark{0%{opacity:0;transform:scale(.4) rotate(0deg)}25%{opacity:1;transform:scale(1.15) rotate(90deg)}60%{opacity:0;transform:scale(.4) rotate(180deg)}100%{opacity:0}}
/* jasie — baby pink */
.tag.jasie{color:#ffd3e6;text-shadow:1px 0 0 #4a0f2c,-1px 0 0 #4a0f2c,0 1px 0 #4a0f2c,0 -1px 0 #4a0f2c,0 0 9px rgba(255,143,192,.9);animation:jbob 2.2s ease-in-out infinite}
.tag.jasie i:nth-child(1){left:-10px;top:0;color:#ff9ec9;animation:float 2.4s infinite}
.tag.jasie i:nth-child(2){right:-10px;top:2px;color:#ffc2dd;animation:float 2.4s infinite 1.2s}
.tag.jasie i:nth-child(3){left:50%;top:-8px;color:#fff0f6;animation:float 3s infinite .6s}
@keyframes jbob{0%,100%{transform:translate(-50%,-100%)}50%{transform:translate(-50%,-116%)}}
@keyframes float{0%{opacity:0;transform:translateY(2px) scale(.6)}30%{opacity:1}100%{opacity:0;transform:translateY(-9px) scale(1)}}
/* guests */
.tag.guest{color:var(--grey);text-shadow:1px 1px 0 #000,-1px 0 0 #000}
/* 富貴 — blue, and never still */
.tag.fugui{color:#bcd8ff;font-size:11px;letter-spacing:2px;text-transform:none;
  text-shadow:1px 0 0 #071530,-1px 0 0 #071530,0 1px 0 #071530,0 -1px 0 #071530,0 0 9px rgba(90,150,255,.95);
  animation:fubob 1.5s ease-in-out infinite}
.tag.fugui i:nth-child(1){left:-10px;top:0;color:#7fb4ff;animation:float 2.4s infinite}
.tag.fugui i:nth-child(2){right:-10px;top:2px;color:#a8ccff;animation:float 2.4s infinite 1.2s}
.tag.fugui i:nth-child(3){left:50%;top:-8px;color:#e6f0ff;animation:float 3s infinite .6s}
@keyframes fubob{0%,100%{transform:translate(-50%,-100%)}50%{transform:translate(-50%,-118%)}}

/* ---------- hud ---------- */
#hud{display:flex;gap:8px;align-items:center;flex-wrap:wrap;justify-content:center;max-width:100%}
#who{display:flex;align-items:center;gap:8px;padding:6px 10px;background:var(--panel);box-shadow:0 0 0 2px var(--line)}
#who .dot{width:7px;height:7px;background:#7ee787;box-shadow:0 0 6px #7ee787}
#who small{color:var(--dim);font-size:10px}
#roster{display:flex;gap:6px;font-size:10px;color:var(--dim);align-items:center}
#roster span{padding:3px 6px;background:#1a1225;box-shadow:0 0 0 1px var(--line)}

/* ---------- login ---------- */
/* the card is centred by margin rather than by align-items, because a flex
   item centred the other way has its overflow cut off at the top instead of
   scrolling — which on a short screen took the top of the keypad with it. */
#login{position:fixed;inset:0;z-index:40;display:flex;align-items:flex-start;justify-content:center;
  padding:16px;overflow-y:auto;overscroll-behavior:contain;
  background:radial-gradient(90% 80% at 50% 42%, rgba(24,22,34,.34) 0%, rgba(11,9,18,.72) 100%);
  backdrop-filter:blur(3px) saturate(.72);
  -webkit-backdrop-filter:blur(3px) saturate(.72);
  animation:loginfade .22s ease-out}
@keyframes loginfade{from{opacity:0;backdrop-filter:blur(0)}to{opacity:1}}
#login .card{width:min(420px,100%);padding:26px 22px;margin:auto;flex:0 0 auto}
.brand{font-size:34px;letter-spacing:-1px;line-height:.9}
.brand b{color:var(--pink)}
.sub{color:var(--dim);font-size:11px;margin-top:8px;line-height:1.6}
.field{margin-top:18px}
.label{font-size:10px;color:var(--dim);text-transform:uppercase;letter-spacing:2px;margin-bottom:6px}
.err{color:#ff8f9e;font-size:11px;margin-top:10px;min-height:16px}
.rowbtns{display:flex;gap:8px;margin-top:16px;flex-wrap:wrap}
.pick{display:flex;gap:10px;margin-top:14px;flex-wrap:wrap}
.pickcard{flex:1;min-width:130px;padding:14px;text-align:center;background:var(--panel2);box-shadow:0 0 0 2px var(--line);cursor:pointer}
.pickcard:hover{background:#33244a}
.pickcard canvas{margin:0 auto 8px;display:block;image-rendering:pixelated}
.pickcard.sel{box-shadow:0 0 0 2px var(--pink-hot)}
.swatches{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.sw{width:44px;height:56px;background:#150e1f;box-shadow:0 0 0 2px var(--line);cursor:pointer;display:grid;place-items:center}
.sw.sel{box-shadow:0 0 0 2px var(--cyan)}
.sw canvas{image-rendering:pixelated}

/* ---------- modal panels ---------- */
#modal{position:fixed;inset:0;z-index:30;display:flex;align-items:center;justify-content:center;padding:14px;background:rgba(8,4,14,.72)}
#modal .panel{width:min(560px,100%);max-height:88vh;display:flex;flex-direction:column}
#modal header{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:2px solid var(--line);background:var(--panel2)}
#modal header h2{font-size:14px;font-weight:400;letter-spacing:1px;text-transform:lowercase;flex:1}
#modal header .ic{font-size:16px}
#mBody{padding:14px;overflow:auto;line-height:1.65}
#mBody h3{font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:2px;margin:14px 0 8px;font-weight:400}
#mBody h3:first-child{margin-top:0}
.row{display:flex;gap:8px;align-items:center}
.row.wrap{flex-wrap:wrap}
.grow{flex:1}
.list{display:flex;flex-direction:column;gap:8px}
.item{padding:9px 11px;background:#170f22;box-shadow:0 0 0 2px #322144;font-size:12px;line-height:1.55}
.item .meta{font-size:10px;color:var(--dim);margin-top:4px;display:flex;gap:8px;flex-wrap:wrap}
.byjosh{box-shadow:0 0 0 2px #5a5a6e}
.byjasie{box-shadow:0 0 0 2px #6b3350}
.empty{color:var(--dim);font-size:11px;padding:12px;text-align:center;background:#170f22;box-shadow:0 0 0 2px #2a1c3a}
.tabs{display:flex;gap:6px;margin-bottom:12px;flex-wrap:wrap}
.tab{padding:5px 10px;font-size:11px;background:#170f22;box-shadow:0 0 0 2px #322144;cursor:pointer}
.tab.on{background:#3a1e30;box-shadow:0 0 0 2px var(--pink-hot);color:var(--pink)}
.gridphotos{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:10px}
.polaroid{background:#f3ece2;padding:6px 6px 20px;position:relative;box-shadow:0 3px 0 rgba(0,0,0,.4);transform:rotate(var(--r,0deg))}
.polaroid img{width:100%;display:block;aspect-ratio:1;object-fit:cover;image-rendering:auto}
.polaroid figcaption{position:absolute;left:6px;right:6px;bottom:4px;color:#3a2c22;font-size:9px;line-height:1.2;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
table{width:100%;border-collapse:collapse;font-size:11px}
th{text-align:left;color:var(--dim);font-weight:400;font-size:10px;text-transform:uppercase;letter-spacing:1px;padding:6px 8px;border-bottom:2px solid var(--line)}
td{padding:7px 8px;border-bottom:1px solid #2a1c3a;vertical-align:top}
tr.owner td{background:rgba(143,227,255,.05)}
tr.fail td{background:rgba(255,90,110,.08);color:#ffb3bd}
.pill{display:inline-block;padding:1px 6px;font-size:9px;box-shadow:0 0 0 1px var(--line);background:#170f22}
.pill.j{color:#fff;box-shadow:0 0 0 1px #8a8a9e}
.pill.s{color:var(--pink);box-shadow:0 0 0 1px var(--pink-hot)}
.pill.g{color:var(--grey)}
.bar{height:8px;background:#170f22;box-shadow:0 0 0 2px #322144;position:relative;overflow:hidden}
.bar i{display:block;height:100%;background:var(--pink)}
.big{font-size:26px;letter-spacing:-.5px}
.mut{color:var(--dim);font-size:11px}
.lock{color:var(--gold);font-size:11px;background:#251a12;box-shadow:0 0 0 2px #5a4020;padding:8px 10px}

/* ---------- the title card ----------
   arriving somewhere is announced the way it is in a game with a map screen:
   held for a breath in the upper third of the picture, then gone. it is not a
   label in the corner and it is not clickable, so nothing about it waits on you.

   line-height is set here on purpose. #stage carries line-height:0 so the
   canvas sits flush in it, and without this the three lines inherit that, come
   out zero pixels tall, and print on top of one another. */
#placard{
  position:absolute;inset:0;z-index:7;pointer-events:none;
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;
  padding-top:19%;gap:5px;text-align:center;line-height:1.45;
  opacity:0;
}
/* the animation lives on a class rather than on #placard, because an
   animation already running does not start again just because the text
   underneath it changed. the class comes off, the layout is forced, and it
   goes back on — which is what makes the card play on every arrival and not
   only on the first one of the session. */
#placard.show{ animation:placard 4.4s ease-out forwards }
#placard .pcName{
  font-size:19px;letter-spacing:5px;color:var(--ink);max-width:92%;
  text-wrap:balance;
  text-shadow:0 2px 0 var(--void), 0 0 16px rgba(11,7,19,.95);
}
#placard .pcCity{
  font-size:11px;letter-spacing:4px;text-transform:uppercase;max-width:92%;
  color:var(--pc, var(--pink));
  text-shadow:0 2px 0 var(--void), 0 0 12px rgba(11,7,19,.9);
}
#placard .pcRule{
  width:112px;height:2px;margin:3px 0 1px;flex:none;
  background:linear-gradient(90deg, transparent 0%, var(--pc, var(--pink-hot)) 50%, transparent 100%);
  transform:scaleX(0);
}
#placard.show .pcRule{ animation:placardRule 4.4s ease-out forwards }
#placard .pcDate{
  font-size:10px;letter-spacing:3px;color:var(--dim);
  text-shadow:0 1px 0 var(--void), 0 0 10px rgba(11,7,19,.9);
}
/* in over half a second, held for two and a half, then a slow count out */
@keyframes placard{
  0%   {opacity:0; transform:translateY(5px)}
  13%  {opacity:1; transform:translateY(0)}
  64%  {opacity:1; transform:translateY(0)}
  100% {opacity:0; transform:translateY(-4px)}
}
/* the rule draws itself outward from the middle as the name settles */
@keyframes placardRule{
  0%   {transform:scaleX(0)}
  28%  {transform:scaleX(1)}
  100% {transform:scaleX(1)}
}
@media (max-width:560px){
  #placard{padding-top:17%}
  #placard .pcName{font-size:14px;letter-spacing:3px}
  #placard .pcCity{font-size:9px;letter-spacing:3px}
  #placard .pcDate{font-size:8px;letter-spacing:2px}
  #placard .pcRule{width:88px}
}

/* ---------- how many are still on the floor ---------- */
#found{
  position:absolute;left:8px;bottom:8px;z-index:6;
  font-size:10px;letter-spacing:.6px;color:var(--dim);
  background:rgba(11,7,19,.72);box-shadow:0 0 0 1px var(--line);padding:3px 7px;
  pointer-events:none;
}
#found b{color:var(--pink);font-weight:400}
#found.all b{color:var(--gold)}
#found.pop{animation:foundpop .55s}
@keyframes foundpop{
  0%{transform:scale(1)} 26%{transform:scale(1.14);color:var(--ink)} 100%{transform:scale(1)}
}
@media (max-width:560px){ #found{font-size:9px;left:6px;bottom:6px} }
@media (prefers-reduced-motion: reduce){ #found.pop{animation:none} }

/* ---------- the polaroid overlay ----------
   the pictures, over the top of the map rather than instead of it: the room
   stays visible round the edges, which is the whole point of standing in it.
   every measurement that depends on the shape of a photograph is set in
   js/photos.js; what is here is the frame, the paper and the shadow. */
#pola{
  position:absolute;inset:0;z-index:34;display:flex;align-items:center;justify-content:center;
  flex-direction:column;gap:8px;padding:10px;line-height:1.4;
  background:radial-gradient(120% 100% at 50% 50%, rgba(8,4,14,.62) 0%, rgba(8,4,14,.90) 100%);
  animation:polafade .18s ease-out;
}
#polaTitle{
  font-size:10px;letter-spacing:1.5px;text-transform:lowercase;color:var(--pink);
  text-shadow:0 2px 0 var(--void);pointer-events:auto;cursor:pointer;
  max-width:88%;text-align:center;
}
#polaGrid{display:grid;justify-content:center;align-items:center;justify-items:center}
#polaClose{
  position:absolute;top:8px;right:8px;width:26px;height:26px;font-size:11px;padding:0;
  background:var(--panel);color:var(--ink);box-shadow:0 0 0 2px var(--line),0 3px 0 var(--void);
}
#polaClose:hover{background:#33244a}

.pola{
  background:var(--tint,#f4efe4);
  position:relative;
  transform:rotate(var(--rot,0deg));
  box-shadow:0 0 0 1px rgba(58,44,34,.28), 0 10px 22px rgba(0,0,0,.55);
  animation:polain .26s cubic-bezier(.2,1.4,.4,1) backwards;
}
.polawell{
  background:#161018;overflow:hidden;position:relative;
  box-shadow:inset 0 0 0 1px rgba(58,44,34,.35);
}
.polawell img{width:100%;height:100%;display:block;object-fit:cover;image-rendering:auto}
/* until a file arrives — and for the placeholder ones that never will —
   the well stays a piece of unexposed paper rather than a broken icon */
.polawell::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(150deg, rgba(255,255,255,.10) 0%, rgba(255,255,255,0) 42%);
}
.polatape{
  position:absolute;top:-5px;left:50%;width:52px;height:10px;
  background:var(--tape,#cbb9a4);opacity:.5;
  box-shadow:0 1px 2px rgba(0,0,0,.35);
  transform:translateX(-50%) rotate(calc(var(--rot,0deg) * -2.2));
}
@keyframes polafade{from{opacity:0}to{opacity:1}}
@keyframes polain{from{opacity:0;transform:rotate(var(--rot,0deg)) translateY(14px) scale(.94)}
                  to{opacity:1;transform:rotate(var(--rot,0deg))}}
@media (prefers-reduced-motion: reduce){
  #pola,.pola{animation:none}
}

/* ---------- toasts ---------- */
#toasts{position:fixed;left:50%;top:14px;transform:translateX(-50%);z-index:50;display:flex;flex-direction:column;gap:6px;align-items:center;pointer-events:none}
.toast{background:var(--panel);box-shadow:0 0 0 2px var(--line),0 4px 0 var(--void);padding:8px 14px;font-size:12px;animation:pop .25s}
.toast.love{box-shadow:0 0 0 2px var(--pink-hot),0 4px 0 var(--void);color:var(--pink)}
@keyframes pop{from{transform:translateY(-8px);opacity:0}to{transform:none;opacity:1}}

/* ---------- touch ---------- */
#pad{position:fixed;left:14px;bottom:14px;width:112px;height:112px;z-index:20;touch-action:none;display:none}
#pad .base{position:absolute;inset:0;border-radius:50%;background:rgba(29,20,40,.55);box-shadow:0 0 0 2px var(--line)}
#pad .nub{position:absolute;left:36px;top:36px;width:40px;height:40px;border-radius:50%;background:var(--panel2);box-shadow:0 0 0 2px var(--pink-hot)}
#act{position:fixed;right:14px;bottom:26px;width:74px;height:74px;border-radius:50%;z-index:20;display:none;
  background:#3a1e30;box-shadow:0 0 0 2px var(--pink-hot),0 4px 0 var(--void);color:var(--pink);font-size:11px}
body.touch #pad,body.touch #act{display:block}
@media (max-width:560px){ .brand{font-size:28px} #hud{font-size:11px} }
@media (prefers-reduced-motion:reduce){*{animation-duration:.001ms!important;animation-iteration-count:1!important}}


/* =========================================================
   the front door keypad
   ========================================================= */
body.gate #hud,body.gate #slider,body.gate #keys,body.gate #act{display:none!important}
body.gate.touch #act{display:block!important}
#login .card.keypad{width:min(330px,100%);padding:0;background:none;box-shadow:none}

/* the plate. bone, like the house, with a soft grey line round it rather than
   a black one — and a row of scallops hanging off the bottom, which is the
   same lace that is under the eaves out there. */
.padplate{
  position:relative;padding:14px 14px 16px;
  background:linear-gradient(180deg,#e4e3e1 0%,#d2d1d2 62%,#c6c5c8 100%);
  box-shadow:0 0 0 2px #a6a6ae, 0 0 0 5px rgba(24,22,34,.55),
             0 12px 0 5px rgba(0,0,0,.34), inset 0 1px 0 #f4f3f1;
}
.padplate::after{
  content:'';position:absolute;left:-5px;right:-5px;bottom:-11px;height:12px;pointer-events:none;
  background:radial-gradient(circle at 6px 0, #d2d1d2 5.6px, transparent 6.2px) repeat-x;
  background-size:12px 12px;
  filter:drop-shadow(0 2px 0 rgba(24,22,34,.45));
}
.padmiffy{position:absolute;top:9px;right:12px;width:34px;height:29px}
.padbrand{font-size:15px;letter-spacing:-.5px;color:#3f3f4a}
.padbrand b{color:#8b948e}
.padbrand span{display:block;font-size:9px;color:#7c7c86;letter-spacing:2px;margin-top:2px}

/* the display: frosted, not a green led. the cursor sits at the end of
   whatever you have typed and blinks whether or not there is anything there,
   which is the whole point of it — it says the panel is listening. */
.padlcd{
  margin-top:11px;padding:9px 11px;min-height:34px;font-size:15px;letter-spacing:5px;
  color:#43434e;background:linear-gradient(180deg,#f2f4f5 0%,#e6e9ec 100%);
  box-shadow:inset 0 0 0 2px #b0b3b8, inset 0 2px 6px rgba(90,100,115,.22);
  display:flex;align-items:center;
}
.padcur{
  display:inline-block;width:2px;height:16px;background:#5a5a66;margin-left:1px;
  animation:padblink 1.06s step-end infinite;
}
.padlcd.empty .padcur{background:#8b948e}
@keyframes padblink{0%,49%{opacity:1}50%,100%{opacity:0}}
.padsay{color:#6b746f;letter-spacing:3px;font-size:12px}

.keypad .err{min-height:14px;font-size:10px;margin:7px 1px 0;color:#9a6b74}
.padkeys{margin-top:9px;display:flex;flex-direction:column;gap:5px}
.padrow{display:flex;gap:5px;justify-content:center}
.padkey{
  flex:1 1 0;min-width:0;height:31px;font-family:inherit;font-size:12px;cursor:pointer;
  color:#3f3f4a;background:linear-gradient(180deg,#f0efed 0%,#dedddc 100%);border:0;
  box-shadow:0 0 0 1px #a6a6ae, 0 3px 0 #a6a6ae;
  transition:transform .05s,box-shadow .05s,background .12s;
}
.padkey:hover{background:linear-gradient(180deg,#ffffff 0%,#e8e7e6 100%)}
.padkey:active{transform:translateY(3px);box-shadow:0 0 0 1px #a6a6ae}
.padkey.wide{flex:1.4 1 0}
.padkey.go{
  flex:1.4 1 0;color:#f0f2ef;
  background:linear-gradient(180deg,#97a09a 0%,#7d8880 100%);
  box-shadow:0 0 0 1px #616b64, 0 3px 0 #616b64;
}
.padkey.go:hover{background:linear-gradient(180deg,#a3aca6 0%,#87928a 100%)}
.padkey.go:active{box-shadow:0 0 0 1px #616b64}
.padfoot{margin-top:12px;font-size:9px;color:#7c7c86;line-height:1.7;text-align:center}
.padback{display:block;margin:20px auto 0}
#login .card.keypad.shake{animation:padshake .34s}
@keyframes padshake{10%,90%{transform:translateX(-2px)}20%,80%{transform:translateX(4px)}
  30%,50%,70%{transform:translateX(-6px)}40%,60%{transform:translateX(6px)}}
#pw{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}
@media (max-width:420px){ .padkey{height:28px;font-size:11px} .padlcd{font-size:13px} }

/* =========================================================
   the machines in ins land
   ========================================================= */
.mgwrap{display:flex;gap:14px;margin-top:14px;align-items:flex-start;flex-wrap:wrap}
.mgcv{image-rendering:pixelated;image-rendering:crisp-edges;flex:0 0 auto;
  box-shadow:0 0 0 2px var(--line),0 6px 0 rgba(0,0,0,.4)}
#pgCv{width:180px;height:225px}
#frCv{width:225px;height:156px}
.mgcv.strip{width:129px;height:264px;box-shadow:0 0 0 2px #cbb9a6,0 8px 0 rgba(0,0,0,.4)}
.mgside{flex:1 1 150px;min-width:140px}
.mgscore{font-size:30px;line-height:1;color:#ffe9a8;text-shadow:0 0 12px rgba(255,200,110,.5)}
.mgscore.crit{color:#9dffcf;text-shadow:0 0 14px rgba(120,255,190,.75)}
.pbstyles{display:grid;grid-template-columns:1fr 1fr;gap:5px;margin-top:6px}
.pbst{text-align:left;padding:6px 7px;font-family:inherit;cursor:pointer;border:0;color:var(--dim);
  background:var(--panel2);box-shadow:0 0 0 1px var(--line)}
.pbst b{display:block;font-size:10px;color:#efe6f6;font-weight:400}
.pbst span{display:block;font-size:8px;line-height:1.4;margin-top:2px}
.pbst.sel{box-shadow:0 0 0 2px var(--pink-hot);color:#ffd7ea}
.pbst:hover{background:#3d2f4c}
@media (max-width:520px){ #pgCv{width:144px;height:180px} #frCv{width:100%;height:auto} }

/* ---------- the stereo ----------
   a note in the top right of the picture, and a player that opens beside the
   picture rather than over it, so you can keep walking about with it open. */
#muBtn{position:absolute;right:6px;top:6px;z-index:6;display:flex;align-items:center;gap:4px;
  background:rgba(11,7,19,.72);box-shadow:0 0 0 2px var(--line);padding:5px 6px;line-height:0;color:var(--pink)}
#muBtn:hover{background:rgba(51,36,74,.9)}
#muBtn:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}
#muBtn svg{width:14px;height:14px;fill:currentColor}
#muBtn.playing{box-shadow:0 0 0 2px var(--pink-hot);background:rgba(58,30,48,.85)}
#muBtn.tap{animation:muTap 1.4s ease-in-out infinite}
@keyframes muTap{0%,100%{box-shadow:0 0 0 2px var(--gold)}50%{box-shadow:0 0 0 2px var(--gold),0 0 12px 2px rgba(255,217,138,.55)}}
.eq{display:none;align-items:flex-end;gap:1px;height:12px}
#muBtn.playing .eq,.eq.on{display:flex}
.eq i{display:block;width:2px;background:currentColor;height:4px;animation:muEq .9s steps(4) infinite}
.eq i:nth-child(2){animation-duration:.7s;animation-delay:-.3s}
.eq i:nth-child(3){animation-duration:1.1s;animation-delay:-.6s}
@keyframes muEq{0%{height:3px}25%{height:11px}50%{height:6px}75%{height:9px}100%{height:3px}}
#muNow{position:absolute;right:6px;top:36px;z-index:6;max-width:62%;line-height:1.5;
  background:rgba(11,7,19,.86);box-shadow:0 0 0 2px var(--line);padding:4px 8px;font-size:10px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--ink);letter-spacing:.4px;
  opacity:0;transform:translateY(-3px);transition:opacity .25s,transform .25s;pointer-events:none}
#muNow.on{opacity:1;transform:none}
#muNow span{color:var(--pink)}

#music{position:fixed;z-index:25;right:14px;top:14px;width:min(360px,calc(100vw - 28px));
  max-height:calc(100vh - 28px);display:flex;flex-direction:column;line-height:1.5}
#music header{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:2px solid var(--line);background:var(--panel2)}
#music header .ic svg{width:14px;height:14px;fill:var(--pink);display:block}
#music header h2{font-size:14px;font-weight:400;letter-spacing:1px}
.muShared{flex:1;font-size:10px;color:var(--dim)}
.muBody{padding:14px 14px 12px;overflow:auto;display:flex;flex-direction:column;gap:12px}

/* the record, half out of its sleeve, turning while it plays */
.muNowPlaying{display:flex;gap:14px;align-items:center}
.muArt{position:relative;width:118px;height:88px;flex:none}
.muArt canvas{position:absolute;left:0;top:0;width:88px;height:88px;image-rendering:pixelated;
  box-shadow:0 0 0 2px var(--void),3px 3px 0 2px rgba(0,0,0,.45)}
.muDisc{position:absolute;left:34px;top:4px;width:80px;height:80px;border-radius:50%;
  background:radial-gradient(circle at 50% 50%, var(--pink) 0 9px, #2a1e33 9px 11px, transparent 11px),
    repeating-radial-gradient(circle at 50% 50%, #3a2c48 0 1px, #221830 1px 3px);
  box-shadow:0 0 0 2px var(--line),0 0 0 4px var(--void);transition:left .5s ease}
.muDisc::after{content:"";position:absolute;left:50%;top:50%;width:4px;height:4px;margin:-2px 0 0 -2px;background:var(--void)}
.muDisc::before{content:"";position:absolute;left:12px;top:14px;width:22px;height:5px;background:rgba(255,255,255,.14);transform:rotate(-40deg)}
#music.isPlaying .muDisc{left:38px;animation:muSpin 2.4s linear infinite}
@keyframes muSpin{to{transform:rotate(360deg)}}
.muInfo{min-width:0;flex:1}
.muKicker{font-size:10px;color:var(--pink);letter-spacing:1.5px}
.muTitle{font-size:16px;line-height:1.3;margin-top:3px;color:var(--ink);overflow-wrap:anywhere;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.muMeta{font-size:10px;color:var(--dim);margin-top:5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.muLast{font-size:10px;color:var(--dim);margin-top:4px;min-height:0}
.muLast:empty{display:none}

/* the slider, drawn to match everything else: a flat track and a square handle */
.muSeekRow{display:flex;align-items:center;gap:8px;font-size:10px;color:var(--dim)}
.muSeekRow span{width:34px;flex:none}
.muSeekRow span:last-child{text-align:right}
#music input[type=range]{-webkit-appearance:none;appearance:none;flex:1;height:6px;min-width:0;cursor:pointer;
  background:linear-gradient(90deg,var(--pink-hot) 0 var(--p,0%),#120c1b var(--p,0%) 100%);
  box-shadow:0 0 0 2px var(--line);border:0;outline:none}
#music input[type=range]:focus-visible{box-shadow:0 0 0 2px var(--cyan)}
#music input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;background:var(--pink);
  box-shadow:0 0 0 2px var(--void);border:0}
#music input[type=range]::-moz-range-thumb{width:12px;height:12px;background:var(--pink);border:0;border-radius:0;box-shadow:0 0 0 2px var(--void)}
#music input[type=range]:disabled{cursor:default}
#music input[type=range]:disabled::-webkit-slider-thumb{background:var(--grey)}
#music input[type=range]:disabled::-moz-range-thumb{background:var(--grey)}
#muVolR{--p:60%;max-width:80px;background:linear-gradient(90deg,var(--grey) 0 var(--p),#120c1b var(--p) 100%)!important}

.muCtl{display:flex;align-items:center;gap:8px}
.muB{width:32px;height:32px;display:grid;place-items:center;flex:none;color:var(--ink);background:var(--panel2);
  box-shadow:0 0 0 2px var(--line),0 3px 0 0 var(--void);transition:transform .06s,box-shadow .06s,background .12s}
.muB svg{width:12px;height:12px;fill:currentColor;display:block}
.muB:hover:not(:disabled){background:#33244a}
.muB:active:not(:disabled){transform:translateY(3px);box-shadow:0 0 0 2px var(--line)}
.muB:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}
.muB:disabled{opacity:.35;cursor:not-allowed}
.muB.on{color:var(--pink);box-shadow:0 0 0 2px var(--pink-hot),0 3px 0 0 var(--void)}
.muB.muPlay{width:42px;height:42px;background:#3a1e30;color:var(--pink);box-shadow:0 0 0 2px var(--pink-hot),0 3px 0 0 var(--void)}
.muB.muPlay svg{width:16px;height:16px}
.muB.muPlay:hover:not(:disabled){background:#4c2740}
.muB.sm{width:26px;height:26px;box-shadow:0 0 0 2px var(--line)}
.muB.xs{width:22px;height:22px;box-shadow:0 0 0 1px var(--line)}
.muB.xs svg{width:9px;height:9px}
.muB.xs:active:not(:disabled){box-shadow:0 0 0 1px var(--line)}
.muVol{margin-left:auto;display:flex;align-items:center;gap:8px}

.muLock,.muTap{display:flex;gap:8px;align-items:center;font-size:10px;padding:7px 9px;line-height:1.45}
.muLock{color:var(--gold);background:#251a12;box-shadow:0 0 0 2px #5a4020}
.muLock svg{width:10px;height:10px;fill:currentColor;flex:none}
.muTap{color:var(--cyan);background:#10202a;box-shadow:0 0 0 2px #2a5566}
.muTabs{margin:2px 0 0}
.muTabs b{font-weight:400;color:var(--dim);margin-left:2px}
.tab.on .muTabs b,.tab.on b{color:var(--pink)}
#muSearch{padding:7px 9px;font-size:12px}

.muList{display:flex;flex-direction:column;gap:6px;min-height:40px}
.muSec{display:flex;align-items:center;justify-content:space-between;font-size:10px;color:var(--dim);letter-spacing:1.5px;margin-top:4px}
.muSec:first-child{margin-top:0}
.muRow{display:flex;align-items:center;gap:9px;padding:5px 7px;background:#170f22;box-shadow:0 0 0 2px #322144}
.muRow.cur{box-shadow:0 0 0 2px var(--pink-hot);background:#22142a;color:var(--pink)}
.muRow.bad{opacity:.5}
.muThumb{width:26px;height:26px;flex:none;image-rendering:pixelated;box-shadow:0 0 0 1px var(--void)}
.muRT{flex:1;min-width:0}
.muRName{font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.muRSub{font-size:9px;color:var(--dim)}
.muRDur{font-size:10px;color:var(--dim);flex:none}
.muRAct{display:flex;gap:5px;flex:none}
.muRAct:empty{display:none}
.muRow .eq{color:var(--pink)}
.muHint{text-align:center;padding:4px 0 2px}
.muHelp{line-height:1.7;text-align:left}
.muHelp code,.muHelp b{color:var(--pink)}

@media (max-width:560px){
  #music{left:8px;right:8px;top:auto;bottom:8px;width:auto;max-height:72vh}
  .muArt{width:98px;height:72px}
  .muArt canvas{width:72px;height:72px}
  .muDisc{left:28px;top:3px;width:66px;height:66px}
  #music.isPlaying .muDisc{left:31px}
  #muVolR{max-width:60px}
}
@media (prefers-reduced-motion: reduce){
  #music.isPlaying .muDisc,.eq i,#muBtn.tap{animation:none}
  .eq i{height:8px}
}
