:root {
  --paper: #f6f1e7; --paper-2: #efe8da; --card: #fffdf8; --line: #ddd5c4; --line-2: #cfc6b3;
  --ink: #1f1c1a; --ink-2: #4a443f; --ink-3: #7d756c;
  --seal: #c8381f; --seal-2: #a92d17; --blue: #2f7bd6; --blue-2: #1f5fa8; --green: #2e9d5a; --amber: #d08a1e;
  --hanzi: "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Noto Sans SC", "Microsoft YaHei", "Source Han Sans SC", sans-serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, var(--hanzi);
  --radius: 12px; --shadow: 0 1px 2px rgba(40, 30, 10, .06), 0 6px 20px rgba(40, 30, 10, .06);
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; padding: 0; }
body { background: var(--paper); color: var(--ink); font-family: var(--sans); font-size: 16px; line-height: 1.45; -webkit-font-smoothing: antialiased; }
a { color: var(--blue-2); text-decoration: none; }
a:hover { text-decoration: underline; }
.hz { font-family: var(--hanzi); }
button, .btn { font: inherit; }
.btn { display: inline-flex; align-items: center; gap: .45em; padding: .5em 1em; border-radius: 999px; border: 1px solid var(--line-2); background: var(--card); color: var(--ink); cursor: pointer; text-decoration: none !important; line-height: 1.2; }
.btn:hover { border-color: var(--ink-3); }
.btn.primary { background: var(--seal); border-color: var(--seal); color: #fff; }
.btn.primary:hover { background: var(--seal-2); }
.btn.blue { background: var(--blue); border-color: var(--blue); color: #fff; }
.btn.small { padding: .3em .75em; font-size: .9em; }
.btn.icon { width: 2.4em; height: 2.4em; padding: 0; justify-content: center; }
.btn:disabled { opacity: .45; cursor: default; }
.btn.quiet { background: transparent; border-color: transparent; color: var(--ink-2); }
.btn.quiet:hover { background: var(--paper-2); }
input[type=text], input[type=password], input[type=search], input[type=number], select, textarea {
  font: inherit; padding: .55em .8em; border: 1px solid var(--line-2); border-radius: 10px; background: #fff; color: var(--ink); }
input:focus, select:focus, textarea:focus { outline: 2px solid rgba(47,123,214,.35); border-color: var(--blue); }

/* top bar */
.top { position: sticky; top: 0; z-index: 20; background: rgba(246,241,231,.92); backdrop-filter: blur(10px); border-bottom: 1px solid var(--line); }
.top-in { max-width: 1180px; margin: 0 auto; padding: .55em 1em; display: flex; align-items: center; gap: 1.2em; }
.brand { display: flex; align-items: center; gap: .5em; font-weight: 700; color: var(--ink); text-decoration: none !important; }
.brand .stamp { display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: 8px; background: var(--seal); color: #fff; font-family: var(--hanzi); font-size: 19px; font-weight: 600; }
.nav { display: flex; gap: .2em; margin-left: .5em; flex-wrap: wrap; }
.nav a { padding: .35em .7em; border-radius: 8px; color: var(--ink-2); }
.nav a.on, .nav a:hover { background: var(--paper-2); color: var(--ink); text-decoration: none; }
.top .spacer { flex: 1; }
.top .who { color: var(--ink-3); font-size: .9em; }
.wrap { max-width: 1180px; margin: 0 auto; padding: 1.2em 1em 4em; }
h1 { font-size: 1.6em; margin: .2em 0 .6em; }
h2 { font-size: 1.15em; margin: 1.2em 0 .5em; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: 1em 1.2em; }
.muted { color: var(--ink-3); }
.small { font-size: .88em; }
.row { display: flex; gap: .6em; align-items: center; flex-wrap: wrap; }
.badge { display: inline-block; padding: .1em .5em; border-radius: 6px; font-size: .75em; font-weight: 600; letter-spacing: .02em; background: var(--paper-2); color: var(--ink-2); vertical-align: middle; }
.badge.hsk { background: #e4efdc; color: #2f6b2b; }
.badge.hsk.l2 { background: #dfeaf7; color: #1f4f86; } .badge.hsk.l3 { background: #f6e9cf; color: #7a5410; }
.badge.hsk.l4 { background: #f3ddd8; color: #8a2f22; } .badge.hsk.l5 { background: #e6dcf2; color: #4f2f86; }
.badge.hsk.l6 { background: #d9eeee; color: #1f5f61; } .badge.hsk.l7 { background: #e8e3dd; color: #4a3b2f; }
.toast { position: fixed; left: 50%; bottom: 1.5em; transform: translateX(-50%); background: var(--ink); color: #fff; padding: .6em 1em; border-radius: 10px; box-shadow: var(--shadow); z-index: 50; opacity: 0; transition: opacity .2s; pointer-events: none; max-width: 90vw; }
.toast.show { opacity: 1; }
.toast.warn { background: var(--seal); }
.toast.good { background: var(--green); }
.progress { height: 8px; background: var(--paper-2); border-radius: 99px; overflow: hidden; }
.progress > i { display: block; height: 100%; background: var(--seal); border-radius: 99px; transition: width .3s; }
.progress.blue > i { background: var(--blue); }
.stage-pips { display: inline-flex; gap: .35em; }
.stage-pips b { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; font-size: .75em; background: var(--paper-2); color: var(--ink-3); font-weight: 700; }
.stage-pips b.on { background: var(--seal); color: #fff; }
.stage-pips b.done { background: var(--green); color: #fff; }
.grid-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: .8em; }
.char-tile { display: flex; flex-direction: column; align-items: center; gap: .15em; padding: .6em .3em; border: 1px solid var(--line); border-radius: 10px; background: var(--card); color: var(--ink); text-decoration: none !important; position: relative; }
.char-tile:hover { border-color: var(--ink-3); }
.char-tile .c { font-family: var(--hanzi); font-size: 2em; line-height: 1.1; }
.char-tile .p { font-size: .8em; color: var(--ink-3); }
.char-tile .bar { width: 80%; height: 4px; background: var(--paper-2); border-radius: 9px; overflow: hidden; margin-top: .3em; }
.char-tile .bar i { display: block; height: 100%; background: var(--seal); }
.char-tile.mastered { border-color: var(--green); background: #f1f8f2; }
.char-tile .st { position: absolute; top: 4px; right: 6px; font-size: .68em; color: var(--ink-3); font-weight: 600; }
.surface { position: relative; touch-action: none; user-select: none; -webkit-user-select: none; background: #fffdf8; border-radius: 6px; }
.tok { cursor: pointer; border-radius: 6px; padding: 0 .08em; position: relative; }
.tok:hover { background: rgba(47,123,214,.12); }
.tok.hl { background: rgba(47,123,214,.22); }
.g0 { color: var(--ink); } .g1 { color: #1f6f8b; } .g2 { color: #b0327a; } .g3 { color: #6f7a17; } .g4 { color: #2c6fd6; } .g5 { color: #c2541a; } .g6 { color: #6b3fb5; } .g7 { color: #1f8a5a; } .g8 { color: #a0522d; } .g9 { color: #7a1f8a; }
.bubble { position: absolute; left: 50%; transform: translateX(-50%); bottom: calc(100% + 6px); background: var(--ink); color: #fff; font-size: .55em; padding: .2em .55em; border-radius: 6px; white-space: nowrap; pointer-events: none; }
.bubble:after { content: ''; position: absolute; left: 50%; top: 100%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: var(--ink); }
.sent-zh { font-family: var(--hanzi); font-size: 2em; line-height: 1.6; }
.sent-en { font-size: 1.25em; line-height: 1.6; }
@media (max-width: 720px) { body { font-size: 15px; } .top-in { gap: .6em; } .nav a { padding: .3em .5em; } .wrap { padding: .8em .7em 4em; } }
@media print { .top, .no-print { display: none !important; } body { background: #fff; } }

/* pronunciation */
.spk-btn.rec { background: var(--seal); color: #fff; border-color: var(--seal); animation: spkpulse 1s infinite; }
@keyframes spkpulse { 50% { opacity: .7; } }
.spk-panel { margin-top: .6em; padding: .7em .9em; background: var(--card); border: 1px solid var(--line); border-radius: 10px; text-align: left; color: var(--ink); font-size: .95em; }
.spk-panel.spk-wide { max-width: 34em; margin: .6em auto 0; }
.spk-msg { color: var(--ink-2); }
.spk-meter { height: 6px; background: var(--line); border-radius: 3px; margin: .5em 0 .3em; overflow: hidden; }
.spk-meter i { display: block; height: 100%; width: 0; background: var(--green); transition: width .08s linear; }
.spk-score { margin-bottom: .4em; }
.spk-chars { display: flex; flex-wrap: wrap; gap: .4em; margin: .4em 0; }
.spk-c { display: inline-flex; flex-direction: column; align-items: center; min-width: 2.6em; padding: .25em .4em; border-radius: 8px; border: 1px solid var(--line); background: #fff; }
.spk-c .hz { font-family: var(--hanzi); font-size: 1.5em; line-height: 1.2; }
.spk-c .py { font-size: .75em; color: var(--ink-3); }
.spk-c .tone { font-size: .8em; }
.spk-c .acc { font-size: .7em; font-weight: 700; }
.spk-c.good { border-color: #b9dcc4; background: #f1f8f2; } .spk-c.good .acc { color: var(--green); }
.spk-c.mid { border-color: #e6cf9c; background: #fbf5e6; } .spk-c.mid .acc { color: var(--amber); }
.spk-c.low { border-color: #e2b4ad; background: #fbeeec; } .spk-c.low .acc { color: var(--seal); }
.spk-c.tonebad .tone { color: var(--seal); font-weight: 700; }
.spk-work { font-size: .92em; color: var(--ink-2); } .spk-work.good { color: var(--green); }
.spk-btns { display: flex; gap: .4em; margin-top: .5em; flex-wrap: wrap; }
.pct { font-variant-numeric: tabular-nums; font-weight: 700; } .pct.good { color: var(--green); } .pct.mid { color: var(--amber); } .pct.low { color: var(--seal); }

/* the teacher's red circle: what the critique says about a finished character */
.critique { margin-top: .6em; padding: .7em .9em; border: 1px solid #e2b4ad; background: #fbeeec; border-radius: 10px; max-width: 46em; text-align: left; }
.critique.pinned { position: fixed; left: 50%; bottom: 16px; transform: translateX(-50%); width: min(46em, calc(100% - 32px)); margin: 0; z-index: 50; box-shadow: 0 6px 28px rgba(40, 30, 10, .18); }
.critique .crit-head { display: flex; align-items: center; gap: .5em; color: var(--seal); }
.critique .crit-mark { font-size: 1.1em; }
.critique p { margin: .4em 0 .6em; color: var(--ink); }
.critique .crit-list { margin: .4em 0 .6em; padding-left: 1.4em; }
.critique .crit-list li { margin-bottom: .35em; }
/* read-along: a square glows while its syllable is spoken; the speaker sits in the square after the sentence */
.ra-glow { position: absolute; pointer-events: none; background: #ffe07a; box-shadow: inset 0 0 0 4px #e0a800; border-radius: 4px; opacity: 0; transition: opacity .06s linear; }
.ra-glow.on { opacity: 1; }
.ra-speaker { position: absolute; display: flex; align-items: center; justify-content: center; border: 2px dashed var(--line-2); background: #fffdf8; border-radius: 10px; cursor: pointer; padding: 0; z-index: 2; }
.ra-speaker .ra-icon { font-size: 2.4em; line-height: 1; }
.ra-speaker:hover, .ra-speaker.playing { border-color: #f2c94c; background: #fff8dc; }
.ra-speaker:focus-visible { outline: 3px solid var(--blue); outline-offset: 2px; }
@media print { .ra-glow, .ra-speaker { display: none !important; } }
.ra-speaker.small { border-width: 1px; border-radius: 6px; }
.ra-speaker.small .ra-icon { font-size: 1em; }
