:root{--bg: #0f1420;--bg-2: #141b2b;--text: #d8def0;--muted: #8f97ad;--line: #2d3750;--ok: #39c89f;--err: #f06d7f;--focus: #ff80b5;--card: rgba(19, 27, 42, .72);--cell-gap: .52em;--display-hanzi-font: "PingFang SC", "Noto Sans SC", "Microsoft YaHei", sans-serif}html[data-display-hanzi-font=system]{--display-hanzi-font: "PingFang SC", "Noto Sans SC", "Microsoft YaHei", sans-serif}html[data-display-hanzi-font=songti]{--display-hanzi-font: "Songti SC", "SimSun", "NSimSun", "STSong", "Noto Serif SC", serif}html[data-display-hanzi-font=kaiti]{--display-hanzi-font: "Kaiti SC", "KaiTi", "STKaiti", "BiauKai", "Noto Serif SC", serif}html[data-display-hanzi-font=xingkai]{--display-hanzi-font: "Xingkai SC", "STXingkai", "KaiTi", "Kaiti SC", serif}html[data-display-hanzi-font=fangsong]{--display-hanzi-font: "FangSong", "STFangsong", "FangSong_GB2312", "Noto Serif SC", serif}html[data-display-hanzi-font=heiti]{--display-hanzi-font: "Heiti SC", "Microsoft YaHei", "SimHei", "Noto Sans SC", sans-serif}*{box-sizing:border-box}html,body{margin:0;min-height:100%;background:radial-gradient(circle at 20% 10%,#20293f 0%,var(--bg) 45%,#0b111c 100%);color:var(--text);font-family:PingFang SC,Noto Sans SC,Microsoft YaHei,sans-serif}.app{max-width:1240px;width:100%;margin:0 auto;padding:clamp(12px,3vw,20px) clamp(12px,4vw,22px) calc(24px + env(safe-area-inset-bottom,0px))}.topbar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px 16px;margin-bottom:22px}.logo{font-size:22px;font-weight:700;letter-spacing:.5px;color:inherit;text-decoration:none}.top-actions{display:flex;flex-wrap:wrap;align-items:center;gap:10px;justify-content:flex-end}.speech-voice-wrap{display:flex;align-items:center;gap:8px}.speech-voice-label{font-size:13px;color:var(--muted);white-space:nowrap}.speech-voice-select{min-width:0;max-width:min(260px,46vw);border:1px solid var(--line);color:var(--text);background:var(--bg-2);padding:8px 10px;border-radius:10px;min-height:44px;font:inherit;cursor:pointer}.speech-voice-select:focus-visible{outline:2px solid var(--focus);outline-offset:2px}.ghost-btn,.primary-btn{border:1px solid var(--line);color:var(--text);background:transparent;padding:8px 14px;border-radius:10px;cursor:pointer;min-height:44px}.primary-btn{background:#1b2653;border-color:#36498e}.ghost-btn:focus-visible,.primary-btn:focus-visible{outline:2px solid var(--focus);outline-offset:2px}.title{margin:0 0 6px;font-size:44px}.subtitle{margin:0 0 22px;color:var(--muted)}.poem-search-bar{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:20px}.poem-search-input{flex:1;min-width:min(100%,220px);border:1px solid var(--line);color:var(--text);background:var(--bg-2);padding:10px 14px;border-radius:10px;min-height:44px;font:inherit}.poem-search-input::placeholder{color:var(--muted);opacity:.85}.poem-search-input:focus-visible{outline:2px solid var(--focus);outline-offset:2px}.search-category-row{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:14px}.search-cat-btn.active{background:#1b2653;border-color:#36498e}.search-loading,.search-empty{color:var(--muted);font-size:15px;margin:0 0 12px}.poem-section{margin-bottom:28px}.poem-section:last-child{margin-bottom:0}.poem-section-title{margin:0 0 12px;font-size:18px;font-weight:600;color:var(--muted);letter-spacing:.04em}.featured-poem{border:1px solid var(--line);border-radius:14px;padding:18px 20px;background:var(--card);margin-bottom:22px}.featured-title{margin:0 0 6px;font-size:26px;font-weight:600}.featured-author{margin:0 0 14px;color:var(--muted)}.section-pager{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-top:14px;justify-content:center}.pager-meta{font-size:14px;color:var(--muted)}.hint-kbd{margin-top:8px;font-size:13px;color:var(--muted)}.speech-hint{margin-top:8px;font-size:13px;color:var(--err)}.continue-box{border:1px solid var(--line);border-radius:12px;padding:14px;background:#182134b8;display:flex;justify-content:space-between;align-items:center;margin-bottom:18px;gap:12px}.continue-text{color:var(--muted)}.course-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}.course-card{border:1px solid #3a4460;border-radius:14px;background:var(--card);min-height:148px;padding:14px;display:flex;flex-direction:column;justify-content:space-between}.course-card.locked{opacity:.55}.course-card-top{display:flex;justify-content:space-between;color:var(--muted)}.course-card-stars{min-height:1.25em}.course-card-stars--empty{font-size:13px;letter-spacing:.02em}.course-card-title{font-size:22px;line-height:1.25}.course-card-author{color:var(--muted);margin-top:4px}.course-card button{margin-top:12px}.practice-header{margin:4px 0 16px}.practice-header h2{margin:0;font-size:clamp(1.35rem,4.2vw,2.125rem);line-height:1.2;word-break:break-word}.practice-author{margin:6px 0 0;color:var(--muted)}.practice-genre{margin:4px 0 0;font-size:13px;color:var(--muted)}.typing-zoom-bar{display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;margin:0 0 10px}.typing-zoom-label{font-size:13px;color:var(--muted)}.typing-zoom-btn{min-width:44px;min-height:44px;border:1px solid var(--line);border-radius:10px;background:var(--bg-2);color:var(--text);font-size:22px;line-height:1;cursor:pointer;padding:0 10px}.typing-zoom-btn:disabled{opacity:.4;cursor:not-allowed}.typing-zoom-btn:focus-visible{outline:2px solid var(--focus);outline-offset:2px}.typing-zoom-value{font-size:14px;color:var(--muted);min-width:3.2em;text-align:center;font-variant-numeric:tabular-nums}.typing-zoom-reset{min-height:44px}.typing-zoom-hint{margin:0 0 14px;font-size:12px;color:var(--muted);line-height:1.45}.typing-panel{border:1px solid var(--line);border-radius:14px;background:#0e1524bf;min-height:min(430px,52vh);max-height:min(72vh,calc(100dvh - 200px));padding:24px 24px 12px;overflow:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;scrollbar-width:none;-ms-overflow-style:none}.typing-panel::-webkit-scrollbar{width:0;height:0}.typing-panel-zoom-root{display:block;width:max-content}.line-block{margin:0 0 22px}.line-grid{display:grid;justify-content:start;width:max-content;column-gap:var(--cell-gap);row-gap:0}.line-cell{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;min-width:max-content;scroll-margin:12px 20px}.py-cell{font-family:Menlo,Monaco,Consolas,monospace;font-size:36px;line-height:1.25;color:#a7b0ca;min-height:1.25em;display:inline-flex;align-items:center;justify-content:center;text-align:center;white-space:nowrap;letter-spacing:.08em;width:max-content;max-width:none;padding:0 .06em}.py-cell:has(.py-letter){letter-spacing:0;gap:.14em}.hz-cell{font-family:var(--display-hanzi-font);font-size:62px;line-height:1.1;color:#9ca8c8;min-height:1.1em;display:inline-flex;align-items:center;justify-content:center}.done{color:var(--ok)}.current{border-bottom:3px solid var(--focus);color:#e3e8f8}.hz-cell.current{border-bottom:none}.py-cell.current:has(.py-letter){border-bottom:none}.error{color:var(--err);background:#f06d7f24}.py-letter{display:inline-block;min-width:.78em;text-align:center}.py-letter.ok{color:var(--ok)}.py-letter.fixed{color:#e8c547}.py-letter.err{color:var(--err);background:#f06d7f24}.py-letter.pending{color:#a7b0ca}.py-letter.next{border-bottom:2px solid var(--focus)}.punct{color:#8692b2}.footer-stats{margin-top:14px;border-top:1px dashed var(--line);padding-top:10px;display:flex;flex-wrap:wrap;gap:clamp(10px,2.5vw,18px);color:var(--muted);font-size:clamp(13px,2.8vw,15px)}.finish-dialog{max-width:min(420px,calc(100vw - 32px));padding:0;border:1px solid var(--line);border-radius:16px;background:var(--bg-2);color:var(--text);box-shadow:0 24px 48px #00000073}.finish-dialog::backdrop{background:#060a12b8;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.finish-dialog-inner{padding:22px 24px 20px}.finish-dialog-title{margin:0 0 12px;font-size:22px}.finish-dialog-summary{margin:0 0 10px;color:var(--muted);font-size:15px;line-height:1.55;white-space:pre-line}.finish-dialog-stars{margin:0 0 18px;font-size:28px;letter-spacing:.12em;color:#e8c547}.finish-dialog-btn{width:100%}.finish-dialog-link{display:block;width:100%;margin-top:12px;padding:8px 16px;background:transparent;border:none;color:var(--muted);font-size:14px;text-decoration:underline;cursor:pointer;text-align:center}.finish-dialog-link:hover{color:var(--text)}.ime-input{position:fixed;left:-9999px;width:1px;height:1px;opacity:0;pointer-events:none}.load-error{border:1px solid var(--err);border-radius:12px;padding:16px;color:var(--text);background:#f06d7f1f}@media(max-width:980px){:root{--cell-gap: .4em}.course-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.py-cell{font-size:28px}.hz-cell{font-size:48px}}@media(max-width:640px){:root{--cell-gap: .3em}.title{font-size:clamp(1.6rem,7vw,2.125rem)}.subtitle{font-size:.95rem}.course-grid{grid-template-columns:1fr}.topbar{flex-direction:column;align-items:stretch}.logo{text-align:center}.top-actions{justify-content:center}.speech-voice-wrap{flex:1 1 auto;min-width:0}.speech-voice-select{max-width:100%;flex:1 1 auto}.practice-header{margin-bottom:12px}.typing-panel{padding:14px;min-height:min(260px,42vh);max-height:calc(100dvh - 168px)}.py-cell{font-size:20px}.hz-cell{font-size:34px}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}
