/* typing.css - Typing Club (all rules start with ty- so nothing else is touched) */
.ty-stage{position:relative;width:min(100%,1100px);flex:1 1 auto;min-height:0;height:calc(100vh - 96px);max-height:calc(100vh - 96px);border-radius:16px;overflow:hidden;
  background:#15163a;box-shadow:0 0 0 4px #3a3e8a,0 14px 30px rgba(0,0,0,.4);--u:8px;margin:4px 0}
.ty-stage .overlay-root{z-index:50}
.ty-root{position:absolute;inset:0;overflow:auto;display:flex;flex-direction:column}
.ty-root>*{margin:auto 0;min-height:0}
.ty-root .ty-play{margin:0;flex:1 1 auto}

/* ---------- home ---------- */
.ty-home,.ty-map,.ty-report{display:flex;flex-direction:column;align-items:center;gap:14px;padding:18px 20px;text-align:center;width:100%}
.ty-title{font-size:clamp(1.8rem,5vw,3rem);font-weight:bold;color:var(--accent);text-shadow:0 3px 0 #0c0d26}
.ty-setup{display:flex;flex-wrap:wrap;gap:12px;justify-content:center;align-items:center}
.ty-years{display:flex;gap:8px;align-items:center;font-weight:bold}
.ty-years .yr{min-width:2.6em;font-size:1.3rem}
.ty-name{font:inherit;font-size:1.1rem;padding:.5em .8em;border-radius:14px;border:3px solid #3a3e8a;background:#1a1b3f;color:var(--ink);width:12em;max-width:100%}
.ty-name:focus{outline:none;border-color:var(--accent)}
.ty-goal{margin:0;font-weight:bold;color:var(--accent);font-size:1.15rem}
.ty-games{display:flex;flex-wrap:wrap;gap:16px;justify-content:center}
.ty-gcard{width:210px;padding:16px 12px;border-radius:22px;border:4px solid var(--c);background:var(--panel);display:flex;flex-direction:column;align-items:center;gap:4px;transition:transform .12s}
.ty-gcard:hover{transform:translateY(-4px) scale(1.02)}
.ty-gcard .gi{font-size:3rem;line-height:1.1}
.ty-gcard .gn{font-size:1.25rem;font-weight:bold}
.ty-gcard .gd{color:var(--ink-dim);font-size:.9rem}
.ty-gcard .gp{color:var(--c);font-weight:bold;font-size:.95rem}
.ty-opts{display:flex;flex-wrap:wrap;gap:10px;justify-content:center}

/* ---------- level map ---------- */
.ty-maptop{width:100%;display:flex;align-items:center;gap:12px}
.ty-maptop h3{margin:0;flex:1;font-size:clamp(1.2rem,3vw,1.8rem)}
.ty-goal2{font-weight:bold;color:var(--accent)}
.ty-levels{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px;width:100%}
.ty-tile{position:relative;display:flex;flex-direction:column;align-items:center;gap:2px;padding:12px 6px 10px;border-radius:18px;border:3px solid #3a3e8a;background:var(--panel);min-width:0;transition:transform .12s}
.ty-tile:hover:not(:disabled){transform:translateY(-3px)}
.ty-tile .n{position:absolute;top:6px;left:10px;font-size:.85rem;font-weight:bold;color:var(--ink-dim)}
.ty-tile .ic{font-size:2.2rem;line-height:1.15}
.ty-tile .nm{font-size:.9rem;font-weight:bold;line-height:1.15;min-height:2.3em;display:flex;align-items:center}
.ty-tile .st{font-size:.8rem;color:var(--accent);min-height:1.2em}
.ty-tile.done{border-color:#6bcb77}

/* ---------- playing ---------- */
.ty-play{display:flex;flex-direction:column;gap:8px;padding:10px 14px;height:100%;min-height:0;background:linear-gradient(#2a3b7a,#15163a);--k:clamp(22px,min(4.2vw,6.2vh),46px)}
.ty-t-jungle{background:linear-gradient(#1d5a3a,#12283a)}
.ty-t-beach{background:linear-gradient(#1c7fa8,#7a6a3a)}
.ty-t-volcano{background:linear-gradient(#6a2020,#241024)}
.ty-t-ocean{background:linear-gradient(#0f4a8a,#0a1a44)}
.ty-t-desert{background:linear-gradient(#a8742a,#4a2a2a)}
.ty-t-snow{background:linear-gradient(#5a7fa8,#1a2444)}
.ty-t-city{background:linear-gradient(#3a2a6a,#14142e)}
.ty-t-lab{background:linear-gradient(#1a5a5a,#0e1a30)}
.ty-t-candy{background:linear-gradient(#a8407a,#3a1a4a)}
.ty-t-sky{background:linear-gradient(#2a6ac8,#7aa8e8)}
.ty-hud{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex:none}
.ty-hud .btn.ico{font-size:1.2rem;padding:.2em .55em}
.ty-hud .btn.off{opacity:.45}
.ty-chip{display:flex;align-items:center;gap:6px;background:rgba(0,0,0,.35);padding:.25em .8em;border-radius:99px;font-weight:bold}
.ty-chip b{background:var(--accent);color:#1a1b3f;border-radius:99px;min-width:1.5em;text-align:center}
.ty-stat{background:rgba(0,0,0,.35);padding:.25em .8em;border-radius:99px;font-weight:bold;white-space:nowrap}
.ty-extra{margin-left:auto}
.ty-main{position:relative;flex:1 1 auto;min-height:0;display:flex;flex-direction:column;justify-content:center;gap:12px}
.ty-count{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:clamp(3rem,12vw,7rem);font-weight:bold;color:#fff;text-shadow:0 6px 0 rgba(0,0,0,.4);z-index:5;pointer-events:none}
.ty-count.pop{animation:tyPop .7s ease-out}
@keyframes tyPop{0%{transform:scale(.4);opacity:0}30%{transform:scale(1.15);opacity:1}100%{transform:scale(1);opacity:.9}}
.ty-finger{flex:none;min-height:1.5em;text-align:center;font-weight:bold;color:#fff3b0;font-size:clamp(.9rem,1.8vw,1.1rem)}

/* the text being typed */
.ty-line{background:rgba(10,12,40,.72);border-radius:16px;padding:14px 18px;font-family:"Courier New",Consolas,monospace;font-size:clamp(1.1rem,2.8vw,1.8rem);line-height:1.6;letter-spacing:.02em;white-space:pre-wrap;overflow-wrap:break-word;border:3px solid #3a3e8a}
.ty-line .c{color:#c9cdf5;border-bottom:3px solid transparent}
.ty-line .c.ok{color:#6bcb77}
.ty-line .c.cur{background:#ffd23f;color:#1a1b3f;border-radius:4px}
.ty-line .c.cur.bad{background:#ff8a9a;animation:tyShake .25s}
@keyframes tyShake{25%{transform:translateX(-3px)}75%{transform:translateX(3px)}}
.wob{animation:tyShake .25s}

/* ---------- animated backgrounds ---------- */
.ty-play{position:relative;overflow:hidden}
.ty-play>*:not(.ty-bg){position:relative;z-index:1}
.ty-bg,.ty-field .ty-bg{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.ty-field .ty-bg{z-index:1}
.bgi{position:absolute;opacity:.55;line-height:1;animation-timing-function:linear;animation-iteration-count:infinite}
.bgi.drift{left:-12%;animation-name:bgDrift}
.bgi.fall{top:-10%;animation-name:bgFall}
.bgi.rise{top:105%;animation-name:bgRise}
@keyframes bgDrift{from{left:-12%}to{left:108%}}
@keyframes bgFall{from{top:-10%;transform:rotate(0)}to{top:105%;transform:rotate(300deg)}}
@keyframes bgRise{from{top:105%;transform:translateX(0)}50%{transform:translateX(14px)}to{top:-10%;transform:translateX(0)}}
.ty-play.still *{animation-play-state:paused !important}

/* racer: a real-looking sports car on a road, with hills that slide past and an evening that slowly arrives */
.ty-track{position:relative;border-radius:16px;overflow:hidden;border:3px solid #1a1b3f;background:linear-gradient(#8fd8ff,#e9f8ff);flex:none}
.ty-track .scn{position:relative;height:clamp(46px,10vh,92px)}
.ty-track .scn .l{position:absolute;inset:0;background-repeat:repeat-x;background-position:0 100%}
.ty-track .scn .far{background-size:auto 100%}
.ty-track .scn .near{background-size:auto 70%}
.ty-track .scn .tint{background:#ff7a3a;opacity:0;mix-blend-mode:multiply;transition:opacity .4s}
.ty-track .lane{position:relative;height:clamp(54px,9.5vh,86px);background:linear-gradient(#5b607a,#464a63);border-top:4px solid #cfd3e8}
.ty-track .lane+.lane{border-top:3px dashed #e8c84a}
.ty-track .lane::after{content:"";position:absolute;left:0;right:0;bottom:5px;height:4px;background:repeating-linear-gradient(90deg,rgba(255,255,255,.55) 0 26px,transparent 26px 58px)}
.ty-track.go .lane::after{animation:tyRoad .35s linear infinite}
@keyframes tyRoad{to{background-position-x:-58px}}
.ty-track .tag{position:absolute;left:8px;top:4px;font-size:.7rem;font-weight:bold;background:rgba(0,0,0,.5);color:#fff;border-radius:99px;padding:.05em .6em;z-index:2}
.ty-track .car{position:absolute;bottom:4px;left:2%;width:clamp(78px,15%,150px);transition:left .12s linear;z-index:1}
.ty-track .car svg{display:block;width:100%;height:auto;filter:drop-shadow(0 3px 2px rgba(0,0,0,.35))}
.ty-track .lane.ghost .car{opacity:.82}
.ty-track .wh{transform-box:fill-box;transform-origin:center}
.ty-track.go .wh{animation:tySpin .3s linear infinite}
@keyframes tySpin{to{transform:rotate(360deg)}}
.ty-track .flag{position:absolute;right:0;top:0;bottom:0;width:18px;background:repeating-conic-gradient(#fff 0 25%,#222 0 50%) 0 0/9px 9px;z-index:0}

/* word blaster: balloons float up over a sky that goes from day to sunset to a starry night */
.ty-field{position:relative;flex:1 1 auto;min-height:150px;border-radius:16px;overflow:hidden;border:3px solid #fff;box-shadow:0 0 0 3px #3a3e8a}
.ty-field .sk{position:absolute;inset:0;opacity:0;transition:opacity 3s}
.ty-field .sk.on{opacity:1}
.sk.d{background:linear-gradient(#6fc8ff,#d8f3ff)}
.sk.s{background:linear-gradient(#ff8a5c,#ffc98a 55%,#ffe9b8)}
.sk.n{background:radial-gradient(2px 2px at 20% 20%,#fff,transparent),radial-gradient(2px 2px at 70% 30%,#fff,transparent),radial-gradient(2px 2px at 40% 60%,#fff,transparent),radial-gradient(2px 2px at 85% 70%,#fff,transparent),radial-gradient(2px 2px at 10% 80%,#fff,transparent),radial-gradient(2px 2px at 55% 12%,#fff,transparent),radial-gradient(2px 2px at 92% 15%,#fff,transparent),linear-gradient(#10204a,#3a2f7a)}
.ty-bal{position:absolute;z-index:2;animation:tySway 2.8s ease-in-out infinite alternate}
.ty-bal .bb{display:flex;justify-content:center;align-items:center;padding:.85em 1.15em 1.15em;min-width:4.2em;font-family:"Courier New",Consolas,monospace;font-weight:bold;font-size:clamp(1rem,2.2vw,1.5rem);color:#1a1b3f;white-space:nowrap;
  background:radial-gradient(circle at 30% 26%,rgba(255,255,255,.8),transparent 34%),var(--c);border-radius:50% 50% 50% 50%/58% 58% 42% 42%;border:3px solid rgba(26,27,63,.75);box-shadow:inset -7px -9px 0 rgba(0,0,0,.12)}
.ty-bal .kn{position:absolute;left:50%;bottom:-8px;width:0;height:0;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:9px solid var(--c);transform:translateX(-50%)}
.ty-bal .sg{position:absolute;left:50%;top:100%;margin-top:1px;width:2px;height:30px;background:rgba(26,27,63,.55);transform:translateX(-50%) rotate(4deg);transform-origin:top}
.ty-bal .c.ok{color:#fff;text-shadow:0 1px 0 #1a1b3f}
.ty-bal.locked .bb{border-color:#fff;box-shadow:inset -7px -9px 0 rgba(0,0,0,.12),0 0 0 4px #ffd23f,0 0 16px #ffd23f}
.ty-bal.shake{animation:tyShake .25s}
.ty-bal.boom{animation:tyBoom .22s ease-out forwards}
.ty-bal.hit{animation:tyFly .6s ease-in forwards}
@keyframes tySway{from{transform:translateX(-7px) rotate(-3deg)}to{transform:translateX(7px) rotate(3deg)}}
@keyframes tyBoom{to{transform:scale(1.6);opacity:0}}
@keyframes tyFly{to{transform:translateY(-70px) scale(.7);opacity:0}}
.ty-field .cf{position:absolute;z-index:3;width:9px;height:9px;border-radius:2px;animation:tyConf .7s ease-out forwards}
@keyframes tyConf{to{transform:translate(var(--dx),var(--dy)) rotate(360deg);opacity:0}}
.ty-field .ship{position:absolute;left:calc(50% - 1.3rem);bottom:2px;font-size:2.4rem;line-height:1;z-index:3}
.ty-field .beam{position:absolute;bottom:46px;width:6px;margin-left:-3px;border-radius:6px;background:linear-gradient(#fff,#ffe27a,#ff8ad8);transform-origin:50% 100%;opacity:0;transition:opacity .12s;z-index:3}

/* boss: each level has its own drawn monster that breathes and blinks */
.ty-boss{display:flex;flex-direction:column;align-items:center;gap:4px}
.ty-boss .face{line-height:0;display:flex;justify-content:center}
.ty-boss .face .mon{height:clamp(96px,22vh,190px);width:auto;animation:tyBreath 2.6s ease-in-out infinite;transform-origin:50% 100%;filter:drop-shadow(0 8px 6px rgba(0,0,0,.35))}
@keyframes tyBreath{50%{transform:scale(1.04,.97)}}
.mon .ey{transform-box:fill-box;transform-origin:center;animation:tyBlink 4.5s infinite}
@keyframes tyBlink{0%,94%,100%{transform:scaleY(1)}97%{transform:scaleY(.1)}}
.mon .mo{transform-box:fill-box;transform-origin:center top}
.ty-boss .face.roar .mo{transform:scaleY(1.4)}
.ty-boss .face.hurt{animation:tyShake .2s}
.ty-boss .face.roar{animation:tyRoar .5s}
@keyframes tyRoar{40%{transform:scale(1.25)}}
.ty-boss .lab{font-size:.8rem;font-weight:bold;color:#e6e8ff;text-shadow:0 1px 2px rgba(0,0,0,.6)}
.ty-boss .bar{width:min(420px,80%);height:14px;border-radius:99px;background:rgba(0,0,0,.45);overflow:hidden;border:2px solid #1a1b3f}
.ty-boss .bar i{display:block;height:100%;width:100%;border-radius:99px;transition:width .2s}
.ty-boss .hp i{background:linear-gradient(90deg,#ff5c72,#ff9f45)}
.ty-boss .pw i{width:0;background:linear-gradient(90deg,#ffd23f,#ff5c72)}
.ty-snum{text-align:center;font-weight:bold;color:#e6e8ff;text-shadow:0 1px 2px rgba(0,0,0,.6)}

/* on-screen keyboard */
.ty-kbwrap{flex:none;display:flex;justify-content:center}
.ty-kb{display:flex;flex-direction:column;gap:3px;align-items:center}
.ty-kb .kr{display:flex;gap:3px;justify-content:center}
.tk{min-width:var(--k);height:calc(var(--k)*.85);padding:0 4px;border-radius:7px;display:flex;align-items:center;justify-content:center;font-size:calc(var(--k)*.38);font-weight:bold;color:#1a1b3f;border-bottom:3px solid rgba(0,0,0,.3);background:#ddd;position:relative}
.tk.space{min-width:calc(var(--k)*6)}
.tk.shift{min-width:calc(var(--k)*1.9);font-size:calc(var(--k)*.3)}
.tk.bump::after{content:"";position:absolute;bottom:3px;width:40%;height:2px;background:rgba(0,0,0,.45);border-radius:2px}
.tk.f-LP{background:#ff9aae}.tk.f-LR{background:#ffb877}.tk.f-LM{background:#ffe27a}.tk.f-LI{background:#8fe09a}
.tk.f-RI{background:#7adbe0}.tk.f-RM{background:#8fb8ff}.tk.f-RR{background:#c4a0ff}.tk.f-RP{background:#ff9ad8}.tk.f-TH{background:#cfd2ee}
.tk.hl{outline:4px solid #fff;outline-offset:1px;transform:translateY(-3px) scale(1.12);z-index:2;box-shadow:0 0 14px #fff}

/* report */
.ty-report h3{margin:0;font-size:clamp(1.1rem,2.6vw,1.6rem)}
.rep-game{width:100%;background:var(--panel);border-radius:16px;padding:10px 12px;border:3px solid #3a3e8a;text-align:left}
.rep-game .rg{font-weight:bold;margin-bottom:6px}
.rep-levels{display:grid;grid-template-columns:repeat(10,minmax(0,1fr));gap:5px}
.rl{background:#1a1b3f;border-radius:8px;padding:4px 2px;text-align:center;font-size:.75rem;display:flex;flex-direction:column;min-width:0}
.rl b{font-size:.9rem}
.rl.ok{background:#1f4a3a}.rl.try{background:#4a3a1f}
.rep-p{margin:0;font-size:1rem}
.rep-note{margin:0;color:var(--ink-dim);font-size:.85rem}

/* small screens: keep everything inside the stage */
@media (max-width:760px){
  .ty-levels{grid-template-columns:repeat(3,minmax(0,1fr))}
  .rep-levels{grid-template-columns:repeat(5,minmax(0,1fr))}
  .ty-track .lab{width:5em;font-size:.7rem}
  .ty-play{padding:8px;--k:24px}
}
@media (max-height:620px){
  .ty-kbwrap .kr:first-child{display:none}
  .ty-line{padding:8px 12px}
}
@media print{
  body *{visibility:hidden}
  .ty-report,.ty-report *{visibility:visible}
  .ty-report{position:absolute;left:0;top:0;width:100%;color:#000;background:#fff}
  .ty-report .ty-opts{display:none}
}

/* short windows: tighten the menu screens so they fit without scrolling */
@media (max-height:700px){
  .ty-home,.ty-map,.ty-report{gap:8px;padding:10px 14px}
  .ty-title{font-size:1.7rem}
  .ty-gcard{padding:10px 10px}.ty-gcard .gi{font-size:2.2rem}
  .rep-game{padding:6px 10px}.rep-game .rg{margin-bottom:3px}
  .ty-tile{padding:8px 4px 6px}.ty-tile .ic{font-size:1.7rem}
}

/* certificate */
.ty-certwrap{display:flex;flex-direction:column;align-items:center;gap:10px;padding:10px 14px;width:100%}
.ty-cert{width:min(100%,calc((100vh - 280px) * 1.414));min-width:min(100%,480px);background:#fff;border-radius:10px;box-shadow:0 8px 30px rgba(0,0,0,.45);overflow:hidden;line-height:0}
.ty-cert svg{width:100%;height:auto;display:block}
@media print{
  @page{size:A4 landscape;margin:0}
  .ty-certwrap,.ty-certwrap *{visibility:visible}
  #mode-typing{height:auto;padding:0;display:block}
  .ty-stage,.ty-root{position:static;overflow:visible;height:auto;max-height:none;box-shadow:none;background:#fff}
  .ty-certwrap{position:absolute;left:0;top:0;width:297mm;padding:0;gap:0}
  .ty-cert{width:297mm;height:210mm;box-shadow:none;border-radius:0}
  .ty-cert svg{width:297mm;height:210mm}
  .ty-certwrap .ty-opts,.ty-certwrap .rep-note{display:none !important}
}

/* the certificate must never be squashed: let the page scroll instead */
.ty-certwrap>*{flex:none}
.ty-root>.ty-certwrap{min-height:min-content}

/* year chooser: a clear round-button group */
.ty-years{display:flex;gap:10px;align-items:center;background:rgba(255,255,255,.08);padding:6px 8px 6px 16px;border-radius:99px;font-weight:bold}
.ty-years .yr{width:2.4em;height:2.4em;padding:0;display:flex;align-items:center;justify-content:center;border-radius:50%;font-size:1.15rem;border:3px solid #5a60b8;background:#2b3170;color:#e6e8ff}
.ty-years .yr:hover{background:#3a418a}
.ty-years .yr.on{background:#ffd23f;border-color:#fff3b0;color:#1a1b3f;box-shadow:0 0 0 3px rgba(255,210,63,.35);transform:scale(1.08)}

/* roomier menus on normal-sized screens */
.ty-home{gap:24px}
.ty-title{font-size:clamp(2.4rem,6vw,3.8rem)}
.ty-gcard{width:240px;padding:24px 14px}
.ty-gcard .gi{font-size:4rem}.ty-gcard .gn{font-size:1.4rem}.ty-gcard .gp{font-size:1rem}
.ty-opts .btn{font-size:1.05rem;padding:.6em 1.1em}
.ty-years{font-size:1.1rem}
@media (max-height:700px){
  .ty-home{gap:12px}
  .ty-title{font-size:2.2rem}
  .ty-gcard{width:210px;padding:12px 10px}.ty-gcard .gi{font-size:2.6rem}.ty-gcard .gn{font-size:1.2rem}
  .ty-opts .btn{font-size:.95rem;padding:.5em .9em}
}
.ty-opts .btn:disabled{background:#1f2358;color:#8a90c8;border-color:#3a3e8a;opacity:1}
@media (max-height:620px){
  .ty-levels{grid-template-columns:repeat(5,minmax(0,1fr));gap:8px}
  .ty-tile{padding:6px 4px 4px}.ty-tile .ic{font-size:1.6rem}.ty-tile .nm{font-size:.8rem;min-height:2em}.ty-tile .n{top:3px;left:6px;font-size:.7rem}
}
