/* The page is a keyboard. Everything you can press is a keycap; game titles, the word you draw on,
   the blanks you fill, the chain you build. Light beige case, dye-sub ink legends, one coloured cap per game.
   One typeface. No rules, no labels. Dark mode (html.jt-dark, chosen on /account) is the same keyboard
   at night: black case, glowing caps, neon accents. */
:root{
  --desk:#faf7f1; --case:#efeae0; --cap:#fffdf8; --cap-edge:#cfc8b8; --cap-line:#e8e2d4; --blue:#1a56e8;   /* three surfaces: desk, case, key */
  --ink:#1b1b1f; --mute:#6e6a60; --bad:#d1242f;
  /* weights: 700 headings and scores, 500 legends and buttons, 400 everything else */
  /* per-game accents, chosen from colour-preference research: azure blue (top-ranked
     across cultures), electric violet (novelty/rarity), teal (calm, clean) */
  --rain:#1b6ef3; --invade:#7c3aed; --wordis:#0d9488; --dopamine:#db2777;
  /* the rainbow holo: a full spectrum with no orange stop, dark enough for white text */
  --holo-grad:linear-gradient(100deg,#b3184a,#a8780a,#1f7a3c,#0e7f8c,#1440c0,#8a16a8,#b3184a);
  --hi:#fff; --sheen:rgba(255,255,255,.5); --field:#fffefb;   /* keycap top light, panel sheen, input fill */
  --font:'Rubik', 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --s1:4px; --s2:8px; --s3:12px; --s4:24px; --s5:40px; --s6:64px; --s7:112px;
  color-scheme:light;
}
*{box-sizing:border-box}
html,body{height:100%}
html{scroll-behavior:smooth;scrollbar-gutter:stable;scrollbar-color:var(--cap-edge) var(--desk)}
/* a page that never scrolls keeps no strip for a scrollbar, so the footer's band runs right to the window's edge:
   one-screen pages (main.fit) from the first paint, any other short page once juketype.js sees it fits (html.footfill) */
html:has(main.fit),html.footfill{scrollbar-gutter:auto}
/* the browser scrollbar as a juketype keycap rail */
::-webkit-scrollbar{width:14px;height:14px}
::-webkit-scrollbar-track{background:var(--desk)}
::-webkit-scrollbar-thumb{background:var(--cap);border:3px solid var(--desk);border-radius:8px;box-shadow:inset 0 0 0 1px var(--cap-edge)}
::-webkit-scrollbar-thumb:hover{background:var(--case)}
::-webkit-scrollbar-corner{background:var(--desk)}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{margin:0;background:var(--desk);color:var(--ink);font-family:var(--font);font-size:16px;line-height:1.5;-webkit-font-smoothing:antialiased;font-variant-numeric:tabular-nums}
.wrap{max-width:1040px;margin:0 auto;padding-block:var(--s4) var(--s6);padding-left:max(16px,env(safe-area-inset-left,0px));padding-right:max(16px,env(safe-area-inset-right,0px))}
header{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);margin-bottom:var(--s5);flex-wrap:wrap}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;padding:0}
.brand{font-weight:700;font-size:30px;letter-spacing:-.015em;display:flex;align-items:center;gap:12px;color:var(--ink);text-decoration:none}
/* the logo: a black keycap with a white music note on it */
.brand::before{content:'';flex:none;width:40px;height:40px;box-sizing:border-box;border-radius:8px;background:#1b1b1f url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpath%20d='M12%203v10.55c-.59-.34-1.27-.55-2-.55-2.21%200-4%201.79-4%204s1.79%204%204%204%204-1.79%204-4V7h4V3h-6z'%20fill='%23000'%20fill-opacity='.35'%20transform='translate%28.6%20.9%29'/%3E%3Cpath%20d='M12%203v10.55c-.59-.34-1.27-.55-2-.55-2.21%200-4%201.79-4%204s1.79%204%204%204%204-1.79%204-4V7h4V3h-6z'%20fill='%23fff'/%3E%3C/svg%3E") calc(50% + 1px) 6px/24px 24px no-repeat;border-bottom:5px solid #000;box-shadow:inset 0 1px 0 rgba(255,255,255,.12);transition:transform .07s,height .07s,border-bottom-width .07s}
/* hovering presses the whole logo: the name sinks with the key, and the key's edge shrinks so its bottom stays put */
.brand{height:40px;transition:transform .07s}
.brand::before{align-self:flex-start}
.brand:hover{transform:translateY(3px)}
.brand:hover::before{height:37px;border-bottom-width:2px}
.brand em{font-style:normal;font-weight:400;color:var(--mute)}
.sub{color:var(--mute);font-size:14px}
:focus-visible{outline:3px solid var(--ink);outline-offset:2px}
#kin{position:absolute;opacity:0;width:1px;height:1px;left:0;top:0;pointer-events:none}

/* keycaps */
.key{display:inline-grid;place-items:center;min-width:1.6em;height:1.6em;padding:0 .3em;background:var(--cap);color:var(--ink);border-radius:.18em;border:1px solid var(--cap-line);border-bottom:.16em solid var(--cap-edge);box-shadow:inset 0 .06em 0 var(--hi);line-height:1;font-weight:500;transition:transform .06s,border-bottom-width .06s;vertical-align:middle}
.key.down,.key:active{transform:translateY(.1em);border-bottom-width:.06em}
.key.gap{background:none;border:0;box-shadow:none;min-width:.6em}
.key.acc{background:var(--acc);color:#fff;border-bottom-color:color-mix(in srgb,var(--acc) 70%,#000)}
.key.cur{outline:3px solid var(--acc);outline-offset:-3px}
.caps{display:inline-flex;gap:.18em;flex-wrap:wrap}

/* buttons are keys too */
.btn{display:inline-grid;place-items:center;padding:0 14px;height:36px;background:var(--cap);border-radius:5px;border:1px solid var(--cap-line);border-bottom:4px solid var(--cap-edge);box-shadow:inset 0 1px 0 var(--hi);font-weight:500;font-size:15px;transition:transform .06s,border-bottom-width .06s}
.btn:hover{background:var(--field)}
.btn:active{transform:translateY(2px);border-bottom-width:2px}
.btn.primary{background:var(--acc);color:#fff;border-color:var(--acc);border-bottom-color:color-mix(in srgb,var(--acc) 70%,#000)}
.btn.primary:hover{background:color-mix(in srgb,var(--acc) 88%,#fff)}
.btn.quiet{background:none;border:0;box-shadow:none;color:var(--mute);text-decoration:underline;text-underline-offset:3px}
.btn.quiet:hover{color:var(--ink);background:none}
.btn[disabled]{opacity:.5;cursor:default}
.row-actions{display:flex;gap:var(--s3);align-items:center;flex-wrap:wrap;justify-content:center}

/* hub: three rows of keys */
.lede{font-size:22px;font-weight:500;margin:0 0 var(--s1);max-width:30ch;line-height:1.3}
.lede-sub{color:var(--mute);max-width:56ch;margin:0 0 var(--s5);font-size:15px}
.games{display:flex;gap:var(--s5);justify-content:center;flex-wrap:wrap;width:100%}
.gcard{--acc:var(--ink);display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--s3);padding:0;width:280px;min-width:0}
.gcard{cursor:pointer}
a.gcard{text-decoration:none;color:inherit}
.gcard:hover .caps .key{transform:translateY(.1em);border-bottom-width:.06em}
.gcard:active .caps .key{transform:translateY(.1em);border-bottom-width:.06em}
.gcard h2{margin:0;font-size:17px;font-weight:700;line-height:1}
.gcard h2 .caps{flex-wrap:nowrap}
.gcard p{margin:0;font-size:16px;max-width:24ch;min-width:0;color:var(--mute)}
.gcard h2.gname{font-size:28px;font-weight:700;letter-spacing:-.015em;line-height:1.1;color:var(--acc)}
/* every game's name, on its card and above its stage: its colour shimmering slowly into
   a lighter tint of itself (and glowing, in dark mode only); pointing at a card wakes it up */
.gcard h2.gname,.shell .strip .name{background:linear-gradient(100deg,var(--acc) 0%,color-mix(in srgb,var(--acc) 72%,#fff) 25%,var(--acc) 50%,color-mix(in srgb,var(--acc) 72%,#fff) 75%,var(--acc) 100%);background-size:400% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;-webkit-text-fill-color:transparent;filter:saturate(1.25);animation:holo 6s linear infinite;transition:filter .25s}
.gcard:hover h2.gname,.gcard:focus-visible h2.gname{filter:saturate(1.45) brightness(1.04);animation-duration:2s} /* light mode: no glow, just the shimmer; the glow is dark mode's */
.jt-dark .gcard h2.gname,.jt-dark .shell .strip .name{filter:drop-shadow(0 0 14px color-mix(in srgb,var(--acc) 70%,transparent)) drop-shadow(0 0 3px var(--acc))}
.jt-dark .gcard:hover h2.gname,.jt-dark .gcard:focus-visible h2.gname{filter:drop-shadow(0 0 22px var(--acc)) drop-shadow(0 0 4px var(--acc)) brightness(1.2)}
@media (prefers-reduced-motion:reduce){.gcard h2.gname,.shell .strip .name{animation:none}}
.shell .strip .name:has(.ntag){background:none;color:inherit;-webkit-text-fill-color:currentColor;filter:none;animation:none} /* a name drawn in a nametag keeps the tag's own look */
@media (min-width:1000px){main.home .gcard h2.gname{font-size:clamp(15px,2.4vh,21px)}} /* the homepage's one-screen sizing */
.gcard .best{font-size:13px;color:var(--mute);white-space:nowrap}
.gcard .best b{color:var(--ink);font-weight:700;font-size:20px;display:block;line-height:1.1}
@media (max-width:760px){.games{gap:var(--s5)}}

/* game shell */
.shell{--acc:var(--ink)}
.strip{display:flex;align-items:center;gap:var(--s4);font-size:15px;color:var(--mute);margin-bottom:var(--s3);flex-wrap:wrap}
.strip .name{font-weight:700;font-size:22px;color:var(--ink)}
.strip .sndwrap{margin-left:auto;position:relative}
.sndmenu{position:absolute;top:calc(100% + 8px);right:0;z-index:30;display:flex;flex-direction:column;gap:3px;padding:6px;background:var(--cap);border:1px solid var(--cap-line);border-bottom:4px solid var(--cap-edge);border-radius:8px;box-shadow:0 10px 24px rgba(0,0,0,.1)}
.sndmenu .snditem{font:inherit;font-size:14px;text-align:left;padding:7px 14px;border:0;background:none;border-radius:5px;cursor:pointer;white-space:nowrap;color:var(--ink)}
.sndmenu .snditem:hover{background:var(--case)}
.sndmenu .snditem.now{background:var(--acc);color:#fff}
.strip b{color:var(--ink);font-weight:700}
.lives{display:inline-flex;gap:5px;vertical-align:middle}
.lives i{width:12px;height:12px;border-radius:3px;background:var(--acc);display:block;border-bottom:2px solid color-mix(in srgb,var(--acc) 70%,#000)}
.lives i.lost{background:var(--case);border-bottom-color:var(--cap-edge)}
/* the arena keeps the page column's width but stretches down to fill the viewport */
.stage{position:relative;border-radius:12px;background:var(--case);min-height:clamp(400px,100dvh - 300px,1400px);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--s4);padding:var(--s5) var(--s4);overflow:hidden;cursor:text}
@media (max-width:640px){.stage{min-height:clamp(320px,100dvh - 215px,1400px);padding:var(--s4) var(--s3)}}
.stage.shake{animation:shake .32s}
@keyframes shake{20%{transform:translateX(-7px)}40%{transform:translateX(6px)}60%{transform:translateX(-4px)}80%{transform:translateX(3px)}}
.flash{position:absolute;inset:0;background:#fff;opacity:0;pointer-events:none}
.flash.on{animation:flash .22s}
@keyframes flash{0%{opacity:.6}100%{opacity:0}}
.hint{color:var(--mute);font-size:14px;margin-top:var(--s3);display:flex;gap:var(--s4);flex-wrap:wrap}
kbd{font:inherit;display:inline-grid;place-items:center;min-width:1.6em;height:1.5em;padding:0 .35em;background:var(--cap);border-radius:4px;border-bottom:2px solid var(--cap-edge);font-size:12px;color:var(--ink)}
.msg{font-size:24px;font-weight:500;line-height:1.25;text-align:center;text-wrap:balance;max-width:26ch}
.msg small{display:block;font-size:15px;font-weight:400;color:var(--mute);margin-top:var(--s3);line-height:1.5;max-width:46ch}
/* the end screen owns the whole stage: it covers the game scene behind it */
.over{position:absolute;inset:0;z-index:6;background:var(--case);border-radius:12px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--s3);text-align:center;padding:var(--s4);overflow:auto}
.over .big{font-size:clamp(48px,9vw,72px);font-weight:700;line-height:1;color:var(--acc)}
.over .unit{color:var(--mute);font-size:15px;margin-top:-8px}
.tbl{display:grid;grid-template-columns:auto auto;gap:var(--s1) var(--s4);font-size:15px;color:var(--mute);margin-top:var(--s1)}
.tbl b{color:var(--ink);font-weight:700;text-align:right}
.tbl .new{color:var(--acc)}
.sub{color:var(--mute);font-size:14px}
@media (hover:none){.hint kbd{display:none}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* High Noon */
@media (max-width:640px){.noon .stage{padding-bottom:180px}}
.cue{font-size:20px;color:var(--mute);z-index:1;text-align:center}
.cue.loud{color:var(--ink);font-size:36px;font-weight:700}
.cue small{display:block;font-size:15px;font-weight:400;color:var(--mute);margin-top:8px}

/* Afterimage */

/* Chain */
@keyframes blink{50%{opacity:0}}

/* Downpour */
.rain .stage{justify-content:center}
.rain .field{position:absolute;inset:0;overflow:hidden}
.rain .drop{position:absolute;top:0;display:flex;gap:.14em;font-size:clamp(18px,2.1vw,30px);transition:opacity .25s}
.rain .drop.lock .key{outline:3px solid var(--acc);outline-offset:-3px}
.rain .drop .key.hit{background:var(--acc);color:#fff;border-color:var(--acc);border-bottom-color:color-mix(in srgb,var(--acc) 70%,#000);outline:0}
.rain .drop.pop{opacity:0}
.rain .puddle{position:absolute;left:0;right:0;bottom:26px;height:2px;background:var(--cap-edge)}

/* Tumbler */
.invade .field{position:absolute;inset:0;overflow:hidden}
.invade .inv{position:absolute;left:0;top:0;display:flex;gap:.14em;font-size:clamp(16px,1.8vw,26px);transition:opacity .25s}
.invade .inv.lock .key{outline:3px solid var(--acc);outline-offset:-3px}
.invade .inv .key.hit{background:var(--acc);color:#fff;border-color:var(--acc);border-bottom-color:color-mix(in srgb,var(--acc) 70%,#000);outline:0}
.invade .inv.pop{opacity:0}
.invade .ground{position:absolute;left:0;right:0;bottom:26px;height:2px;background:var(--cap-edge)}

/* Tightrope */
@media (max-width:640px){.rope .stage{padding-bottom:175px}}
.wordis .tower{position:absolute;bottom:34px;left:50%;transform:translateX(-50%);display:flex;flex-direction:column-reverse;align-items:center;gap:5px;z-index:1}
.wordis .brick{display:flex;gap:.14em;font-size:clamp(18px,2.3vw,30px);padding:3px 0;transform-origin:bottom;animation:brickland .22s cubic-bezier(.55,0,1,.45)}
.wordis .brick .key.hit{background:var(--acc);color:#fff;border-color:var(--acc);border-bottom-color:color-mix(in srgb,var(--acc) 70%,#000)}
.wordis .brick.pull{transform:translateX(140px) rotate(6deg);opacity:0;transition:transform .22s,opacity .22s}
.wordis .tower.danger .brick:last-child{outline:3px solid var(--bad);outline-offset:2px}
/* each brick free-falls from the very top of the stage; --drop is measured per brick */
@keyframes brickland{from{transform:translateY(calc(-1 * var(--drop,320px)))}88%{transform:translateY(0) scaleY(1)}94%{transform:translateY(0) scaleY(.88)}to{transform:none}}
.wordis .floorline{position:absolute;left:0;right:0;bottom:26px;height:2px;background:var(--cap-edge)}
@media (prefers-reduced-motion:reduce){.wordis .brick{animation:none}}

/* Forge */

/* Tempo */

/* Popcorn */

/* versus games (Crossfire, Tug of War, Hot Potato) */

/* Crossfire */
@media (max-width:640px){.cross .stage{padding-bottom:140px}}

/* Tug of War */

/* Hot Potato */

/* landing */
/* signed in (html.jt-in, set in <head> from the stored session): Account instead of Log in / Create account */
#navme{display:none}
.jt-in #navme{display:inline}
.jt-in #navlogin,.jt-in #navacct{display:none}
.nav{display:flex;gap:var(--s4);align-items:center;font-size:15px}
.nav a{color:var(--ink);text-decoration:none;padding:8px 2px}
.nav a.btn{padding:0 16px;height:36px;border-bottom:4px solid #000;line-height:1;position:relative;top:3px}
.nav a:not(.btn){border-bottom:2px solid transparent}
.nav a:not(.btn):hover{border-bottom-color:var(--cap-edge)}
.nav a.on{border-bottom-color:var(--ink)}
.nav .btn{--acc:var(--blue)}
@media (max-width:640px){.nav{gap:var(--s3)}}
.sets{display:flex;gap:var(--s2);flex-wrap:wrap;align-items:center}
.sets .key{height:40px;padding:0 14px;font-size:15px;cursor:pointer;--acc:var(--ink)}
.sets .key.acc{background:var(--ink);color:var(--cap);border-bottom-color:#000}
section{margin-top:var(--s7);scroll-margin-top:var(--s4);text-align:center;display:flex;flex-direction:column;align-items:center}
/* the first section sits as far under the hero keyboard as the hero sits under the navbar (40+40 = 40+40) */
.open + section{margin-top:var(--s5)}
section h2{font-size:clamp(28px,3.8vw,38px);font-weight:700;margin:0 0 var(--s4);letter-spacing:-.02em}
section > p{color:var(--mute);margin:-8px 0 var(--s5);max-width:48ch;font-size:18px}
/* word rarity: untyped keys carry a tinted edge so you can spot a rare word coming */
.tiered .key{border-bottom-color:color-mix(in srgb,var(--acc) 55%,var(--cap-edge));border-color:color-mix(in srgb,var(--acc) 25%,var(--cap-line))}
/* rainbow tier: a holographic shimmer, loud and proud of its 0.3% odds.
   deeper hues + a dark halo keep the letters readable on the moving gradient */
.tier-rainbow .key{color:#fff;font-weight:700;text-shadow:0 1px 2px rgba(0,0,0,.7),0 0 4px rgba(0,0,0,.45);border-color:transparent;background:var(--holo-grad);background-size:400% 100%;animation:holo 2.2s linear infinite;border-bottom-color:rgba(0,0,0,.4)}
.tier-rainbow .key.hit{background:var(--holo-grad);background-size:400% 100%;animation:holo .9s linear infinite;border-color:transparent;border-bottom-color:rgba(0,0,0,.5)}
@keyframes holo{to{background-position:400% 0}}
/* the buy button is the rarest drop on the site: full rainbow-tier holo - nav chip included */
.btn.primary.buybtn,.btn.primary.holo,.nav a.btn.primary{color:#fff;font-weight:700;text-shadow:0 1px 2px rgba(0,0,0,.55),0 0 4px rgba(0,0,0,.35);border-color:transparent;background:var(--holo-grad);background-size:400% 100%;animation:holo 2.4s linear infinite;border-bottom:4px solid rgba(0,0,0,.4)}
.nav a.btn.primary:hover{background:var(--holo-grad);background-size:400% 100%;filter:brightness(1.1)}
.btn.primary.buybtn:hover,.btn.primary.holo:hover{background:var(--holo-grad);background-size:400% 100%;filter:brightness(1.1)}
.btn.primary.buybtn:active,.btn.primary.holo:active{border-bottom-width:2px}
.stage.megahit{animation:megahit .6s}
@keyframes megahit{12%{transform:scale(1.04) rotate(.5deg)}30%{transform:scale(1.005) rotate(-.4deg)}48%{transform:scale(1.025)}70%{transform:scale(1.005)}}
@media (prefers-reduced-motion:reduce){.tier-rainbow .key,.tier-rainbow .key.hit,.stage.megahit,.btn.primary.buybtn,.btn.primary.holo,.nav a.btn.primary{animation:none}}

/* juice: floating score pops, confetti, combo badge, big-hit pulse */
.spop{position:absolute;z-index:4;font-weight:700;font-size:clamp(22px,2.4vw,30px);transform:translate(-50%,0);animation:spop .85s ease-out forwards;pointer-events:none;text-shadow:0 1px 0 rgba(255,255,255,.6)}
.spop.big{font-size:clamp(32px,3.6vw,44px)}
@keyframes spop{20%{opacity:1}100%{transform:translate(-50%,-46px);opacity:0}}
.confetti{position:absolute;z-index:5;width:8px;height:8px;border-radius:2px;border-bottom:2px solid rgba(0,0,0,.25);animation:confet .8s ease-out forwards;pointer-events:none}
@keyframes confet{to{transform:translate(var(--dx),var(--dy)) rotate(var(--rot));opacity:0}}
.combo{position:absolute;top:10px;right:12px;z-index:4;font-weight:700;font-size:22px;color:var(--mute);pointer-events:none}
.combo.bump{animation:combobump .25s}
.combo.h1{color:#b8860b}
.combo.h2{color:#c2184c;text-shadow:0 0 7px rgba(194,24,76,.45)}
.wash{position:absolute;inset:0;z-index:4;border-radius:12px;pointer-events:none;animation:washout .6s ease-out forwards}
@keyframes washout{from{opacity:.9}to{opacity:0}}
.stage.chase::before,.over.chase::before{content:'';position:absolute;inset:0;border-radius:12px;padding:3px;z-index:7;background:conic-gradient(from var(--ca,0deg),transparent 0 78%,#d4a017 90%,transparent 100%);-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude;animation:chasespin 1s linear 2;pointer-events:none}
@property --ca{syntax:'<angle>';initial-value:0deg;inherits:false}
@keyframes chasespin{to{--ca:720deg}}
@media (prefers-reduced-motion:reduce){.wash,.stage.chase::before,.over.chase::before{animation:none;opacity:0}}
@keyframes combobump{40%{transform:scale(1.35) rotate(-4deg)}}
.stage.bighit{animation:bighit .28s}
@keyframes bighit{30%{transform:scale(1.015)}}
.over .pctv{opacity:0;transition:opacity .4s,transform .4s;transform:translateY(4px)}
.over .pctv.show{opacity:1;transform:none}
.over .stamp{display:inline-block;margin-left:8px;padding:1px 8px;border-radius:4px;background:var(--acc);color:#fff;font-weight:700;font-size:13px;animation:stampin .35s cubic-bezier(.2,1.6,.4,1)}
@keyframes stampin{from{transform:scale(2.2) rotate(-8deg);opacity:0}}
@media (prefers-reduced-motion:reduce){.spop,.confetti,.combo.bump,.stage.bighit,.over .stamp{animation:none}}

/* casino layer: pity meter, banners, gold rush glow, combo loss, big win, collection strip, streak */
.comboloss{position:absolute;top:40px;right:12px;z-index:4;font-weight:700;font-size:20px;color:var(--bad);animation:spop .9s ease-out forwards;pointer-events:none}
.over:has(.bwbanner){padding-top:76px}
.over .bwbanner{position:absolute;top:14px;left:50%;transform:translateX(-50%);z-index:2;font-weight:700;font-size:clamp(34px,7vw,56px);color:#b8860b;letter-spacing:-.02em;white-space:nowrap;pointer-events:none;animation:bwin .45s cubic-bezier(.2,1.6,.4,1) both;text-shadow:0 2px 0 rgba(255,255,255,.7)}
@keyframes bwin{from{transform:translateX(-50%) scale(2.2) rotate(-8deg);opacity:0}to{transform:translateX(-50%) scale(1) rotate(0)}}
.streakline{font-size:14px;color:var(--mute);margin:0}
.streakline b{color:var(--ink)}
@media (prefers-reduced-motion:reduce){.comboloss,.over .bwbanner{animation:none;opacity:1}}

/* each game owns one fixed colour; it shows in the floor line, nothing washes the stage */
.rain .puddle{background:color-mix(in srgb,var(--rain) 55%,var(--cap-edge));height:3px}
.invade .ground{background:color-mix(in srgb,var(--invade) 55%,var(--cap-edge));height:3px}
.wordis .floorline{background:color-mix(in srgb,var(--wordis) 55%,var(--cap-edge));height:3px}
.strip .name{color:var(--acc)}

/* mini vignette of each game on its card */
.gprev{position:relative;width:100%;height:120px;background:var(--case);border-radius:8px;overflow:hidden}
.gprev .pit{position:absolute;transform:translate(-50%,-50%)}
.gprev .pcaps{display:flex;gap:2px}
.gprev .pk{display:grid;place-items:center;min-width:18px;height:20px;padding:0 3px;background:var(--cap);border:1px solid var(--cap-line);border-bottom:2px solid var(--cap-edge);border-radius:4px;font-size:11.5px;font-weight:500;color:var(--ink);line-height:1}
.gprev .pcaps.acc .pk{background:var(--acc);color:#fff;border-color:var(--acc);border-bottom-color:color-mix(in srgb,var(--acc) 70%,#000)}
.gprev .pcaps.rainbow .pk{color:#fff;font-weight:700;text-shadow:0 1px 2px rgba(0,0,0,.7);border-color:transparent;border-bottom-color:rgba(0,0,0,.4);background:var(--holo-grad);background-size:400% 100%;animation:holo 2.2s linear infinite}
.gprev .pcaps.mys .pk{background:#2b2b33;color:#fffdf8;border-color:#2b2b33;border-bottom-color:#0d0d10}
.gprev .pcaps.mys::after{content:'?';position:absolute;top:-7px;right:-8px;width:13px;height:13px;border-radius:50%;display:grid;place-items:center;font-size:9px;line-height:1;font-weight:700;color:#fff;background:var(--holo-grad);background-size:400% 100%;animation:holo 1.4s linear infinite}
.gprev .pline{position:absolute;left:8%;right:8%;height:2px;background:var(--cap-edge)}
/* downpour: words fall into the puddle */
.pv-rain .pline{background:color-mix(in srgb,var(--rain) 55%,var(--cap-edge))}
.pv-rain .pfall{animation:pvfall 3.6s linear infinite}
@keyframes pvfall{0%{top:-12%;opacity:0}10%{opacity:1}84%{top:80%;opacity:1}92%,100%{top:84%;opacity:0}}
/* invasion: the fleet bobs and marches, the ship lasers one word */
.pv-invade .pform{position:absolute;inset:0;animation:pvmarch 4.8s ease-in-out infinite}
@keyframes pvmarch{0%,100%{transform:translate(-4px,0)}50%{transform:translate(4px,7px)}}
.pv-invade .pzap{animation:pvzap 2.4s ease-out infinite}
@keyframes pvzap{0%,46%{opacity:1;transform:translate(-50%,-50%) scale(1)}56%{opacity:0;transform:translate(-50%,-50%) scale(1.6)}86%{opacity:0;transform:translate(-50%,-50%) scale(.5)}100%{opacity:1;transform:translate(-50%,-50%) scale(1)}}
.pv-invade .plaser{position:absolute;left:calc(50% - 1px);top:56%;bottom:16%;width:2px;border-radius:1px;background:var(--invade);box-shadow:0 0 6px var(--invade);opacity:0;animation:pvlaser 2.4s linear infinite}
@keyframes pvlaser{0%,40%{opacity:0}42%,50%{opacity:1}54%,100%{opacity:0}}
.pv-invade .pship{width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:12px solid var(--invade)}
/* wordis: the rainbow bottom brick slides out and the pile drops */
.pv-wordis .pstack{position:absolute;inset:0;animation:pvstack 3.4s linear infinite}
@keyframes pvstack{0%{opacity:0}6%,88%{opacity:1}100%{opacity:0}}
.pv-wordis .pdrop{position:absolute;inset:0;animation:pvdrop 3.4s cubic-bezier(.5,0,1,.5) infinite}
@keyframes pvdrop{0%,56%{transform:none}68%,100%{transform:translateY(22%)}} /* one row: the bricks sit 22% apart */
.pv-wordis .ppull{animation:pvpull 3.4s ease-in infinite}
@keyframes pvpull{0%,38%{transform:translate(-50%,-50%);opacity:1}54%{transform:translate(70%,-50%) rotate(8deg);opacity:0}100%{transform:translate(70%,-50%);opacity:0}}
.pv-wordis .pline{height:3px;border-radius:2px;background:var(--cap-edge)} /* the pile's floor, in plain gray */
/* dopamine: words pop in with draining bars and burst; the fever meter fills */
.pv-dopamine .ppop{animation:pvpop 3.6s ease-out infinite}
@keyframes pvpop{0%{transform:translate(-50%,-50%) scale(0);opacity:0}7%{transform:translate(-50%,-50%) scale(1.1);opacity:1}11%,64%{transform:translate(-50%,-50%) scale(1);opacity:1}72%{transform:translate(-50%,-50%) scale(1.5);opacity:0}100%{opacity:0}}
.pv-dopamine .plife{position:absolute;left:4%;right:4%;bottom:-6px;height:3px;border-radius:2px;background:var(--dopamine);transform-origin:left;animation:pvlife 3.6s linear infinite}
.pv-dopamine .ppop.acc .plife{background:var(--acc)}
.pv-dopamine .ppop.mys .plife{background:#2b2b33}
@keyframes pvlife{0%,8%{transform:scaleX(1)}64%{transform:scaleX(.18)}100%{transform:scaleX(.18)}}
.pv-dopamine .pplus{position:absolute;transform:translate(-50%,-50%);font-size:12px;font-weight:700;color:#d4a017;opacity:0;animation:pvplus 3.6s ease-out infinite}
@keyframes pvplus{0%,64%{opacity:0;transform:translate(-50%,-50%)}70%{opacity:1}92%,100%{opacity:0;transform:translate(-50%,calc(-50% - 16px))}}
/* the fever meter as the game draws it: ten separate rounded cells across the top, lighting one by one */
.pv-dopamine .pmeter{--off:color-mix(in srgb,var(--cap-edge) 60%,var(--case));position:absolute;top:8%;left:50%;transform:translateX(-50%);display:flex;gap:calc(1.6 * var(--u))}
.pv-dopamine .pmeter i{width:calc(6.6 * var(--u));height:calc(3.6 * var(--u));border-radius:calc(1.2 * var(--u));background:var(--off);animation:3.6s steps(1,end) infinite}
.pv-dopamine .pmeter i:nth-child(1){animation-name:pvc0}
@keyframes pvc0{0%,6%,94%,100%{background:var(--off)}6.01%,93.99%{background:var(--dopamine);box-shadow:0 0 calc(1.2 * var(--u)) color-mix(in srgb,var(--dopamine) 60%,transparent)}}
.pv-dopamine .pmeter i:nth-child(2){animation-name:pvc1}
@keyframes pvc1{0%,14%,94%,100%{background:var(--off)}14.01%,93.99%{background:var(--dopamine);box-shadow:0 0 calc(1.2 * var(--u)) color-mix(in srgb,var(--dopamine) 60%,transparent)}}
.pv-dopamine .pmeter i:nth-child(3){animation-name:pvc2}
@keyframes pvc2{0%,22%,94%,100%{background:var(--off)}22.01%,93.99%{background:var(--dopamine);box-shadow:0 0 calc(1.2 * var(--u)) color-mix(in srgb,var(--dopamine) 60%,transparent)}}
.pv-dopamine .pmeter i:nth-child(4){animation-name:pvc3}
@keyframes pvc3{0%,30%,94%,100%{background:var(--off)}30.01%,93.99%{background:var(--dopamine);box-shadow:0 0 calc(1.2 * var(--u)) color-mix(in srgb,var(--dopamine) 60%,transparent)}}
.pv-dopamine .pmeter i:nth-child(5){animation-name:pvc4}
@keyframes pvc4{0%,38%,94%,100%{background:var(--off)}38.01%,93.99%{background:var(--dopamine);box-shadow:0 0 calc(1.2 * var(--u)) color-mix(in srgb,var(--dopamine) 60%,transparent)}}
.pv-dopamine .pmeter i:nth-child(6){animation-name:pvc5}
@keyframes pvc5{0%,46%,94%,100%{background:var(--off)}46.01%,93.99%{background:var(--dopamine);box-shadow:0 0 calc(1.2 * var(--u)) color-mix(in srgb,var(--dopamine) 60%,transparent)}}
.pv-dopamine .pmeter i:nth-child(7){animation-name:pvc6}
@keyframes pvc6{0%,54%,94%,100%{background:var(--off)}54.01%,93.99%{background:var(--dopamine);box-shadow:0 0 calc(1.2 * var(--u)) color-mix(in srgb,var(--dopamine) 60%,transparent)}}
.pv-dopamine .pmeter i:nth-child(8){animation-name:pvc7}
@keyframes pvc7{0%,62%,94%,100%{background:var(--off)}62.01%,93.99%{background:var(--dopamine);box-shadow:0 0 calc(1.2 * var(--u)) color-mix(in srgb,var(--dopamine) 60%,transparent)}}
.pv-dopamine .pmeter i:nth-child(9){animation-name:pvc8}
@keyframes pvc8{0%,70%,94%,100%{background:var(--off)}70.01%,93.99%{background:var(--dopamine);box-shadow:0 0 calc(1.2 * var(--u)) color-mix(in srgb,var(--dopamine) 60%,transparent)}}
.pv-dopamine .pmeter i:nth-child(10){animation-name:pvc9}
@keyframes pvc9{0%,78%,94%,100%{background:var(--off)}78.01%,93.99%{background:var(--dopamine);box-shadow:0 0 calc(1.2 * var(--u)) color-mix(in srgb,var(--dopamine) 60%,transparent)}}
@media (prefers-reduced-motion:reduce){.gprev *,.gprev *::after{animation:none!important}}
.price{display:flex;flex-direction:column;align-items:center;gap:var(--s4)}
.price .amt{font-size:clamp(64px,10vw,104px);font-weight:700;line-height:1;letter-spacing:-.03em}
.price .amt small{display:inline;font-size:24px;font-weight:500;color:var(--mute);letter-spacing:0;margin-left:10px}
.price p{margin:0;color:var(--mute);font-size:18px}
.price .note{font-size:14px;color:var(--mute);margin-top:var(--s2)}
a.btn{text-decoration:none}
.buybtn{--acc:var(--blue);height:52px;padding:0 28px;font-size:18px}
.price .note,section .note{font-size:14px;color:var(--mute);min-height:1.5em}
.faq{display:flex;flex-direction:column;gap:var(--s1);margin:0;max-width:62ch;text-align:left}
.faq dt{font-weight:700;margin-top:var(--s4)}
.faq dt:first-child{margin-top:0}
.faq dd{margin:2px 0 0;color:var(--mute);max-width:60ch}
.how{display:flex;flex-direction:column;gap:var(--s4);margin:0;padding:0;list-style:none;counter-reset:s;max-width:52ch;text-align:left}
.how li{display:grid;grid-template-columns:40px 1fr;gap:var(--s3);align-items:start}
.how li::before{counter-increment:s;content:counter(s);display:grid;place-items:center;width:40px;height:40px;background:var(--cap);border:1px solid var(--cap-line);border-radius:5px;border-bottom:4px solid var(--cap-edge);box-shadow:inset 0 1px 0 var(--hi);font-weight:700;grid-row:1/3}
.how b{grid-column:2;font-weight:700}
.how span{grid-column:2;color:var(--mute)}
.how kbd{font:inherit;font-size:13px;display:inline-grid;place-items:center;min-width:1.6em;height:22px;padding:0 6px;background:var(--cap);border-radius:3px;border-bottom:2px solid var(--cap-edge);color:var(--ink);vertical-align:middle}
/* leaderboards under each game, reached by scrolling: all-time and last-24h */
.lbzone{margin-top:var(--s6);text-align:center}
.lbtitle{font-size:clamp(24px,3vw,32px);font-weight:700;letter-spacing:-.02em;margin:0 0 var(--s4)}
.lbrow{display:flex;gap:var(--s5);justify-content:center;align-items:flex-start;flex-wrap:wrap}
.lb .tm{font-size:11px;color:var(--mute);min-width:32px;text-align:right}
.lbrow .lb{width:min(340px,100%)}
.lb{display:flex;flex-direction:column;gap:var(--s3);text-align:left}
.lb h4{margin:0 0 6px;font-size:12px;font-weight:700;letter-spacing:.05em;color:var(--mute)}
.lb ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px;counter-reset:lb}
.lb li{display:flex;align-items:center;gap:8px;font-size:14px;line-height:1.2}
.lb li::before{counter-increment:lb;content:counter(lb);display:grid;place-items:center;width:20px;height:20px;background:var(--cap);border:1px solid var(--cap-line);border-bottom:2px solid var(--cap-edge);border-radius:4px;font-size:11px;font-weight:700;flex:none}
/* rainbow name and rank number, like the buy button, is reserved for lifetime owners (li.pro), wherever they rank */
.lb li.pro::before{background:var(--holo-grad);background-size:400% 100%;animation:holo 2.4s linear infinite;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.6);border-color:transparent;border-bottom-color:rgba(0,0,0,.4)}
.lb li.pro .nm{font-weight:700;background:var(--holo-grad);background-size:400% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;-webkit-text-fill-color:transparent;animation:holo 2.4s linear infinite}
/* everyone who hasn't bought Juketype is gray: name and rank keycap, like gray-tier words; owners (li.pro) shimmer rainbow above */
.lb li:not(.mute):not(.pro) .nm{color:#6d7078}
.lb li:not(.mute):not(.pro)::before{background:#6d7078;color:#fff;border-color:transparent;border-bottom-color:#4f525a}
@media (prefers-reduced-motion:reduce){.lb li.pro .nm,.lb li.pro::before{animation:none}}
.lb li.mute{color:var(--mute);font-size:13px}
.lb li.mute::before{content:none}
.lb .nm{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--mute)}
.lb li b{font-weight:700;flex:none}

/* account page: auth panel and score history */
.authbox{display:flex;flex-direction:column;gap:var(--s3);width:min(360px,100%);margin-top:var(--s2)}
.authbox input{font:inherit;font-size:16px;height:44px;padding:0 14px;background:var(--field);color:var(--ink);border:1px solid var(--cap-line);border-bottom:4px solid var(--cap-edge);border-radius:5px;box-shadow:inset 0 1px 0 var(--hi)}
.authbox input:focus{outline:2px solid var(--blue);outline-offset:1px}
.authbox .btn{height:44px;font-size:16px;cursor:pointer}
.authbox .btn.primary{--acc:var(--blue)} /* --acc is unset outside nav/buy scopes; without this the button paints white */
.authbox .row{display:flex;gap:var(--s2)}
.authbox .row .btn{flex:1}
.authbox .note{font-size:14px;color:var(--mute);margin:0;min-height:1.5em}
.ubox .row input{flex:1;min-width:0}
.ubox .row .btn{flex:0 0 auto;padding:0 18px}
section.danger{border-top:1px solid var(--cap-edge);padding-top:var(--s5);width:100%;max-width:720px;margin-left:auto;margin-right:auto;gap:var(--s4)}
.danger .btn.danger{background:var(--bad);color:#fff;border-color:var(--bad);border-bottom:4px solid color-mix(in srgb,var(--bad) 60%,#000);cursor:pointer}
.danger .btn.danger:hover{background:color-mix(in srgb,var(--bad) 85%,#000)}
.danger .note{font-size:13px;color:var(--mute);max-width:44ch;margin:var(--s2) auto 0}
/* account hero: username spelled in keycaps over a quiet email line */
.acct .acctname .caps{font-size:clamp(22px,3.4vw,32px);font-weight:700}
.acctmail{margin:0;font-size:14px;color:var(--mute)}
/* account and player pages: "equipped <tag>" over the scores, left-aligned, the tag's name in its own lettering */
.equipped{margin:0 0 var(--s2);font-size:14px;font-weight:500;color:var(--mute);text-align:left}
.equipped .ntext,.equipped b{font-size:15px;font-weight:700}
.acctstats{display:flex;gap:var(--s4);justify-content:center;flex-wrap:wrap;margin:var(--s4) 0 var(--s2)}
.stile{display:flex;flex-direction:column;align-items:flex-start;gap:6px;min-width:120px}
.stile b{font-size:26px;font-weight:700;line-height:1}
.stile span{font-size:12px;color:var(--mute)}
.shist{display:flex;flex-direction:column;gap:var(--s4);width:100%;max-width:720px;margin-top:var(--s4)}
.sgame{display:flex;flex-direction:column;gap:var(--s3);padding:var(--s4) 0;text-align:left}
.sgame + .sgame{border-top:1px solid color-mix(in srgb,var(--cap-edge) 45%,transparent)} /* no cards: a hairline between games */
.sghead{display:flex;justify-content:space-between;align-items:center;gap:var(--s3);flex-wrap:wrap}
.sgame h3{margin:0;font-size:16px;font-weight:700;line-height:1}
.sgame .note{font-size:14px;color:var(--mute);margin:0}
.sstats{display:flex;gap:var(--s4);font-size:12px;color:var(--mute);align-items:baseline}
.sstats b{color:var(--ink);font-weight:700;font-size:17px;margin-right:4px}
.stile.ghost b,.stile.ghost span{visibility:hidden}
.sghost{aspect-ratio:640/185;border-radius:8px;background:color-mix(in srgb,var(--cap-edge) 22%,transparent)}
.chartwrap{position:relative;width:100%}
.schart{display:block;width:100%;height:auto}
.ctip{position:absolute;pointer-events:none;background:var(--ink);color:var(--desk);font-size:12.5px;line-height:1.35;padding:7px 11px;border-radius:7px;transform:translate(-50%,calc(-100% - 12px));white-space:nowrap;z-index:5;opacity:0;transition:opacity .12s}
.ctip.on{opacity:1}
.ctip b{color:var(--desk);font-size:14px}
.ctip::after{content:'';position:absolute;top:100%;left:50%;transform:translateX(-50%);border:5px solid transparent;border-top-color:var(--ink)}

footer{margin-top:var(--s7);padding-top:var(--s3);text-align:center;color:var(--mute);font-size:14px;display:flex;justify-content:center;gap:var(--s3);flex-wrap:wrap}

/* opener, same as the post-download page */
body{text-transform:lowercase}
button,a{text-transform:inherit}
textarea,input{text-transform:none}
.brand,.jt{text-transform:none}
[hidden]{display:none!important}
.open{display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--s4);padding-block:var(--s5) var(--s5)}
.open h1{font-size:clamp(32px,6vw,58px);font-weight:700;line-height:1.05;letter-spacing:-.025em;margin:0;text-wrap:balance}
.open .lead{font-size:20px;line-height:1.5;margin:0;color:var(--mute);max-width:44ch;min-height:3em;text-wrap:balance}
/* wide screens: header and subtext each on one line, and the keyboard spreads out to match */
@media (min-width:1000px){.open h1,.open .lead{white-space:nowrap;max-width:none}.open .lead{min-height:1.5em}}
.open .setsWrap{display:inline-flex;flex-direction:column;gap:var(--s3);align-self:center;max-width:100%;margin-top:var(--s2)}
/* the hero is one object: a keyboard. function row (sets + volume) on top, live board below */
.deck{background:var(--case);border-radius:14px;padding:var(--s4);display:flex;flex-direction:column;align-items:center;gap:var(--s4);max-width:100%;margin-top:var(--s2);box-shadow:inset 0 2px 0 var(--sheen),inset 0 -3px 0 rgba(0,0,0,.06)}
.fnrow{display:flex;justify-content:space-between;align-items:center;gap:var(--s3);width:100%;flex-wrap:wrap}
.fnrow .sets{gap:6px}
.open .deck .sets .key{height:30px;padding:0 10px;font-size:13px;cursor:pointer}
.board{display:flex;flex-direction:column;gap:.4em;font-size:clamp(12px,2.9vw,21px)}
.desk{display:flex;align-items:stretch;justify-content:center;gap:var(--s4);max-width:100%;margin-top:var(--s2)}
.desk .deck{margin-top:0}
@media (min-width:1000px){.desk .board{font-size:clamp(21px,2.2vw,28px)}}
/* the mousepad: the same case surface as the keyboard, as tall as it, so they read as a set */
.mousepad{display:flex;align-items:center;justify-content:center;padding:0 var(--s4);background:var(--case);border-radius:14px;box-shadow:inset 0 2px 0 var(--sheen),inset 0 -3px 0 rgba(0,0,0,.06)}
/* the mouse: one cream keycap body, two buttons split down the middle, a wheel between */
.mouse{position:relative;flex:none;width:4.6em;height:7.4em;font-size:clamp(12px,2.2vw,28px);background:var(--cap);border:2px solid var(--cap-edge);border-bottom-width:.3em;border-radius:2.3em 2.3em 2.5em 2.5em/2.7em 2.7em 3.6em 3.6em;box-shadow:inset 0 .08em 0 #fff,0 .2em .5em rgba(0,0,0,.06);overflow:hidden}
.mouse .mb{position:absolute;top:0;width:50%;height:44%;padding:0;margin:0;background:transparent;border:0;border-bottom:2px solid var(--cap-edge);cursor:pointer;transition:background .07s}
.mouse .mb.l{left:0;border-right:2px solid var(--cap-edge)}
.mouse .mb.r{right:0}
.mouse .mb:hover{background:color-mix(in srgb,var(--cap-edge) 18%,var(--cap))}
.mouse .mb.down{background:var(--ink)}
.mouse .wheel{position:absolute;left:50%;top:13%;width:.66em;height:1.35em;margin-left:-.33em;border-radius:.33em;background-color:var(--case);background-image:repeating-linear-gradient(180deg,var(--cap-edge) 0 2px,transparent 2px 5px);border:2px solid var(--cap-edge);pointer-events:none;z-index:1}
@media (max-width:999px){.mousepad{display:none}}
.brow{display:flex;gap:.4em;justify-content:center}
.brow .key{width:2.1em;height:2.1em;min-width:0;padding:0;font-weight:500;font-size:inherit;cursor:pointer;border-radius:.24em;border-bottom-width:.18em;transition:transform .07s,border-bottom-width .07s}
.brow .key.space{width:13.5em}
.brow .key.down{transform:translateY(.1em);border-bottom-width:.06em;background:var(--ink);color:var(--cap);border-bottom-color:#000}
.vctl{display:flex;gap:8px;align-items:center;font-size:13px;color:var(--mute)}
.vctl .key{height:26px;min-width:26px;padding:0 8px;font-size:14px;cursor:pointer}
.vctl b{font-weight:500;color:var(--ink);min-width:1.4em;text-align:center;font-variant-numeric:tabular-nums}
@media (max-width:640px){.deck{padding:var(--s3)}.fnrow{justify-content:center}}
.open .sets .key{height:44px;padding:0 18px;font-size:16px;cursor:pointer;--acc:var(--ink)}
.open .sets .key.acc{background:var(--blue);color:#fff;border-color:var(--blue);border-bottom-color:color-mix(in srgb,var(--blue) 70%,#000)}
footer a{color:var(--mute)}
footer a:hover{color:var(--ink)}

/* ---------- Dopamine (was the Frenzy test build) ---------- */
.dopamine .stage{overflow:hidden}
.dopamine .strip b{display:inline-block}
@keyframes dpulse{50%{opacity:.4;transform:scaleY(.75)}}
/* floating words: keycaps that pop in, glow by tier, explode on clear */
.dopamine .fw{position:absolute;display:flex;gap:.12em;font-size:clamp(19px,2.3vw,32px);animation:fwin .22s cubic-bezier(.2,1.6,.4,1);z-index:1}
.dopamine .fw .key{display:grid;place-items:center;min-width:1.45em;height:1.5em;padding:0 .26em;border-radius:.13em}
.dopamine .fw:not(.tskin) .key{background:var(--cap);border:1px solid var(--cap-line);border-bottom:.13em solid var(--cap-edge);font-weight:500;color:var(--ink);box-shadow:inset 0 1px 0 var(--hi)} /* a word in a nametag skin keeps the skin's look */
.dopamine .fw .key.hit{background:var(--acc);color:#fff;border-color:var(--acc);border-bottom-color:color-mix(in srgb,var(--acc) 70%,#000);animation:hitpop .14s}
.dopamine .fw .life{position:absolute;left:2%;right:2%;bottom:-9px;height:4px;border-radius:2px;background:color-mix(in srgb,var(--acc) 70%,#fff);transform-origin:left}
.dopamine .fw.low .life{background:var(--bad)}
.dopamine .fw.pop{animation:fwpop .3s forwards;pointer-events:none}
.dopamine .fw.burn{animation:fwburn .4s forwards}
/* words arrive by fading and rising, never by scaling: after a scale animation the browser can keep
   the letters drawn at an in-between size, which reads as blur */
@keyframes fwin{from{transform:translateY(10px);opacity:0}}
@keyframes hitpop{50%{transform:translateY(-.16em)}}
@keyframes fwpop{to{transform:scale(1.55);opacity:0}}
/* the pop's flash: a white layer fading out (a brightness filter forced a repaint per pop) */
.dopamine .fw.pop::after{content:'';position:absolute;inset:-3px;border-radius:.2em;background:#fff;opacity:0;pointer-events:none;animation:popflash .3s ease-out}
@keyframes popflash{0%{opacity:.55}100%{opacity:0}}
@keyframes fwburn{to{transform:scale(.7) rotate(5deg);opacity:0}}
/* fever: ten cells across the top; full = the whole stage goes rainbow */
.dopamine .fmeter{position:absolute;top:10px;left:50%;transform:translateX(-50%);display:flex;gap:4px;z-index:3}
.dopamine .fmeter i{width:22px;height:8px;border-radius:3px;background:color-mix(in srgb,var(--cap-edge) 60%,var(--case))}
.dopamine .fmeter i.on{background:var(--acc);box-shadow:0 0 6px color-mix(in srgb,var(--acc) 60%,transparent)}
.dopamine .fmeter.full i{background:var(--holo-grad);background-size:400% 100%;animation:holo 1.2s linear infinite}
.dopamine .fword{position:absolute;top:24px;left:50%;transform:translateX(-50%);font-weight:700;font-size:13px;color:var(--acc);letter-spacing:.14em;z-index:3;opacity:0;transition:opacity .2s}
.dopamine .fword.on{opacity:1}
.dopamine .stage.fever::before{content:'';position:absolute;inset:0;background:var(--holo-grad);background-size:400% 100%;animation:holo 2s linear infinite;opacity:.1;pointer-events:none;z-index:0;will-change:transform}
.dopamine .stage.fever{box-shadow:0 0 0 3px color-mix(in srgb,#8a16a8 35%,transparent),0 0 34px color-mix(in srgb,#c2184c 25%,transparent)}
/* words about to die tremble */
/* a word about to burn: its bar pulses red. The word itself stays still, because moving or tilting
   text by fractions of a screen pixel (any scaling but 100%) is what made letters blurry */
.dopamine .fw.low .life{height:5px;animation:lowpulse .5s ease-in-out infinite alternate}
@keyframes lowpulse{from{opacity:1}to{opacity:.35}}
/* coins fly from the kill to the score, which bumps as they land */
.orb{position:fixed;width:11px;height:11px;border-radius:50%;background:var(--oc,#d4a017);box-shadow:inset 0 2px 0 var(--sheen),0 1px 2px rgba(0,0,0,.25);z-index:60;pointer-events:none;transition:transform .55s cubic-bezier(.25,.6,.3,1),opacity .55s;opacity:1}
.orb.rb{background:var(--holo-grad);background-size:400% 100%;animation:holo 1.2s linear infinite}
.strip b.bump{display:inline-block;animation:scorebump .2s} /* the points number, as each orb lands (every game) */
@keyframes scorebump{40%{transform:scale(1.4);color:#b8860b}}
/* fever's final seconds: everything strobes, clutch pops pay extra */
.dopamine .fmeter.clutch i{background:var(--bad);animation:dpulse .22s ease-in-out infinite}
/* embers off every keystroke */
.dopamine .fspark{position:absolute;width:5px;height:5px;border-radius:50%;z-index:4;pointer-events:none;animation:fsparkup .6s ease-out forwards}
@keyframes fsparkup{to{transform:translate(var(--dx,0),-46px) scale(.3);opacity:0}}
/* milestone callouts: the game narrates your streak */
.dopamine .fcall{position:absolute;left:50%;top:38%;transform:translateX(-50%);z-index:5;font-weight:700;font-size:clamp(30px,5.4vw,52px);color:var(--acc);letter-spacing:-.02em;white-space:nowrap;pointer-events:none;animation:fcallin 1.1s cubic-bezier(.2,1.6,.4,1) forwards;text-shadow:0 2px 0 rgba(255,255,255,.7)}
.dopamine .fcall.gold{color:#b8860b}
@keyframes fcallin{0%{transform:translateX(-50%) scale(2.1) rotate(-5deg);opacity:0}14%{transform:translateX(-50%) scale(1) rotate(0);opacity:1}78%{opacity:1}100%{opacity:0}}
/* two cells from fever: the meter can feel it coming */
.dopamine .fmeter.near i.on{animation:dpulse .5s ease-in-out infinite}
/* mystery words: dark caps with a holo "?", rarity hidden until the last letter */
.dopamine .fw.mys .key{background:#2b2b33;color:#fffdf8;border-color:#2b2b33;border-bottom-color:#0d0d10;box-shadow:inset 0 1px 0 rgba(255,255,255,.12)}
.dopamine .fw.mys .key.hit{background:var(--holo-grad);background-size:400% 100%;animation:holo 1.2s linear infinite;border-color:transparent;border-bottom-color:rgba(0,0,0,.4);color:#fff}
.dopamine .fw.mys .life{background:#2b2b33}
.dopamine .fw.mys::before{content:'?';position:absolute;top:-.55em;right:-.45em;width:1.3em;height:1.3em;border-radius:50%;display:grid;place-items:center;font-size:.6em;line-height:1;text-align:center;font-weight:700;color:#fff;background:var(--holo-grad);background-size:400% 100%;animation:holo 1.4s linear infinite;z-index:2}
.dopamine .fw.revealing{z-index:3}
@media (prefers-reduced-motion:reduce){.dopamine .fw,.dopamine .fw.pop,.dopamine .fw.burn,.dopamine .fmeter.full i,.dopamine .fmeter.near i.on,.dopamine .stage.fever::before,.dopamine .fw .key.hit,.dopamine .fspark,.dopamine .fcall,.dopamine .fw.mys::before{animation:none}}

/* the hub card preview: a mystery cap */

/* admin roster editing on /games: the pencil, tiles with controls, the add shelf */
.gwrap{position:relative;width:100%;display:flex;flex-direction:column;align-items:center;gap:var(--s4)}
.gpen{position:absolute;top:-52px;right:0;display:grid;place-items:center;min-width:40px;height:40px;padding:0 12px;font:inherit;font-size:14px;font-weight:700;color:var(--ink);background:var(--cap);border:1px solid var(--cap-line);border-bottom:4px solid var(--cap-edge);border-radius:8px;box-shadow:inset 0 1px 0 var(--hi);cursor:pointer}
.gpen:hover{background:var(--field)}
.gpen.on{background:var(--ink);color:var(--desk);border-color:var(--ink);border-bottom-color:#000}
.gtile{position:relative;display:flex;flex-direction:column;align-items:center;gap:var(--s3);padding:var(--s3);border:2px dashed transparent;border-radius:12px}
.gtile.off{border-color:var(--cap-edge)}
.gtile.off .gcard{opacity:.4}
.gtile.add{border-color:var(--cap-edge);background:color-mix(in srgb,var(--case) 50%,transparent)}
.gtile .gcard{cursor:default}
.gtag{position:absolute;top:8px;left:8px;font-size:11px;font-weight:700;letter-spacing:.12em;color:var(--mute);background:var(--case);padding:2px 8px;border-radius:5px}
.gtools{display:flex;gap:var(--s2);justify-content:center}
.gtools .btn{cursor:pointer}
.gtools .btn.primary{--acc:var(--blue)}
.gshelf{display:flex;flex-direction:column;align-items:center;gap:var(--s3);width:100%;margin-top:var(--s4);padding-top:var(--s4);border-top:1px solid var(--cap-edge)}
.gshelf h3{margin:0;font-size:15px;color:var(--mute);font-weight:700}
.gstatus{margin:0;min-height:1.5em;font-size:14px;color:var(--mute)}

/* admin tools: a section at the bottom of the sound pack dropdown */
.tmsec{display:flex;flex-direction:column;gap:8px;width:240px;margin-top:4px;padding:10px 8px 4px;border-top:1px solid var(--cap-line)}
.tmpanel{display:flex;flex-direction:column;gap:8px}
.tmhead{font-weight:700;font-size:14px;color:var(--ink)}
.tmrow{display:flex;align-items:center;gap:8px;font-size:14px;color:var(--mute)}
.tmrow input{width:96px;font:inherit;font-size:15px;height:34px;padding:0 10px;border:1px solid var(--cap-line);border-bottom:3px solid var(--cap-edge);border-radius:6px;background:var(--field);color:var(--ink)}
.tmchips{display:flex;flex-wrap:wrap;gap:5px}
.tmchip{font:inherit;font-size:12px;padding:3px 8px;border:1px solid var(--cap-line);border-bottom:2px solid var(--cap-edge);border-radius:5px;background:var(--cap);color:var(--ink);cursor:pointer}
.tmchip:hover{background:var(--case)}
.tmnote{margin:0;font-size:12px;color:var(--mute);line-height:1.45}
.tmsec .btn{height:34px;cursor:pointer}
.tmsec .btn.primary{--acc:var(--blue)}
.tmsec .tmitem.live{color:var(--bad);font-weight:700}

/* performance slider, low end: hold the costliest animations still */
:root[data-perf="1"] .dopamine .stage.fever::before,:root[data-perf="2"] .dopamine .stage.fever::before,
:root[data-perf="1"] .tier-rainbow .key,:root[data-perf="1"] .tier-rainbow .key.hit,
:root[data-perf="1"] .dopamine .fw.mys .key.hit,:root[data-perf="1"] .dopamine .fw.mys::before,
:root[data-perf="1"] .dopamine .fmeter.full i,:root[data-perf="1"] .dopamine .fw.low .life,
:root[data-perf="1"] .dopamine .fw.pop::after{animation:none}
.tmrange{flex:1;min-width:0;accent-color:var(--blue);cursor:pointer}
/* about page: plain reading text */
.prose{max-width:56ch;text-align:left;display:flex;flex-direction:column;gap:var(--s3)}
.prose p{margin:0;font-size:18px;line-height:1.55}
/* games: signed-out players see this on the stage instead of the game */
.gate{display:flex;flex-direction:column;align-items:center;gap:var(--s3);text-align:center}
.gate h2{font-size:clamp(28px,3.8vw,38px);font-weight:700;margin:0;letter-spacing:-.02em}
.gate p{margin:0;color:var(--mute);font-size:18px}
.gatebtns{display:flex;gap:var(--s3);flex-wrap:wrap;justify-content:center;margin-top:var(--s2)}
.gatebtns .btn{height:44px;padding:0 22px;font-size:16px}
.gate .btn.primary{--acc:var(--blue)} /* the site's blue, not the game colour */
/* leaderboard names open the player's page; hovering bolds them */
.lb a.nm{color:inherit;text-decoration:none}
.lb a.nm:hover{font-weight:700;color:var(--ink)}
/* account page: shown when the account's email has bought Juketype, in rainbow lettering */
/* the account labels hold still: the gradient is spread once across the words, never moving */
.lifetag{display:inline-block;margin-left:10px;font-size:13px;font-weight:700;color:transparent;background:var(--holo-grad);background-size:100% 100%;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
/* owners: your name on /account is rainbow, like the buy button (Buy stays in the nav for everyone: it sells nametags too) */
.jt-own .acctname.mine .key,.acctname.own .key{color:#fff;font-weight:700;text-shadow:0 1px 2px rgba(0,0,0,.7),0 0 4px rgba(0,0,0,.45);border-color:transparent;background:var(--holo-grad);background-size:400% 100%;animation:holo 2.2s linear infinite;border-bottom-color:rgba(0,0,0,.4)}
@media (prefers-reduced-motion:reduce){.jt-own .acctname.mine .key,.acctname.own .key{animation:none}}
/* owners: the buy button becomes a plain thank-you */
.buythanks{display:none;margin:0;font-size:22px;font-weight:700}
/* rainbow lettering, shimmering like the buy button it replaces (beats the grey .price p) */
.jt-in.jt-own .buythanks{display:block;color:transparent;background:var(--holo-grad);background-size:400% 100%;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;animation:holo 2.4s linear infinite}
@media (prefers-reduced-motion:reduce){.jt-in.jt-own .buythanks{animation:none}}
.jt-in.jt-own .buybtn{display:none}
.lifetag.solo{margin-left:0}
/* browser autofill paints saved logins pale blue: keep the cream input instead (a wide inset
   shadow covers the browser's own background, which pages can't set directly) */
input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus{-webkit-box-shadow:inset 0 0 0 1000px var(--field);box-shadow:inset 0 0 0 1000px var(--field);-webkit-text-fill-color:var(--ink);caret-color:var(--ink)}
input:autofill{-webkit-box-shadow:inset 0 0 0 1000px var(--field);box-shadow:inset 0 0 0 1000px var(--field);-webkit-text-fill-color:var(--ink);caret-color:var(--ink)} /* separate rule: one unknown selector would drop the whole list */
/* account page: a quiet gray link under the email */
.forgot{background:none;border:0;padding:0;margin:-6px 0 0;font:inherit;font-size:13px;color:var(--mute);cursor:pointer}
.forgot:hover:not(:disabled){color:var(--ink);text-decoration:underline}
.forgot:disabled{cursor:default}
/* the restart hint under each game: big enough to notice */
.shell .hint{font-size:18px;color:var(--ink);align-items:center}
.shell .hint kbd{font-size:16px;height:1.8em;min-width:2em;padding:0 .55em;border-bottom-width:3px;margin-right:4px}
/* games: a bigger game name and start button, and under the stage how it works, then the hotkeys */
.strip .name{font-size:34px;letter-spacing:-.02em}
.stage .row-actions .btn{height:56px;padding:0 40px;font-size:22px;border-radius:8px;border-bottom-width:5px}
/* the start button (Start, Play again): a rare tag of a button. A holographic shimmer through the game's own
   colour and pink, cyan and gold, a bright sheen sweeping across, a soft glow breathing around it, and it
   still presses down like a keycap. Dark mode turns the glow to neon */
.stage .row-actions .btn.primary.go{position:relative;overflow:hidden;isolation:isolate;color:#fff;font-weight:700;letter-spacing:.02em;text-shadow:0 1px 2px rgba(0,0,0,.45),0 0 6px rgba(0,0,0,.2);border:0;border-bottom:5px solid color-mix(in srgb,var(--acc) 55%,#000);
  background:linear-gradient(100deg,var(--acc) 0%,color-mix(in srgb,var(--acc) 55%,#ff5fd2) 25%,color-mix(in srgb,var(--acc) 55%,#38d9ff) 50%,color-mix(in srgb,var(--acc) 55%,#ffcf3f) 75%,var(--acc) 100%);background-size:400% 100%;
  box-shadow:0 6px 18px color-mix(in srgb,var(--acc) 35%,transparent);animation:holo 5s linear infinite,gobreathe 2.4s ease-in-out infinite;transition:transform .06s,border-bottom-width .06s,filter .2s}
.stage .row-actions .btn.primary.go::after{content:'';position:absolute;top:-30%;bottom:-30%;left:-45%;width:32%;z-index:-1;transform:skewX(-20deg);background:linear-gradient(90deg,transparent,rgba(255,255,255,.7),transparent);animation:gosheen 2.6s ease-in-out infinite;pointer-events:none}
@keyframes gosheen{0%,50%{left:-45%}82%,100%{left:125%}}
@keyframes gobreathe{50%{box-shadow:0 8px 30px color-mix(in srgb,var(--acc) 60%,transparent),0 0 16px color-mix(in srgb,var(--acc) 40%,transparent)}}
.stage .row-actions .btn.primary.go:hover{filter:brightness(1.08) saturate(1.2)}
.stage .row-actions .btn.primary.go:hover::after{animation-duration:1.3s}
.stage .row-actions .btn.primary.go:active{transform:translateY(3px);border-bottom-width:2px}
.jt-dark .stage .row-actions .btn.primary.go{animation:holo 5s linear infinite,gobreathedark 2.4s ease-in-out infinite}
@keyframes gobreathedark{0%,100%{box-shadow:0 0 14px color-mix(in srgb,var(--acc) 55%,transparent),0 0 2px var(--acc)}50%{box-shadow:0 0 34px var(--acc),0 0 10px var(--acc)}}
@media (prefers-reduced-motion:reduce){.stage .row-actions .btn.primary.go,.stage .row-actions .btn.primary.go::after{animation:none}}
.shell .hint{flex-direction:column;align-items:flex-start;gap:var(--s3)}
.shell .hint .gabout{margin:0;font-size:17px;line-height:1.5;color:var(--mute);max-width:72ch}
.shell .hint .gkeys{display:flex;align-items:center}
/* end screen: the count, stats sized to sit with it, play again + share */
.over{justify-content:safe center} /* too tall for a short screen: start at the top and scroll, never clip */
.over .big{font-size:clamp(56px,9vw,84px);letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.over .unit{font-size:17px;margin-top:-10px}
.over .tbl{font-size:17px;gap:6px var(--s4)}
.over .row-actions{margin-top:var(--s2)}
.stage .row-actions .btn.sharebtn{background:var(--cap);color:var(--ink);border:1px solid var(--cap-line);border-bottom:5px solid var(--cap-edge)}
/* inside the stage everything is centred: the start screen, the end screen and the log-in gate.
   Under the stage, the leaderboards read from the left */
.front{display:flex;flex-direction:column;align-items:center;gap:14px;z-index:2}
.lbzone{text-align:center} /* the leaderboards under a game: centred, three boards in one row */
.lbzone .lbrow{justify-content:center;flex-wrap:nowrap;gap:var(--s4)}
@media (max-width:800px){.lbzone .lbrow{flex-wrap:wrap}}
/* the leaderboards under each game: bigger, to sit with the game above them */
.lbzone .lbrow .lb{flex:1 1 0;width:auto;min-width:0;max-width:340px} /* three boards side by side, sharing the row: your friends, all-time, 24 hours */
@media (max-width:800px){.lbzone .lbrow .lb{flex:1 1 100%;max-width:none}}
/* a board's empty message: one line of text, its link a quiet underline in the ink colour */
.lb li.mute .lbmsg{display:block}
.lb li.mute a{color:var(--ink);text-decoration:underline;text-decoration-color:var(--cap-edge);text-underline-offset:3px}
.lb li.mute a:hover{text-decoration-color:currentColor}
.lbzone .lb h4{font-size:14px}
.lbzone .lb ol{gap:9px}
.lbzone .lb li{font-size:18px;gap:11px}
.lbzone .lb li::before{width:27px;height:27px;font-size:14px;border-radius:5px;border-bottom-width:3px}
.lbzone .lb .tm{font-size:13px;min-width:38px}
.lbzone .lb li.mute{font-size:16px}
/* developer accounts (public.admins): shining red, outranking an owner's rainbow and the gray.
   Your own name on /account (html.jt-dev), a player page (.acctname.dev) and leaderboard rows (li.dev) */
:root{--dev-grad:linear-gradient(100deg,#7a0b17,#c8102e,#ff4d5a,#c8102e,#7a0b17)}
.jt-dev .acctname.mine .key,.acctname.dev .key{color:#fff;font-weight:700;text-shadow:0 1px 2px rgba(0,0,0,.7),0 0 4px rgba(0,0,0,.45);border-color:transparent;background:var(--dev-grad);background-size:400% 100%;animation:holo 2.2s linear infinite;border-bottom-color:rgba(0,0,0,.45)}
.devtag{display:inline-block;margin-left:10px;font-size:13px;font-weight:700;color:transparent;background:var(--dev-grad);background-size:100% 100%;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.devtag.solo{margin-left:0}
.lb li.dev:not(.mute) .nm{font-weight:700;background:var(--dev-grad);background-size:400% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;-webkit-text-fill-color:transparent;animation:holo 2.4s linear infinite}
.lb li.dev:not(.mute)::before{background:var(--dev-grad);background-size:400% 100%;animation:holo 2.4s linear infinite;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.6);border-color:transparent;border-bottom-color:rgba(0,0,0,.45)}
@media (prefers-reduced-motion:reduce){.jt-dev .acctname.mine .key,.acctname.dev .key,.devtag,.lb li.dev:not(.mute) .nm,.lb li.dev:not(.mute)::before{animation:none}}
/* developers never see the Buy on /about (html.jt-dev, set before the first paint); the nav keeps its Buy */
.jt-in.jt-dev .buybtn{display:none}
/* the nav reads at the size of the page, not smaller: 17px links and a matching Buy (phones keep 15px so it fits) */
.nav{font-size:17px}
.nav a.btn{height:40px}
@media (max-width:640px){.nav{font-size:15px}.nav a.btn{height:36px}}
/* hovering a leaderboard name always answers: gray names darken (beating the gray rule above),
   owners' rainbow and developers' red brighten and shimmer faster, since their letters are see-through */
.lb li:not(.mute) a.nm:hover{color:var(--ink)}
.lb li.pro a.nm:hover,.lb li.dev:not(.mute) a.nm:hover{filter:brightness(1.25) saturate(1.3);animation-duration:.8s}
/* ---------- Dopamine on the dark site (html.jt-dark, toggled on /account) ----------
   The stage goes darker than the rest of the site: a black machine where every colour glows.
   Words wear their tier's neon twin (NEON in juketype.js) as --acc. */
.jt-dark .dopamine .stage{--case:#000;--ink:#f5f7ff;--mute:#a3a9c2;--cap:#12121c;--cap-line:#2b2b40;--cap-edge:#000;background:var(--case);color:var(--ink);box-shadow:inset 0 0 0 1px #16161f}
/* keycaps: dark glass, lit from inside by the tier colour */
.jt-dark .dopamine .fw:not(.tskin) .key{background:#0d0d16;color:#fff;font-weight:700;border-color:color-mix(in srgb,var(--acc) 75%,transparent);border-bottom-color:var(--acc);box-shadow:0 0 12px color-mix(in srgb,var(--acc) 55%,transparent),inset 0 0 8px color-mix(in srgb,var(--acc) 30%,transparent);text-shadow:0 0 8px var(--acc),0 0 2px var(--acc)}
.jt-dark .dopamine .fw:not(.tskin) .key.hit{background:var(--acc);color:#05050a;text-shadow:none;border-color:var(--acc);border-bottom-color:color-mix(in srgb,var(--acc) 60%,#fff);box-shadow:0 0 22px var(--acc),0 0 6px var(--acc)}
.jt-dark .dopamine .fw .life{background:var(--acc);box-shadow:0 0 8px var(--acc)}
.jt-dark .dopamine .fw.low .life{background:#ff2a4a;box-shadow:0 0 10px #ff2a4a}
/* mystery words: dark violet caps with a white glow, still keeping their secret */
.jt-dark .dopamine .fw:not(.tskin).mys .key{background:#1a1030;color:#fff;border-color:#b98cff;border-bottom-color:#7a4dff;box-shadow:0 0 14px rgba(160,110,255,.55);text-shadow:0 0 8px #c9a8ff}
.jt-dark .dopamine .fw.mys .life{background:#b98cff;box-shadow:0 0 8px #b98cff}
/* the rainbow tier: brighter still, with a halo */
.jt-dark .dopamine .fw:not(.tskin).tier-rainbow .key{filter:brightness(1.35) saturate(1.4);box-shadow:0 0 22px rgba(255,80,200,.7)}
/* fever on the dark site: a celebration you can still read through. The rainbow lives only at the
   stage's rim, faint and slow, so the black middle stays black and the words stay the brightest thing
   on screen; the stage gets a thin magenta edge with a soft glow, the meter lights without halos */
.jt-dark .dopamine .fmeter i{background:#2a2a42}
.jt-dark .dopamine .fmeter i.on{background:#ff3dff;box-shadow:0 0 5px rgba(255,61,255,.55)}
.jt-dark .dopamine .fmeter.full i{filter:none;box-shadow:none}
.jt-dark .dopamine .fword{color:#ff3dff;text-shadow:0 0 6px rgba(255,61,255,.55)}
.jt-dark .dopamine .stage.fever::before{opacity:.16;filter:none;animation-duration:6s;-webkit-mask:radial-gradient(ellipse 80% 75% at 50% 50%,transparent 55%,#000 100%);mask:radial-gradient(ellipse 80% 75% at 50% 50%,transparent 55%,#000 100%)}
.jt-dark .dopamine .stage.fever{box-shadow:0 0 0 1px rgba(255,61,255,.45),0 0 22px rgba(255,61,110,.18)}
.jt-dark .dopamine .stage.fever .confetti{filter:none} /* the fever drizzle, at its own colours rather than boosted */
/* callouts, score pops, combo and cues glow instead of sitting on paper */
.jt-dark .dopamine .fcall{text-shadow:0 0 18px var(--acc),0 0 4px var(--acc)}
.jt-dark .dopamine .fcall.gold{color:#ffe11a;text-shadow:0 0 18px #ffe11a}
.jt-dark .dopamine .spop{text-shadow:0 0 12px currentColor,0 0 3px currentColor}
.jt-dark .dopamine .combo.h1{color:#ffe11a;text-shadow:0 0 10px #ffe11a}
.jt-dark .dopamine .combo.h2{color:#ff3d6e;text-shadow:0 0 12px #ff3d6e}
.jt-dark .dopamine .confetti{filter:brightness(1.3) saturate(1.4)}
.jt-dark .dopamine .fspark{box-shadow:0 0 8px rgba(255,255,255,.8)}
/* coins fly over the page itself, so they glow wherever they are */
.jt-dark .orb{background:var(--oc,#ffe11a);box-shadow:0 0 10px var(--oc,#ffe11a),0 0 3px var(--oc,#ffe11a)}
@media (prefers-reduced-motion:reduce){.jt-dark .dopamine .stage.fever::before{animation:none}}
/* the lowest performance level keeps the neon colours but drops the per-word glow */
:root[data-perf="1"].jt-dark .dopamine .fw:not(.tskin) .key,:root[data-perf="1"].jt-dark .dopamine .fw:not(.tskin) .life{box-shadow:none;text-shadow:none}
:root[data-perf="1"].jt-dark .dopamine .fw:not(.tskin).tier-rainbow .key{filter:none}
/* account settings: one row per setting, its control on the right */
section.acctset{width:100%;max-width:720px;margin-left:auto;margin-right:auto}
.setrow{width:100%;box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:var(--s4);padding:var(--s3) 0;text-align:left}
.settxt{display:flex;flex-direction:column;gap:4px}
.settxt b{font-size:17px;font-weight:700}
.settxt span{font-size:14px;color:var(--mute)}
.jt-dark .dopamine .over .big{color:#ff3da0;text-shadow:0 0 22px #ff3da0,0 0 6px #ff3da0}
.jt-dark .dopamine .over .tbl b.new{color:#ffe11a;text-shadow:0 0 10px #ffe11a}
/* ---------- dark mode: the whole site (html.jt-dark, set before the first paint) ----------
   The three surfaces go night-black, ink turns bright, and every accent is pushed to neon */
:root.jt-dark{
  --desk:#07070d; --case:#121220; --cap:#1c1c2e; --cap-edge:#05050a; --cap-line:#2e2e4a; --blue:#3d8bff;
  --ink:#f4f6ff; --mute:#a5abc6; --bad:#ff3b5c;
  --rain:#2eb0ff; --invade:#a970ff; --wordis:#16f2c6; --dopamine:#ff3da0;
  --holo-grad:linear-gradient(100deg,#ff2d75,#ffb81a,#2bff88,#1fe0ff,#4d7dff,#d43dff,#ff2d75);
  --hi:rgba(255,255,255,.07); --sheen:rgba(255,255,255,.05); --field:#141424;
  color-scheme:dark;
}
/* chart grid lines and the floor: drawn in the cap edge, which is black here */
.jt-dark .schart line{stroke:var(--cap-line)}
/* game titles and rainbow lettering shine */
/* gray names and caps (non-owners) are lifted so they read on black */
.jt-dark .lb li:not(.mute):not(.pro):not(.dev) .nm{color:#9aa1b8}
.jt-dark .lb li:not(.mute):not(.pro):not(.dev)::before{background:#3a3e4c;border-bottom-color:#22252f}
.jt-dark .lb li:not(.mute):not(.pro):not(.dev) a.nm:hover{color:var(--ink)}
.jt-dark .pv-dopamine .pplus{color:#ffe11a;text-shadow:0 0 8px #ffe11a}
.jt-dark .pv-dopamine .ppop.mys .plife{background:#b98cff}
/* ---------- dark mode readability ----------
   The glow lives around the keycaps, never on the letters: coloured text-glow bloomed into
   the light neons (green, yellow, white) and blurred them. Letters stay crisp. */
/* words waiting to be typed: crisp white letters on dark glass, a soft rim of the tier colour */
.jt-dark .dopamine .fw:not(.tskin) .key{text-shadow:0 1px 2px rgba(0,0,0,.85);box-shadow:0 0 8px color-mix(in srgb,var(--acc) 32%,transparent),inset 0 0 5px color-mix(in srgb,var(--acc) 14%,transparent)}
/* typed letters light up: the whole key fills solid neon in the word's colour, dark letter on top,
   like a pressed key on the home keyboard. Same in every game; rainbow and unrevealed mystery
   words keep their shimmer */
.jt-dark .dopamine .fw:not(.tskin):not(.tier-rainbow):not(.mys):not(.burn) .key.hit,
.jt-dark .rain .drop:not(.tskin):not(.tier-rainbow) .key.hit,
.jt-dark .invade .inv:not(.tskin):not(.tier-rainbow) .key.hit,
.jt-dark .wordis .brick:not(.tskin):not(.tier-rainbow) .key.hit{background:var(--acc);color:#07070d;font-weight:700;text-shadow:none;border-color:var(--acc);border-bottom-color:color-mix(in srgb,var(--acc) 60%,#000);box-shadow:0 0 16px color-mix(in srgb,var(--acc) 75%,transparent),0 0 4px var(--acc)}
.jt-dark .dopamine .fw:not(.tskin).mys .key{text-shadow:0 1px 2px rgba(0,0,0,.85);box-shadow:0 0 9px rgba(160,110,255,.4)}
.jt-dark .dopamine .fw:not(.tskin).tier-rainbow .key{filter:brightness(1.15) saturate(1.3);box-shadow:0 0 14px rgba(255,80,200,.5)}
/* accent keycaps and primary buttons: dark letters on the bright fill (white vanished on green and cyan). The name keycaps on /account and player pages keep their own colours */
.jt-dark .key.acc:not(.acctname .key){color:#07070d}
.jt-dark .btn.primary:not(.holo):not(.buybtn){color:#07070d}
.jt-dark .open .sets .key.acc{color:#07070d}
/* white lettering on the brighter rainbow gets a firmer shadow */
.jt-dark .btn.primary.buybtn,.jt-dark .btn.primary.holo,.jt-dark .nav a.btn.primary,.jt-dark .tier-rainbow .key,.jt-dark .jt-own .acctname.mine .key,.jt-dark .acctname.own .key{text-shadow:0 1px 2px rgba(0,0,0,.95),0 0 5px rgba(0,0,0,.7)}
/* glowing headline numbers and words: a tighter, dimmer halo so the shapes stay sharp */
.jt-dark .dopamine .fcall{text-shadow:0 0 10px color-mix(in srgb,var(--acc) 60%,transparent)}
.jt-dark .dopamine .fcall.gold,.jt-dark .dopamine .combo.h1{text-shadow:0 0 8px rgba(255,225,26,.5)}
.jt-dark .dopamine .spop{text-shadow:0 1px 2px rgba(0,0,0,.9),0 0 8px color-mix(in srgb,currentColor 45%,transparent)}
.jt-dark .dopamine .over .big{text-shadow:0 0 14px rgba(255,61,160,.55)}
.jt-dark .dopamine .over .tbl b.new{text-shadow:0 0 6px rgba(255,225,26,.45)}
.jt-dark .dopamine .fword{text-shadow:0 0 6px rgba(255,61,255,.6)}
/* rainbow and mystery typed letters keep their shimmer on dark (the neon-hit rules above would flatten them) */
.jt-dark .dopamine .fw:not(.tskin).tier-rainbow .key.hit,.jt-dark .dopamine .fw:not(.tskin).mys .key.hit{background:var(--holo-grad);background-size:400% 100%;animation:holo 1s linear infinite;color:#fff;font-weight:700;border-color:transparent;border-bottom-color:rgba(0,0,0,.5);text-shadow:0 1px 2px rgba(0,0,0,.95),0 0 5px rgba(0,0,0,.7);box-shadow:0 0 12px rgba(255,80,200,.45)}
@media (prefers-reduced-motion:reduce){.jt-dark .dopamine .fw:not(.tskin).tier-rainbow .key.hit,.jt-dark .dopamine .fw:not(.tskin).mys .key.hit{animation:none}}
/* the logo's black keycap: a plain edge so it doesn't vanish into the dark page */
.jt-dark .brand::before{box-shadow:0 0 0 1px #34345a}
/* dark mode keeps the site plain; only what you press and the words you type are neon.
   The home keyboard's pressed keys and the mouse buttons light up in a neon colour */
.jt-dark .brow .key.down{background:var(--press,#1fc8ff);color:#07070d;border-color:var(--press,#1fc8ff);border-bottom-color:var(--press,#1fc8ff)}
.jt-dark .mouse .mb.down{background:#ff3dff}
/* every game gets Dopamine's dark stage: a black machine with dark-glass keycaps and bold white
   letters, rimmed in the word's colour (Dopamine's own rules above add its fever and meters) */
.jt-dark .shell .stage{--case:#000;--cap:#12121c;--cap-line:#2b2b40;--cap-edge:#000;background:var(--case);box-shadow:inset 0 0 0 1px #16161f}
.jt-dark :is(.rain .drop:not(.tskin):not(.tier-rainbow),.invade .inv:not(.tskin):not(.tier-rainbow),.wordis .brick:not(.tskin):not(.tier-rainbow)) .key{background:#0d0d16;color:#fff;font-weight:700;border-color:color-mix(in srgb,var(--acc) 75%,transparent);border-bottom-color:var(--acc);text-shadow:0 1px 2px rgba(0,0,0,.85)}
/* every word in every game carries a slight glow of its colour on the dark site: around the keycaps,
   never on the letters (typed keys glow a touch more, set above). The lowest performance level drops it */
.jt-dark :is(.rain .drop:not(.tskin),.invade .inv:not(.tskin),.wordis .brick:not(.tskin),.dopamine .fw:not(.tskin)) .key{box-shadow:0 0 12px color-mix(in srgb,var(--acc) 60%,transparent),0 0 3px color-mix(in srgb,var(--acc) 50%,transparent)}
:root[data-perf="1"].jt-dark :is(.rain .drop:not(.tskin),.invade .inv:not(.tskin),.wordis .brick:not(.tskin),.dopamine .fw:not(.tskin)) :is(.key,.key.hit){box-shadow:none}
/* phones: the nav wraps onto a second line instead of pushing the page wider than the screen */
@media (max-width:640px){.nav{flex-wrap:wrap;row-gap:2px;column-gap:var(--s3)}}
/* the nav's rainbow Buy keeps white letters in dark mode (the dark-letters rule for bright buttons skips it) */
.jt-dark #navbuy.btn.primary{color:#fff}
/* leaderboards: the box and its preset rows are simply there from the first paint; when the scores
   arrive, the names flick up very quickly from #1 down (movement only, never scaling, so text stays sharp) */
@keyframes lbin{from{opacity:0;transform:translateY(6px)}}
.lb li:not(.ghost):not(.blank){animation:lbin .18s cubic-bezier(.2,.8,.3,1) both}
.lb li:nth-child(2){animation-delay:.015s}.lb li:nth-child(3){animation-delay:.03s}.lb li:nth-child(4){animation-delay:.045s}
.lb li:nth-child(5){animation-delay:.06s}.lb li:nth-child(6){animation-delay:.075s}.lb li:nth-child(7){animation-delay:.09s}
.lb li:nth-child(8){animation-delay:.105s}.lb li:nth-child(9){animation-delay:.12s}.lb li:nth-child(10){animation-delay:.135s}
@media (prefers-reduced-motion:reduce){.lb li{animation:none!important}}
/* one footer on every page (siteFooter in juketype.js): the wrap fills the window, main takes the slack,
   so the footer is always the same distance from the bottom, and its links are evenly spaced */
.wrap{min-height:100dvh;box-sizing:border-box;display:flex;flex-direction:column;padding-bottom:0}
.wrap > main{flex:1 0 auto}
/* the footer is a band in the case colour, full window width (a shadow paints it past the wrap
   without widening the page) and running down to the bottom edge */
footer.sitefoot{margin-top:var(--s7);padding:var(--s4) 0;gap:var(--s4);justify-content:center;align-items:center;background:var(--case);box-shadow:0 0 0 100vmax var(--case);clip-path:inset(0 -100vmax -100vmax)}
footer.sitefoot a{text-decoration:none}
/* one-screen pages (main.fit: leaderboards, nametags): on desktops and laptops the page is exactly the
   window and never scrolls; main gives up the slack, so the footer sits at the very bottom, in the same
   place as on every other page that fits */
@media (min-width:1000px){
  html:has(main.fit){overflow:hidden}
  .wrap:has(> main.fit){height:100dvh}
  main.fit{flex:1 1 0;min-height:0}
  main.fit + footer.sitefoot{margin-top:2.5vh}
}
/* the homepage is one screen, no scrolling: on desktops and laptops everything on it (headline,
   subtext, keyboard, mouse, the game cards) is sized from the window's height, so the whole page
   shrinks together to fit, games included */
@media (min-width:1000px){
  main.home .open{gap:1.6vh;padding-block:var(--s4) 0}
  main.home .open h1{font-size:clamp(28px,5.4vh,58px)}
  main.home .open .lead{font-size:clamp(15px,2.2vh,20px);min-height:0}
  main.home .desk{gap:2vh}
  main.home .deck{padding:1.8vh;gap:1.6vh}
  main.home .desk .board{font-size:clamp(10px,1.5vh,22px)}
  main.home .mouse{font-size:clamp(9px,1.5vh,22px)}
  main.home .mousepad{padding:0 1.8vh}
  main.home #games{margin-top:3vh}
  main.home #games > h2{font-size:clamp(20px,3vh,32px);margin-bottom:1.6vh}
  main.home .games{gap:3vh}
  main.home #games{width:max(var(--deskw,100%),820px);max-width:100%;margin-left:auto;margin-right:auto} /* as wide as the keyboard and mouse above, but never so narrow the previews crowd */
  main.home .games{flex-wrap:nowrap}
  main.home .gcard{flex:1 1 0;width:auto;min-width:250px;gap:1vh}
  /* the scenes place fixed-size keycaps by percent, so the box keeps enough room for them: below
     about 96px tall or 250px wide the words run into each other */
  main.home .gcard .gprev{height:clamp(96px,13vh,120px)}
  main.home .gcard h2{font-size:clamp(11px,2.1vh,17px)}
  main.home .gcard p{font-size:clamp(13px,1.8vh,16px)}
  main.home + footer.sitefoot{margin-top:3vh}
}
@media (min-width:1000px) and (max-height:900px){main.home .gcard p{display:none}} /* short windows: the previews say enough */
@media (min-width:1000px) and (max-height:720px){main.home .gcard .best{display:none}main.home .open{padding-top:var(--s2)}} /* very short windows */
/* every page opens the same way, so moving between them is seamless: the title block starts at the
   same height (overriding each page's own padding or centring), the title is the same size, and the
   subtext sits under it in the same grey */
main > .open:first-child{padding-top:var(--s4);justify-content:flex-start}
.open > .lead{font-size:20px;color:var(--mute);margin:0}
/* short windows (a 150%-scaled laptop is about 680px tall inside the browser): every page tightens the
   same shared chrome the same way, so titles still line up from page to page and the one-screen pages fit */
@media (max-height:760px){
  .wrap{padding-top:var(--s3)}
  main > .open:first-child{padding-top:var(--s3)}
  .open{gap:var(--s3)}
  footer.sitefoot{padding:var(--s3) 0}
}
/* ---- game previews keep their proportions at any size: the scenes place things by percent, so the
   keycaps, ship, bars and meter scale with the box too, by --u: 1% of the height, capped by the width near the
   design's shape (120px tall, ~280px wide), so a taller box only adds room, never bigger keys. The home page shrinks the boxes to fit short windows, and with
   fixed-size keys the rows ran into each other ---- */
.gprev{container-type:size;--u:min(1cqh,.7cqw)} /* one unit: 1% of the height, but never more than the width allows, so a tall scene keeps three-letter words clear of each other */
.gprev .pcaps{gap:calc(1.7 * var(--u))}
.gprev .ntag{font-size:calc(10 * var(--u))} /* the words in nametags: big enough to read at a glance */
/* a short scene (the homepage's): the words at their old size, and the extra words (.pextra) left out, so nothing crowds */
@container (max-height:180px){.gprev .ntag{font-size:calc(8.5 * var(--u))}.gprev .pextra{display:none}}
.gprev .ntag .key{box-shadow:none} /* preview words drawn in nametags */
.gprev .ptag{width:max-content} /* hug the tag, so a word's bar and its centre match the word */
/* the games tab with singleplayer only (multiplayer off): the row of games sits halfway between the title
   and the footer, as wide as the navbar above it (never past its edges), with tall scenes */
@media (min-width:1000px){
  /* the row fills the space between the subtitle and the footer: the scenes grow tall (up to about square),
     and anything left over is shared above and below, so the games sit centred in it */
  main.ghub.solo > .gwrap{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;justify-content:center;margin:2.5vh 0 0}
  main.ghub.solo > .gwrap > .games{flex:1 1 auto;min-height:0;max-height:600px;align-items:stretch}
  main.ghub.solo .gcard{min-height:0;justify-content:center}
  main.ghub.solo .gcard .gprev{flex:1 1 auto;height:auto;min-height:130px;max-height:362px}
}
.gprev .pk{min-width:calc(15 * var(--u));height:calc(16.7 * var(--u));padding:0 calc(2.5 * var(--u));font-size:calc(9.6 * var(--u));border-radius:calc(3.3 * var(--u));border-bottom-width:calc(1.7 * var(--u))}
.gprev .pcaps.mys::after{top:calc(-5.8 * var(--u));right:calc(-6.7 * var(--u));width:calc(10.8 * var(--u));height:calc(10.8 * var(--u));font-size:calc(7.5 * var(--u))}
.pv-dopamine .plife{bottom:calc(-5 * var(--u));height:calc(2.5 * var(--u))}
.pv-invade .pship{border-left-width:calc(6.7 * var(--u));border-right-width:calc(6.7 * var(--u));border-bottom-width:calc(10 * var(--u))}
.pv-dopamine .pplus{font-size:calc(10 * var(--u))}
/* ---- leaderboard boxes: equal lengths and pages ----
   Every row is the same height whatever is in it (a tag's rank key, wave lettering, a plain name), and
   short lists are padded with blank rows, so all the boxes on a page come out the same length. Your own
   row is marked, and under each list a small navigator moves ten at a time (‹ 1 2 … 48 ›) */
.lb li{height:22px;flex:none}
.lbzone .lb li{height:30px}
.lb li.blank::before{content:none}
.lb li.me{margin:0 -6px;padding:0 6px;border-radius:6px;background:color-mix(in srgb,var(--acc,#1a56e8) 13%,transparent)}
.lb li.me .nm::after{content:' · you';font-weight:500;color:var(--mute);-webkit-text-fill-color:var(--mute)}
.lbpages{display:flex;justify-content:center;align-items:center;gap:4px;margin-top:4px}
.lbpages.one{visibility:hidden}
.lbpg{display:grid;place-items:center;min-width:22px;height:22px;padding:0 6px;border-radius:5px;background:var(--cap);border:1px solid var(--cap-line);border-bottom:2px solid var(--cap-edge);font:inherit;font-size:11px;font-weight:700;color:var(--ink);cursor:pointer;transition:transform .06s}
.lbpg:active:not(:disabled){transform:translateY(1px)}
.lbpg.on{background:var(--acc,#1b1b1f);color:#fff;border-color:transparent;border-bottom-color:color-mix(in srgb,var(--acc,#1b1b1f) 65%,#000);cursor:default}
.lbpg.mine:not(.on){box-shadow:inset 0 0 0 1.5px var(--acc,#1a56e8)}
.lbpg.step{font-size:13px}
.lbpg:disabled{opacity:.35;cursor:default}
.lbgap{font-size:11px;color:var(--mute);padding:0 1px}
.lbzone .lbpg{min-width:28px;height:28px;font-size:13px}
/* the one-screen leaderboards page sizes everything from the window height, rows and navigator included */
@media (min-width:1000px){
  #boards .lb li{height:clamp(14px,2.05vh,22px)}
  #boards .lbpages{margin-top:.3vh;gap:.4vh}
  #boards .lbpg{min-width:clamp(14px,2vh,22px);height:clamp(14px,2vh,22px);font-size:clamp(8px,1.1vh,11px);padding:0 .5vh}
}
/* the preset rows a board shows before it arrives: its rank keys, faint, and two quiet bars */
.lb li.ghost::before{opacity:.35}
.lbpages.ghost .lbpg{opacity:.35;cursor:default} /* and the navigator under them, just as faint */
.lb li.ghost .gbar{flex:1;height:7px;border-radius:4px;background:color-mix(in srgb,var(--cap-edge) 55%,transparent)}
.lb li.ghost .gbar.gsc{flex:none;width:34px}
.lb li.ghost:nth-child(3n) .gbar:first-of-type{flex:.7}
.lb li.ghost:nth-child(3n+1) .gbar:first-of-type{flex:.85}

/* ---- every word wears the nametag of its rarity (applyTier in juketype.js adds .tskin and the tag's
   classes; nametags.css draws the skin). A word arrives as an outline: plain keys ringed in its colour,
   its letters in that colour. Each letter you type fills in with the skin itself, shimmering, and pops,
   so the word colours in as you go ---- */
.tskin .key{position:relative}
.tskin.tskin.tskin .key:not(.hit){background:var(--cap);background-image:none;color:color-mix(in srgb,var(--acc) 75%,#000);font-weight:700;text-shadow:none;filter:none;border:1px solid var(--cap-line);border-bottom:.12em solid var(--cap-edge);box-shadow:inset 0 0 0 2px var(--acc);animation:none}
.tskin.tskin.tskin .key:not(.hit)::after,.tskin.tskin.tskin .key.hit::after{display:none}
/* typed: the skin shows through, and the key springs up and lands with a ring in its colour bursting out */
.tskin.tskin.tskin .key.hit{transform:translateY(.1em);box-shadow:0 0 14px color-mix(in srgb,var(--acc) 55%,transparent);animation:keyhit .26s cubic-bezier(.2,1.6,.4,1),holo var(--sp,3s) linear infinite}
.tskin.tskin.tskin .key.hit::before{content:'';position:absolute;inset:-3px;border-radius:.32em;border:2px solid var(--acc);opacity:0;pointer-events:none;animation:keyring .4s ease-out}
@keyframes keyhit{0%{transform:translateY(.1em) scale(1)}35%{transform:translateY(-.24em) scale(1.24);filter:brightness(1.55)}100%{transform:translateY(.1em) scale(1);filter:none}}
@keyframes keyring{0%{opacity:.95;transform:scale(.85)}100%{opacity:0;transform:scale(1.75)}}
/* rainbow and mystery words: outlined in hot pink; each typed letter fills with a clean neon rainbow (never
   the muddy prism) and its glow runs through the spectrum */
.tskin.tskin.tskin:is(.tier-rainbow,.mys) .key:not(.hit){color:#b0186f;box-shadow:inset 0 0 0 2px #e0379a,0 0 10px rgba(224,55,154,.35)}
.tskin.tskin.tskin:is(.tier-rainbow,.mys) .key.hit{background:linear-gradient(100deg,#ff2d75,#ffb81a,#2bff88,#1fe0ff,#4d7dff,#d43dff,#ff2d75);background-size:400% 100%;border:0;border-bottom:.14em solid rgba(0,0,0,.45);color:#fff;font-weight:700;text-shadow:0 1px 2px rgba(0,0,0,.9),0 0 5px rgba(0,0,0,.55);animation:keyhit .26s cubic-bezier(.2,1.6,.4,1),holo 1.1s linear infinite,rbglow 1.6s linear infinite}
.tskin.tskin.tskin:is(.tier-rainbow,.mys) .key.hit::before{border-color:#ff3dff}
@keyframes rbglow{0%,100%{box-shadow:0 0 18px rgba(255,45,117,.9),0 0 42px rgba(255,45,117,.35)}25%{box-shadow:0 0 18px rgba(255,184,26,.9),0 0 42px rgba(255,184,26,.35)}50%{box-shadow:0 0 18px rgba(43,255,136,.9),0 0 42px rgba(43,255,136,.35)}75%{box-shadow:0 0 18px rgba(31,224,255,.9),0 0 42px rgba(212,61,255,.4)}}
/* dark mode: the outlines are dark keys with neon rings and neon letters, and a typed letter blazes */
.jt-dark .tskin.tskin.tskin .key:not(.hit){background:#0d0d16;color:var(--acc);border-color:color-mix(in srgb,var(--acc) 35%,transparent);border-bottom-color:#000;box-shadow:inset 0 0 0 2px var(--acc),0 0 10px color-mix(in srgb,var(--acc) 45%,transparent)}
.jt-dark .tskin.tskin.tskin .key.hit{box-shadow:0 0 22px var(--acc),0 0 6px var(--acc)}
.jt-dark .tskin.tskin.tskin .key.hit::before{box-shadow:0 0 10px var(--acc)}
.jt-dark .tskin.tskin.tskin:is(.tier-rainbow,.mys) .key:not(.hit){color:#ff6ad5;box-shadow:inset 0 0 0 2px #ff3dff,0 0 14px rgba(255,61,255,.5)}
@media (prefers-reduced-motion:reduce){.tskin.tskin.tskin .key.hit,.tskin.tskin.tskin:is(.tier-rainbow,.mys) .key.hit{animation:none}.tskin.tskin.tskin .key.hit::before{display:none}}
/* the performance slider's lowest level holds the glow and the rainbow still */
:root[data-perf="1"] .tskin.tskin.tskin :is(.key,.key.hit){box-shadow:none}
:root[data-perf="1"] .tskin.tskin.tskin:is(.tier-rainbow,.mys) .key.hit{animation:none}
/* the flash when a word is cleared: on the dark site a full white flash is blinding, so it is a faint glow in the word's colour */
.jt-dark .flash{background:color-mix(in srgb,var(--acc,#fff) 40%,#fff)}
.jt-dark .flash.on{animation:flashdim .22s}
@keyframes flashdim{0%{opacity:.12}100%{opacity:0}}
