:root,[data-theme=dark]{--accent:#7c5cbf;--accent-soft:color-mix(in srgb, var(--accent) 22%, #1f1c27);--accent-ink:#5b3f96;--bg:#16141c;--surface:#1f1c27;--text:#f3eefc;--muted:#b4adbf;--line:#352f42;--shadow:0 10px 30px #00000047;--error-bg:#fff5f5;--error-text:#9b2c2c;--radius:20px;--sans:"Noto Sans SC", "Noto Sans CJK SC", system-ui, sans-serif;--hand:"Ma Shan Zheng", "KaiTi", "STKaiti", "Noto Serif SC", serif;--serif:var(--hand);--body-glow:#2a2140;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}[data-theme=light]{--accent:#7c5cbf;--accent-soft:color-mix(in srgb, var(--accent) 14%, white);--accent-ink:#5b3f96;--bg:#f6f3fb;--surface:#fff;--text:#2a2438;--muted:#6b6375;--line:#e6e1ef;--shadow:0 10px 30px #50348214;--error-bg:#fff5f5;--error-text:#9b2c2c;--body-glow:#efe8ff;--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}*,:before,:after{box-sizing:border-box}html,body,#root{min-height:100%}html{height:100%}body{font-family:var(--sans);color:var(--text);background:radial-gradient(1000px 500px at 50% -10%, var(--body-glow) 0%, transparent 55%), var(--bg);-webkit-font-smoothing:antialiased;margin:0}button,a{font-family:inherit}#root{max-width:760px;margin:0 auto;padding:24px 16px 48px}#root:has(.page.practice){box-sizing:border-box;flex-direction:column;height:100dvh;min-height:100dvh;max-height:100dvh;padding:4px 10px 6px;display:flex;overflow:hidden}.page{flex-direction:column;gap:24px;display:flex}.page.home{gap:14px}.page.practice{flex:1;gap:6px;height:100%;min-height:0;max-height:100%;overflow:hidden}.home-header,.practice-bar{text-align:left}.home-header-top,.practice-bar-top{justify-content:space-between;align-items:center;gap:8px;display:flex}.home-header-top{margin-bottom:4px}.home-header-top .eyebrow{margin:0}.theme-toggle{border:1px solid var(--line);background:var(--surface);min-height:32px;color:var(--text);cursor:pointer;border-radius:999px;flex-shrink:0;padding:4px 10px;font-size:12px;font-weight:600;line-height:1.2}.theme-toggle:hover,.theme-toggle:focus-visible{border-color:color-mix(in srgb, var(--accent) 45%, var(--line));outline:none}.eyebrow{letter-spacing:.18em;text-transform:uppercase;color:var(--accent);margin:0 0 8px;font-size:13px;font-weight:500}h1{letter-spacing:-.03em;margin:0;font-size:clamp(32px,6vw,44px);font-weight:700;line-height:1.15}.lede,.practice-meta p,.next-hint{color:var(--muted);margin:8px 0 0;line-height:1.55}.char-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:0;padding:0;list-style:none;display:grid}@media (width>=640px){.char-grid{grid-template-columns:repeat(5,minmax(0,1fr))}}.char-tile{min-height:148px;color:inherit;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);flex-direction:column;align-items:center;gap:4px;padding:16px 10px 14px;text-decoration:none;transition:transform .15s,border-color .15s,box-shadow .15s;display:flex}.char-tile:hover,.char-tile:focus-visible{border-color:color-mix(in srgb, var(--accent) 45%, white);outline:none;transform:translateY(-2px);box-shadow:0 14px 28px #7c5cbf29}.char-rank{color:var(--accent);opacity:.8;align-self:flex-start;font-size:11px;font-weight:700}.char-glyph{font-family:var(--sans);color:var(--text);font-size:clamp(48px,10vw,64px);line-height:1}.char-pinyin{color:var(--accent-ink);font-size:15px;font-weight:500}.char-meaning{color:var(--muted);text-align:center;font-size:12px;line-height:1.3}.practice-bar{flex-direction:column;flex-shrink:0;gap:0;display:flex}.practice-bar-row{align-items:center;gap:8px;min-width:0;display:flex}.practice-bar-row .practice-meta{flex:1;min-width:0}.practice .back-link{flex-shrink:0;padding:4px 2px;font-size:18px;line-height:1;text-decoration:none}.practice .practice-meta h1{flex-wrap:wrap;align-items:baseline;gap:6px;font-size:clamp(20px,5vw,28px);line-height:1.1;display:flex}.practice-glyph-btn{appearance:none;cursor:pointer;color:inherit;font:inherit;background:0 0;border:0;margin:0;padding:0;line-height:1}.practice-glyph-btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}.practice .practice-glyph{margin-right:0}.practice .practice-meta-sub,.practice .practice-meta p{color:var(--muted);white-space:nowrap;text-overflow:ellipsis;margin:0;font-size:12px;line-height:1.25;overflow:hidden}.back-link{width:fit-content;color:var(--accent-ink);font-weight:500;text-decoration:none}.back-link:hover,.next-hint a:hover{text-decoration:underline}.practice-glyph{font-family:var(--serif);margin-right:12px}.practice-pinyin{color:var(--accent);vertical-align:middle;font-size:.55em;font-weight:500}.stroke-progress{flex-direction:column;flex-shrink:0;gap:4px;width:min(100%,520px);margin:0 auto;display:flex}.stroke-progress-label{color:var(--accent-ink);letter-spacing:.01em;font-size:12px;font-weight:600}.stroke-progress-track{background:var(--accent-soft);border-radius:999px;height:4px;overflow:hidden}.stroke-progress-fill{border-radius:inherit;height:100%;transition:width .25s;display:block}.grade-meter{text-align:center;width:min(100%,520px);color:var(--accent-ink);flex-shrink:0;margin:0 auto;font-size:12px;font-weight:600;line-height:1.35}.grade-meter-gates{color:var(--muted);font-weight:500}.grade-meter.is-ok .grade-meter-gates{color:var(--accent-ink);font-weight:600}.grade-meter-row{flex-direction:column;flex-shrink:0;align-items:center;gap:4px;width:min(100%,520px);margin:0 auto;display:flex}.show-strokes-toggle{appearance:none;border:1px solid var(--line);background:var(--surface);color:var(--muted);font:inherit;cursor:pointer;border-radius:999px;padding:4px 10px;font-size:11px;font-weight:600;line-height:1.2}.show-strokes-toggle:hover{color:var(--accent-ink);border-color:color-mix(in srgb, var(--accent) 40%, var(--line))}.show-strokes-toggle.is-on{color:var(--accent-ink);border-color:color-mix(in srgb, var(--accent) 55%, var(--line));background:var(--accent-soft)}.trace-toolbar{flex-shrink:0;justify-content:center;align-items:center;gap:6px;width:min(100%,520px);margin:0 auto;display:flex}.icon-btn{appearance:none;border:1px solid var(--line);background:var(--surface);width:36px;height:36px;color:var(--muted);cursor:pointer;border-radius:10px;flex-shrink:0;place-items:center;padding:0;font-size:16px;line-height:1;display:inline-grid}.icon-btn:hover:not(:disabled),.icon-btn:focus-visible{color:var(--accent-ink);border-color:color-mix(in srgb, var(--accent) 40%, var(--line));outline:none}.icon-btn.is-on{color:var(--accent-ink);border-color:color-mix(in srgb, var(--accent) 55%, var(--line));background:var(--accent-soft)}.icon-btn:disabled{opacity:.4;cursor:not-allowed}.trace-voice-note{text-align:center;max-width:520px;color:var(--muted);flex-shrink:0;margin:0 auto;font-size:11px;line-height:1.3}.next-char-banner{flex-shrink:0;justify-content:center;display:flex}.next-char-btn{justify-content:center;align-items:center;text-decoration:none;display:inline-flex}.next-caught-up{text-align:center;margin:0}.trace-actions-guide{flex-wrap:wrap}.trace-hint{text-align:center;max-width:520px;color:var(--muted);flex-shrink:0;margin:0 auto;font-size:12px;line-height:1.4}.trace-hint strong{color:var(--accent-ink);font-weight:600}.trace-error{background:var(--error-bg);color:var(--error-text);text-align:center;pointer-events:none;border-radius:12px;padding:10px 14px;font-size:14px;font-weight:500;position:absolute;inset:auto 16px 16px}.trace-pad{flex-direction:column;flex:1;gap:4px;min-height:0;display:flex}.trace-stage-slot{flex:auto;justify-content:center;align-items:center;width:100%;min-height:0;display:flex}.trace-stage{--accent:#7c5cbf;box-sizing:border-box;aspect-ratio:1;background:var(--surface);border:1px solid var(--line);width:min(100%,520px);max-width:100%;height:auto;max-height:100%;box-shadow:var(--shadow);touch-action:none;-webkit-user-select:none;user-select:none;border-radius:20px;flex:none;margin:0 auto;position:relative;overflow:hidden}.trace-stage.is-done{box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 40%, white)}.tianzige,.tianzige span{pointer-events:none}.tianzige{border:2px solid color-mix(in srgb, var(--accent) 28%, white);border-radius:8px;position:absolute;inset:18px}.tianzige-h,.tianzige-v,.tianzige-d1,.tianzige-d2{background:color-mix(in srgb, var(--accent) 18%, white);position:absolute}.tianzige-h{background:repeating-linear-gradient(90deg, color-mix(in srgb, var(--accent) 35%, white) 0 8px, transparent 8px 14px);height:1px;top:50%;left:8%;right:8%}.tianzige-v{background:repeating-linear-gradient(180deg, color-mix(in srgb, var(--accent) 35%, white) 0 8px, transparent 8px 14px);width:1px;top:8%;bottom:8%;left:50%}.tianzige-d1,.tianzige-d2{background:0 0;border:0;inset:6%}.tianzige-d1{background:linear-gradient(to bottom right, transparent calc(50% - .5px), color-mix(in srgb, var(--accent) 16%, white) calc(50% - .5px), color-mix(in srgb, var(--accent) 16%, white) calc(50% + .5px), transparent calc(50% + .5px))}.tianzige-d2{background:linear-gradient(to bottom left, transparent calc(50% - .5px), color-mix(in srgb, var(--accent) 16%, white) calc(50% - .5px), color-mix(in srgb, var(--accent) 16%, white) calc(50% + .5px), transparent calc(50% + .5px))}.hanzi-host{pointer-events:none;place-items:center;display:grid;position:absolute;inset:0}.hanzi-host-interactive{pointer-events:auto;touch-action:none;cursor:crosshair}.hanzi-host>svg,.hanzi-host>canvas{display:block;width:100%!important;height:100%!important}.trace-canvas{touch-action:none;cursor:crosshair;width:100%;height:100%;position:absolute;inset:0}.trace-success{background:color-mix(in srgb, var(--accent) 92%, black);color:#fff;pointer-events:none;border-radius:999px;justify-content:center;align-items:center;gap:8px;padding:10px 14px;font-weight:600;animation:.28s pop;display:flex;position:absolute;inset:auto 16px 16px}.trace-check{width:22px;height:22px;color:var(--accent);background:#fff;border-radius:50%;place-items:center;font-size:14px;display:grid}@keyframes pop{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}.trace-actions{flex-wrap:wrap;flex-shrink:0;justify-content:center;gap:6px;display:flex}.trace-actions .btn-compact{min-width:0;min-height:32px;padding:4px 12px;font-size:12px}.btn{cursor:pointer;border:1px solid #0000;border-radius:999px;min-width:88px;min-height:40px;padding:8px 14px;font-size:14px;font-weight:600}.btn:disabled{opacity:.45;cursor:not-allowed}.btn-ghost{background:var(--surface);border-color:var(--line);color:var(--text)}.btn-primary{background:var(--accent);color:#fff}.btn-primary:hover:not(:disabled),.btn-ghost:hover{filter:brightness(1.05)}.btn-danger{border-color:color-mix(in srgb, var(--error-text) 55%, var(--line));color:var(--error-text);background:0 0}.btn-danger:hover:not(:disabled){background:var(--error-bg);border-color:var(--error-text);filter:none}.home-wipe-all{margin-top:6px}.home-wipe-all .btn{min-width:0;min-height:34px;padding:6px 12px;font-size:13px}.next-hint a{color:var(--accent-ink);font-weight:600;text-decoration:none}.guide-canvas{pointer-events:none;width:100%;height:100%;position:absolute;inset:0}.trace-demo-badge{background:color-mix(in srgb, var(--accent) 88%, black);color:#fff;pointer-events:none;letter-spacing:.04em;z-index:2;border-radius:999px;padding:5px 10px;font-size:12px;font-weight:600;position:absolute;top:10px;left:auto;right:10px;transform:none}.level-pips{flex-wrap:wrap;flex-shrink:0;justify-content:center;gap:4px;width:min(100%,520px);margin:0 auto;display:flex}.level-pip{cursor:pointer;color:var(--muted);background:0 0;border:none;flex-direction:column;align-items:center;gap:2px;min-width:28px;padding:4px 6px;display:inline-flex}.level-pip:disabled{cursor:not-allowed;opacity:.45}.level-pip-dot{border:2px solid var(--line);background:0 0;border-radius:50%;width:12px;height:12px;transition:background .15s,border-color .15s,box-shadow .15s}.level-pip.is-beaten .level-pip-dot{background:var(--pip,var(--accent));border-color:var(--pip,var(--accent))}.level-pip.is-active .level-pip-dot{box-shadow:0 0 0 3px color-mix(in srgb, var(--pip,var(--accent)) 35%, transparent);border-color:var(--pip,var(--accent))}.level-pip.is-locked .level-pip-dot{background:var(--line)}.level-pip-num{font-size:11px;font-weight:700;line-height:1}.level-pip.is-active .level-pip-num{color:var(--accent-ink)}.char-levels{flex-wrap:wrap;justify-content:center;gap:3px;max-width:100%;margin-top:6px;display:flex}.char-level-dot{background:var(--line);border-radius:50%;width:6px;height:6px}.char-level-dot.is-on{background:var(--accent)}@media (height<=850px){.practice .practice-meta-sub,.practice .practice-meta p,.trace-hint,.next-hint:not(.next-caught-up),.practice-wipe-row,.next-char-banner{display:none}.practice-bar{gap:0}.practice .practice-meta h1{font-size:clamp(18px,4.5vw,24px)}.stroke-progress-label{font-size:11px}.stroke-progress{gap:2px}.grade-meter{font-size:11px}.level-pip{min-width:24px;padding:2px 4px}.level-pip-num{font-size:10px}.level-pip-dot{width:10px;height:10px}.icon-btn{width:34px;height:34px;font-size:15px}.btn{min-width:72px;min-height:32px;padding:4px 10px;font-size:12px}.trace-stage{border-radius:14px}.tianzige{inset:10px}.trace-pad{gap:3px}}@media (width>=640px) and (height>=800px){.trace-stage{width:min(100%,520px)}.btn{min-width:104px;min-height:44px;padding:10px 18px;font-size:15px}.stroke-progress-label{font-size:14px}.stroke-progress-track{height:6px}}[data-theme=light] .tianzige{border-color:color-mix(in srgb, var(--accent) 32%, var(--line))}[data-theme=light] .tianzige-h{background:repeating-linear-gradient(90deg, color-mix(in srgb, var(--accent) 40%, var(--line)) 0 8px, transparent 8px 14px)}[data-theme=light] .tianzige-v{background:repeating-linear-gradient(180deg, color-mix(in srgb, var(--accent) 40%, var(--line)) 0 8px, transparent 8px 14px)}[data-theme=light] .tianzige-d1{background:linear-gradient(to bottom right, transparent calc(50% - .5px), color-mix(in srgb, var(--accent) 22%, var(--line)) calc(50% - .5px), color-mix(in srgb, var(--accent) 22%, var(--line)) calc(50% + .5px), transparent calc(50% + .5px))}[data-theme=light] .tianzige-d2{background:linear-gradient(to bottom left, transparent calc(50% - .5px), color-mix(in srgb, var(--accent) 22%, var(--line)) calc(50% - .5px), color-mix(in srgb, var(--accent) 22%, var(--line)) calc(50% + .5px), transparent calc(50% + .5px))}.practice-bar-actions{align-items:center;gap:8px;display:flex}.btn-compact{min-width:0;min-height:32px;padding:4px 10px;font-size:12px}.practice-wipe-row{flex-shrink:0;justify-content:center;margin-top:-2px;display:flex}.link-danger{color:var(--muted);text-underline-offset:2px;cursor:pointer;background:0 0;border:0;padding:4px 8px;font-size:12px;text-decoration:underline}.link-danger:hover,.link-danger:focus-visible{color:#c45c5c;outline:none}.home-title-row{flex-wrap:wrap;align-items:baseline;gap:8px 10px;min-width:0;display:flex}.page.home h1{letter-spacing:-.02em;font-size:clamp(26px,5.5vw,34px)}.home-lede{margin-top:4px;font-size:14px;line-height:1.4}.practice-bar-actions{flex-shrink:0;align-items:center;gap:8px;display:flex}.app-version{font-variant-numeric:tabular-nums;letter-spacing:.04em;color:color-mix(in srgb, var(--muted,#887) 90%, transparent);-webkit-user-select:none;user-select:none;white-space:nowrap;margin:0;font-size:12px}.page.home{-webkit-overflow-scrolling:touch;overflow:hidden auto}.home-header-sticky{z-index:5;background:color-mix(in srgb, var(--bg) 92%, transparent);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-bottom:1px solid color-mix(in srgb, var(--line) 70%, transparent);padding-bottom:8px;position:sticky;top:0}.home-toggles{flex-direction:column;gap:8px;margin-top:10px;display:flex}.home-seg{border:1px solid var(--line);background:var(--surface);border-radius:999px;width:100%;display:flex;overflow:hidden}.home-seg-btn{min-height:34px;color:var(--muted);cursor:pointer;background:0 0;border:0;flex:1;padding:6px 8px;font-size:12px;font-weight:600}.home-seg-btn.is-on{background:color-mix(in srgb, var(--accent) 88%, black);color:#fff}.home-bands{flex-direction:column;gap:10px;padding:10px 0 24px;display:flex}.home-empty{color:var(--muted);margin:12px 0;font-size:14px}.hsk-band{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);overflow:hidden}.hsk-band-head,.hsk-lesson-head{width:100%;color:inherit;cursor:pointer;text-align:left;background:0 0;border:0;align-items:center;gap:8px;padding:12px;font-size:14px;font-weight:600;display:flex}.hsk-band-title{flex:1;min-width:0}.hsk-band-meta,.hsk-lesson-meta{color:var(--muted);font-variant-numeric:tabular-nums;font-size:12px;font-weight:500}.hsk-band-chev{color:var(--accent);text-align:center;width:1em}.hsk-band-body{border-top:1px solid var(--line);flex-direction:column;gap:6px;padding:4px 8px 10px;display:flex}.hsk-lesson{background:color-mix(in srgb, var(--bg) 55%, var(--surface));border-radius:10px}.hsk-lesson-head{padding:10px;font-size:13px}.hsk-lesson-head span:first-child{flex:1}.char-grid-compact{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;padding:0 8px 10px}.char-grid-compact .char-tile{gap:2px;min-height:0;padding:10px 6px 8px}.char-grid-compact .char-glyph{font-size:clamp(36px,9vw,48px)}.char-grid-compact .char-pinyin{font-size:13px}.char-grid-compact .char-meaning{display:none}.char-hsk-badge{letter-spacing:.04em;color:var(--accent-ink);background:color-mix(in srgb, var(--accent) 16%, transparent);border-radius:999px;margin-top:2px;padding:2px 7px;font-size:10px;font-weight:700}.char-tile-locked{opacity:.55;cursor:not-allowed;position:relative}.char-tile-locked .char-glyph.is-muted{color:var(--muted)}.char-lock{font-size:12px;position:absolute;top:6px;right:8px}@media (width>=640px){.char-grid-compact{grid-template-columns:repeat(3,minmax(0,1fr))}.home-toggles{flex-flow:wrap}.home-seg{width:auto;min-width:220px}}.theme-toggle{min-width:36px;padding:4px 8px}.theme-toggle-icon{font-size:16px;line-height:1}
