/* One desktop shell: Home's real sidebar is moved beside the active workspace.
   No copied navigation, palette, icon, or spacing can drift from Home. */
@media (min-width: 900px) {
  .review-view,.practice-view { width:100%; max-width:none; min-height:100dvh; height:100dvh; margin:0; padding:0 32px 0 0; overflow:hidden; box-sizing:border-box; background:#fbf6eb; font-family:"Avenir Next",Avenir,-apple-system,BlinkMacSystemFont,"PingFang SC",sans-serif; }
  .review-view { display:grid; grid-template-columns:232px minmax(0,1fr) 196px; grid-template-rows:92px minmax(0,1fr); column-gap:28px; }
  .review-view > .home-sidebar { grid-column:1; grid-row:1 / -1; display:flex; width:232px; min-height:100dvh; height:100dvh; }
  .review-header { grid-column:2 / 4; grid-row:1; display:grid; grid-template-columns:52px 1fr 52px; align-items:center; height:92px; margin:0; border-bottom:0; }
  .review-header .circle-button { width:52px; height:52px; border:0; border-radius:50%; color:#1d1d1d; background:#fff; box-shadow:0 2px 8px rgba(40,32,21,.08); }.review-header .circle-button .ff-symbol { width:24px; height:24px; }.review-header .review-progress { justify-self:center; padding:10px 16px; border:0; color:#777; background:#fff; box-shadow:0 2px 8px rgba(40,32,21,.08); font-family:"Avenir Next",Avenir,sans-serif; font-size:16px; font-weight:600; }.review-header .review-progress b { color:var(--trophy); font-size:16px; font-weight:600; }
  .card-stack { grid-column:2; grid-row:2; align-self:center; width:100%; height:min(66dvh,620px); min-height:470px; margin:0; }.card-stack > #study-card { position:relative; z-index:2; }.card-stack > .next-flashcard { position:absolute; inset:0; z-index:1; transform:scale(.96) translateY(10px); pointer-events:none; }
  .flashcard { --artwork-size:min(40vw,540px); grid-template-columns:minmax(290px,.9fr) minmax(0,1.1fr); grid-template-rows:minmax(0,1fr) 88px 86px; column-gap:44px; padding:34px 48px 25px; border-radius:34px; background:#fff; box-shadow:0 10px 24px rgba(49,37,20,.11); }.flashcard > .artwork { width:var(--artwork-size); height:var(--artwork-size); }.flashcard > .card-hanzi { color:#1d1d1d; font-family:"PingFang SC","Hiragino Sans GB",sans-serif; font-size:clamp(76px,6vw,120px); font-weight:700; letter-spacing:-.05em; }.flashcard > .card-pinyin { color:#ad3d2d; font-family:"Avenir Next",Avenir,sans-serif; font-size:clamp(38px,3.4vw,58px); font-weight:600; letter-spacing:-.04em; }.flashcard > .card-footer { padding-left:18px; }.card-english { color:rgba(0,0,0,.45); font-family:"Avenir Next",Avenir,sans-serif; font-size:23px; font-weight:600; }.card-footer button { color:var(--audio); }
  .result-controls { grid-column:3; grid-row:2; align-self:start; display:grid; grid-template-columns:1fr; grid-template-rows:76px 76px 64px; gap:15px; width:100%; margin:clamp(62px,10dvh,112px) 0 0; }.collect-button,.result-button { width:100%; height:100%; border-radius:19px; }.collect-button { background:var(--trophy); box-shadow:0 5px 0 var(--trophy-shadow); }.not-yet { background:var(--not-yet); box-shadow:0 5px 0 var(--not-yet-shadow); }.knew-it { background:var(--knew-it); box-shadow:0 5px 0 var(--knew-it-shadow); }.result-button .ff-symbol { width:38px; height:38px; }.collect-button .ff-symbol { width:31px; height:31px; }
  .display-controls { grid-column:3; grid-row:2; align-self:end; display:grid; grid-template-columns:repeat(2,48px); justify-content:center; gap:13px; width:100%; margin:0 0 34px; padding:0; }.display-controls button { width:48px; height:48px; border:1px solid rgba(0,0,0,.16); border-radius:50%; font-family:"Avenir Next",Avenir,sans-serif; font-size:16px; font-weight:600; }.display-controls button:focus-visible { outline:none; }.display-controls button[data-toggle="random"].is-on { background:#3885c2; }.display-controls button[data-toggle="english"].is-on { background:#4d78c7; }.display-controls button[data-toggle="artwork"].is-on { background:#3899c7; }.display-controls button[data-toggle="characters"].is-on { background:#4563bd; }.display-controls button[data-toggle="pinyin"].is-on { background:#59add1; }

  .review-header-center { display:flex; align-items:center; justify-self:center; gap:10px; min-width:0; }.review-header-center > .display-controls { align-self:center; display:flex; align-items:center; justify-content:center; gap:7px; width:auto; margin:0; padding:0; }.review-header-center > .display-controls button { flex:0 0 auto; width:36px; height:36px; font-size:14px; }.review-header-center > .display-controls .ff-symbol { width:17px; height:17px; }

  .practice-view { display:grid; grid-template-columns:232px minmax(0,1fr); grid-template-rows:92px minmax(0,1fr) 70px; column-gap:32px; }.practice-view > .home-sidebar { grid-column:1; grid-row:1 / -1; display:flex; width:232px; min-height:100dvh; height:100dvh; }.practice-header { grid-column:2; grid-row:1; align-self:center; width:min(100%,760px); justify-self:center; }.practice-prompt,.practice-grid { grid-column:2; }.practice-prompt { align-self:start; }.practice-grid { align-self:center; width:min(100%,760px); justify-self:center; }.practice-controls { grid-column:2; grid-row:3; align-self:center; }.practice-audio { grid-column:2; grid-row:3; justify-self:end; align-self:center; }
}

/* Closed desktop card compositions. They deliberately remove inactive slots
   instead of keeping an empty half-card alive. */
@media (min-width: 900px) {
  .card-stack { width:min(100%,1280px,calc((100dvh - 145px) * 1.82)); height:auto; min-height:0; aspect-ratio:1.82; justify-self:center; overflow:visible; }
  .flashcard { min-width:0; min-height:0; height:100%; overflow:hidden; transition:transform .3s ease-in,opacity .3s ease-in,background .12s ease; }.flashcard > * { min-width:0; }.flashcard.is-resetting { transition:none !important; }.flashcard:focus-visible { outline:none; }
  /* Artwork-on layouts share one immutable desktop coordinate system. The
     left artwork frame and bottom footer are never repurposed by a language
     toggle; only the two text slots on the right change contents. */
  .flashcard.layout-full,.flashcard.layout-art-characters,.flashcard.layout-art-pinyin,.flashcard.layout-art-only { grid-template-areas:"art primary" "art secondary" "art footer"; grid-template-rows:minmax(0,1fr) 88px 86px; }
  .flashcard.layout-full > .card-hanzi,.flashcard.layout-art-characters > .card-hanzi { display:block; grid-area:primary; align-self:center; }
  .flashcard.layout-full > .card-pinyin { display:block; grid-area:secondary; align-self:center; }
  /* With Chinese hidden, pinyin takes its primary slot without moving art,
     English, or audio. */
  .flashcard.layout-art-pinyin > .card-pinyin { display:block; grid-area:primary; align-self:center; padding:0; }
  .flashcard.layout-art-characters > .card-pinyin,.flashcard.layout-art-pinyin > .card-hanzi,.flashcard.layout-art-only > .card-hanzi,.flashcard.layout-art-only > .card-pinyin { display:none; }
  .flashcard.layout-characters-pinyin,.flashcard.layout-characters-hero,.flashcard.layout-pinyin-hero,.flashcard.layout-audio-hero { grid-template-areas:"hero" "footer"; grid-template-columns:1fr; grid-template-rows:minmax(0,1fr) 86px; }.flashcard.layout-characters-pinyin > .artwork,.flashcard.layout-characters-hero > .artwork,.flashcard.layout-pinyin-hero > .artwork,.flashcard.layout-audio-hero > .artwork { grid-area:hero; width:100%; height:100%; }.flashcard.layout-characters-pinyin > .artwork > img,.flashcard.layout-characters-hero > .artwork > img,.flashcard.layout-pinyin-hero > .artwork > img,.flashcard.layout-audio-hero > .artwork > img { display:none; }.flashcard.layout-characters-pinyin .card-art-fallback,.flashcard.layout-characters-hero .card-art-fallback,.flashcard.layout-pinyin-hero .card-art-fallback,.flashcard.layout-audio-hero .card-art-fallback { display:grid; }.flashcard.layout-characters-pinyin .fallback-disc,.flashcard.layout-characters-hero .fallback-disc { display:block; width:min(48vh,390px); }.flashcard.layout-characters-pinyin #hero-hanzi,.flashcard.layout-characters-hero #hero-hanzi { display:block; color:#1d1d1d; font-family:"PingFang SC","Hiragino Sans GB",sans-serif; font-size:clamp(92px,10vw,168px); font-weight:700; }.flashcard.layout-characters-pinyin #hero-pinyin { display:block; margin-top:150px; color:#ad3d2d; font-size:clamp(40px,4vw,66px); font-weight:600; }.flashcard.layout-pinyin-hero #hero-pinyin { display:block; color:#ad3d2d; font-size:clamp(58px,6vw,98px); font-weight:600; }.flashcard.layout-audio-hero #hero-audio-button { display:block; }
  .flashcard.layout-characters-pinyin > .card-hanzi,.flashcard.layout-characters-pinyin > .card-pinyin,.flashcard.layout-characters-hero > .card-hanzi,.flashcard.layout-characters-hero > .card-pinyin,.flashcard.layout-pinyin-hero > .card-hanzi,.flashcard.layout-pinyin-hero > .card-pinyin,.flashcard.layout-audio-hero > .card-hanzi,.flashcard.layout-audio-hero > .card-pinyin { display:none !important; }.flashcard.layout-audio-hero > .card-footer > button { display:none; }
  .card-english { padding-left:12px; font-size:28px; }.card-footer button { width:72px; height:62px; }.card-footer .ff-symbol { width:35px; height:35px; }
  .flashcard.layout-characters-pinyin [id$="hero-hanzi"],.flashcard.layout-characters-hero [id$="hero-hanzi"] { display:block; color:#1d1d1d; font-family:"PingFang SC","Hiragino Sans GB",sans-serif; font-size:clamp(92px,10vw,168px); font-weight:700; }.flashcard.layout-characters-pinyin [id$="hero-pinyin"] { display:block; margin-top:150px; color:#ad3d2d; font-size:clamp(40px,4vw,66px); font-weight:600; }.flashcard.layout-pinyin-hero [id$="hero-pinyin"] { display:block; color:#ad3d2d; font-size:clamp(58px,6vw,98px); font-weight:600; }.flashcard.layout-audio-hero [id$="hero-audio-button"] { display:block; }
  /* The no-art Chinese+pinyin state is a compact, centered pair. Keeping its
     two anchors explicit prevents pinyin from stretching the fallback grid. */
  .flashcard.layout-characters-pinyin .card-art-fallback { position:relative; display:block; }
  .flashcard.layout-characters-pinyin .fallback-disc { top:50%; left:50%; transform:translate(-50%,-50%); }
  .flashcard.layout-characters-pinyin #hero-hanzi,.flashcard.layout-characters-pinyin #next-hero-hanzi { position:absolute; top:calc(50% - 56px); left:50%; display:block; margin:0; transform:translate(-50%,-50%); color:#1d1d1d; font-family:"PingFang SC","Hiragino Sans GB",sans-serif; font-size:clamp(92px,10vw,168px); font-weight:700; white-space:nowrap; }
  .flashcard.layout-characters-pinyin #hero-pinyin,.flashcard.layout-characters-pinyin #next-hero-pinyin { position:absolute; top:calc(50% + 118px); left:50%; display:block; margin:0; transform:translate(-50%,-50%); color:#ad3d2d; font-size:clamp(40px,4vw,66px); font-weight:600; white-space:nowrap; }
  /* Desktop's no-photo states are text compositions, not the mobile disc
     component. This keeps long terms legible and gives pinyin its own space. */
  .flashcard.layout-characters-pinyin .fallback-disc,.flashcard.layout-characters-hero .fallback-disc { display:none; }
  .flashcard.layout-characters-pinyin #hero-hanzi,.flashcard.layout-characters-pinyin #next-hero-hanzi { top:calc(50% - 40px); }
  .flashcard.layout-characters-pinyin #hero-pinyin,.flashcard.layout-characters-pinyin #next-hero-pinyin { top:calc(50% + 92px); }
  .flashcard.layout-characters-hero .card-art-fallback,.flashcard.layout-pinyin-hero .card-art-fallback { position:relative; display:block; }
  .flashcard.layout-characters-hero #hero-hanzi,.flashcard.layout-characters-hero #next-hero-hanzi,.flashcard.layout-pinyin-hero #hero-pinyin,.flashcard.layout-pinyin-hero #next-hero-pinyin { position:absolute; top:50%; left:50%; margin:0; transform:translate(-50%,-50%); white-space:nowrap; }
  /* Art + pinyin centers pinyin vertically in the right content region. */
  .flashcard.layout-art-pinyin { grid-template-areas:"art pinyin" "art pinyin" "art footer"; }.flashcard.layout-art-pinyin > .card-pinyin { grid-area:pinyin; align-self:center; }
  /* When both labels are on, they form one compact group instead of occupying
     independently centered rows. */
  .flashcard.layout-full { grid-template-areas:"art labels" "art labels" "art footer"; }.flashcard.layout-full > .card-hanzi,.flashcard.layout-full > .card-pinyin { grid-area:labels; align-self:center; }.flashcard.layout-full > .card-hanzi { transform:translateY(-72px); font-size:clamp(96px,7.2vw,156px); }.flashcard.layout-full > .card-pinyin { transform:translateY(72px); font-size:clamp(46px,4vw,70px); }.flashcard.layout-art-characters > .card-hanzi { font-size:clamp(96px,7.2vw,156px); }
  .result-controls > #knew-it-button { order:1; }.result-controls > #practice-button { order:2; }.result-controls > #collect-button { order:3; }
}
@media (min-width:900px) {
  .review-view { --compact-card-width:min(100%,calc((100dvh - 178px) * 1.58)); grid-template-columns:232px minmax(0,1fr); grid-template-rows:82px minmax(0,1fr) 88px; column-gap:24px; padding-right:24px; }.review-header { grid-column:2; grid-row:1; height:82px; }.card-stack { grid-column:2; grid-row:2; width:var(--compact-card-width); aspect-ratio:1.58; }
  /* Compact has its own closed card grid.  In particular, the two labels
     occupy real rows instead of sharing a desktop area and being pulled apart
     with transforms.  That makes the vertical rhythm shrink with the card
     and means a short card cannot push Hanzi above its clipping edge. */
  .flashcard { container-type:size; --artwork-size:min(40cqi,58cqb); grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr); grid-template-rows:minmax(0,1fr) minmax(34px,14cqb) minmax(38px,16cqb); column-gap:min(3cqi,5cqb); padding:clamp(10px,4cqb,24px) clamp(12px,4cqi,30px) clamp(9px,3cqb,18px); }
  .flashcard > .artwork { width:var(--artwork-size); height:var(--artwork-size); }
  .flashcard > .card-hanzi,.flashcard > .card-pinyin,.flashcard > .card-footer { min-height:0; }
  .flashcard > .card-hanzi,.flashcard.layout-art-characters > .card-hanzi { font-size:var(--compact-hanzi-size,clamp(1px,19cqb,120px)); font-weight:500; line-height:.95; }
  .flashcard > .card-pinyin { font-size:var(--compact-pinyin-size,clamp(1px,9cqb,60px)); line-height:1; white-space:nowrap; }
  /* Full compact cards have one explicit label area alongside the artwork.
     Both labels position from that area's midpoint, so their group stays
     vertically aligned with the image as the card changes height. */
  .flashcard.layout-full { --compact-label-gap:clamp(8px,3cqb,18px); --compact-content-offset:clamp(-14px,-2cqb,-10px); --compact-label-offset:var(--compact-label-center-offset,0px); grid-template-areas:"art labels" "art labels" "art labels"; }
  .flashcard.layout-full > .artwork { transform:translateY(var(--compact-content-offset)); }
  .flashcard.layout-full > .card-hanzi,.flashcard.layout-full > .card-pinyin { grid-area:labels; position:absolute; right:0; left:0; width:auto; margin:0; text-align:center; }
  .flashcard.layout-full > .card-hanzi { top:50%; align-self:auto; transform:translateY(calc(-100% - var(--compact-label-gap) + var(--compact-content-offset) + var(--compact-label-offset))); font-size:var(--compact-hanzi-size,clamp(1px,19cqb,120px)); }
  .flashcard.layout-full > .card-pinyin { top:50%; align-self:auto; transform:translateY(calc(var(--compact-label-gap) + var(--compact-content-offset) + var(--compact-label-offset))); padding:0; font-size:var(--compact-pinyin-size,clamp(1px,9cqb,60px)); }
  /* Every artwork-visible state shares the full card's stable artwork anchor
     and footer. Removing one language label must not reflow either one. */
  .flashcard.layout-art-characters,.flashcard.layout-art-pinyin,.flashcard.layout-art-only { --compact-content-offset:0px; }
  .flashcard.layout-art-characters > .artwork,.flashcard.layout-art-pinyin > .artwork,.flashcard.layout-art-only > .artwork { transform:none; }
  .flashcard.layout-art-characters > .card-hanzi,.flashcard.layout-art-pinyin > .card-pinyin { transform:translateY(var(--compact-content-offset)); }
  /* English belongs to the right-side text region, not the centre of a
     full-width footer.  Its speaker shares that region's true right edge and
     both receive card-relative insets, keeping them inside the front card. */
  .flashcard.layout-full > .card-footer,.flashcard.layout-art-characters > .card-footer,.flashcard.layout-art-pinyin > .card-footer,.flashcard.layout-art-only > .card-footer,.flashcard.layout-characters-pinyin > .card-footer,.flashcard.layout-characters-hero > .card-footer,.flashcard.layout-pinyin-hero > .card-footer { grid-area:auto; position:absolute; right:clamp(12px,4cqi,30px); bottom:clamp(10px,4cqb,24px); left:clamp(12px,4cqi,30px); display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr); column-gap:min(3cqi,5cqb); align-items:center; width:auto; height:clamp(30px,10cqb,52px); padding:0; }
  .flashcard.layout-full > .card-footer .card-english,.flashcard.layout-art-characters > .card-footer .card-english,.flashcard.layout-art-pinyin > .card-footer .card-english,.flashcard.layout-art-only > .card-footer .card-english,.flashcard.layout-characters-pinyin > .card-footer .card-english,.flashcard.layout-characters-hero > .card-footer .card-english,.flashcard.layout-pinyin-hero > .card-footer .card-english { position:static; grid-column:1; justify-self:center; padding:0; text-align:center; transform:none; }
  .flashcard.layout-full > .card-footer button { right:0; }
  .flashcard.layout-art-characters { grid-template-areas:"art hanzi" "art hanzi" "art hanzi"; }
  .flashcard.layout-art-characters > .card-hanzi { grid-area:hanzi; align-self:center; transform:translateY(var(--compact-content-offset)); font-size:var(--compact-hanzi-size,clamp(1px,19cqb,120px)); }
  .flashcard.layout-art-pinyin { grid-template-areas:"art pinyin" "art pinyin" "art pinyin"; }
  .flashcard.layout-art-pinyin > .card-pinyin { grid-area:pinyin; align-self:center; transform:translateY(var(--compact-content-offset)); font-size:var(--compact-pinyin-size,clamp(1px,9cqb,60px)); }
  .flashcard.layout-art-only { grid-template-areas:"art art" "art art" "art art"; }
  .flashcard.layout-art-only > .card-footer { grid-template-columns:1fr; }
  .flashcard > .card-footer { grid-area:footer; position:relative; display:grid; grid-template-columns:1fr; place-items:center; width:100%; padding:0; }
  .card-english { padding:0; font-size:var(--compact-english-size,clamp(1px,4.5cqb,28px)); font-weight:500; text-align:center; white-space:nowrap; }.card-footer button { position:absolute; right:0; top:50%; width:clamp(32px,11cqb,62px); height:clamp(30px,10cqb,62px); padding:0; transform:translateY(-50%); }.card-footer .ff-symbol { width:clamp(18px,6cqb,35px); height:clamp(18px,6cqb,35px); }
  .flashcard.layout-characters-pinyin .card-art-fallback { position:relative; }.flashcard.layout-characters-pinyin #hero-hanzi,.flashcard.layout-characters-pinyin #next-hero-hanzi { top:50%; font-size:var(--compact-hero-hanzi-size); transform:translate(-50%,calc(-100% - clamp(2px,.75cqb,4.5px))); }.flashcard.layout-characters-pinyin #hero-pinyin,.flashcard.layout-characters-pinyin #next-hero-pinyin { top:50%; font-size:var(--compact-hero-pinyin-size); transform:translate(-50%,clamp(2px,.75cqb,4.5px)); }.flashcard.layout-characters-hero #hero-hanzi,.flashcard.layout-characters-hero #next-hero-hanzi { font-size:var(--compact-hero-hanzi-size); }.flashcard.layout-pinyin-hero #hero-pinyin,.flashcard.layout-pinyin-hero #next-hero-pinyin { font-size:var(--compact-hero-pinyin-size); }
  /* With no artwork, the two-label composition is one visual group.  Shift
     that group within its existing hero frame; single-label states retain
     their already-correct centre anchor. */
  .flashcard.layout-characters-pinyin #hero-hanzi,.flashcard.layout-characters-pinyin #next-hero-hanzi,.flashcard.layout-characters-pinyin #hero-pinyin,.flashcard.layout-characters-pinyin #next-hero-pinyin { top:calc(50% + clamp(48px,9cqb,84px)); }
  /* A lone label is a different composition from the pair: it has more room,
     so it uses a larger fitted type scale and a lower hero anchor. */
  .flashcard.layout-characters-hero #hero-hanzi,.flashcard.layout-characters-hero #next-hero-hanzi { top:calc(50% + clamp(48px,9cqb,84px)) !important; font-size:var(--compact-solo-hero-hanzi-size) !important; }
  .flashcard.layout-pinyin-hero #hero-pinyin,.flashcard.layout-pinyin-hero #next-hero-pinyin { top:calc(50% + clamp(48px,9cqb,84px)) !important; font-size:var(--compact-solo-hero-pinyin-size) !important; }
  /* Without artwork, English is a conventional bottom-left card label.  It
     is not part of the old left artwork column, so its available width is
     measured separately in updateArtworkGeometry(). */
  .flashcard.layout-characters-pinyin > .card-footer,.flashcard.layout-characters-hero > .card-footer,.flashcard.layout-pinyin-hero > .card-footer { grid-template-columns:1fr; }
  .flashcard.layout-characters-pinyin > .card-footer .card-english,.flashcard.layout-characters-hero > .card-footer .card-english,.flashcard.layout-pinyin-hero > .card-footer .card-english { justify-self:start; padding-left:clamp(10px,2cqi,14px); text-align:left; }
  /* Audio-only has no footer speaker column—the speaker lives in the hero.
     Give English one full-width footer cell so its centre is the card centre. */
  .flashcard.layout-audio-hero > .card-footer { grid-template-columns:1fr !important; padding-right:0; padding-left:0; }
  .flashcard.layout-audio-hero > .card-footer .card-english { grid-column:1; justify-self:center; width:100%; padding:0; text-align:center; }
  /* These are deliberately final declarations.  The earlier desktop
     compositions predate the fitted compact variables and otherwise let a
     single visible label fall back to a large viewport-sized type scale. */
  .flashcard.layout-art-characters > .card-hanzi {
    font-size:var(--compact-hanzi-size,clamp(1px,19cqb,120px)) !important;
    min-inline-size:0;
    max-inline-size:100%;
    overflow:hidden;
  }
  .flashcard.layout-art-pinyin > .card-pinyin {
    font-size:var(--compact-pinyin-size,clamp(1px,9cqb,60px)) !important;
    min-inline-size:0;
    max-inline-size:100%;
    /* Pinyin descenders (g, y, p) extend beneath Avenir's nominal line box.
       This is the sole-label desktop layout, so protect that vertical ink
       without constraining it to the old tight clipping box. */
    line-height:1.16;
    overflow:visible;
  }
  /* Spanish, French, and German terms are phrases, not a character string to
     * squeeze into one line. Use the generous desktop text column and allow
     * up to two balanced lines at normal word boundaries. */
  html[data-program-format="single-language"] .flashcard.layout-art-pinyin > .card-pinyin {
    max-block-size:2.32em;
    overflow:hidden;
    overflow-wrap:normal;
    word-break:normal;
    line-height:1.12;
    text-align:center;
    text-wrap:balance;
    white-space:normal;
  }
  /* Artwork by itself is the one artwork-visible state whose English label
     belongs to the whole card rather than to the reserved artwork column. */
  .flashcard.layout-art-only > .card-footer .card-english {
    grid-column:1;
    justify-self:center;
    text-align:center;
  }
  /* Action controls follow the same height-derived width cap as the card.
     They retain comfortable touch targets, while shorter compact windows no
     longer leave a full-size button row beneath a scaled-down card. */
  .result-controls { grid-column:2; grid-row:3; align-self:center; display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); grid-template-rows:clamp(48px,8dvh,64px); gap:clamp(8px,1.5dvh,12px); width:var(--compact-card-width); justify-self:center; margin:0; }.collect-button,.result-button { border-radius:clamp(14px,2.4dvh,19px); }.result-button .ff-symbol { width:clamp(28px,4.4dvh,38px); height:clamp(28px,4.4dvh,38px); }.collect-button .ff-symbol { width:clamp(25px,3.8dvh,31px); height:clamp(25px,3.8dvh,31px); }.result-controls > #collect-button { order:1; }.result-controls > #practice-button { order:2; }.result-controls > #knew-it-button { order:3; }
}

/* The rail is transparent: every desktop width uses the same bottom action
   * row as compact Review. */
.review-action-rail { display:contents; }

/* The navigation is physically moved into each desktop workspace. Keep its
   world identity through that move instead of falling back to Home's red. */
@media (min-width:900px) {
  .home-sidebar .brand-lockup {
    color:var(--world-foreground,#94291a);
  }
  .home-sidebar .sidebar-links button:hover,
  .home-sidebar .sidebar-links button.is-active {
    color:var(--world-foreground,#94291a);
    background:color-mix(in srgb,var(--world-background,#c23d26) 16%,white);
  }
}

/* The front and queued Review cards have different element IDs.  Hero audio is
   * only valid for the explicit audio-only composition; otherwise the footer
   * owns the one visible speaker. */
@media (min-width:900px) {
  .flashcard .card-art-fallback [id$="hero-audio-button"] { display:none !important; }
  .flashcard.layout-audio-hero .card-art-fallback [id$="hero-audio-button"] { display:block !important; }
}

/* Trophy browsing gets the same desktop workspace as review: the actual
   left navigation remains in place while the full area to its right becomes
   a dense, browsable collection. */
@media (min-width:900px) {
  /* Settings shares the desktop navigation rail, while its content remains
     the same lightweight character selector used on phone. */
  .settings-view { display:grid; grid-template-columns:232px minmax(0,1fr); width:100%; max-width:none; min-height:100dvh; height:100dvh; margin:0; padding:0; overflow:hidden; background:#fbf6eb; font-family:"Avenir Next",Avenir,-apple-system,BlinkMacSystemFont,"PingFang SC",sans-serif; }
  .settings-view > .home-sidebar { grid-column:1; grid-row:1 / -1; display:flex; width:232px; min-height:100dvh; height:100dvh; }
  .home-view .brand-lockup,.settings-view .brand-lockup { color:var(--world-foreground,#94291a); }
  .settings-swift { grid-column:2; display:grid; grid-template-columns:minmax(0,900px); justify-content:center; align-content:start; min-height:0; height:100%; overflow:auto; padding:clamp(44px,8vh,80px) clamp(30px,6vw,96px) 64px; }
  .settings-swift-header { display:flex; align-items:center; justify-content:center; min-height:38px; }.settings-heading { display:flex; align-items:center; gap:10px; }.settings-heading h1 { margin:0; color:#46515a; font-family:"Avenir Next",Avenir,sans-serif; font-size:22px; font-weight:600; letter-spacing:-.35px; }.settings-help-button { display:grid; place-items:center; width:28px; height:28px; padding:0; border:0; border-radius:50%; color:var(--pinyin); background:color-mix(in srgb,var(--pinyin) 12%,transparent); font:700 13px "Avenir Next",Avenir,sans-serif; }.settings-close { display:none; }
  .settings-character-help { margin:22px 0 0; padding:16px 20px; border-radius:16px; color:#635d56; background:rgba(255,255,255,.72); font-size:15px; font-weight:600; line-height:1.42; text-align:center; }
  .settings-script-choices { display:grid; grid-template-columns:repeat(2,minmax(220px,1fr)); gap:clamp(18px,3vw,32px); width:100%; margin-top:24px; }
  .settings-script-choice { display:flex; flex-direction:column; align-items:center; min-width:0; min-height:clamp(250px,35vh,340px); padding:18px 18px 20px; border:1px solid rgba(171,59,41,.18); border-radius:28px; color:#1f1f1f; background:rgba(255,255,255,.92); box-shadow:0 6px 0 rgba(171,59,41,.16); font-family:"Avenir Next",Avenir,sans-serif; text-align:center; transition:transform .15s ease,box-shadow .15s ease; }.settings-script-choice:hover { transform:translateY(-3px); box-shadow:0 9px 0 rgba(171,59,41,.20); }.settings-script-choice.is-selected { border:3px solid rgba(171,59,41,.8); box-shadow:0 6px 0 rgba(171,59,41,.5); }.settings-script-choice img { width:100%; height:clamp(120px,18vh,178px); object-fit:contain; margin-bottom:auto; }.settings-script-choice strong { font-size:40px; font-weight:800; line-height:1.05; }.settings-script-choice > span { margin-top:4px; color:var(--pinyin); font-size:17px; font-weight:600; }.settings-script-choice small { margin-top:4px; color:#746e67; font-size:15px; font-weight:600; }
  .settings-about-footer { display:flex; flex-direction:column; align-items:center; padding:38px 0 20px; color:#79736b; text-align:center; }.settings-globe { width:116px; height:116px; }.settings-about-footer > strong { color:var(--pinyin); font-size:24px; font-weight:600; }.settings-about-footer > b { margin-top:5px; font-size:14px; font-weight:600; }.settings-about-footer > span { margin-top:2px; font-size:14px; }.settings-about-footer p { display:flex; align-items:center; gap:9px; margin:12px 0 0; }.settings-about-footer a { color:var(--pinyin); font-size:14px; font-weight:600; text-decoration:none; }.settings-about-footer i { width:3px; height:3px; border-radius:50%; background:#b7afa5; }

  .trophy-room-view,.trophy-case-view { display:grid; grid-template-columns:232px minmax(0,1fr); grid-template-rows:104px minmax(0,1fr); width:100%; max-width:none; min-height:100dvh; height:100dvh; margin:0; padding:0; overflow:hidden; background:#fbf6eb; font-family:"Avenir Next",Avenir,-apple-system,BlinkMacSystemFont,"PingFang SC",sans-serif; }
  .trophy-room-view > .home-sidebar,.trophy-case-view > .home-sidebar { grid-column:1; grid-row:1 / -1; display:flex; width:232px; min-height:100dvh; height:100dvh; }
  .trophy-room-header,.trophy-case-header { grid-column:2; grid-row:1; display:grid; grid-template-columns:52px 1fr 52px; align-items:center; gap:0; height:104px; padding:0 26px; border-bottom:1px solid color-mix(in srgb,var(--workspace-accent,#c23d26) 20%,transparent); }
  .trophy-room-header > div,.trophy-case-header > div { text-align:center; }
  .trophy-room-header h1,.trophy-case-header h1 { margin:0; color:#1d1d1d; font-size:28px; font-weight:700; letter-spacing:-.03em; }
  .trophy-room-header p,.trophy-case-header p { display:flex; justify-content:center; align-items:center; gap:5px; margin:4px 0 0; color:var(--trophy); font-size:15px; font-weight:600; }
  .trophy-room-header p img { width:18px; height:18px; object-fit:contain; }
  .trophy-case-header p { margin:0; font-size:24px; font-weight:700; }
  .trophy-case-header p img { width:30px; height:30px; object-fit:contain; }
  .trophy-room-header .circle-button,.trophy-case-header .circle-button { display:grid; place-items:center; width:52px; height:52px; padding:0; border:0; border-radius:50%; color:#1d1d1d; background:#fff; box-shadow:0 2px 8px rgba(40,32,21,.08); font-size:26px; }
  .trophy-room-header .circle-button .ff-symbol { width:24px; height:24px; }
  .trophy-case-header .case-reset { display:grid; place-items:center; }
  .trophy-case-header .case-reset-icon { display:block; width:24px; height:24px; background:#7a3d75; -webkit-mask:url("counterarrow.webp") center / contain no-repeat; mask:url("counterarrow.webp") center / contain no-repeat; }
  .trophy-room-header .room-help-button { display:grid; place-items:center; justify-self:end; width:40px; height:40px; border:0; border-radius:50%; color:var(--workspace-accent,#c23d26); background:color-mix(in srgb,var(--workspace-accent,#c23d26) 12%,white); font-size:18px; font-weight:800; }
  .trophy-case-divider { display:none; }
  /* The scrolling viewport owns the full workspace. Its contents live in a
     centered inner column, so the scrollbar never becomes part of a pack
     grid and every category begins on the same calm inset. */
  .trophy-room-list,.trophy-case-content { grid-column:2; grid-row:2; display:grid; grid-template-columns:minmax(0,1480px); justify-content:center; align-content:start; min-height:0; overflow:auto; padding:42px clamp(30px,4vw,80px) 56px; scrollbar-gutter:auto; }
  .trophy-room-list { gap:36px; }
  .trophy-pack-section { display:grid; gap:15px; }
  .trophy-pack-section > header,.trophy-case-content > header { display:flex; align-items:baseline; gap:9px; min-width:0; white-space:nowrap; }
  .trophy-pack-section > header span,.trophy-case-content > header span { color:#1d1d1d; font-family:"PingFang SC","Hiragino Sans GB",sans-serif; font-size:29px; font-weight:700; }
  .trophy-pack-section > header strong,.trophy-case-content > header strong { overflow:hidden; color:#1d1d1d; font-size:22px; font-weight:700; text-overflow:ellipsis; }
  .trophy-pack-section > header small,.trophy-case-content > header small { color:rgba(0,0,0,.48); font-size:16px; font-weight:600; }
  .trophy-room-grid { display:grid; grid-template-columns:repeat(12,minmax(0,1fr)); gap:13px 10px; }
  .trophy-case-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(128px,1fr)); gap:25px 18px; margin-top:22px; }
  .trophy-artwork-tile,.trophy-case-tile { display:grid; grid-template-rows:minmax(104px,1fr) auto; place-items:center; min-width:0; min-height:150px; padding:6px; border:0; border-radius:17px; background:rgba(255,255,255,.68); box-shadow:0 4px 0 rgba(51,37,20,.07); transition:transform .15s ease,background .15s ease; }
  .trophy-case-tile { min-height:178px; border-radius:20px; }
  .trophy-artwork-tile:hover:not(:disabled),.trophy-case-tile:hover:not(:disabled) { background:#fff; transform:translateY(-3px); }
  .trophy-room-art,.trophy-case-art { display:grid; place-items:center; width:100%; height:100%; min-height:0; }
  .trophy-room-art img,.trophy-room-art .trophy-locked-art,.trophy-case-art img,.trophy-case-art .trophy-locked-art { width:100%; height:100%; object-fit:contain; }
  .trophy-room-character,.trophy-case-character { display:block; max-width:100%; min-height:28px; margin-top:5px; overflow:hidden; color:rgba(0,0,0,.88); font-family:"PingFang SC","Hiragino Sans GB",sans-serif; font-size:23px; font-weight:700; line-height:1.14; text-align:center; text-overflow:ellipsis; white-space:nowrap; }
  .trophy-artwork-tile:not(.is-collected),.trophy-case-tile:not(.is-collected) { background:rgba(255,255,255,.34); box-shadow:none; }
  .trophy-artwork-tile:not(.is-collected) .trophy-room-character,.trophy-case-tile:not(.is-collected) .trophy-case-character { color:rgba(0,0,0,.38); }
  .trophy-artwork-tile:disabled,.trophy-case-tile:disabled { opacity:.82; cursor:default; }
  .trophy-artwork-tile:focus-visible,.trophy-case-tile:focus-visible { outline:3px solid var(--workspace-accent,#c23d26); outline-offset:3px; }
  /* TrophyRoomView in Swift is an image-only dictionary: its artwork is
     transparent against the canvas, without captions or card chrome. */
  .trophy-room-grid .trophy-artwork-tile { display:grid; grid-template-rows:1fr; aspect-ratio:1; min-height:0; padding:1px; border-radius:0; background:transparent; box-shadow:none; }
  .trophy-room-grid .trophy-artwork-tile:hover:not(:disabled) { background:transparent; transform:scale(1.04); }
  .trophy-room-grid .trophy-room-art { aspect-ratio:1; }
  .trophy-room-grid .trophy-artwork-tile:not(.is-collected) { background:transparent; }
  /* A case tile is two stable blocks: a square artwork frame and an
     unconstrained Chinese label below it. The label can never steal height
     from the artwork or sit on top of it. */
  .trophy-case-grid .trophy-case-tile { grid-template-rows:auto auto; align-content:start; aspect-ratio:auto; min-height:0; padding:0; border-radius:0; background:transparent; box-shadow:none; }
  .trophy-case-grid .trophy-case-art { width:100%; height:auto; min-height:0; aspect-ratio:1; padding:7px; border-radius:20px; background:transparent; box-shadow:none; }
  .trophy-case-grid .trophy-case-tile:hover:not(:disabled) { background:transparent; transform:translateY(-3px); }
  .trophy-case-grid .trophy-case-tile:hover:not(:disabled) .trophy-case-art { background:transparent; }
  .trophy-case-grid .trophy-case-character { display:block; width:100%; max-width:100%; min-height:0; margin-top:9px; overflow:hidden; font-size:clamp(19px,1.7vw,25px); line-height:1.16; text-align:center; text-overflow:clip; white-space:nowrap; }
  .trophy-case-grid .trophy-case-tile:not(.is-collected) { background:transparent; }
  .reset-case-dialog { position:fixed; top:50%; left:calc(232px + (100vw - 232px) / 2); width:min(420px,calc(100% - 48px)); margin:0; padding:28px 24px 24px; border:0; border-radius:28px; background:#fff; box-shadow:0 12px 30px rgba(0,0,0,.2); font-family:"Avenir Next",Avenir,-apple-system,BlinkMacSystemFont,sans-serif; text-align:center; transform:translate(-50%,-50%); }
  .reset-case-dialog::backdrop { background:rgba(0,0,0,.3); }
  .reset-case-warning { display:grid; place-items:center; width:54px; height:54px; margin:0 auto 14px; border-radius:50%; color:#fff; background:var(--not-yet); font-family:inherit; font-size:31px; font-weight:500; }
  .reset-case-dialog h2,.reset-case-dialog p { width:100%; margin:0; font-family:inherit; text-align:center; }.reset-case-dialog h2 { color:var(--pinyin); font-size:24px; font-weight:600; }.reset-case-dialog p { margin-top:10px; color:rgba(0,0,0,.62); font-size:16px; font-weight:500; line-height:1.35; }
  .reset-case-dialog > div { display:grid; grid-template-columns:1fr 1.25fr; gap:10px; width:100%; margin-top:22px; }.reset-case-dialog button { display:grid; place-items:center; height:47px; border:0; border-radius:14px; font-family:inherit; font-size:16px; font-weight:600; text-align:center; }.reset-case-dialog #cancel-case-reset { color:var(--pinyin); background:color-mix(in srgb,var(--pinyin) 10%,#fff); }.reset-case-dialog #confirm-case-reset { color:#fff; background:var(--not-yet); box-shadow:0 4px 0 var(--not-yet-shadow); }
}

@media (min-width:900px) and (max-width:1240px) {
  .trophy-room-grid { grid-template-columns:repeat(8,minmax(0,1fr)); }
}

/* Match is one composition, not two independently centered components.
   The prompt frame and its 2 x 3 answer frame share this exact canvas width;
   swapping direction changes only their contents, never their anchors. */
@media (min-width:900px) {
  .practice-view.mode-match {
    --match-gap:clamp(9px,1.05vw,14px);
    /* Keep the answer-tile rhythm unchanged; this is only the breathing room
       between the prompt panel and its answer-panel counterpart. */
    --match-panel-gap:calc(var(--match-gap) * 2);
    /* Optical correction for the artwork's transparent edge: move the whole
       two-panel canvas together, without changing either panel's anchors. */
    --match-canvas-offset:clamp(-42px,-2.6vw,-28px);
    /* This is Review's double-card rule: height establishes the canvas,
       then the available workspace bounds it. There is intentionally no
       fixed maximum content width. */
    /* The former reserve was leaving a visibly unused lower third on shorter
       desktop windows. Keep a balanced edge buffer, but let both square
       panels claim more of the available practice stage. */
    --match-canvas-width:min(calc(100vw - 296px), calc((100dvh - 122px) * 1.82));
    --match-panel-size:calc((var(--match-canvas-width) - var(--match-panel-gap)) / 2);
    /* The controls live in the header, but their visual footprint extends
       below the header track. A matching trailing gutter centers the canvas
       between the control row and the bottom edge—not above a large footer. */
    --match-stage-trailing-gutter:35px;
    grid-template-rows:92px minmax(0,1fr) var(--match-stage-trailing-gutter);
  }
  .practice-view.mode-match .practice-header {
    width:100%;
    height:82px;
  }
  .practice-view.mode-match .practice-header-center { display:flex; align-items:center; justify-content:center; justify-self:center; gap:clamp(24px,2.5vw,38px); }
  .practice-view.mode-match .practice-header .circle-button {
    width:52px;
    height:52px;
    border:0;
    border-radius:50%;
    background:#fff;
    box-shadow:0 2px 8px rgba(40,32,21,.08);
  }
  .practice-view.mode-match .practice-header .circle-button .ff-symbol { width:24px; height:24px; }
  .practice-view.mode-match .practice-streak {
    justify-self:center;
    display:grid;
    grid-template-columns:31px clamp(104px,9vw,140px) auto;
    align-items:center;
    gap:7px;
    min-width:0;
    height:42px;
    padding:0;
    border:0;
    border-radius:0;
    background:transparent;
    color:var(--practice-level,#9aa0a3);
    font-family:ui-rounded,"SF Pro Rounded",sans-serif;
  }
  .practice-view.mode-match .practice-fire { display:grid; place-items:center; width:31px; height:31px; color:inherit; }
  .practice-view.mode-match .practice-fire svg { width:29px; height:29px; }
  .practice-view.mode-match .practice-streak-track { display:block; height:10px; overflow:hidden; border-radius:999px; background:rgba(0,0,0,.12); }
  .practice-view.mode-match .practice-streak-track i { display:block; height:100%; border-radius:inherit; background:linear-gradient(90deg,var(--practice-fill-a,#aaa),var(--practice-fill-b,#777)); }
  .practice-view.mode-match .practice-streak strong { min-width:23px; color:inherit; font-size:20px; font-weight:800; font-variant-numeric:tabular-nums; }
  .practice-view.mode-match .practice-streak.is-collapsed { display:flex; width:auto; }.practice-view.mode-match .practice-streak.is-collapsed .practice-fire,.practice-view.mode-match .practice-streak.is-collapsed .practice-streak-track { display:none; }
  .practice-view.mode-match .practice-streak.level-yellow { --practice-level:#ed9f10; --practice-fill-a:#f7bd19; --practice-fill-b:#f18a17; }
  .practice-view.mode-match .practice-streak.level-orange { --practice-level:#ef7b17; --practice-fill-a:#ffae13; --practice-fill-b:#ee641d; }
  .practice-view.mode-match .practice-streak.level-red { --practice-level:#e44836; --practice-fill-a:#ff8d1b; --practice-fill-b:#df3e32; }
  .practice-view.mode-match .practice-streak.level-blue { --practice-level:#278ed2; --practice-fill-a:#49cae0; --practice-fill-b:#2588d0; }
  .practice-view.mode-match .practice-prompt,
  .practice-view.mode-match .practice-grid {
    grid-column:2;
    grid-row:2;
    align-self:center;
    margin:0;
  }
  .practice-view.mode-match .practice-prompt {
    display:grid;
    place-items:center;
    width:var(--match-panel-size);
    height:var(--match-panel-size) !important;
    min-height:var(--match-panel-size);
    max-height:var(--match-panel-size);
    justify-self:center;
    overflow:hidden;
    transform:translateX(calc(var(--match-panel-size) * -.5 - var(--match-panel-gap) * .5 + var(--match-canvas-offset)));
  }
  .practice-view.mode-match .practice-prompt.picture-prompt img {
    display:block;
    width:94%;
    height:94%;
    aspect-ratio:1;
    object-fit:contain;
  }
  /* Keep Match pronunciation animation out of the prompt's layout flow in
     both directions: picture prompt and text prompt with picture answers. */
  .practice-view.mode-match .practice-prompt { position:relative; isolation:isolate; }
  .practice-view.mode-match .practice-prompt > :not(.match-audio-animation) { position:relative; z-index:2; }
  .practice-view.mode-match .practice-prompt > .match-audio-animation { position:absolute; z-index:1; inset:0; display:block; width:100%; height:100%; pointer-events:none; }
  .practice-view.mode-match .match-audio-animation svg { display:block; width:100% !important; height:100% !important; }
  .practice-view.mode-match .practice-prompt.text-prompt {
    align-content:center;
    gap:clamp(9px,1.5cqi,16px);
    container-type:inline-size;
  }
  .practice-view.mode-match .practice-prompt.text-prompt { grid-template-rows:auto auto; gap:var(--match-prompt-gap,12px); padding:clamp(8px,1.5cqi,18px); }
  .practice-view.mode-match .practice-prompt .practice-prompt-hanzi {
    /* Four-character terms are still a single prompt, not a wrapped title. */
    max-width:100%;
    overflow:hidden;
    font-size:clamp(44px,18cqi,98px);
    white-space:nowrap;
    margin:0;
    color:#1d1d1d;
    font-family:"PingFang SC","Hiragino Sans GB",sans-serif;
    font-size:var(--match-prompt-hanzi-size,clamp(44px,18cqi,98px));
    font-weight:700;
    line-height:1.05;
  }
  .practice-view.mode-match .practice-prompt .practice-prompt-pinyin {
    width:100%;
    max-width:100%;
    overflow:hidden;
    font-size:clamp(25px,9cqi,50px);
    white-space:nowrap;
    margin:0;
    color:var(--pinyin);
    font-family:"Avenir Next",Avenir,sans-serif;
    font-size:var(--match-prompt-pinyin-size,clamp(25px,9cqi,50px));
    font-weight:600;
    line-height:1.16;
    text-align:center;
  }
  .practice-view.mode-match .practice-prompt .practice-prompt-hanzi.is-solo { font-size:var(--match-prompt-hanzi-size,clamp(56px,23cqi,120px)); }
  .practice-view.mode-match .practice-prompt .practice-prompt-pinyin.is-solo { font-size:var(--match-prompt-pinyin-size,clamp(34px,15cqi,76px)); }
  .practice-view.mode-match .practice-prompt.allows-two-lines .practice-prompt-pinyin { display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; line-clamp:2; overflow:hidden; white-space:normal; }
  .practice-view.mode-match .practice-grid {
    display:grid;
    grid-template-columns:repeat(2,minmax(0,1fr));
    grid-template-rows:repeat(3,minmax(0,1fr));
    gap:var(--match-gap);
    width:var(--match-panel-size);
    height:var(--match-panel-size) !important;
    min-height:var(--match-panel-size);
    max-height:var(--match-panel-size);
    justify-self:center;
    padding:0;
    transform:translateX(calc(var(--match-panel-size) * .5 + var(--match-panel-gap) * .5 + var(--match-canvas-offset)));
  }
  .practice-view.mode-match .practice-choice {
    display:grid;
    place-items:center;
    min-width:0;
    min-height:0;
    padding:clamp(4px,.7cqi,10px);
    border:1px solid rgba(33,28,20,.09);
    border-radius:clamp(13px,2.1cqi,19px);
    box-shadow:0 4px 0 rgba(46,37,23,.13);
    container-type:inline-size;
  }
  .practice-view.mode-match .practice-choice.choice-artwork { padding:0; overflow:hidden; }
  .practice-view.mode-match .practice-choice img {
    display:block;
    width:var(--match-choice-artwork-size,100%);
    height:var(--match-choice-artwork-size,100%);
    object-fit:contain;
  }
  .practice-view.mode-match .practice-choice.choice-text { grid-template-rows:auto auto; align-content:center; gap:var(--match-choice-gap,4px); }
  .practice-view.mode-match .practice-choice .practice-hanzi { min-width:0; max-width:100%; margin:0; font-size:var(--match-choice-hanzi-size,clamp(1px,18cqi,72px)); line-height:1.05; text-align:center; white-space:nowrap; }
  .practice-view.mode-match .practice-choice .practice-pinyin { min-width:0; max-width:100%; margin:0; font-size:var(--match-choice-pinyin-size,clamp(1px,8.5cqi,34px)); line-height:1.16; text-align:center; white-space:nowrap; }
  .practice-view.mode-match .practice-choice.choice-text .practice-pinyin:only-child { font-size:var(--match-choice-pinyin-size,clamp(1px,12cqi,48px)); }
  .practice-view.mode-match .practice-choice.allows-two-lines .practice-pinyin { display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; line-clamp:2; overflow:hidden; white-space:normal; }
  .practice-view.mode-match .practice-controls {
    grid-column:2;
    grid-row:1;
    z-index:2;
    justify-self:center;
    align-self:center;
    display:flex;
    gap:8px;
    /* The controls follow the complete streak meter; they must not cover its
       numeric count when the meter is expanded. */
    margin-left:clamp(350px,30vw,390px);
  }
  .practice-view.mode-match .practice-header-center .practice-controls { position:static; display:flex; align-items:center; width:auto; height:auto; margin:0; padding:0; gap:7px; }
  .practice-view.mode-match .practice-control {
    width:36px;
    height:36px;
    /* Same compact control token as Review's header display controls. */
    border:1px solid rgba(0,0,0,.16);
    border-radius:50%;
    color:#fff;
    background:var(--control-color,#4563bd);
    box-shadow:0 3px 0 rgba(0,0,0,.18);
    font-family:"Avenir Next",Avenir,sans-serif;
    font-size:14px;
    font-weight:600;
  }
  .practice-view.mode-match .practice-control.is-off { color:var(--control-color,#4563bd); background:#fff; box-shadow:0 3px 0 rgba(0,0,0,.12),0 0 0 1px rgba(0,0,0,.12); }
  .practice-view.mode-match .practice-control .ff-symbol { width:17px; height:17px; }
  /* Match's prompt direction is a stateful binary switch, not an ambiguous
     action button. Its colours and depth use the same Review control tokens. */
  .practice-view.mode-match .practice-mode-toggle { position:relative; display:grid; grid-template-columns:1fr 1fr; align-items:center; width:68px; height:36px; padding:0 5px; border:0; border-radius:999px; color:#fff; background:#0aa6cf; box-shadow:0 3px 0 rgba(0,0,0,.18); font-family:"Avenir Next",Avenir,sans-serif; font-size:18px; font-weight:500; }
  .practice-view.mode-match .practice-mode-toggle.is-text { background:#0769b5; }
  .practice-view.mode-match .practice-mode-toggle-text,.practice-view.mode-match .practice-mode-toggle-image { z-index:1; display:grid; place-items:center; width:26px; height:26px; justify-self:center; }
  .practice-view.mode-match .practice-mode-toggle-image .ff-symbol { width:21px; height:21px; }
  .practice-view.mode-match .practice-mode-toggle i { position:absolute; top:4px; left:4px; width:28px; height:28px; border-radius:50%; background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.16); transition:transform .18s ease; }
  .practice-view.mode-match .practice-mode-toggle.is-text i { transform:translateX(32px); }
  .practice-view.mode-match .practice-mode-toggle.is-picture .practice-mode-toggle-text,.practice-view.mode-match .practice-mode-toggle.is-text .practice-mode-toggle-image { visibility:hidden; }
  .practice-view.mode-match .practice-audio { display:none; }
}

/* Listen shares Match's desktop shell, but its single centered answer canvas
   is audio-led: display controls are followed by the Review speaker action. */
@media (min-width:900px) {
  .practice-view.mode-listen {
    --listen-gap:clamp(9px,1.05vw,14px);
    --listen-header-gap:clamp(14px,1.5vw,24px);
    /* Match's responsive stage rule also applies to Listen: use the available
       post-header space rather than constraining its answer canvas early. */
    --listen-grid-width:min(calc(100vw - 296px), calc((100dvh - 122px) * 1.82));
    --listen-grid-height:calc(var(--listen-grid-width) / 1.82);
    /* Header controls are already in row one. This small trailing gutter
       balances their visual footprint against the bottom of the answer grid. */
    --listen-stage-trailing-gutter:35px;
    grid-template-rows:92px minmax(0,1fr) var(--listen-stage-trailing-gutter);
  }
  .practice-view.mode-listen .practice-header { display:grid; grid-template-columns:52px minmax(0,1fr) max-content minmax(0,1fr) 52px; align-items:center; width:100%; height:82px; }
  .practice-view.mode-listen #close-practice { grid-column:1; grid-row:1; justify-self:start; }
  .practice-view.mode-listen .practice-header-center { display:flex; grid-column:3; grid-row:1; align-items:center; justify-content:center; justify-self:center; gap:var(--listen-header-gap); min-width:0; }
  .practice-view.mode-listen #practice-undo { grid-column:5; grid-row:1; justify-self:end; }
  .practice-view.mode-listen .practice-streak { display:grid; grid-template-columns:31px clamp(104px,9vw,140px) auto; align-items:center; gap:7px; min-width:0; height:42px; margin:0; padding:0; border:0; border-radius:0; background:transparent; color:var(--practice-level,#9aa0a3); font-family:ui-rounded,"SF Pro Rounded",sans-serif; }
  .practice-view.mode-listen .practice-fire { display:grid; place-items:center; width:31px; height:31px; color:inherit; }
  .practice-view.mode-listen .practice-fire svg { width:29px; height:29px; }
  .practice-view.mode-listen .practice-streak-track { display:block; height:10px; overflow:hidden; border-radius:999px; background:rgba(0,0,0,.12); }
  .practice-view.mode-listen .practice-streak-track i { display:block; height:100%; border-radius:inherit; background:linear-gradient(90deg,var(--practice-fill-a,#aaa),var(--practice-fill-b,#777)); }
  .practice-view.mode-listen .practice-streak strong { min-width:23px; color:inherit; font-size:20px; font-weight:800; font-variant-numeric:tabular-nums; }
  .practice-view.mode-listen .practice-streak.is-collapsed { display:flex; width:auto; }.practice-view.mode-listen .practice-streak.is-collapsed .practice-fire,.practice-view.mode-listen .practice-streak.is-collapsed .practice-streak-track { display:none; }
  .practice-view.mode-listen .practice-streak.level-yellow { --practice-level:#ed9f10; --practice-fill-a:#f7bd19; --practice-fill-b:#f18a17; }.practice-view.mode-listen .practice-streak.level-orange { --practice-level:#ef7b17; --practice-fill-a:#ffae13; --practice-fill-b:#ee641d; }.practice-view.mode-listen .practice-streak.level-red { --practice-level:#e44836; --practice-fill-a:#ff8d1b; --practice-fill-b:#df3e32; }.practice-view.mode-listen .practice-streak.level-blue { --practice-level:#278ed2; --practice-fill-a:#49cae0; --practice-fill-b:#2588d0; }
  .practice-view.mode-listen .practice-header-center .practice-controls { position:static; display:flex; align-items:center; width:auto; height:auto; margin:0; padding:0; gap:7px; }
  .practice-view.mode-listen .practice-control { width:36px; height:36px; border:1px solid rgba(0,0,0,.16); border-radius:50%; color:#fff; background:var(--control-color,#4563bd); box-shadow:0 3px 0 rgba(0,0,0,.18); font-family:"Avenir Next",Avenir,sans-serif; font-size:14px; font-weight:600; }
  .practice-view.mode-listen .practice-control.is-off { color:var(--control-color,#4563bd); background:#fff; box-shadow:0 3px 0 rgba(0,0,0,.12),0 0 0 1px rgba(0,0,0,.12); }
  .practice-view.mode-listen .practice-control .ff-symbol { width:17px; height:17px; }
  .practice-view.mode-listen .practice-audio { position:static; display:grid; grid-column:4; grid-row:1; place-items:center; justify-self:center; width:36px; height:36px; margin:0; padding:0; border:0; color:var(--practice-accent,#2f95c3); background:transparent; }
  .practice-view.mode-listen .practice-audio .ff-symbol { width:29px; height:29px; }
  .practice-view.mode-listen .practice-grid { display:grid; grid-column:2; grid-row:2; grid-template-columns:repeat(3,minmax(0,1fr)); grid-template-rows:repeat(2,minmax(0,1fr)); align-self:center; width:var(--listen-grid-width); height:var(--listen-grid-height); min-height:0; margin:0; padding:0; gap:var(--listen-gap); justify-self:center; }
  .practice-view.mode-listen .practice-choice { display:grid; place-items:center; align-content:center; min-width:0; min-height:0; padding:clamp(6px,.9cqi,14px); border:1px solid rgba(33,28,20,.09); border-radius:clamp(13px,2.1cqi,19px); box-shadow:0 4px 0 rgba(46,37,23,.13); container-type:inline-size; }
  .practice-view.mode-listen .practice-choice img { display:block; width:var(--listen-choice-artwork-size,100%); height:var(--listen-choice-artwork-size,100%); min-height:0; object-fit:contain; }
  .practice-view.mode-listen .practice-choice.layout-artwork-characters { grid-template-rows:auto auto; gap:var(--listen-choice-gap,4px); }.practice-view.mode-listen .practice-choice.layout-artwork-pinyin { grid-template-rows:auto auto; gap:var(--listen-choice-gap,4px); }.practice-view.mode-listen .practice-choice.layout-artwork-full { grid-template-rows:auto auto auto; gap:var(--listen-choice-gap,4px); }.practice-view.mode-listen .practice-choice.layout-characters-pinyin { grid-template-rows:auto auto; gap:var(--listen-choice-gap,4px); }
  .practice-view.mode-listen .practice-choice .practice-hanzi,.practice-view.mode-listen .practice-choice .practice-pinyin { min-width:0; max-width:100%; margin:0; overflow:hidden; text-align:center; }.practice-view.mode-listen .practice-choice .practice-hanzi { font-size:var(--listen-choice-hanzi-size,clamp(1px,18cqi,72px)); line-height:1.05; white-space:nowrap; }.practice-view.mode-listen .practice-choice .practice-pinyin { /* Tone marks are part of the glyph, not overflow to crop. Dynamic sizing keeps this label within its tile. */ overflow:visible; font-size:var(--listen-choice-pinyin-size,clamp(1px,8.5cqi,34px)); line-height:1.32; white-space:nowrap; }.practice-view.mode-listen .practice-choice.allows-two-lines .practice-pinyin { display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; line-clamp:2; overflow:hidden; line-height:1.12; white-space:normal; }
}

/* Phone Match remains a deliberately vertical reading order, but it uses the
   same square prompt / square answer-system measurements rather than fixed
   artwork dimensions. */
@media (max-width:899px) {
  .practice-view.mode-match {
    --match-phone-gap:11px;
    /* One responsive unit for the top prompt. As height tightens, its image
       or text yields space to the three answer rows instead of staying fixed. */
    --match-phone-prompt-size:min(288px,31dvh,calc(100vw - 40px));
  }
  .practice-view.mode-match .practice-prompt,
  .practice-view.mode-match .practice-prompt.picture-prompt {
    flex:0 0 var(--match-phone-prompt-size);
    width:var(--match-phone-prompt-size);
    height:var(--match-phone-prompt-size) !important;
    min-height:0;
    aspect-ratio:auto;
    margin:clamp(4px,1.15dvh,10px) auto;
  }
  .practice-view.mode-match .practice-prompt.picture-prompt img { width:100%; height:100%; }
  .practice-view.mode-match .practice-grid { gap:var(--match-phone-gap); }
  .practice-view.mode-match .practice-choice.choice-artwork { padding:0; }
}

/* Listen uses the same resilient measured content rules as Match, while each
   answer may combine artwork, Chinese, and pinyin in one tile. */
@media (max-width:899px) {
  .practice-view.mode-listen .practice-grid { margin-top:clamp(4px,1.5dvh,14px); }
  .practice-view.mode-listen .practice-choice { display:grid; place-items:center; align-content:center; min-width:0; min-height:0; padding:clamp(8px,2.2vw,14px); container-type:inline-size; }
  .practice-view.mode-listen .practice-choice img { display:block; width:var(--listen-choice-artwork-size,100%); height:var(--listen-choice-artwork-size,100%); min-height:0; object-fit:contain; }
  .practice-view.mode-listen .practice-choice.layout-artwork-characters { grid-template-rows:auto auto; gap:var(--listen-choice-gap,4px); }.practice-view.mode-listen .practice-choice.layout-artwork-pinyin { grid-template-rows:auto auto; gap:var(--listen-choice-gap,4px); }.practice-view.mode-listen .practice-choice.layout-artwork-full { grid-template-rows:auto auto auto; gap:var(--listen-choice-gap,4px); }.practice-view.mode-listen .practice-choice.layout-characters-pinyin { grid-template-rows:auto auto; gap:var(--listen-choice-gap,4px); }
  .practice-view.mode-listen .practice-choice .practice-hanzi,.practice-view.mode-listen .practice-choice .practice-pinyin { min-width:0; max-width:100%; margin:0; overflow:hidden; text-align:center; }.practice-view.mode-listen .practice-choice .practice-hanzi { font-size:var(--listen-choice-hanzi-size,34px) !important; line-height:1.05; white-space:nowrap; }.practice-view.mode-listen .practice-choice .practice-pinyin { overflow:visible; font-size:var(--listen-choice-pinyin-size,19px) !important; line-height:1.32; white-space:nowrap; }.practice-view.mode-listen .practice-choice.allows-two-lines .practice-pinyin { display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; line-clamp:2; overflow:hidden; line-height:1.12; white-space:normal; }
}
