/* 练习页版面（Steven 的设计稿：docs/assets/ui-references/design-phone.png、design-desktop.png）。
   颜色、字号、间距、圆角来自 css/tokens.css；按钮组件在 css/base.css。

   骨架：所有级别、所有状态都是同一个结构——页面底色 + 顶栏 + 一张白色底板。底板里从上到下固定五行：
     ① 图片区（正方形）  ② 文字区（固定高度：两行英文 + 一行中文）  ③ 图标行（3 个 52px 圆）
     ④ 反馈行（固定 44px，一行）  ⑤ 按钮行（← → 等宽，高 52）
   任何按钮都不出现、不消失、不移动，只在「可用」和「灰色」之间切换；元素全在文档流里（flex），不用绝对定位。

   尺寸由 CSS 实时算（不用 JS 量尺寸）：先算图片区边长 --media，底板宽 --board-w 由它推出。
   手机（默认）：五行上下摞；电脑与横屏（宽 ≥ 768 且宽 > 高）：左右两栏，左栏图片区，右栏其余四行垂直居中。
   一屏放下、不滚动；教学用图一律不裁切（contain）。 */

:root {
  --page-x: var(--pad-x);          /* 底板到屏幕左右边的距离（≤ 360 宽收到 8px，见 tokens.css） */
  --page-y: 16px;                  /* 顶栏与底板、底板与屏幕下沿的距离 */
  --top-h: 56px;                   /* 顶栏高度 */
  --board-pad: 16px;               /* 底板内边距 */
  --row-gap: clamp(10px, 2dvh, 18px); /* 五行之间的间距：窗口越矮越紧（844 高时约 17px，568 高时约 11px） */
  --tile-gap: 12px;                /* 2×2 选项之间的间距 */

  --icon: 52px;                    /* 图标行：圆形按钮直径 */
  --icon-gap: 20px;                /* 图标之间的间距 */
  --fb-h: 44px;                    /* 反馈行高度 */
  --act-h: 52px;                   /* 按钮行高度 */
  --act-gap: 12px;                 /* ← → 之间的间距 */
  /* 文字区高度 = 两行英文（行高 1.35）+ 4px + 一行中文（行高 1.4）；始终固定，英文只有一行时中文紧跟其后，剩余留在下面 */
  --text-h: calc(2 * 1.35 * var(--fs-sentence) + 4px + 1.4 * var(--fs-gloss));

  /* 手机：图片区边长 = 底板内宽、剩余高度能给的、源图清晰度上限（512），三者取最小。
     高度：视口高 − 顶栏 − 上下留白 − 底板上下内边距 − 文字区 − 图标行 − 反馈行 − 按钮行 − 4 处行间距。
     上限 512：源图 1024×1024，2 倍屏每个 CSS 像素要 2 个源像素，再大就是放大后模糊（docs/standards/media-assets.md）。
     底板宽 ≤ 544（= 512 + 2 × 16），平板竖屏上不会拉得太宽。 */
  --board-w: min(100vw - 2 * var(--page-x), 544px);
  --media: max(64px, min(var(--board-w) - 2 * var(--board-pad),
    100dvh - var(--top-h) - 2 * var(--page-y) - 2 * var(--board-pad) - var(--text-h) - var(--icon) - var(--fb-h) - var(--act-h) - 4 * var(--row-gap), 512px));
}

/* 电脑与横屏：宽大于高、且宽度 ≥ 768。左右两栏，顺序不变。
   1280×600 时：图片区 464（= 600 − 56 − 2×16 − 2×24），底板 944×512（= 464 + 400 + 32 + 2×24）。 */
@media (min-width: 768px) and (orientation: landscape) {
  :root {
    --board-pad: 24px;
    --row-gap: 20px;
    --tile-gap: 16px;
    --col-gap: 32px;               /* 左栏与右栏之间 */
    --side-max: 400px;             /* 右栏最宽 */
    --side-min: 320px;             /* 右栏最窄（装得下一行反馈与两个按钮） */
    --media: max(64px, min(100dvh - var(--top-h) - 2 * var(--page-y) - 2 * var(--board-pad),
      100vw - 2 * var(--page-x) - 2 * var(--board-pad) - var(--col-gap) - var(--side-min), 512px));
    --side-w: min(var(--side-max), 100vw - 2 * var(--page-x) - 2 * var(--board-pad) - var(--col-gap) - var(--media));
    --board-w: calc(var(--media) + var(--side-w) + var(--col-gap) + 2 * var(--board-pad));
  }
}

body { overflow: hidden; }
.app { height: 100dvh; display: flex; flex-direction: column; }

/* 顶栏与底板同宽、同一条中轴 */
.top { flex: none; }
.top-in { display: flex; align-items: center; gap: var(--sp-3); width: var(--board-w); height: var(--top-h); margin-inline: auto; }
.scene { flex: none; font-size: var(--fs-small); color: var(--c-text-2); }

/* 内容区：占满剩余高度，底板在里面垂直、水平居中 */
.content { flex: 1; min-height: 0; display: grid; place-items: center; padding: var(--page-y) var(--page-x); }

/* 底板：白色、圆角 20、极淡阴影。手机上五行摞起来 */
.board { width: var(--board-w); padding: var(--board-pad); border-radius: var(--r-card); background: var(--c-card); box-shadow: var(--shadow-0);
  display: flex; flex-direction: column; gap: var(--row-gap); }
.media { align-self: center; flex: none; width: var(--media); height: var(--media); }
.side { display: flex; flex-direction: column; gap: var(--row-gap); min-width: 0; }

/* ① 图片区：第 1 级一张大图，第 2、3 级 2×2；两者占同样大小 */
.hero { display: block; width: 100%; height: 100%; object-fit: contain; border-radius: var(--r-img); }
.options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(2, minmax(0, 1fr)); gap: var(--tile-gap); width: 100%; height: 100%; }
.opt { position: relative; min-width: 0; min-height: 0; padding: 4px; border: 2px solid var(--c-line); border-radius: var(--r-img); background: var(--c-card); cursor: pointer; transition: border-color .15s; }
.opt:hover:not(:disabled) { border-color: var(--c-line-strong); }
.opt img { display: block; width: 100%; height: 100%; object-fit: contain; border-radius: 8px; transition: opacity .2s; }
.opt:disabled { cursor: default; }
/* 对错：3px 彩色边（2px 边框 + 1px 内描边，尺寸不跳）；选错的图变淡、不可再点；右上角小圆标 */
.opt.right { border-color: var(--c-ok); box-shadow: inset 0 0 0 1px var(--c-ok); }
.opt.wrong { border-color: var(--c-bad); box-shadow: inset 0 0 0 1px var(--c-bad); animation: shake .3s; }
.opt.wrong img { opacity: .45; }
.badge { position: absolute; top: 6px; right: 6px; display: grid; place-items: center; width: 22px; height: 22px; border-radius: var(--r-pill); background: var(--c-card); }
.badge .ico { width: 14px; height: 14px; }
.opt.right .badge { color: var(--c-ok); border: 2px solid var(--c-ok); }
.opt.wrong .badge { color: var(--c-bad); border: 2px solid var(--c-bad); }
@keyframes shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }

/* ② 文字区：固定高度，从顶部排起；英文居中、常规粗细、#4D4D4D，变化词块加粗 + 浅蓝底（base.css 的 mark.chunk）；中文紧贴英文下方居中 */
.text { height: var(--text-h); text-align: center; overflow: hidden; }
.sentence { margin: 0; font-size: var(--fs-sentence); font-weight: var(--fw-regular); color: var(--c-text-2); line-height: 1.35; overflow-wrap: anywhere; }
.gloss-line { margin: 4px 0 0; font-size: var(--fs-gloss); line-height: 1.4; color: var(--c-text-2); visibility: hidden; } /* 始终占位，只切换可见性 */
.gloss-line.on { visibility: visible; }

/* ③ 图标行：3 个 52px 圆，间距 20，整组居中 */
.icons { display: flex; justify-content: center; gap: var(--icon-gap); height: var(--icon); }

/* ④ 反馈行：固定 44px，只能一行，居中；状态图标与标签不被挤压、不折行，反馈句放不下时由 test-ui/feedback-fit.spec.js 报警 */
.feedback { display: flex; align-items: center; justify-content: center; gap: var(--sp-2); height: var(--fb-h); margin: 0; font-size: var(--fs-small); white-space: nowrap; overflow: hidden; }
.fb-label { flex: none; font-weight: var(--fw-bold); }
.fb-text { min-width: 0; color: var(--c-text-2); }
.fb-ico { flex: none; display: inline-flex; }
.feedback.ok .fb-ico, .feedback.ok .fb-label { color: var(--c-ok-text); }
.feedback.bad .fb-ico, .feedback.bad .fb-label { color: var(--c-bad); }
.fb-ico .ico { width: 16px; height: 16px; }

/* ⑤ 按钮行：← 和 → 等宽，各占一半，间距 12，高 52，胶囊形（样式在 base.css 的 .nav-btn） */
.actions { display: flex; gap: var(--act-gap); height: var(--act-h); }

/* 完成页：同一张底板，图片区放大 ✓，文字区写小结，按钮行是 ↻ 与 → */
.done-mark { display: grid; place-items: center; width: 100%; height: 100%; border-radius: var(--r-img); background: var(--c-ok-tint); color: var(--c-ok); }
.done-mark .ico { width: 40%; height: 40%; }
.done-title { margin: 0; font-size: var(--fs-title); font-weight: var(--fw-bold); line-height: 1.2; }
.done-summary { margin: 4px 0 0; font-size: var(--fs-gloss); color: var(--c-text-2); }
.error-text { margin: 0; color: var(--c-text); }

/* 电脑与横屏：左栏图片区（正方形），右栏四行垂直居中 */
@media (min-width: 768px) and (orientation: landscape) {
  .board { flex-direction: row; align-items: center; gap: var(--col-gap); }
  .media { align-self: center; }
  .side { flex: none; width: var(--side-w); }
}

/* ===== 第 9 级「你想到了吗」（设计稿 docs/assets/ui-references/level9-design.html）=====
   图片区（正方形）里竖着放：缩略图、中文场景句、输入框（含麦克风）。缩略图是可压缩的那一块：
   图片区高度不到 280px（如 320×568 的手机、横过来的手机）时，缩略图整个不显示（容器查询；不认识容器查询的旧浏览器里它会被压成一小点，不影响其余部分）：
   场景句最多 4 行（约 87px）+ 输入框至少 96px + 缩略图 64px + 间距，需要约 270px。 */
.board.write .media { container-type: size; }
@container (max-height: 280px) { .l9-thumb { display: none; } }
.l9 { display: flex; flex-direction: column; align-items: center; gap: var(--sp-3); width: 100%; height: 100%; min-height: 0; }
.l9-thumb { flex: 0 1 calc(var(--media) * .34); min-height: 0; aspect-ratio: 1; max-width: 100%; padding: 4px; border: 2px solid var(--c-line); border-radius: var(--r-card); background: var(--c-card); }
.l9-thumb img { display: block; width: 100%; height: 100%; object-fit: contain; border-radius: 8px; }
.l9-scene { flex: none; width: 100%; margin: 0; font-size: var(--fs-gloss); line-height: 1.45; color: var(--c-text-2); text-align: center; overflow-wrap: anywhere; }

/* 输入框：作答时白底、聚焦时主色边；出结果后变成浅灰底（done），里面显示学习者的回答（带改正标记） */
.l9-box { flex: 1 0 96px; width: 100%; min-height: 0; padding: var(--sp-3) var(--sp-3) var(--sp-2); border: 2px solid var(--c-line); border-radius: 14px; background: var(--c-card);
  display: flex; flex-direction: column; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.l9-box:focus-within { border-color: var(--c-primary); }
.l9-box.done { background: var(--c-bg); border-color: var(--c-bg); }
.l9-input, .l9-ans { flex: 1; width: 100%; min-height: 0; margin: 0; padding: 0; border: 0; background: transparent; color: var(--c-text); font: inherit;
  font-size: var(--fs-sentence); line-height: 1.45; text-align: center; overflow-y: auto; overflow-wrap: anywhere; }
.l9-input { resize: none; outline: none; }
.l9-input::placeholder { color: var(--c-disabled); }
.l9-mic { flex: none; width: 44px; height: 44px; background: var(--c-bg); color: var(--c-primary); }
.l9-box:focus-within .l9-mic { background: var(--c-tint); }
.l9-mic:disabled, .l9-box.done .l9-mic { background: var(--c-card); color: var(--c-disabled); }
.l9-mic.on { background: var(--c-primary); color: #FFFFFF; }
.l9-mic.on:hover:not(:disabled) { background: var(--c-primary-deep); color: #FFFFFF; }

/* 改正标记：删去的词红色加删除线，补上的词绿色加粗 */
.del { color: var(--c-bad); text-decoration: line-through; }
.ins { color: var(--c-ok-deep); font-weight: var(--fw-bold); } /* 输入框结果态是浅灰底，#00892F 在上面只有 4.25:1，用加深的 --c-ok-deep（4.64:1） */

/* 文字区：作答前是隐私提示（灰色小字，一行）；出结果后是「参考」小标签 + 参考答案（词块高亮）+ 译文行 */
.l9-privacy { margin: 0; font-size: var(--fs-small); line-height: 1.4; color: var(--c-text-2); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ref { font-size: 12px; line-height: 1.5; color: var(--c-text-2); background: var(--c-bg); border-radius: var(--r-pill); padding: 1px 8px; margin-right: 6px; vertical-align: 2px; }

/* 反馈行：标签 + 短评，必须一行（短评不超过 12 个字，在 320 宽上放得下；依据见设计文档「反馈两层」），万一超出用省略号，完整文字在 title 里；
   完整讲解不放在这一行，放在作答框里（.l9-explain） */
.feedback.fb9 .fb-text { overflow: hidden; text-overflow: ellipsis; }
.feedback.warn .fb-ico, .feedback.warn .fb-label { color: var(--c-warn-text); }
.feedback.busy .fb-ico { color: var(--c-primary); }
.feedback.hint .fb-ico { color: var(--c-text-2); }
.feedback.fb9 .fb-ico .ico { width: 18px; height: 18px; }

/* 批改后作答框里：学习者的句子 + 完整讲解（灰色小字）。原来麦克风的位置不再显示麦克风；内容多时在框内滚动（.l9-ans 的 overflow-y），不撑开版面 */
.l9-sent { font-size: var(--fs-sentence); line-height: 1.45; color: var(--c-text); }
.l9-explain { margin: var(--sp-2) 0 0; font-size: var(--fs-small); line-height: 1.45; color: var(--c-text-2); }

/* ===== 打字模式（html.typing，由 level9.js 在输入时加上）=====
   原因：安卓微信等浏览器弹出键盘后会压缩网页高度，而图片区的正方形边长是按高度算的，高度一小它就缩成一窄条，下面各行互相重叠。
   做法：输入时不再用「按高度算的正方形」，改成自然流式、可滚动的布局——隐藏缩略图和图标行，场景句占满卡片内容宽度，
   下面是输入框、隐私提示 / 反馈行、提交按钮；内容放不下就页面滚动，不压缩任何元素。
   提交按钮「贴在键盘上方」靠文档流做到：页面至少一屏高（键盘弹出后一屏就是键盘上方那一截），按钮行用 margin-top:auto 推到最底；
   内容比一屏长时按钮在内容末尾，滚到底就能点。不用固定 / 粘性定位（style.spec.js 禁止：按钮全在文档流里，从结构上不会重叠）。
   这是对「按钮不出现、不消失、不移动」的明确例外：只在输入的这一小段时间里，左边的灰色 ← 隐藏，提交占满宽。 */
html.typing, html.typing body { height: auto; overflow-y: auto; }
html.typing .app { height: auto; min-height: 100dvh; }
html.typing .content { display: flex; flex-direction: column; align-items: center; justify-content: flex-start; }
html.typing .board { flex: 1 0 auto; flex-direction: column; align-items: stretch; gap: var(--row-gap); }
html.typing .board.write .media { width: 100%; height: auto; container-type: normal; align-self: stretch; }
html.typing .l9 { height: auto; }
html.typing .l9-thumb, html.typing .icons { display: none; }
html.typing .side { flex: 1 0 auto; width: auto; }
html.typing .text { height: auto; }
html.typing .l9-box { flex: none; min-height: 128px; }
html.typing .l9-input { flex: 1 0 auto; min-height: 72px; }
html.typing .actions { margin-top: auto; }
html.typing .actions > [data-act="prev"] { display: none; }
