/* ตุ๊กไทป์ · TukType — design tokens lifted from TukType.dc.html */
:root{
  --bg:#0B0E12;
  --panel:#11151B;
  --raised:#171C24;
  --key:#1F2630;
  --line:#232B36;
  --line-2:#323B49;
  --mute:#2A3340;
  /* Contrast-checked against --bg and --panel. --dim carries small labels, so it
     needs WCAG AA 4.5:1; --dim-2 is the not-yet-typed prompt text, which is
     large (24px+) and only needs 3:1 — but it was at 2.33:1, i.e. genuinely hard
     to read the characters you are about to type. */
  --dim-2:#646E80;   /* 3.76:1 on bg */
  --dim-3:#5B6577;
  --dim:#828C9E;     /* 5.70:1 on bg, 4.49:1 on a keycap */
  --sub:#A6AEBC;
  --text:#E9EDF3;
  --lime:#C8F75A;
  --sky:#7DD3FC;
  --green:#4ADE80;
  --red:#F87171;
  --violet:#A78BFA;

  --th:'IBM Plex Sans Thai',system-ui,sans-serif;
  --en:'IBM Plex Sans',system-ui,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,Menlo,monospace;
  --display:'Space Grotesk',system-ui,sans-serif;
  --loop:'Noto Sans Thai Looped','IBM Plex Sans',sans-serif;

  --glow:0 0 0 1px var(--lime),0 0 28px rgba(200,247,90,.18);
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;background:var(--bg);color:var(--text);
  font-family:var(--th);
  -webkit-font-smoothing:antialiased;
}
button{font:inherit;color:inherit;background:none;border:none;padding:0;cursor:pointer}
input{font:inherit}
a{color:inherit;text-decoration:none}

/* ---------- animations ---------- */
@keyframes tt-blip{0%{box-shadow:0 0 0 0 rgba(200,247,90,.45)}60%{box-shadow:0 0 0 10px rgba(200,247,90,0)}100%{box-shadow:0 0 0 0 rgba(200,247,90,0)}}
@keyframes tt-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
@keyframes tt-pop{from{transform:scale(.9);opacity:0}to{transform:scale(1);opacity:1}}
@keyframes tt-rise{from{transform:translateY(6px);opacity:0}to{transform:translateY(0);opacity:1}}
@keyframes tt-float{from{transform:translate(-50%,0);opacity:1}to{transform:translate(-50%,-46px);opacity:0}}

/* ---------- shell ---------- */
.shell{min-height:100%;display:flex;flex-direction:column}
.wrap{width:100%;max-width:1280px;margin:0 auto;padding:24px}
.view{animation:tt-rise .22s ease-out}

.topbar{
  display:flex;align-items:center;justify-content:space-between;
  height:56px;padding:0 20px;background:var(--panel);
  border-bottom:1px solid var(--line);position:sticky;top:0;z-index:20;
}
.brand{display:flex;align-items:center;gap:10px}
.brand-mark{
  width:28px;height:28px;border-radius:7px;background:var(--lime);color:var(--bg);
  display:grid;place-items:center;font:700 15px/1 var(--th);
}
.brand-name{font:500 15px/1 var(--th);letter-spacing:-.01em}
.brand-sub{font:500 9.5px/1 var(--mono);letter-spacing:.14em;color:var(--dim);margin-top:3px}
.nav{display:flex;gap:4px}
.nav a{
  padding:7px 14px;border-radius:999px;font:500 12.5px/1 var(--th);color:var(--sub);
  transition:background .15s,color .15s;
}
.nav a .en{color:var(--dim-2);font-size:11px}
.nav a:hover{color:var(--text)}
.nav a.on{background:var(--key);color:var(--text)}
.nav a.on .en{color:var(--dim)}
.topbar-right{display:flex;align-items:center;gap:14px}
.streak-pill{display:flex;align-items:center;gap:7px;padding:6px 12px;border-radius:999px;border:1px solid var(--line-2)}
.avatar{width:28px;height:28px;border-radius:50%;background:var(--mute);display:grid;place-items:center;font:500 11px/1 var(--th);color:var(--sub)}

.blip{width:7px;height:7px;border-radius:50%;background:var(--lime);animation:tt-blip 2.4s infinite;flex:none}

/* Off-screen until focused — the first tab stop on the page. */
.skip-link{
  position:absolute;left:-9999px;top:0;z-index:100;
  padding:12px 18px;border-radius:0 0 8px 0;background:var(--lime);color:var(--bg);
  font:600 13px/1 var(--th);
}
.skip-link:focus{left:0}
.view:focus{outline:none}

/* A visible focus ring everywhere the keyboard can land. The typing stage draws
   its own affordance (the glowing prompt card), so it opts out. */
:focus-visible{outline:2px solid var(--lime);outline-offset:2px;border-radius:4px}
.stage:focus-visible,.field:focus-visible,.lyr-wrap:focus-visible{outline:none}

/* ---------- primitives ---------- */
.card{padding:18px;border-radius:8px;background:var(--panel);border:1px solid var(--line)}
.card-hero{padding:24px;border-radius:10px;background:var(--raised);box-shadow:var(--glow)}
.eyebrow{font:500 10.5px/1 var(--mono);letter-spacing:.14em;color:var(--dim);text-transform:uppercase}
.muted{color:var(--sub)}
.dim{color:var(--dim)}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
.stack{display:flex;flex-direction:column}
.row{display:flex;align-items:center}
.spread{display:flex;align-items:center;justify-content:space-between}
.grow{flex:1}

.btn{
  padding:12px 24px;border-radius:8px;background:var(--lime);color:var(--bg);
  font:600 14px/1 var(--th);transition:filter .15s,transform .05s;
}
.btn:hover{filter:brightness(1.08)}
.btn:active{transform:translateY(1px)}
.btn-ghost{
  padding:10px 18px;border-radius:8px;border:1px solid var(--line-2);
  font:500 12.5px/1 var(--th);color:var(--sub);background:none;
}
.btn-ghost:hover{border-color:var(--dim);color:var(--text)}
.btn-soft{padding:10px 18px;border-radius:8px;background:var(--key);font:500 12.5px/1 var(--th);color:var(--text)}
.btn-soft:hover{background:var(--mute)}
.btn[disabled],.btn-ghost[disabled]{opacity:.45;cursor:not-allowed}

.bar{height:8px;border-radius:999px;background:var(--key);overflow:hidden}
.bar > i{display:block;height:100%;border-radius:999px;background:var(--lime);transition:width .25s ease}
.bar.sky > i{background:var(--sky)}

.kv{display:flex;justify-content:space-between;padding:11px 0;border-bottom:1px solid var(--line);font:400 12.5px/1.2 var(--th);color:var(--sub)}
.kv:last-child{border-bottom:none}

.toggle{width:38px;height:22px;border-radius:999px;background:var(--key);display:flex;align-items:center;padding:0 3px;transition:background .15s}
.toggle > i{display:block;width:16px;height:16px;border-radius:50%;background:var(--dim);transition:transform .15s,background .15s}
.toggle.on{background:var(--lime)}
.toggle.on > i{background:var(--bg);transform:translateX(16px)}

.chip{padding:5px 9px;border-radius:5px;background:var(--key);border:1px solid var(--line-2);font:500 13px/1 var(--mono);color:var(--sub)}
.chip.bad{background:rgba(248,113,113,.10);border-color:rgba(248,113,113,.35);color:var(--red);font:600 14px/1 var(--loop)}

.note{padding:10px 14px;border-radius:6px;background:rgba(200,247,90,.10);font:400 12px/1.45 var(--th);color:var(--text)}

/* ---------- mascot (ตุ๊ก) ---------- */
.tuk{position:relative;background:var(--lime);border-radius:16px;flex:none;animation:tt-bob 3.2s ease-in-out infinite}
.tuk i{position:absolute;background:var(--bg);display:block;transition:height .12s,border-radius .12s,transform .12s}
.tuk .eye{border-radius:5px}
.tuk .mouth{border-radius:0 0 10px 10px}
.tuk.happy{animation-duration:1.4s}

/* ---------- home ---------- */
.home-grid{display:grid;grid-template-columns:1fr 320px;gap:20px;align-items:start}
.score-big{font:500 64px/1 var(--display);letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.spark{display:flex;align-items:flex-end;gap:5px;height:78px}
.spark > i{display:block;width:16px;background:var(--mute);border-radius:2px}
.spark > i.hot{background:var(--lime)}
.lang-cols{display:grid;grid-template-columns:1fr 1fr;gap:24px}
.stat-n{font:500 22px/1 var(--mono);font-variant-numeric:tabular-nums}
.stat-l{font:400 10.5px/1.3 var(--th);color:var(--dim);margin-top:3px}
.tiles{display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px}
.dial{width:64px;height:64px;border-radius:50%;display:grid;place-items:center}
.dial > i{width:48px;height:48px;border-radius:50%;background:var(--panel);display:grid;place-items:center;font:500 15px/1 var(--mono);color:var(--text);font-style:normal}
.dots{display:flex;align-items:flex-end;gap:6px}
.dots > i{width:10px;height:10px;border-radius:3px;background:var(--lime)}
.dots > i.off{background:none;border:1px dashed var(--dim-3)}
.continue{
  display:flex;align-items:center;gap:20px;padding:20px 24px;border-radius:10px;
  background:linear-gradient(90deg,var(--raised) 0%,var(--panel) 100%);border:1px solid var(--line);
}
.quick{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;border-radius:6px;background:var(--key);width:100%;text-align:left;transition:background .15s}
.quick:hover{background:var(--mute)}

.dense-head{display:flex;align-items:stretch;border-bottom:1px solid var(--line);background:var(--panel)}
.dense-cells{flex:1;display:grid;grid-template-columns:repeat(4,1fr)}
.dense-body{display:grid;grid-template-columns:1fr 1px 1fr}
.hbars{display:flex;align-items:flex-end;gap:4px;height:96px;margin-top:20px}
.hbars > i{flex:1;background:var(--mute);min-height:2px}

/* ---------- practice ---------- */
.stage{outline:none;padding:26px 30px 30px;display:flex;flex-direction:column;gap:20px}
.segmented{display:flex;padding:3px;border-radius:999px;background:var(--panel);border:1px solid var(--line)}
.segmented button{padding:7px 16px;border-radius:999px;font:600 12.5px/1 var(--th);color:var(--sub);transition:background .15s,color .15s}
.segmented button.on{background:var(--lime);color:var(--bg)}
.hud{display:flex;align-items:center;gap:26px}
.hud-n{font:500 26px/1 var(--mono);font-variant-numeric:tabular-nums}
.hud-l{font:400 10px/1 var(--mono);letter-spacing:.12em;color:var(--dim);margin-top:5px}

.prompt-card{padding:34px 36px;border-radius:10px;background:var(--raised);box-shadow:var(--glow)}
.prompt{
  font:400 40px/1.7 var(--loop);letter-spacing:.01em;word-break:break-word;
  min-height:68px;
}
.prompt.en{font-family:var(--en);font-size:36px}
.prompt .cl{border-radius:3px;padding:1px 0;color:var(--dim-2);transition:color .06s}
.prompt .cl.done{color:var(--lime)}
.prompt .cl.cur{color:var(--text);box-shadow:inset 0 -3px 0 var(--lime)}
.prompt .cl.bad{color:var(--bg);background:var(--red)}
.track{flex:1;height:4px;border-radius:999px;background:var(--key);position:relative}
.track > .fill{position:absolute;left:0;top:0;height:100%;border-radius:999px;background:var(--lime);width:0}
.track > .ghost{position:absolute;top:-4px;left:0;width:2px;height:12px;background:var(--dim)}

.kb{display:flex;flex-direction:column;gap:6px;align-items:center}
.kb-row{display:flex;gap:6px}
.keycap{
  width:56px;height:58px;border-radius:6px;background:var(--key);
  border:1px solid var(--line-2);border-bottom:2px solid var(--line-2);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;
  transition:background .09s,border-color .09s,box-shadow .09s,transform .09s;
}
.keycap .glyph{font:600 24px/1 var(--loop);color:var(--text)}
/* The mono face runs wider than the Thai looped face, so latin caps sit a
   little smaller to keep the same optical size inside the same 56px cap. */
.kb.en .keycap .glyph{font-family:var(--mono);font-size:20px}
.keycap .sub{font:400 11px/1 var(--mono);color:var(--dim)}
.keycap.hot{background:var(--lime);border-color:var(--lime);box-shadow:0 0 18px rgba(200,247,90,.45);transform:translateY(1px)}
.keycap.hot .glyph,.keycap.hot .sub{color:var(--bg)}
.keycap.shifted{border-bottom-color:var(--violet)}
.keycap.weak{background:rgba(248,113,113,.14);border-color:rgba(248,113,113,.45)}
.keycap.weak .glyph{color:var(--red)}
.keycap.wide{width:118px;display:grid;place-items:center;font:400 10px/1 var(--mono);color:var(--dim)}
.keycap.space{width:430px;display:grid;place-items:center;font:400 10px/1 var(--mono);color:var(--dim);border-bottom-color:var(--green)}
.keycap.wide.hot,.keycap.space.hot{color:var(--bg)}

/* ---------- hands ---------- */
.kb-area{display:flex;align-items:center;justify-content:center;gap:18px;flex-wrap:wrap}
.hands-caption{
  margin-top:16px;padding-top:14px;border-top:1px solid var(--line);text-align:center;
}
/* Inside a teaching card the rule reads as a stray divider — the card already
   has its own edges. */
.tip-visual .hands-caption{border-top:none;padding-top:0;margin-top:10px;min-height:32px}
.hand{width:132px;height:150px;overflow:visible;opacity:.55;transition:opacity .18s;flex:none}
.hand.active{opacity:1}
.palm{fill:var(--key);stroke:var(--line-2);stroke-width:1.5}
.finger{
  fill:var(--key);stroke:var(--line-2);stroke-width:1.5;
  transition:fill .12s ease,transform .12s ease;
  transform-box:fill-box;transform-origin:50% 100%;
}
.finger.next{stroke:none;filter:drop-shadow(0 0 10px rgba(200,247,90,.45))}
.finger.shift{fill:var(--violet);stroke:none;filter:drop-shadow(0 0 8px rgba(167,139,250,.45))}
.finger.press{animation:tt-tap .16s ease-out}
.finger.miss{animation:tt-tap-miss .22s ease-out}
@keyframes tt-tap{0%{transform:translateY(0) scaleY(1)}45%{transform:translateY(7px) scaleY(.9)}100%{transform:translateY(0) scaleY(1)}}
@keyframes tt-tap-miss{0%{transform:translateY(0)}30%{transform:translateY(7px)}100%{transform:translateY(0)}}
.finger.miss{fill:var(--red) !important}

/* Too narrow to flank: the keyboard takes the full row and the hands drop
   beneath it, still side by side rather than stacked. */
@media (max-width:1200px){
  .kb-area > .kb{order:-1;flex-basis:100%}
  .kb-area{gap:16px 40px}
}

@media (prefers-reduced-motion:reduce){
  .finger.press,.finger.miss{animation:none}
  .tuk,.blip,.word{animation:none !important}
}

.overlay{
  position:absolute;inset:0;display:grid;place-items:center;
  background:rgba(11,14,18,.72);backdrop-filter:blur(2px);border-radius:10px;z-index:5;
}
.overlay .msg{text-align:center;font:500 14px/1.5 var(--th);color:var(--sub)}

/* ---------- journey ---------- */
.lanes{position:relative}
.lane-line{position:absolute;left:0;right:0;height:2px;background:var(--line)}
.lane-grid{position:relative;display:grid;gap:16px}
.node{
  border-radius:50%;display:grid;place-items:center;position:relative;
  transition:transform .15s,box-shadow .15s;
}
.node.big{width:58px;height:58px;font:700 22px/1 var(--loop)}
.node.sm{width:52px;height:52px;font:600 18px/1 var(--mono)}
.node.done{background:var(--lime);color:var(--bg)}
.node.done.en{background:var(--sky)}
.node.cur{width:70px;height:70px;background:var(--raised);border:2px solid var(--lime);color:var(--lime);font:700 26px/1 var(--loop);box-shadow:0 0 30px rgba(200,247,90,.3)}
.node.cur.en{border-color:var(--sky);color:var(--sky);box-shadow:0 0 30px rgba(125,211,252,.3)}
.node.next{background:var(--key);border:1px solid var(--line-2);color:var(--dim);font:500 15px/1 var(--mono)}
.node.lock{background:var(--key);border:1px dashed var(--dim-3);color:var(--dim-3)}
.node.click{cursor:pointer}
.node.click:hover{transform:translateY(-2px)}
.node .badge{
  position:absolute;bottom:-6px;right:-6px;width:24px;height:24px;border-radius:50%;
  background:var(--lime);color:var(--bg);display:grid;place-items:center;font:600 10px/1 var(--mono);
}
.boss{
  border-radius:12px;background:linear-gradient(180deg,rgba(167,139,250,.16),var(--raised));
  border:1px solid var(--violet);display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:12px;padding:16px;text-align:center;
}

/* ---------- arcade ---------- */
.field{position:relative;height:430px;overflow:hidden;background:radial-gradient(120% 80% at 50% 0%,#141A22 0%,var(--bg) 70%)}
.field::before{content:"";position:absolute;inset:0;background:repeating-linear-gradient(90deg,rgba(255,255,255,.025) 0 1px,transparent 1px 64px)}
.word{position:absolute;top:0;transform:translateY(-60px)}
.word > span{
  display:block;padding:9px 16px;border-radius:8px;background:var(--raised);
  border:1px solid var(--line-2);font:600 22px/1 var(--loop);white-space:nowrap;
}
.word.en > span{font:500 20px/1 var(--mono);color:var(--sky)}
.word.active > span{
  background:rgba(200,247,90,.14);border-color:var(--lime);color:var(--lime);
  box-shadow:0 0 24px rgba(200,247,90,.3);
}
.deadline{position:absolute;left:0;right:0;bottom:96px;height:2px;background:linear-gradient(90deg,transparent,rgba(248,113,113,.7),transparent)}
.dock{position:absolute;left:0;right:0;bottom:0;height:96px;display:flex;align-items:center;justify-content:center;gap:20px}
.buffer{
  min-width:340px;padding:14px 18px;border-radius:10px;background:var(--panel);
  border:1px solid var(--lime);font:600 24px/1 var(--loop);display:flex;align-items:center;gap:2px;
}
.caret{width:2px;height:26px;background:var(--lime);margin-left:4px}
.pop{position:absolute;transform:translate(-50%,0);font:600 14px/1 var(--mono);color:var(--lime);animation:tt-float .8s ease-out forwards;pointer-events:none}
.lives{display:flex;gap:5px}
.lives > i{width:9px;height:9px;border-radius:50%;background:var(--lime)}
.lives > i.off{background:var(--mute)}

/* ---------- lyrics ---------- */
.lyr-wrap{background:radial-gradient(90% 120% at 50% 120%,#1A2130 0%,var(--bg) 65%)}
.lyr-body{padding:56px 30px 30px;display:flex;flex-direction:column;align-items:center;gap:30px}
.lyr-prev{font:400 22px/1.5 var(--loop);color:var(--dim-2);text-align:center}
.lyr-next{font:400 22px/1.5 var(--loop);color:var(--mute);text-align:center}
.lyr-cur{font:400 46px/1.55 var(--loop);text-align:center;max-width:1000px}
.lyr-cur.en{font-family:var(--en);font-size:38px}
.lyr-cur .cl{color:var(--dim-2)}
.lyr-cur .cl.done{color:var(--lime)}
.lyr-cur .cl.cur{color:var(--text);box-shadow:inset 0 -4px 0 var(--lime)}
.lyr-cur .cl.bad{color:var(--bg);background:var(--red);border-radius:3px}
.eq{display:flex;align-items:flex-end;gap:3px;height:26px}
.eq > i{width:4px;background:var(--lime);transition:height .12s}

/* ---------- results ---------- */
.res-grid{display:grid;grid-template-columns:1fr 340px;gap:22px;align-items:start}
.wpm-chart{margin-top:24px;height:120px;display:flex;align-items:flex-end;gap:3px;position:relative;border-bottom:1px solid var(--line)}
.wpm-chart > i{flex:1;background:var(--lime);min-height:2px}
.wpm-chart > i.err{background:var(--red)}
.ghostline{position:absolute;left:0;right:0;height:1px;background:repeating-linear-gradient(90deg,var(--dim-3) 0 6px,transparent 6px 12px)}

/* ---------- onboarding ---------- */
.steps{padding:26px 30px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:14px}
.step{display:flex;align-items:center;gap:8px}
.step .n{width:22px;height:22px;border-radius:50%;background:var(--raised);border:1px solid var(--line-2);color:var(--dim);display:grid;place-items:center;font:600 11px/1 var(--mono)}
.step.on .n{background:var(--raised);border-color:var(--lime);color:var(--lime)}
.step.past .n{background:var(--lime);border-color:var(--lime);color:var(--bg)}
.step span{font:500 12.5px/1 var(--th);color:var(--dim)}
.step.on span{font-weight:600;color:var(--lime)}
.step.past span{color:var(--text)}
.step-line{flex:1;height:1px;background:var(--line)}
.step-line.past{background:var(--lime)}
.pick{
  display:flex;align-items:center;justify-content:space-between;width:100%;text-align:left;
  padding:14px 16px;border-radius:8px;background:var(--key);border:1px solid var(--line-2);
  transition:border-color .15s,background .15s;
}
.pick:hover{border-color:var(--dim)}
.pick.on{background:rgba(200,247,90,.10);border-color:var(--lime)}
.pick .tick{width:20px;height:20px;border-radius:50%;background:var(--lime);color:var(--bg);display:grid;place-items:center;font:600 11px/1 sans-serif}
.pick.soft{background:var(--panel);border-style:dashed}

/* ---------- stats ---------- */
.heat{display:grid;grid-template-columns:repeat(auto-fill,minmax(46px,1fr));gap:6px}
.heat-cell{padding:8px 4px;border-radius:6px;background:var(--key);border:1px solid var(--line-2);text-align:center}
.heat-cell .g{font:600 18px/1 var(--loop)}
.heat-cell .p{font:400 9.5px/1 var(--mono);color:var(--dim);margin-top:6px}

/* ---------- stars ---------- */
.stars{display:inline-flex;gap:3px;line-height:1}
.stars .star{color:var(--mute);transition:color .2s,transform .2s}
.stars .star.on{color:var(--lime);text-shadow:0 0 10px rgba(200,247,90,.45)}
/* Earned stars pop in one after another on the results screen. */
.stars.reveal .star.on{animation:tt-star .32s cubic-bezier(.2,1.4,.4,1) backwards}
.stars.reveal .star.on:nth-child(1){animation-delay:.05s}
.stars.reveal .star.on:nth-child(2){animation-delay:.15s}
.stars.reveal .star.on:nth-child(3){animation-delay:.25s}
.stars.reveal .star.on:nth-child(4){animation-delay:.35s}
.stars.reveal .star.on:nth-child(5){animation-delay:.45s}
@keyframes tt-star{from{transform:scale(.2) rotate(-25deg);opacity:0}to{transform:scale(1) rotate(0);opacity:1}}
.node .node-stars{
  position:absolute;bottom:-13px;left:50%;transform:translateX(-50%);
  font-size:9px;white-space:nowrap;
}
@media (prefers-reduced-motion:reduce){ .stars.reveal .star.on{animation:none} }

/* ---------- ad slots ---------- */
/* Height is reserved inline by ads.js so a late-arriving ad cannot push the
   page around. The slot is visually quiet — it should read as clearly separate
   from the app's own surfaces, never as a card the user might act on. */
.ad-slot{
  margin:20px auto 0;width:100%;max-width:970px;
  display:flex;flex-direction:column;align-items:center;gap:8px;
}
.ad-label{
  font:400 9.5px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim-2);align-self:flex-start;
}
.ad-slot .adsbygoogle{width:100%}
.ad-ghost{
  width:100%;display:grid;place-items:center;border-radius:8px;
  border:1px dashed var(--line-2);background:rgba(255,255,255,.015);
  font:400 11px/1 var(--mono);color:var(--dim-2);
}

.toast{
  position:fixed;left:50%;bottom:28px;transform:translateX(-50%);z-index:60;
  padding:12px 20px;border-radius:8px;background:var(--raised);border:1px solid var(--lime);
  font:500 13px/1 var(--th);animation:tt-pop .2s ease-out;
}

@media (max-width:1100px){
  .home-grid,.res-grid{grid-template-columns:1fr}
  .keycap{width:44px;height:48px}
  .keycap .glyph{font-size:18px}
  .kb.en .keycap .glyph{font-size:15px}
  .keycap .sub{font-size:9.5px}
  .keycap.space{width:320px}
  .keycap.wide{width:88px}
  .prompt{font-size:32px}
}
