/* Book pages: /books/ (shelf), /books/<book>/ (lessons), /books/<book>/<lesson>/ — on top of theme.css.
   Generated by HeHeChinese/03-materialy/ksiazki/skrypty/build-books.py; the look is here. */
.cjk{font-family:var(--cjk)}
.lx,.booklist,.shelfrow,.lnav,.bmore,.sech,.secnote,.wmodes{max-width:1080px;margin-left:auto;margin-right:auto}

/* THE section heading of the site (lessons, book pages, home page): always on the page background, above its content.
   Chinese name in bold, the name in the page language in grey, an optional count; the instruction is a small line of its own
   (.secnote) under it. The same space above every section. (h2.sec = the same heading written by assets/app.js for 手机上.) */
.sech,h2.sec{display:flex;align-items:baseline;flex-wrap:wrap;gap:.25em .55em;margin-top:34px;margin-bottom:10px;font-size:1.05rem;font-weight:700;line-height:1.25;
  color:var(--ink-soft);scroll-margin-top:76px;letter-spacing:0;text-transform:none}
.sech .cjk,h2.sec .cjk{font-family:var(--cjk);color:var(--ink);font-size:1.3em;font-weight:700;letter-spacing:0;margin:0}
.sech small{font-size:.92em;font-weight:700;color:#8CA3B6}
.secnote{margin-top:-6px;margin-bottom:10px;font-size:.88rem;font-weight:600;color:var(--ink-soft);line-height:1.4}
.grid > .sech.ghead{grid-column:1 / -1;margin:18px 0 0}

/* lesson header: back button + book, then the title in a frame in the book's colour with the chapter picture */
.lhdr{display:block;margin-bottom:18px}
.lrow1{display:flex;align-items:center;gap:10px}
.lbook{display:inline-flex;align-items:center;gap:10px;margin:0 0 12px auto;text-decoration:none;color:var(--ink);font-weight:700;font-size:.95rem;min-height:44px;border-radius:10px;text-align:right;line-height:1.2}
.lbook:hover span.cjk{text-decoration:underline}
.lrow1 a.crumb{white-space:nowrap;flex:none}
.lbshort{display:none}
@media (max-width:560px){.lbfull{display:none}.lbshort{display:inline}}
.cover.cv-xxs{font-size:3.1px;box-shadow:0 1px 2px rgba(22,50,79,.3)}
.ltbox{--bk:var(--ink);display:flex;align-items:center;gap:16px;background:var(--paper);border:3px solid var(--bk);border-radius:22px;padding:14px 18px}
.lttxt{flex:1;min-width:0}
.lkick{margin:0 0 2px;font-size:.8rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--bk)}
.ltitle{margin:0;font-size:2.3rem;line-height:1.15}
.ltitle .lzh{font-family:var(--cjk)}
.lpy{margin:4px 0 0;font-size:1.15rem;font-weight:700;display:flex;flex-wrap:wrap;gap:.3em;justify-content:flex-start;opacity:1;transform:none;min-height:0}
.lmean{margin:2px 0 0;font-size:1.05rem;font-weight:600;color:var(--ink-soft)}
.chap{position:relative;display:block;overflow:hidden;background:var(--sky)}
.chap img{width:100%;height:100%;object-fit:cover;display:block}
.chzi{position:absolute;right:4%;bottom:4%;width:38%;height:38%;border-radius:22%;background:rgba(255,255,255,.92);color:var(--ink);font-weight:700;display:flex;align-items:center;justify-content:center;font-size:1.6rem;line-height:1;box-shadow:0 1px 3px rgba(22,50,79,.25)}
.lpic .chzi{font-size:1.05rem}
.ltbox .chap{flex:none;width:112px;height:112px;border-radius:18px}
.ltabs{display:flex;gap:8px;margin-top:12px;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;padding-bottom:2px}
.ltabs::-webkit-scrollbar{display:none}
.ltab{flex:none;display:inline-flex;align-items:center;min-height:44px;padding:0 18px;border:2px solid var(--line);border-radius:999px;background:var(--paper);color:var(--ink);font-weight:700;font-size:.98rem;text-decoration:none;white-space:nowrap}
.ltab:hover{border-color:#9EBBD2}
.ltab.play{background:var(--ok);border-color:var(--ok);color:#fff}
.ltab.play:hover{filter:brightness(1.08)}
.ltab:focus-visible,.playcard:focus-visible,.gclose:focus-visible,.wpart:focus-visible{outline:3px solid var(--glow);outline-offset:3px}
.lx{scroll-margin-top:76px}

/* words: "test yourself" — two ways to look at the cards. Hidden parts keep their place (a quiet "?"), so the cards never move. */
/* words: one switch, three segments (Learn / Read / Speak), always one chosen; the hint line under it follows the mode */
.wmodes{display:flex;gap:4px;padding:4px;margin-bottom:8px;background:var(--paper);border:2px solid var(--line);border-radius:16px}
.wmodes button{flex:1 1 0;min-width:0;appearance:none;font:inherit;font-size:.95rem;font-weight:700;color:var(--ink);background:transparent;border:0;border-radius:12px;
  min-height:48px;padding:4px 6px;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:7px;white-space:nowrap}
.wmodes button svg{width:22px;height:22px;flex:none}
.wmodes button:hover{background:#EEF4F9}
.wmodes button[aria-pressed="true"]{background:var(--ink);color:#fff}
.wmodes button:focus-visible{outline:3px solid var(--glow);outline-offset:2px}
@media (max-width:360px){.wmodes button{font-size:.86rem;gap:5px}.wmodes button svg{width:19px;height:19px}}
.wmhint{max-width:1080px;margin-left:auto;margin-right:auto}
.wmhint .secnote{display:none;margin-top:0}
body:not(.wm-read):not(.wm-speak) .wmh-learn,body.wm-read .wmh-read,body.wm-speak .wmh-speak{display:block}
/* Learn: the pinyin is on the card from the start (tone colours), not only after a tap */
body:not(.wm-read):not(.wm-speak) #grid .tile .pinyin{opacity:1;transform:none}
body.wm-read .tile:not(.on) .pic,body.wm-speak .tile:not(.on) .hanzi{position:relative}
body.wm-read .tile:not(.on) .pic > *,body.wm-read .tile:not(.on) .en{visibility:hidden}
body.wm-read .tile:not(.on) .pic::after,body.wm-speak .tile:not(.on) .hanzi::after{content:"?";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:3.2rem;height:3.2rem;border-radius:14px;background:var(--sky);color:#A9BFD2;font:700 1.5rem/3.2rem var(--ui);text-align:center}
body.wm-speak .tile:not(.on) .hanzi{color:transparent;min-width:3.2rem;min-height:3.2rem}
body.wm-speak .tile:not(.on) .hanzi::after{width:100%;min-width:3.2rem;height:100%}
body.wm-speak .tile:not(.on):not(.nq) .en{visibility:hidden}
/* a picture that is not clear enough to ask about: the meaning stands in its place */
body.wm-speak .tile.nq:not(.on) .pic{display:none}
body.wm-speak .tile.nq:not(.on) .en{order:-1;margin-top:0;min-height:3.4rem;display:flex;align-items:center;justify-content:center;font-size:1.02rem;color:var(--ink);font-weight:700}

/* 生字 strip: tiles in the tone colour — colours, border, hover and focus are the shared .ztile/.zi rules in theme.css */
.zis{margin-bottom:0}
.zirow{display:flex;flex-wrap:wrap;gap:8px}
.zi{appearance:none;border-radius:14px;min-width:3.6rem;padding:6px 8px 5px;cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:0}
.zi .zih{font-size:1.75rem;line-height:1.15}
.zi .zip{font-family:var(--py);font-size:.86rem;font-weight:700;line-height:1.25;color:var(--tc)}
.zi.playing{border-color:var(--tc);box-shadow:0 0 0 3px var(--glow)}
.zi[aria-pressed="true"]{border-color:var(--tc);background:#fff;box-shadow:0 2px 0 var(--tc)}
.pbtn:focus-visible,.snd:focus-visible,.lcard:focus-visible,.bcard:focus-visible,.lnav a:focus-visible,.lbook:focus-visible{outline:3px solid var(--glow);outline-offset:3px}

/* "★ I know it!" (assets/book.js): a word the child had in another of its books. Violet = outside the four tone colours.
   The seal is small, its touch area is 44 px (::after); the bubble opens under the card with an arrow (.up = above it). */
.tile,.zi{position:relative}
.xue{position:absolute;top:7px;left:7px;z-index:2;display:inline-flex;align-items:center;font-weight:800;font-size:.78rem;line-height:1;
  color:#fff;background:#7B4FD6;border-radius:8px;padding:4px 7px 3px;transform:rotate(-8deg);box-shadow:0 1px 0 rgba(0,0,0,.12);
  cursor:pointer;white-space:nowrap;-webkit-tap-highlight-color:transparent}
.xue::before{content:"★";font-size:.72rem;margin-right:3px;color:#FFD76B}
.xue::after{content:"";position:absolute;inset:-12px -8px}
.xue:focus-visible{outline:3px solid var(--glow);outline-offset:2px}
.zi .xue{top:-9px;left:-9px;font-size:.6rem;padding:3px 4px 2px}
.zi .xue::before{display:none}
.tile.known{border-color:#D9CCF5}
.xuesum{max-width:1080px;margin:-4px auto 12px;display:flex;align-items:center;gap:12px;font-size:.95rem;font-weight:700;color:var(--ink);
  background:#F4EFFD;border:2px solid #E2D7F8;border-radius:14px;padding:9px 14px}
.xuesum .xue{position:static;flex:none}
.xuesum .xue::after{display:none}
.xuesum .stx{min-width:0}
.xuesum small{display:block;font-weight:600;color:var(--ink-soft);font-size:.8rem}
.xuesum .scov{margin-left:auto;display:flex;gap:8px;flex:none}
.xuesum .scov a{line-height:0;display:block}
.xuesum .scov .cover{font-size:4.6px}
.xuepop{position:absolute;z-index:50;width:min(300px,calc(100vw - 32px));background:var(--paper);border:2px solid #D9CCF5;border-radius:16px;
  box-shadow:0 10px 30px rgba(22,50,79,.18);padding:8px 10px;color:var(--ink)}
.xuepop::before{content:"";position:absolute;left:var(--ax,24px);top:-9px;width:14px;height:14px;background:var(--paper);
  border-left:2px solid #D9CCF5;border-top:2px solid #D9CCF5;transform:rotate(45deg)}
.xuepop.up::before{top:auto;bottom:-9px;transform:rotate(225deg)}
.xuepop a{display:flex;align-items:center;gap:14px;text-decoration:none;color:var(--ink);padding:8px;border-radius:10px}
.xuepop a:hover{background:#F4EFFD}
.xuepop .pcov{flex:none;display:block;line-height:0}
.xuepop .pcov .cover{font-size:6.2px}
.xuepop .ptx{display:flex;flex-direction:column;gap:2px;min-width:0}
.xuepop .kn{font-style:normal;font-weight:700;font-size:.85rem;color:#7B4FD6}
.xuepop b{font-size:1.1rem;line-height:1.2}
.xuepop small{color:var(--ink-soft);font-weight:600;font-size:.82rem}
.xuepop .go{margin-left:auto;font-size:1.2rem;color:var(--ink-soft)}
@media (max-width:560px){.xuesum{gap:10px;padding:8px 10px;font-size:.9rem}.xuesum .scov{gap:5px}.xuesum .scov .cover{font-size:3.3px}}

/* sentences with pinyin */
.says{margin-top:0;margin-bottom:0}
.says .zhp{display:flex;flex-direction:column;gap:2px}
.says .pinyin{justify-content:flex-start;font-size:1rem;opacity:1;transform:none}
.sndrow{display:flex;flex-wrap:wrap;gap:8px}
.snd{font-family:var(--py);font-weight:700;font-size:1.25rem;min-width:3rem;text-align:center;text-decoration:none;color:var(--ink);background:var(--paper);border:2px solid var(--line);border-radius:14px;padding:6px 14px}
.snd:hover{border-color:#9EBBD2}
.pbtn{appearance:none;font-family:var(--ui);font-size:1rem;font-weight:700;color:#fff;background:var(--ok);border:0;border-radius:999px;padding:11px 20px;cursor:pointer;
  display:inline-flex;align-items:center;gap:.4em;min-height:44px;text-decoration:none}
.pbtn.run{background:var(--ink)}
.pbtn:hover{filter:brightness(1.08)}
.playrow{display:grid;gap:12px;grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:860px){.playrow{grid-template-columns:1fr}}
.playcard{appearance:none;font:inherit;text-align:left;cursor:pointer;display:flex;align-items:center;gap:12px;border:2px solid var(--line);border-radius:18px;padding:12px 14px;background:#F3FAF6;
  color:var(--ink);text-decoration:none;min-height:72px;transition:border-color .15s,transform .15s,box-shadow .15s}
.playcard:hover{border-color:var(--ok);transform:translateY(-2px);box-shadow:0 6px 16px rgba(22,50,79,.08)}
.pico{flex:none;width:44px;height:44px;object-fit:contain}
.pico.spk{border-radius:50%;background:var(--ok);display:flex;align-items:center;justify-content:center}
.ptxt{flex:1;min-width:0;display:flex;flex-direction:column}
.ptxt b{font-size:1.08rem;line-height:1.2}
.ptxt b .cjk{font-size:.85rem;color:var(--ink-soft);margin-left:.2em;white-space:nowrap}
.ptxt small{font-size:.84rem;font-weight:600;color:var(--ink-soft)}
/* a lesson with too few words: its games also ask earlier lessons — "Lesson 5 + review of lessons 3–4" under the game's line;
   a lesson without a game (too few even with the review): one line under the cards, "Game from lesson 3" (build-books.py) */
.ptxt .grev{display:block;margin-top:3px;color:var(--ok);font-weight:700}
.gfrom{margin-top:10px;font-size:.92rem;font-weight:700}
.gfrom a{color:var(--ok);text-decoration:underline;text-underline-offset:3px}
.playcard .gplay{flex:none;background:var(--ok);color:#fff;font-weight:700;border-radius:999px;padding:5px 14px;font-size:.95rem;white-space:nowrap}
/* AI practice card: locked until a parent turns AI practice on — assets/tutor.js puts "ai-on" on <html>; without it (also
   when the script has not loaded) the card is grey with a lock, and a tap opens the parent gate, not the practice */
.playcard .gplay.lock{display:none;align-items:center;gap:6px;background:#5A748C}
html:not(.ai-on) .playcard[data-open="ai"]{filter:grayscale(1);flex-wrap:wrap;background:#F6F8FA}
html:not(.ai-on) .playcard[data-open="ai"] .pico,html:not(.ai-on) .playcard[data-open="ai"] .ptxt{opacity:.6}
html:not(.ai-on) .playcard[data-open="ai"] .ptxt{flex:1 1 60%}
html:not(.ai-on) .playcard[data-open="ai"] .gplay.go{display:none}
html:not(.ai-on) .playcard[data-open="ai"] .gplay.lock{display:inline-flex}
@media (prefers-reduced-motion:reduce){.playcard{transition:none}.playcard:hover{transform:none}}

/* "Listen and find": full-screen layer */
body.game-open{overflow:hidden}
.govl{position:fixed;inset:0;z-index:80;background:var(--sky);overflow-y:auto;-webkit-overflow-scrolling:touch;padding:0 16px 32px}
.gotop{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:12px;max-width:1080px;margin:0 auto;padding:10px 0;background:var(--sky)}
.gotitle{flex:1;min-width:0;font-weight:700;color:var(--ink-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gotitle .cjk{color:var(--ink);font-size:1.1rem}
.gclose{appearance:none;flex:none;width:48px;height:48px;border-radius:50%;border:2px solid var(--line);background:var(--paper);color:var(--ink);font-size:1.3rem;font-weight:700;cursor:pointer;line-height:1}
.gclose:hover{border-color:#9EBBD2}
.govl .game{margin-top:6px}

/* lessons: one row — previous · all lessons · next */
.lnav{margin-top:34px;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);gap:10px;align-items:stretch}
.lnav a{display:flex;align-items:center;gap:10px;text-decoration:none;color:var(--ink);background:var(--paper);border:2px solid var(--line);border-radius:18px;padding:8px 14px;min-height:56px;min-width:0}
.lnav a:hover{border-color:#9EBBD2}
.lnav .next{justify-content:flex-end;text-align:right}
.lnav .next .ar{order:2}
.lnav .ar{font-size:1.7rem;line-height:1;color:var(--ink-soft)}
.lnav small{display:block;font-size:.8rem;font-weight:700;color:var(--ink-soft)}
.lnav b{display:block;font-size:1.1rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lnav a > span:not(.ar){min-width:0}
.lnav .all{justify-content:center;text-align:center;font-weight:700;font-size:.9rem;color:var(--ink-soft);padding:8px 16px;line-height:1.2}
.bmore{margin-top:18px;font-size:.92rem;font-weight:600;color:var(--ink-soft)}
.bmore a{color:var(--ink)}

/* book page: the header is a frame in the book's colour, like the title of a lesson (.ltbox) — kicker, title with the volume
   in a circle, one grey line, three numbers and the main button on the left; the cover, slightly turned, on the right.
   --bk / --bkd (darker) / --bkg (16 % glow) come from build-books.py (bk_vars). Phone: small cover in the top right corner
   next to the title, numbers and button full width under it. */
.bhdr{display:block}
.bkbox{--bk:var(--ink);--bkd:var(--ink);--bkg:rgba(22,50,79,.12);display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:30px;align-items:start;margin-top:4px;
  background:radial-gradient(circle at 100% 0,var(--bkg),rgba(255,255,255,0) 58%),var(--paper);border:3px solid var(--bk);border-radius:22px;padding:22px 26px}
.bkbox > *{grid-column:1;min-width:0}
.bkbox > .cover{grid-column:2;grid-row:1 / span 6;align-self:center;font-size:17px;margin:8px 10px 8px 0;transform:rotate(4deg);box-shadow:0 14px 28px rgba(22,50,79,.28)}
.bktitle{margin:0;font-size:2.4rem;line-height:1.15;display:flex;align-items:center;flex-wrap:wrap;gap:.25em}
.bzh{font-size:1em!important;margin-left:-.25em!important;color:var(--ink)!important}
.bkvol{flex:none;display:inline-flex;align-items:center;justify-content:center;width:1.55em;height:1.55em;border-radius:50%;background:#FFE14D;border:3px solid var(--bk);
  font-size:.62em;font-weight:800;line-height:1;color:var(--ink)}
.bname{margin:6px 0 0;color:var(--ink-soft);font-weight:600;line-height:1.4}
.bsub{margin:2px 0 0;font-weight:700;color:var(--ink-soft)}
.bkstats{display:flex;gap:10px;margin-top:16px}
.bkstats div{flex:0 1 128px;min-width:0;display:flex;flex-direction:column;background:var(--paper);border:2px solid var(--line);border-radius:16px;padding:8px 14px 9px}
.bkstats b{font-size:1.8rem;line-height:1.1;color:var(--bk)}
.bkstats span{font-size:.84rem;font-weight:700;color:var(--ink-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bkgo{justify-self:start;display:inline-flex;align-items:baseline;gap:.45em;max-width:100%;box-sizing:border-box;margin-top:18px;padding:12px 24px;border-radius:999px;
  background:var(--bk);color:#fff;font-weight:700;font-size:1.17rem;line-height:1.3;text-decoration:none;white-space:nowrap;box-shadow:0 3px 0 var(--bkd);transition:transform .1s,box-shadow .1s}
.bkgo .bkgot{flex:none}
.bkgo .cjk{font-family:var(--cjk);min-width:0;overflow:hidden;text-overflow:ellipsis}
.bkgo:hover{filter:brightness(1.06)}
.bkgo:active{transform:translateY(2px);box-shadow:0 1px 0 var(--bkd)}
.bkgo:focus-visible{outline:3px solid var(--glow);outline-offset:3px}
.bknote{margin:14px 0 0;font-size:.88rem;font-weight:600;color:var(--ink-soft);line-height:1.4}
@media (max-width:640px){
  .bkbox{padding:16px 16px 18px;column-gap:12px}
  .bkbox > .cover{grid-row:1 / span 3;align-self:start;font-size:8.4px;margin:2px 4px 0 0;box-shadow:0 8px 16px rgba(22,50,79,.28)}
  .bkbox > .bkstats,.bkbox > .bkgo,.bkbox > .bknote{grid-column:1 / -1}
  .bktitle{font-size:1.7rem}
  .bname{font-size:.9rem}
  .bkstats{gap:8px}
  .bkstats div{flex:1 1 auto;padding:7px 8px 8px}
  .bkstats span{font-size:.8rem}
  .bkstats b{font-size:1.55rem}
  .bkgo{justify-self:stretch;justify-content:center;gap:.35em;padding:12px 10px;font-size:1rem}
}
@media (prefers-reduced-motion:reduce){.bkgo{transition:none}}
.lessons{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(270px,1fr))}
.lcard{display:grid;grid-template-columns:auto 1fr;gap:2px 14px;align-items:center;text-decoration:none;color:var(--ink);background:var(--paper);border:2px solid var(--line);border-radius:20px;padding:12px 14px;
  transition:border-color .15s,transform .15s,box-shadow .15s}
.lcard:hover{border-color:#9EBBD2;transform:translateY(-2px);box-shadow:0 6px 16px rgba(22,50,79,.08)}
/* the lesson the phone remembers: border and glow in the book's colour + the badge "You are here" on a row of its own above
   the picture and the title (it can never cover the title or the pinyin, however long they are) */
.lcard.last{border-color:var(--bk,var(--ink));box-shadow:0 0 0 4px var(--bkg,rgba(22,50,79,.12))}
.lcard.last .lpic{grid-row:2 / span 2;grid-column:1}.lcard.last .lt{grid-row:2;grid-column:2}.lcard.last .lm{grid-row:3;grid-column:2}
.lhere{grid-row:1;grid-column:1 / -1;justify-self:start;margin:0 0 10px;padding:3px 11px;border-radius:999px;background:var(--bkd,var(--ink));color:#fff;font-size:.76rem;font-weight:700;letter-spacing:.02em;line-height:1.3;white-space:nowrap}
.lpic{grid-row:1 / span 2;position:relative;width:72px;height:72px;border-radius:16px;background:var(--sky);display:block}
.lpic .chap{width:100%;height:100%;border-radius:16px}
.lno{position:absolute;left:-6px;top:-6px;min-width:26px;height:26px;padding:0 6px;border-radius:13px;background:var(--ink);color:#fff;font-weight:700;font-size:.85rem;line-height:26px;text-align:center;box-shadow:0 0 0 2px var(--paper)}
.lcard.nopic .lpic{width:52px;height:52px;border-radius:50%}
.lcard.nopic .lno{position:static;display:flex;align-items:center;justify-content:center;width:52px;height:52px;border-radius:50%;background:none;color:var(--ink);font-size:1.2rem;box-shadow:none;padding:0}
.lt{display:flex;align-items:baseline;gap:.5em;flex-wrap:wrap}
.lt b{font-size:1.4rem;line-height:1.2}
.lt .pinyin{font-size:.9rem;opacity:1;transform:none;min-height:0}
.lm{font-size:.92rem;font-weight:600;color:var(--ink-soft);align-self:start}
.lprev{grid-column:1 / -1;margin-top:8px;display:flex;gap:6px;flex-wrap:wrap;font-weight:700;font-size:1.05rem;color:var(--ink-soft)}
.lprev i{font-style:normal}
.lcount{grid-column:1 / -1;font-size:.8rem;font-weight:700;color:#8CA3B6}
@media (prefers-reduced-motion:reduce){.lcard{transition:none}.lcard:hover{transform:none}}
/* preview page of the chapter pictures */
.chprev{display:flex;flex-direction:column;gap:14px}
.chrow{display:grid;grid-template-columns:minmax(120px,220px) 1fr;gap:4px 16px;align-items:center}
.chrow > span{grid-column:1;font-size:.85rem;color:var(--ink-soft);font-weight:600}
.chrow > div{grid-column:2;grid-row:1 / span 2;display:flex;gap:18px;flex-wrap:wrap}
.chrow figure{margin:0;display:flex;align-items:flex-end;gap:8px}
.chrow figure .chap{border-radius:18px;width:112px;height:112px}
.chrow figure .chap + .chap{width:72px;height:72px;border-radius:16px}
.chrow figcaption{font-weight:700;color:var(--ink-soft)}

/* shelf */
.shelfrow{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(230px,1fr))}
.bcard{display:flex;flex-direction:column;gap:2px;text-decoration:none;color:var(--ink);background:var(--paper);border:2px solid var(--line);border-left:10px solid var(--t4);border-radius:8px 20px 20px 8px;padding:18px 18px 16px;min-height:150px}
.bcard:nth-child(2){border-left-color:var(--t3)}.bcard:nth-child(3){border-left-color:var(--t2)}.bcard:nth-child(4){border-left-color:var(--t1)}
.bcard:hover{border-color:#9EBBD2;border-left-color:var(--ink)}
.bcard b{font-size:1.7rem;line-height:1.2}
.bcard .bsub{font-size:.95rem}
.bage{margin-top:auto;font-size:.88rem;font-weight:600;color:var(--ink-soft)}
.bn{font-size:.8rem;font-weight:700;color:#8CA3B6}

@media (max-width:560px){
  .zi{min-width:3.1rem;padding:5px 6px 4px}.zi .zih{font-size:1.5rem}
  .lnav b{font-size:1.05rem}
  .ltbox{padding:12px 14px;gap:12px}
  .ltitle{font-size:1.8rem}
  .ltbox .chap{width:84px;height:84px;border-radius:16px}
  .ltbox .chzi{font-size:1.2rem}
  .lbook{font-size:.84rem}
  .lnav{gap:6px}.lnav a{padding:6px 8px;gap:6px;border-radius:14px}.lnav b{font-size:.92rem}.lnav small{font-size:.72rem}.lnav .all{padding:6px 8px;font-size:.78rem;max-width:5.6em}.lnav .ar{font-size:1.3rem}
  .sech{margin-top:28px}
}

/* ---------- book covers, our own interpretation (not scans): colour, layout and title like the real book so a parent
   recognises it; our own illustration; title and volume number are set by the page. Everything is in em:
   the size class sets font-size, a cover is always 10em x 14em. ---------- */
.cover{position:relative;display:inline-block;flex:none;width:10em;height:14em;font-size:12px;border-radius:.25em .55em .55em .25em;overflow:hidden;
  box-shadow:0 .12em .35em rgba(22,50,79,.28), inset .22em 0 .3em -.18em rgba(0,0,0,.35);background:#fff;color:#16324F;line-height:1;text-align:center;user-select:none}
.cover.cv-xs{font-size:6.4px}.cover.cv-s{font-size:9px}.cover.cv-m{font-size:12px}.cover.cv-l{font-size:20px}.cover.cv-xl{font-size:28px}
.cover > *{position:absolute;margin:0;white-space:nowrap}
.cover img{display:block}
.cover .cjk{font-family:var(--cjk)}

/* 《幼儿汉语》: flat colour per volume, leafy green frame, number in a yellow oval, red title with a white edge, picture cards */
.cv-youer{background:
  radial-gradient(circle at 30% 30%, #49C34D 0 34%, transparent 36%) 0 0/.62em .62em,
  radial-gradient(circle at 70% 75%, #1C8A2B 0 30%, transparent 32%) .31em .2em/.62em .62em, #2FA63A}
.cv-youer .cv-panel{left:.5em;top:.5em;right:.5em;bottom:.5em;border-radius:.2em;background:var(--vol,#FFC928)}
.cv-y1{--vol:#FFC928}.cv-y2{--vol:#F58BE2}.cv-y3{--vol:#A5EC4E}.cv-y4{--vol:#88C4F0}
.cv-youer .cv-num{left:50%;top:1em;width:1.7em;height:1.05em;margin-left:-.85em;border-radius:50%;background:#FFEE4D;box-shadow:0 0 0 .07em #16324F;
  font:700 .95em/1.1 Georgia,"Times New Roman",serif;color:#16324F}
.cv-youer .cv-num b{font-size:1em;line-height:1.1}
.cv-youer .cv-latin{left:0;right:0;top:2.75em;font-family:var(--ui);font-weight:700;font-size:.82em;letter-spacing:.04em;color:#fff;
  text-shadow:.06em 0 0 #5B6B2E,-.06em 0 0 #5B6B2E,0 .06em 0 #5B6B2E,0 -.06em 0 #5B6B2E,.05em .05em 0 #5B6B2E,-.05em .05em 0 #5B6B2E,.05em -.05em 0 #5B6B2E,-.05em -.05em 0 #5B6B2E}
.cv-youer .cv-title{left:0;right:0;top:1.85em;font-family:var(--cjk);font-weight:700;font-size:1.95em;letter-spacing:.06em;color:#E8231A;
  text-shadow:.045em 0 0 #fff,-.045em 0 0 #fff,0 .045em 0 #fff,0 -.045em 0 #fff,.035em .035em 0 #fff,-.035em .035em 0 #fff,.035em -.035em 0 #fff,-.035em -.035em 0 #fff,.08em .09em .02em rgba(0,0,0,.25)}
.cv-youer .cv-art{left:.8em;right:.8em;bottom:.8em;top:5.9em}
.cv-youer .cv-art img,.cv-zw .cv-art img{width:100%;height:100%;object-fit:contain}

/* 《汉语拼音》: cream cover sprinkled with pale letters, green latin title, yellow Chinese title, blue field with letters */
.cv-py{background:#F5F2E7;font-family:var(--py)}
.cv-py .cv-l{font-weight:700;color:#B9D36A}
.cv-py .cv-g{color:#C9C7C2}
.cv-py .cv-tag{left:50%;top:.55em;transform:translateX(-50%);white-space:nowrap;font-family:var(--cjk);font-weight:700;font-size:.42em;letter-spacing:.12em;color:#fff;background:#C8A72C;padding:.25em .7em}
.cv-py .cv-latin{left:0;right:0;top:1.75em;font-family:Georgia,"Times New Roman",serif;font-size:.78em;letter-spacing:.12em;color:#3F8A3A}
.cv-py .cv-title{left:0;right:0;top:1.4em;font-family:var(--cjk);font-weight:700;font-size:1.9em;letter-spacing:.04em;color:#FFD21F;
  text-shadow:.05em .06em 0 #A8641A,.03em .03em 0 #A8641A}
.cv-py .cv-field{left:2em;top:5.1em;width:6.3em;height:7.4em;background:#789FD4;box-shadow:.05em .08em .12em rgba(0,0,0,.25)}
.cv-py .cv-field span{position:absolute;font-weight:700;font-size:1em;color:#fff;text-shadow:.04em .05em .05em rgba(0,0,0,.25)}
.cv-py .cv-art{width:2.5em;height:2.5em}
.cv-py .cv-art img{width:100%;height:100%;object-fit:contain}

/* 《中文》 小学·欧洲版: white cover, brush title with a red volume seal, "CHINESE", children playing outdoors below */
.cv-zw{background:#fff;box-shadow:0 .12em .35em rgba(22,50,79,.28), inset 0 0 0 .05em #E3E8EC, inset .22em 0 .3em -.18em rgba(0,0,0,.25)}
.cv-zw .cv-ed{right:.6em;top:.55em;font-family:var(--cjk);font-weight:700;font-size:.4em;color:#7A8794;letter-spacing:.05em}
.cv-zw .cv-title{left:0;right:.35em;top:.24em;font-family:"Ma Shan Zheng","Kaiti SC","STKaiti","KaiTi",var(--cjk);font-weight:400;font-size:3.5em;color:#111;letter-spacing:.02em}
.cv-zw .cv-seal{right:3.1em;top:2.6em;width:1.4em;padding:.3em 0;border-radius:.16em;background:#C6261E;color:#fff;font-family:var(--cjk);font-weight:700;font-size:.55em;line-height:1.12;
  display:flex;flex-direction:column;align-items:center}
.cv-zw .cv-seal i{font-style:normal;display:block}
.cv-zw .cv-latin{left:0;right:0;top:5.05em;font-family:Georgia,"Times New Roman",serif;font-size:.95em;letter-spacing:.06em;color:#8A5A2B}
.cv-zw .cv-art{left:0;right:0;bottom:0;top:6.3em}
.cv-zw .cv-art img{object-fit:cover;object-position:50% 100%;-webkit-mask-image:linear-gradient(transparent 4%,#000 34%);mask-image:linear-gradient(transparent 4%,#000 34%)}

/* covers on the shelf and on a book page */
.bcard.has-cover{flex-direction:row;gap:14px;align-items:flex-start;border-left-width:2px;border-radius:20px;min-height:0}
.bcard.has-cover .binfo{display:flex;flex-direction:column;gap:2px;min-height:168px;flex:1}
.covpick{max-width:1080px;margin:0 auto 26px;background:var(--paper);border:2px solid var(--line);border-radius:20px;padding:16px 18px}
.covpick h2{margin:0 0 4px;font-size:1.2rem}
.covpick p{margin:0 0 12px;color:var(--ink-soft);font-size:.92rem}
.covrow{display:flex;flex-wrap:wrap;gap:22px;align-items:flex-end}
.covrow figure{margin:0;display:flex;flex-direction:column;align-items:center;gap:6px}
.covrow figcaption{font-size:.8rem;font-weight:700;color:var(--ink-soft)}
.shelfrow{grid-template-columns:repeat(auto-fill,minmax(300px,1fr))}
.bcard.has-cover b{font-size:1.45rem;white-space:nowrap}
.bcard.has-cover .bsub{white-space:nowrap}

/* characters and writing: the box under the strip — stroke stage, what the character means, the two buttons */
.wbox{display:flex;flex-wrap:wrap;gap:16px;align-items:flex-start;margin-top:14px;background:var(--paper);border:2px solid var(--line);border-radius:20px;padding:14px}
.wstage{flex:none;width:240px;height:240px;max-width:100%;border:2px solid var(--line);border-radius:16px;display:flex;align-items:center;justify-content:center;touch-action:none;
  background-color:#FCFDFE;
  background-image:linear-gradient(to right,transparent calc(50% - 1px),#DCE7F0 calc(50% - 1px),#DCE7F0 calc(50% + 1px),transparent calc(50% + 1px)),
    linear-gradient(to bottom,transparent calc(50% - 1px),#DCE7F0 calc(50% - 1px),#DCE7F0 calc(50% + 1px),transparent calc(50% + 1px))}
.wbig{font-size:150px;line-height:1;font-weight:500;color:#16324F}
.wside{flex:1 1 240px;min-width:0;display:flex;flex-direction:column;gap:14px}
.winfo{display:flex;align-items:center;gap:14px;min-height:72px}
.wpic{flex:none;width:64px;height:64px;object-fit:contain}
.wtxt{display:flex;flex-direction:column;gap:2px;min-width:0}
.wzi{display:flex;align-items:baseline;gap:.5em}
.wzi b{font-size:1.9rem;line-height:1.1}
.wpy{font-family:var(--py);font-weight:700;font-size:1.25rem}
.wpy.t1{color:var(--t1)}.wpy.t2{color:var(--t2)}.wpy.t3{color:var(--t3)}.wpy.t4{color:var(--t4)}.wpy.t0{color:var(--t0)}
.wmean{font-size:1.05rem;font-weight:700;color:var(--ink)}
.wpart{appearance:none;font:inherit;text-align:left;cursor:pointer;margin-top:4px;font-size:.92rem;font-weight:600;color:var(--ink-soft);background:var(--sky);border:0;border-radius:12px;padding:6px 10px;line-height:1.35}
.wpart b{color:var(--ink);font-size:1.15em}
.wpart img{width:30px;height:30px;object-fit:contain;vertical-align:middle;margin-right:6px}
.wppy{font-family:var(--py);font-weight:700}
.wpart.playing{box-shadow:0 0 0 3px var(--glow)}
.wctl{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.wmsg{font-weight:700;color:var(--ok);min-height:1.4em}
@media (max-width:560px){ .wbox{padding:12px} .wstage{width:100%;height:auto;aspect-ratio:1/1;max-width:300px;margin:0 auto} .wside{flex-basis:100%} .wctl .pbtn{flex:1 1 100%;justify-content:center} }

/* 打印 · print sheets at the bottom of a topic page (food, drinks) */
.psheets{max-width:1080px;margin:0 auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,170px));gap:16px;background:var(--paper);border:2px solid var(--line);border-radius:20px;padding:16px}
.psheet{display:flex;flex-direction:column;gap:8px;text-decoration:none;color:var(--ink)}
.psheet img{display:block;width:100%;height:auto;aspect-ratio:210/297;object-fit:cover;border:2px solid var(--line);border-radius:8px;background:#fff}
.psheet:hover img{border-color:#9EBBD2}
.psheet .cap{display:flex;align-items:center;gap:8px}
.psheet .titles{display:flex;flex-direction:column}
.psheet .t{font-weight:700;font-size:1rem}
.psheet .s{font-size:.8rem;font-weight:600;color:var(--ink-soft)}
.psheet .dl{margin-left:auto;font-weight:700;font-size:1.1rem}
.psheet:focus-visible{outline:3px solid var(--glow);outline-offset:3px}

/* 说一说 as a conversation (15 Oct 2026): bubbles, pinyin under each character, tap = play */
.dlg{max-width:1080px;margin:0 auto 22px;display:flex;flex-direction:column;gap:14px}
.dctl{display:flex;gap:10px;flex-wrap:wrap}
.dbtn{border:2px solid var(--line);background:var(--paper);border-radius:999px;padding:8px 16px;font:inherit;font-weight:700;cursor:pointer;color:var(--ink)}
.dbtn.you{background:#2E7D32;border-color:#2E7D32;color:#fff}
.dbtn:disabled{opacity:.5;cursor:default}
.dl{display:flex;align-items:flex-end;gap:10px;width:100%;max-width:800px}
.dl.r{flex-direction:row-reverse}
.dav{width:44px;height:44px;flex:none;background:var(--paper);border:2px solid var(--line);border-radius:50%;padding:5px;box-sizing:border-box}
.dcol{display:flex;flex-direction:column;max-width:calc(100% - 56px)}
.dl.r .dcol{align-items:flex-end}
.dlg .bub{margin:0;position:relative;display:block;text-align:left;border:2px solid var(--line);background:var(--paper);border-radius:22px 22px 22px 6px;padding:14px 46px 12px 18px;font:inherit;cursor:pointer;color:var(--ink);transition:transform .12s,border-color .12s}
.dl.r .bub{border-radius:22px 22px 6px 22px;background:#F1F8F1;border-color:#CFE5CF}
.dlg .bub:hover{border-color:#9EBBD2;transform:translateY(-1px)}
.dlg .bub.playing{border-color:var(--ink);box-shadow:0 0 0 4px var(--glow)}
.bub .spk{position:absolute;right:14px;top:12px;font-size:1.05rem;opacity:.55}
.rr{display:flex;flex-wrap:wrap;align-items:flex-end;gap:0 7px}
.rb{display:inline-flex;flex-direction:column;align-items:center;min-width:1.15em}
.rz{font-family:var(--cjk,inherit);font-size:2.4rem;line-height:1.15;font-weight:700}
.rp{font-size:.95rem;font-weight:700;line-height:1.2;margin-top:2px}
.rb.pu{min-width:.6em}
.dcol .tr{font-size:.85rem;color:var(--ink-soft);margin:5px 8px 0}
.bub .zh{font-size:1.8rem;font-weight:700;display:block}
.dlg.turn .dl.mine .bub{border-style:dashed;animation:dpulse 1s ease-in-out infinite}
.dlg.turn .dl.mine .bub .rr,.dlg.turn .dl.mine .tr{visibility:hidden}
.dlg.turn .dl.mine .bub::after{content:"🎤";position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:2rem}
@keyframes dpulse{50%{transform:scale(1.03)}}
@media (max-width:560px){.rr{gap:0 4px}.rz{font-size:1.7rem}.rp{font-size:.8rem}.dav{width:36px;height:36px}.dlg .bub{padding:12px 38px 10px 14px}}
@media (prefers-reduced-motion:reduce){.dlg.turn .dl.mine .bub{animation:none}}
.rp{font-family:var(--py)}
.rg{display:inline-flex;align-items:flex-end;white-space:nowrap}
.rb.pu{min-width:0}
.rb.pu .rz{margin-left:-2px}
/* spacing (16 Oct): a bit more air under the buttons, less under the last bubble (its translation already adds some) */
.dlg{gap:12px;margin-bottom:-12px}
.dctl{margin-bottom:6px}
/* your turn: record, then "You:" + "Model:" (16 Oct) */
.dlg.turn .dl.mine .bub::after{content:none}
.dlg.turn .dl.mine .bub{animation:none;border-color:#2E7D32}
.drec{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;background:inherit;border-radius:inherit;padding:8px;cursor:default}
.drec b{font-size:.95rem}
.dbar{display:block;width:70%;height:6px;background:#DCEBDC;border-radius:3px;overflow:hidden}
.dbar i{display:block;height:100%;width:100%;background:#2E7D32;transform-origin:left;transform:scaleX(1)}
.drec.go .dbar i{animation:dshrink linear forwards}
@keyframes dshrink{to{transform:scaleX(0)}}
.drec .ddone{padding:4px 12px;font-size:.85rem}
.dtag{font-size:.8rem;font-weight:700;color:#2E7D32;margin:0 8px 3px}
/* 16 Oct, round 3: narrower talk, clauses wrap only after a comma, your turn shows the characters (pinyin behind a hint) */
.dl{max-width:680px}
.rcl{display:inline-flex;flex-wrap:nowrap;align-items:flex-end;gap:0 7px}
.rr{row-gap:10px}
@media (max-width:560px){.rcl{gap:0 4px;flex-wrap:wrap}}
.dlg.turn .dl.mine .bub .rr{visibility:visible}
.dlg.turn .dl.mine .rp{visibility:hidden}
.dlg.turn .dl.mine.hint .rp{visibility:visible}
.dlg.memo.turn .dl.mine .rz{visibility:hidden}
.dlg.memo.turn .dl.mine.hint .rz{visibility:visible}
.drec{position:static;inset:auto;background:none;padding:10px 0 0;flex-direction:row;flex-wrap:wrap;justify-content:flex-start;gap:8px 10px}
.drec b{flex-basis:100%}
.drec .dbar{flex:1 1 120px;width:auto}
.dbtn.memo[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:#fff}
/* three modes (16 Oct, round 4) */
.dlg .dmodes{width:100%;max-width:none;margin:0}
.dmodes button{flex:1;display:flex;align-items:center;justify-content:center;gap:8px;border:0;background:none;border-radius:12px;padding:10px 8px;font:inherit;font-weight:700;cursor:pointer;color:var(--ink)}
.dmhint p{display:none;margin:0}
.dmhint[data-m="all"] .dmh-all,.dmhint[data-m="you"] .dmh-you,.dmhint[data-m="memo"] .dmh-memo{display:block}
.dlg .dmhint{margin-top:-4px}
/* roles (16 Oct, round 5): your bubble shows the characters only; pinyin + translation come back with the check */
.dlg.turn .dl.mine .tr{visibility:hidden}
/* centred conversation + big screens / classroom board (16 Oct, round 6) */
.dl{margin-left:auto;margin-right:auto}
.dmhint{text-align:center}
@media (min-width:1600px){
  .dl{max-width:900px}
  .rz{font-size:3.2rem}
  .rp{font-size:1.2rem}
  .dav{width:60px;height:60px}
  .dcol{max-width:calc(100% - 72px)}
  .dcol .tr{font-size:1rem}
  .dmodes button{font-size:1.05rem;padding:13px 8px}
}
/* the hint of the role modes (Listen / I answer / I ask) — the old rule above only knew all/you/memo */
.dmhint[data-m="ans"] .dmh-ans,.dmhint[data-m="ask"] .dmh-ask{display:block}
/* /say/: conversations by situation, one after another (16 Oct 2026) */
.sayset header h1{display:flex;align-items:center;gap:.35em;flex-wrap:wrap}
.sayset .sayic{width:1.15em;height:1.15em}
.saynav{max-width:1080px;margin:0 auto 18px;display:flex;flex-wrap:wrap;gap:8px}
.saynav a{display:inline-flex;align-items:center;gap:6px;padding:6px 12px 6px 8px;border:2px solid var(--line);border-radius:999px;background:var(--paper);color:var(--ink);text-decoration:none;font-weight:700;font-size:.9rem}
.saynav a:hover{border-color:#9EBBD2}
.saynav a[aria-current="page"]{border-color:#1E8E52;background:#EFF9F2}
.dlgset{max-width:1080px;margin:0 auto;display:flex;flex-direction:column;gap:12px}
.dlgset > .dmodes{width:100%;max-width:none;margin:0}
/* /say/: the lesson's scene above the conversation (17 Oct 2026). Phone: cropped across the width, 120 px;
   from 601 px a card of 480 x 190 px in the middle, nothing around it (Dave, 11:20: no wide banner, no blur) */
.dscene{position:relative;max-width:900px;height:120px;margin:0 auto 16px;border-radius:16px;overflow:hidden;background:var(--sky)}
.dscene img{display:block;width:100%;height:100%;object-fit:cover;object-position:50% 40%}
@media (min-width:601px){
.dscene{width:min(100%,480px);height:190px;margin-bottom:18px;box-shadow:0 8px 24px rgba(22,50,79,.18),0 1px 3px rgba(22,50,79,.16)}
}
.dlgnav{display:flex;align-items:center;gap:10px;margin-top:18px;max-width:900px;margin-left:auto;margin-right:auto}
.dlgnav button{flex:none;appearance:none;width:52px;height:52px;border-radius:50%;border:2px solid var(--line);background:var(--paper);font:inherit;font-size:1.8rem;line-height:1;font-weight:700;color:var(--ink);cursor:pointer}
.dlgnav .dnext:not(:disabled){background:var(--ink);border-color:var(--ink);color:#fff}
.dlgnav button:disabled{opacity:.3;cursor:default}
.dsrc{flex:1;min-width:0;display:flex;align-items:center;gap:10px;padding:6px 6px 6px 12px;border:2px solid var(--line);border-radius:16px;background:var(--paper);color:var(--ink);text-decoration:none}
.dsrc:hover{border-color:#9EBBD2}
.dsrc .cover{flex:none}
.dsl .cjk.brk{margin-left:-.5em}
.dsl{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.25;font-size:.9rem;font-weight:700}
.dsl .cjk{font-size:1em;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dles{color:var(--ink-soft);font-weight:600;font-size:.85rem}
.dcount{flex:none;padding:6px 10px;border-radius:10px;background:var(--sky);color:var(--ink);font-size:.95rem;font-variant-numeric:tabular-nums}
.dlgi .dlg{margin-bottom:0}
/* a conversation is over (/say/, 17 Oct 2026): › becomes a green "Next ›" pill and pulses until the child taps it */
.dlgset.dready .dnext:not(:disabled){width:auto;padding:0 18px 0 20px;border-radius:26px;display:inline-flex;align-items:center;gap:6px;
  background:#1E8E52;border-color:#1E8E52;animation:dpulse 1.5s ease-in-out infinite}
.dnext .dnl{font-size:1.1rem;line-height:1}
@keyframes dpulse{0%,100%{box-shadow:0 0 0 0 rgba(30,142,82,.45)}50%{box-shadow:0 0 0 9px rgba(30,142,82,0)}}
@media (prefers-reduced-motion:reduce){.dlgset.dready .dnext{animation:none}}
@media (max-width:420px){.dlgset.dready .dlgnav .dcount{display:none}.dlgset.dready .dnext:not(:disabled){padding:0 14px 0 16px}}

/* ---------- lesson header with the big scene ("Netflix" title page, Dave 16 Oct 2026) ----------
   The lesson's scene (Real-ESRGAN x4 of the 1024 px original, 1400 / 800 px) fills the right ~62 % of the card and fades into white on
   the left, where the kicker, title, pinyin, meaning and the buttons stand. Light, not dark: tone colours must stay readable.
   ▶ = the lesson's Panda run, ♪ = the lesson's sounds (pinyin book). Phone: the scene on top over the full width, the text under it. */
.ltbox.hero{position:relative;display:block;height:460px;padding:0;border:0;border-radius:28px;overflow:hidden;background:#fff;
  box-shadow:0 1px 0 var(--line),0 10px 30px rgba(22,50,79,.08)}
.ltbox.hero .chap{position:absolute;top:0;right:0;bottom:0;width:62%;height:auto;border-radius:0;cursor:default}
.ltbox.hero .chap[data-snd]{cursor:pointer}
.ltbox.hero .chap img{object-position:50% 45%}
.ltbox.hero .chap::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,#fff 0%,rgba(255,255,255,.9) 9%,rgba(255,255,255,.45) 22%,rgba(255,255,255,0) 38%)}
.ltbox.hero .lttxt{position:relative;z-index:1;width:46%;height:100%;box-sizing:border-box;display:flex;flex-direction:column;justify-content:center;padding:0 0 0 44px}
.ltbox.hero .lkick{font-size:.85rem;margin-bottom:6px}
.ltbox.hero .ltitle{font-size:3.3rem;line-height:1.1}
.ltbox.hero .lpy{font-size:1.5rem;margin-top:8px}
.ltbox.hero .lmean{font-size:1.2rem;margin-top:4px}
.hbtns{display:flex;gap:10px;margin-top:22px;flex-wrap:wrap}
.hbtn{appearance:none;display:inline-flex;align-items:center;gap:.55em;min-height:52px;padding:0 24px 0 8px;border-radius:999px;border:0;font:inherit;
  font-weight:800;font-size:1.1rem;text-decoration:none;cursor:pointer;box-shadow:0 4px 0 rgba(22,50,79,.14);transition:transform .12s}
.hbtn:hover{transform:translateY(-2px)}
.hbtn:active{transform:translateY(2px)}
.hbtn:focus-visible{outline:3px solid var(--glow);outline-offset:3px}
.hbic{display:inline-grid;place-items:center;width:38px;height:38px;border-radius:50%;font-size:1rem}
.hbic svg{margin-left:3px}
.hplay{background:var(--bk);color:#fff}
.hplay .hbic{background:#fff;color:var(--bk)}
.hsnd{background:#fff;color:var(--ink);box-shadow:inset 0 0 0 2px var(--line),0 4px 0 rgba(22,50,79,.08)}
.hsnd .hbic{background:var(--sky)}
@media (max-width:760px){
  .ltbox.hero{height:auto;border-radius:22px;display:flex;flex-direction:column}
  .ltbox.hero .chap{position:relative;order:-1;width:100%;height:auto;aspect-ratio:1 / 1;max-height:360px}
  .ltbox.hero .chap::after{background:linear-gradient(0deg,#fff 0%,rgba(255,255,255,.7) 10%,rgba(255,255,255,0) 32%)}
  .ltbox.hero .lttxt{width:auto;height:auto;padding:0 18px 18px;margin-top:-36px}
  .ltbox.hero .ltitle{font-size:2.3rem}
  .ltbox.hero .lpy{font-size:1.2rem}
  .ltbox.hero .lmean{font-size:1.05rem}
  .hbtns{margin-top:14px}
  .hbtn{min-height:48px;font-size:1rem}
}

/* ---------- 玩一玩 on a lesson = the cards of the home page (.gk, same rules as index.html; 16 Oct 2026) ----------
   Panda run and Listen and find are wide cards; AI practice stays a strip under them. */
.playrow.gkrow{grid-template-columns:repeat(6,minmax(0,1fr));gap:44px 14px;padding-top:28px}
.playrow.gkrow .playcard:not(.gk){grid-column:1 / -1}
.playrow .gk{--c:#1E8E52;--c2:#146B3C;appearance:none;font:inherit;text-align:left;cursor:pointer;margin:0;border:0;position:relative;display:flex;flex-direction:column;
  align-items:stretch;gap:0;min-width:0;min-height:236px;grid-column:span 2;padding:0;border-radius:24px;background:var(--c);color:#fff;text-decoration:none;
  box-shadow:0 6px 0 var(--c2),0 12px 22px rgba(22,50,79,.16);transition:transform .12s,box-shadow .12s;isolation:isolate}
.playrow .gk::before{content:"";position:absolute;inset:0;border-radius:24px;z-index:-1;overflow:hidden;
  background:radial-gradient(circle at var(--cx,50%) var(--cy,28%),rgba(255,255,255,.2) 0 var(--cr,82px),rgba(255,255,255,0) calc(var(--cr,82px) + 1px)),
             radial-gradient(circle at 88% 104%,rgba(0,0,0,.10) 0 24%,rgba(0,0,0,0) 25%)}
.playrow .gk:hover{border:0;transform:translateY(-3px);box-shadow:0 9px 0 var(--c2),0 16px 26px rgba(22,50,79,.18)}
.playrow .gk:active{transform:translateY(4px);box-shadow:0 2px 0 var(--c2),0 6px 12px rgba(22,50,79,.14)}
.playrow .gk:focus-visible{outline:4px solid var(--glow);outline-offset:4px}
.playrow .gk .gkart{position:relative;height:136px;margin-top:-16px;display:flex;align-items:flex-end;justify-content:center;pointer-events:none}
.playrow .gk .gkart img{height:150px;width:auto;max-width:100%;object-fit:contain;filter:drop-shadow(0 6px 6px rgba(0,0,0,.18))}
.playrow .gk .gkbody{display:flex;flex-direction:column;gap:3px;padding:8px 16px 18px;flex:1 1 auto}
.playrow .gk .gktag{align-self:flex-start;display:inline-flex;align-items:center;gap:5px;border-radius:999px;background:rgba(255,255,255,.22);
  font-size:.72rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase;padding:4px 10px 3px;margin-bottom:4px}
.playrow .gk .gktag svg{flex:none}
.playrow .gk .gkt{font-size:1.32rem;font-weight:800;line-height:1.1}
.playrow .gk .gkzh{font-family:var(--cjk);font-weight:700;font-size:1rem;opacity:.85}
.playrow .gk .gkd{font-size:.93rem;font-weight:600;line-height:1.35;margin-top:4px;margin-bottom:10px;opacity:.95;padding-right:44px}
.playrow .gk .grev{display:block;margin-top:4px;font-weight:800;color:#fff}
.playrow .gk .gkgo{position:absolute;right:14px;bottom:16px;width:42px;height:42px;border-radius:50%;background:#fff;display:flex;align-items:center;justify-content:center;
  box-shadow:0 3px 0 rgba(0,0,0,.15)}
.playrow .gk .gkgo svg{margin-left:3px}
.playrow .gk.wide{grid-column:span 3;flex-direction:row;min-height:200px;--cx:22%;--cy:58%;--cr:96px}
.playrow .gk.wide .gkart{flex:0 0 44%;height:auto;margin:-30px 0 0;align-items:flex-end}
.playrow .gk.wide .gkart img{height:calc(100% + 18px);max-height:250px}
.playrow .gk.wide .gkbody{justify-content:center;padding:22px 18px 22px 4px}
@media (max-width:760px){
  .playrow.gkrow{grid-template-columns:minmax(0,1fr);gap:40px 12px}
  .playrow .gk.wide{grid-column:1 / -1;--cr:70px;min-height:0}
  .playrow .gk.wide .gkart{flex-basis:42%}
  .playrow .gk.wide .gkart img{max-height:176px}
  .playrow .gk.wide .gkbody{padding:18px 14px 18px 0}
  .playrow .gk .gkt{font-size:1.12rem}
  .playrow .gk .gkd{font-size:.86rem}
  .playrow .gk .gkgo{width:36px;height:36px;right:10px;bottom:12px}
  .playrow .gk .gktag{font-size:.66rem;padding:3px 8px 2px}
}
@media (prefers-reduced-motion:reduce){.playrow .gk,.hbtn{transition:none}.playrow .gk:hover,.hbtn:hover{transform:none}}

/* ---------- A tiles (the three kinds of cards, 17 Oct 2026): book page lessons and the row of other lessons ----------
   The scene over the whole tile, one dark fade at the bottom with the Chinese title and its meaning, badges only top left, one white
   round ▶ bottom right — the same tile as 我的课本 on the home page (assets/polka.css .pk-tile). */
.atile{position:relative;display:block;aspect-ratio:1 / 1;border-radius:22px;overflow:hidden;text-decoration:none;color:#fff;isolation:isolate;
  background:var(--bk,#16324F);box-shadow:0 1px 2px rgba(22,50,79,.08),0 8px 18px rgba(22,50,79,.10);transition:transform .18s,box-shadow .18s}
.atile:hover{color:#fff;transform:translateY(-4px);box-shadow:0 2px 4px rgba(22,50,79,.10),0 14px 28px rgba(22,50,79,.16)}
.atile:focus-visible{outline:4px solid var(--glow);outline-offset:3px}
.atimg{position:absolute;left:0;top:0;width:100%;height:100%;object-fit:cover;z-index:-1;transition:transform .35s}
.atile:hover .atimg{transform:scale(1.04)}
.atbs{position:absolute;left:10px;top:10px;right:10px;display:flex;flex-wrap:wrap;gap:6px}
.atb,.atile .lhere{border-radius:999px;background:rgba(11,30,51,.72);color:#fff;font-size:.74rem;font-weight:700;padding:5px 10px 4px;line-height:1;white-space:nowrap}
.atb.here,.atile .lhere{background:var(--bkd,var(--ink))}
.atile .lhere{position:absolute;left:10px;top:38px;margin:0;z-index:2}
.attx{position:absolute;left:0;right:0;bottom:0;padding:40% 60px 16px 14px;display:flex;flex-direction:column;gap:3px;
  background:linear-gradient(to top,rgba(9,22,38,.86) 0,rgba(9,22,38,.6) 36%,rgba(9,22,38,0) 100%);text-shadow:0 2px 10px rgba(0,0,0,.35)}
.atzh{font-size:1.35rem;font-weight:700;line-height:1.2;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}   /* a long title wraps (二 lines), never "…" */
.atzh.cjk{font-family:var(--cjk);letter-spacing:.04em}
.atzh.py{font-family:var(--py)}
.atm{font-size:.86rem;font-weight:700;opacity:.92;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.atgo{position:absolute;right:12px;bottom:14px;width:40px;height:40px;border-radius:50%;background:#fff;color:var(--bk,#16324F);display:flex;align-items:center;justify-content:center;
  box-shadow:0 3px 0 rgba(0,0,0,.15)}
.atgo svg{margin-left:3px}
.atile.cur,.lessons .atile.last{box-shadow:0 0 0 4px var(--bk,var(--ink)),0 8px 18px rgba(22,50,79,.14)}
.lessons{grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:18px}
.lessons .lcard.atile{display:block;padding:0;border:0;border-radius:22px}
.leps .sech{align-items:center}
.sechall{margin-left:auto;font-size:.88rem;font-weight:700;color:var(--ink);text-decoration:none;border:2px solid var(--line);border-radius:999px;padding:6px 14px;background:var(--paper)}
.sechall:hover{border-color:#9EBBD2}
.eprow{display:flex;gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;padding:6px 6px 14px;margin:0 -6px;scrollbar-width:thin;-webkit-overflow-scrolling:touch}
.eprow .atile{flex:none;width:196px;scroll-snap-align:start}
.eprow .atzh{font-size:1.2rem}
@media (max-width:600px){
  .lessons{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px}
  .atile{border-radius:20px}
  .attx{padding:40% 48px 12px 12px}
  .atzh{font-size:1.15rem}
  .atm{font-size:.78rem}
  .atgo{width:34px;height:34px;right:10px;bottom:12px}
  .eprow .atile{width:156px}
  .eprow .atzh{font-size:1.1rem}
}
@media (prefers-reduced-motion:reduce){.atile,.atimg{transition:none}.atile:hover{transform:none}.atile:hover .atimg{transform:none}}

/* ---------- 说一说 and 写一写 side by side from ~1100 px (Dave, 17 Oct 2026): conversation ~55 %, writing ~45 % ---------- */
@media (min-width:1100px){
  .lduo{display:grid;grid-template-columns:minmax(0,55fr) minmax(0,45fr);gap:0 28px;max-width:1080px;margin:0 auto;align-items:start}
  .lduo .wstage{width:100%;height:auto;aspect-ratio:1 / 1;max-width:300px}
  .lduo .wside{flex-basis:100%}
}

/* B cards on a lesson (17 Oct 2026): no category pill; one short line on a computer, none on the phone; the age */
.playrow .gk .gkage{align-self:flex-start;margin-top:auto;border-radius:999px;background:rgba(0,0,0,.16);color:#fff;font-size:.76rem;font-weight:800;padding:5px 10px 4px;line-height:1}
@media (max-width:760px){ .playrow .gk .gkd{display:none} .playrow .gk .gkage{margin-top:10px} }

/* ---------- book page = series page (17 Oct 2026) ----------
   The scene of the lesson the child is on fills the right half of the header and fades into white (assets/book.js swaps it to the
   lesson the phone remembers; first visit: lesson 1). Left: the cover as a sticker, title, one grey line of counts, the main button in
   two lines ("▶ Back to lesson 3" + the Chinese title). Phone: the scene on top, the cover overlapping its lower left corner. */
.bkbox.bkhero{position:relative;display:block;min-height:440px;padding:0;border:0;border-radius:28px;overflow:hidden;background:#fff;
  box-shadow:0 1px 0 var(--line),0 10px 30px rgba(22,50,79,.08)}
.bkhero .bkscene{position:absolute;top:0;right:0;bottom:0;width:50%;display:block;background:var(--sky)}
.bkhero .bkscene img{width:100%;height:100%;object-fit:cover;display:block}
.bkhero .bkscene::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,#fff 0%,rgba(255,255,255,.9) 9%,rgba(255,255,255,.4) 24%,rgba(255,255,255,0) 40%)}
.bknow{position:absolute;right:16px;bottom:16px;z-index:1;border-radius:999px;background:rgba(11,30,51,.78);color:#fff;font-size:.85rem;font-weight:700;padding:7px 14px 6px;line-height:1.1}
.bkhero .bkin{position:relative;z-index:1;display:flex;align-items:center;gap:34px;width:60%;min-height:440px;box-sizing:border-box;padding:36px 0 36px 40px}
.bkhero .bkin > .cover{flex:none;font-size:24px;margin:0;transform:rotate(-4deg);box-shadow:0 0 0 4px #fff,0 16px 30px rgba(22,50,79,.3)}
.bkhero .bktx{min-width:0}
.bkline{margin:8px 0 0;font-size:.95rem;font-weight:700;color:var(--ink-soft)}
.bkhero .bkgo{flex-direction:column;align-items:flex-start;gap:2px;margin-top:22px;padding:12px 26px 13px;border-radius:22px}
.bkhero .bkgo .bkgot{font-size:.9rem;opacity:.92}
.bkhero .bkgo .cjk{font-size:1.45rem;line-height:1.2}
/* lessons: 4 columns; a unit is as wide as its lessons, so short units stand side by side */
.bkunits{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0 18px;align-items:start}
.bkunits .lessons{gap:18px}
.bku[data-span="1"] .sech,.bku[data-span="2"] .sech{flex-direction:column;align-items:flex-start;gap:2px;min-height:3.3em}
@media (max-width:900px){
  .bkhero .bkin{width:64%;gap:22px;padding-left:28px}
  .bkhero .bkin > .cover{font-size:17px}
  .bkhero .bkscene{width:44%}
}
@media (max-width:760px){
  .bkbox.bkhero{min-height:0;border-radius:22px;display:flex;flex-direction:column}
  .bkhero .bkscene{position:relative;width:100%;aspect-ratio:4 / 3;max-height:300px}
  .bkhero .bkscene::after{background:linear-gradient(0deg,#fff 0%,rgba(255,255,255,.6) 12%,rgba(255,255,255,0) 34%)}
  .bknow{top:12px;bottom:auto;right:12px;font-size:.78rem}
  .bkhero .bkin{display:block;width:auto;min-height:0;padding:0 16px 18px;margin-top:-120px}
  .bkhero .bkin > .cover{display:block;font-size:11px;margin-left:4px}
  .bkhero .bktx{padding-top:14px}
  .bkhero .bktitle{font-size:1.6rem}
  .bkhero .bkgo{display:flex;width:auto;box-sizing:border-box}
}
@media (max-width:600px){
  .bkunits{grid-template-columns:repeat(2,minmax(0,1fr));gap:0 12px}
  .bku{grid-column:span 2 !important}
  .bku[data-span="1"]{grid-column:span 1 !important}
  .bku .lessons{grid-template-columns:repeat(2,minmax(0,1fr)) !important;gap:12px}
  .bku[data-span="1"] .lessons{grid-template-columns:minmax(0,1fr) !important}
}

/* ---------- 《汉语拼音》 lesson (17 Oct 2026): big sound cards; 拼音 | 写字母 side by side from ~1100 px ---------- */
.sndrow.sndbig{display:grid;grid-template-columns:repeat(auto-fill,minmax(104px,1fr));gap:12px}
.sndrow.sndbig .snd{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;min-height:132px;padding:10px 8px;border-radius:22px;
  font-family:var(--py);text-decoration:none;line-height:1.1}
.sndrow.sndbig .snd b{font-size:2.6rem;font-weight:700}
.sndrow.sndbig .snd small{font-size:.8rem;font-weight:600;color:#6B7C8F}
@media (min-width:1100px){ .lduo.lduo-py{grid-template-columns:minmax(0,42fr) minmax(0,58fr)} }
@media (max-width:600px){ .sndrow.sndbig{grid-template-columns:repeat(auto-fill,minmax(88px,1fr));gap:10px} .sndrow.sndbig .snd{min-height:104px} .sndrow.sndbig .snd b{font-size:2.1rem} }
