/* DuoMi app 公共样式。
   画布 1260×2712（3px = 1dp），所有坐标取自 research/duolingo-replica 的实测复刻件；
   #stage 按视口等比缩放。颜色、圆角、描边厚度不要改，它们是量出来的。 */
:root{
  --page:#FFFFFD; --ink:#4B4B4B; --muted:#AFAFAF; --line:#E5E5E5;
  --green:#58CC02; --green-dk:#58A700; --green-lt:#79D635; --green-tray:#D7FFB8; --green-bd:#A5ED6E;
  --blue:#1CB0F6; --blue-bd:#84D8FF; --blue-lt:#DDF4FF;
  --red:#FF4B4B; --red-dk:#EA2B2B; --red-tray:#FFDFE0; --red-bd:#FFB2B2;
  --yellow:#FFC800; --yellow-dk:#E7A601; --yellow-tray:#FFF5D3; --yellow-ink:#CD7900;
  --purple:#CE82FF; --orange:#FF9600; --pink:#FF86CD;
  --font:"Nunito","Noto Sans SC","PingFang SC","Microsoft YaHei","Segoe UI",sans-serif;
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
/* 手机上页面底色与画布同色，不留深色边；只有宽屏（桌面预览）才用深色衬底 */
html,body{height:100%;background:var(--page);overflow:hidden;font-family:var(--font)}
@media (min-width:700px) and (min-aspect-ratio:3/4){html,body{background:#0e1418}}
#stage{position:fixed;left:50%;top:0;width:1260px;height:var(--H,2712px);transform-origin:0 0;
       background:var(--page);overflow:hidden;color:var(--ink);user-select:none;-webkit-user-select:none}
#screen{position:absolute;inset:0}
.abs{position:absolute}
.qbody{pointer-events:none}
.qbody > *{pointer-events:auto}
.hit{cursor:pointer}

/* —— 顶栏：关闭叉、进度轨、能量 —— */
.quit{position:absolute;left:60px;top:133px;width:72px;height:72px;cursor:pointer}
.track{position:absolute;left:192px;top:138px;width:801px;height:60px;background:var(--line);border-radius:30px;overflow:hidden}
.fill{position:absolute;left:0;top:0;height:60px;background:var(--green);border-radius:30px;transition:width .35s ease-out}
.shine{position:absolute;left:12px;right:12px;top:15px;height:13px;background:var(--green-lt);border-radius:6.5px}
.energy-ico{position:absolute;left:1041px;top:143px;width:70px;height:47px}
.enum{position:absolute;left:1137px;top:143px;color:var(--pink);font-size:52px;font-weight:700;line-height:1}
.combo{position:absolute;top:66px;color:var(--green);font-size:46px;font-weight:700;line-height:1;white-space:nowrap}

/* —— 指令区：徽标 + 题型标题 —— */
.badge-ico{position:absolute;left:65px;top:289px;width:77px;height:75px}
.badge{position:absolute;left:166px;top:299px;font-size:45px;font-weight:700;line-height:1;white-space:nowrap}
.inst{position:absolute;left:48px;color:var(--ink);font-size:74px;font-weight:700;line-height:1;white-space:nowrap}

/* —— 控件族：6px 描边 + 12px 厚底 + 48px 圆角 —— */
.ctl{position:absolute;display:flex;align-items:center;justify-content:center;
     border-style:solid;border-width:6px;border-bottom-width:12px;border-radius:48px;
     border-color:var(--line);background:var(--page);color:var(--ink);
     font-size:56px;font-weight:500;line-height:1;cursor:pointer;text-align:center}
.ctl:active{transform:translateY(6px);border-bottom-width:6px}
.ctl.on{border-color:var(--blue-bd);background:var(--blue-lt);color:var(--blue)}
.ctl.ok{border-color:var(--green-bd);background:var(--green-tray);color:var(--green-dk)}
.ctl.bad{border-color:var(--red-bd);background:var(--red-tray);color:var(--red-dk)}
.ctl.faded{color:var(--line)}
.ctl.locked{pointer-events:none}
.ctl.used{border:0;background:var(--line);color:transparent;pointer-events:none}
.opt{left:48px;width:1164px;height:163px}
.opt.wrap{white-space:normal;line-height:1.15;padding:0 40px;font-size:48px}

/* —— 角色 + 气泡 —— */
.char{position:absolute}
.bub{position:absolute;background:var(--page);border:6px solid var(--line);border-radius:48px;
     display:flex;align-items:center;padding:0 48px;color:var(--ink);font-size:60px;font-weight:500;line-height:1.5;
     min-height:178px;max-width:690px}
.tail{position:absolute;width:51px;height:56px}

/* —— 提交按钮 —— */
.submit{position:absolute;left:48px;bottom:48px;width:1164px;height:144px;display:flex;align-items:center;justify-content:center;
        font-size:52px;font-weight:700;border-radius:48px;background:var(--line);color:var(--muted);cursor:default;letter-spacing:1px}
.submit.on{bottom:60px;background:var(--green);color:var(--page);box-shadow:0 12px 0 var(--green-dk);cursor:pointer}
.submit.on:active{bottom:48px;box-shadow:none}
.submit.wrong{bottom:60px;background:var(--red);color:var(--page);box-shadow:0 12px 0 var(--red-dk);cursor:pointer}
.submit.warn{bottom:60px;background:var(--yellow);color:var(--yellow-ink);box-shadow:0 12px 0 var(--yellow-dk);cursor:pointer}

/* —— 反馈托盘 —— */
.tray{position:absolute;left:0;bottom:0;width:1260px;background:var(--green-tray)}
.tray.ok{height:429px;animation:slide .115s cubic-bezier(.345,1.235,.405,.755) both}
/* 答错托盘高度 = 实测 670px 起步，答案折行时由引擎按内容算出 --th 往上撑（托盘底边贴屏底，子元素按托盘顶定位，所以整块一起上移） */
.tray.bad{height:var(--th,670px);background:var(--red-tray);animation:rise .217s linear both}
.tray.warn{height:429px;background:var(--yellow-tray);animation:slide .115s cubic-bezier(.345,1.235,.405,.755) both}
@keyframes slide{from{transform:translateY(429px)}to{transform:translateY(0)}}
@keyframes rise{0%{height:0}23%{height:467px}76%{height:467px}100%{height:var(--th,670px)}}
.no-anim .tray{animation:none !important}
.tray-ico{position:absolute;left:48px;width:72px;height:72px}
.tray-title{position:absolute;left:145px;font-size:75px;font-weight:700;line-height:1;white-space:nowrap}
.tray.ok .tray-title,.tray.ok .tray-sub{color:var(--green-dk)}
.tray.bad .tray-title,.tray.bad .tray-sub,.tray.bad .tray-ans{color:var(--red-dk)}
.tray.warn .tray-title{color:var(--yellow-ink);left:51px}
.tray-sub{position:absolute;left:51px;font-size:58px;font-weight:700;line-height:1}
.tray-ans{position:absolute;left:50px;right:50px;font-size:50px;font-weight:500;line-height:1.25}

/* —— 配对格 —— */
.cell{width:546px;height:216px}

/* —— 词块 —— */
.tok{height:165px;padding:0 42px;white-space:nowrap}
.tok.small{height:148px;font-size:50px}
.slotline{position:absolute;left:48px;width:1164px;height:6px;background:var(--line)}

/* —— 填空卡 —— */
.card{position:absolute;left:96px;top:571px;width:1068px;min-height:619px;border:6px solid var(--line);border-radius:48px;background:var(--page);
      padding:40px 60px;font-size:56px;font-weight:500;line-height:189px;color:var(--ink)}
.blank{display:inline-block;min-width:250px;border-bottom:6px solid var(--blue);text-align:center;color:var(--blue);line-height:1.2;vertical-align:baseline}
.blank.ok{border-color:var(--green-dk);color:var(--green-dk)}
.blank.bad{border-color:var(--red-dk);color:var(--red-dk)}

/* —— 对话气泡 —— */
.dlg{position:absolute;background:var(--page);border:6px solid var(--line);border-radius:48px;
     color:var(--ink);font-size:60px;font-weight:500;line-height:111px;padding:20px 56px}
.dlg .spk{display:inline-block;width:93px;height:71px;vertical-align:middle;margin-right:24px;cursor:pointer}
.dlg .dash{border-bottom:6px dashed var(--muted);padding-bottom:2px}

/* —— 听力：喇叭盒 —— */
.spkbox{position:absolute;left:525px;top:596px;width:582px;height:288px;background:var(--page);border:6px solid var(--line);border-radius:48px;display:flex}
.spkbox > div{flex:1;display:flex;align-items:center;justify-content:center;cursor:pointer}
.spkbox > div + div{border-left:6px solid var(--line)}
.skip{position:absolute;left:394px;bottom:252px;width:471px;height:156px;display:flex;align-items:center;justify-content:center;
      color:var(--muted);font-size:53px;font-weight:700;cursor:pointer;white-space:nowrap}

/* —— 角色动效 ——
   由 app/web/actor.js 脚本驱动（待机随机眨眼/视线/挑眉、对嘴、答对答错专属反应），这里只定部件的变换基准。
   依据：逐帧回看 capture/videos 与 references 里的真机录屏，见 characters.js 文件头。 */
.char{overflow:visible}
.char .c-whole{transform-box:fill-box;transform-origin:50% 100%}
.char .c-body{transform-box:fill-box;transform-origin:50% 100%}
.char .c-head{transform-box:fill-box;transform-origin:50% 85%}
.char .c-eyes,.char .c-happy{transform-box:fill-box;transform-origin:50% 50%}
.char .c-pupils{transform-box:fill-box;transform-origin:50% 50%}
.char .c-browL,.char .c-browR{transform-box:fill-box;transform-origin:50% 50%}
.char .c-armL,.char .c-armR{transform-box:fill-box;transform-origin:50% 6%}
.char-falstaff .c-armL,.char-falstaff .c-armR{transform-origin:50% 50%}
.char .c-rider{transform-box:view-box;transform-origin:0 0}
.char.locked{filter:grayscale(1) opacity(.55)}
@media (prefers-reduced-motion:reduce){.char,.char *{animation:none !important}}

/* —— 喇叭声波动画：播放中两道声波依次亮灭 —— */
.spk-ico .w1,.spk-ico .w2{transition:opacity .1s}
.playing .spk-ico .w1,.spk-ico.playing .w1{animation:wave1 .75s steps(1) infinite}
.playing .spk-ico .w2,.spk-ico.playing .w2{animation:wave2 .75s steps(1) infinite}
@keyframes wave1{0%{opacity:0}33%{opacity:1}100%{opacity:1}}
@keyframes wave2{0%{opacity:0}66%{opacity:1}100%{opacity:1}}
.playing .spk-ico,.spk-ico.playing{transform-origin:center}
.spkbox > div.playing{background:#DDF4FF}

/* —— 输入填空 —— */
.typein{display:inline-block;border:0;border-bottom:6px solid var(--blue);outline:0;background:transparent;
        font:500 56px/1.2 var(--font);color:var(--blue);text-align:center;padding:0 8px;vertical-align:baseline;caret-color:var(--blue)}
.typein::placeholder{color:#CFCFCF;letter-spacing:6px}
.typein.ok{border-color:var(--green-dk);color:var(--green-dk)}
.typein.bad{border-color:var(--red-dk);color:var(--red-dk)}
.hintzh{position:absolute;left:96px;width:1068px;color:#777;font-size:50px;font-weight:500;line-height:1.4}

/* —— 学习地图 —— */
.mnode{position:absolute;width:212px;height:202px;z-index:2;cursor:pointer}
.mnum{position:absolute;font-weight:700;line-height:1;font-size:47px;white-space:nowrap}

/* —— 首页 / 设置 / 完成页 —— */
.htitle{position:absolute;left:0;top:113px;width:1260px;text-align:center;color:var(--muted);font-size:62px;font-weight:700;line-height:1}
.hrule{position:absolute;left:0;top:210px;width:1260px;height:6px;background:var(--line)}
.back{position:absolute;left:54px;top:115px;width:60px;height:58px;cursor:pointer}
.gear{position:absolute;left:1120px;top:112px;width:72px;height:72px;cursor:pointer}
.sect{position:absolute;left:50px;color:#777;font-size:56px;font-weight:700;line-height:1}
.scard{position:absolute;left:48px;width:1164px;border:6px solid var(--line);border-radius:48px;background:var(--page)}
.sep{position:absolute;left:48px;width:1164px;height:6px;background:var(--line)}
.row{position:absolute;left:98px;color:var(--ink);font-size:56px;font-weight:700;line-height:1;white-space:nowrap}
.sw{position:absolute;left:996px;width:168px;height:96px;cursor:pointer}
.sw::before{content:"";position:absolute;left:0;top:12px;width:168px;height:72px;background:var(--line);border-radius:36px}
.sw::after{content:"";position:absolute;left:0;top:0;width:90px;height:96px;background:var(--page);border:6px solid var(--line);border-bottom-width:12px;border-radius:30px;transition:left .15s}
.sw.on::before{background:var(--blue)}
.sw.on::after{left:78px;border-color:var(--blue)}
.radio{position:absolute;width:94px;height:94px;border-radius:47px;border:6px solid var(--line);cursor:pointer}
.radio.on{border-color:var(--blue)}
.radio.on::after{content:"";position:absolute;left:20px;top:20px;width:42px;height:42px;background:var(--blue);border-radius:21px}
.rlab{position:absolute;color:var(--ink);font-size:52px;font-weight:500;line-height:1;cursor:pointer;white-space:nowrap}
.lesson-btn{left:48px;width:1164px;height:180px;font-size:56px;font-weight:700;justify-content:space-between;padding:0 60px}
.lesson-btn .sub{font-size:40px;font-weight:500;color:#777}
.lesson-btn.done{border-color:var(--green-bd);background:var(--green-tray);color:var(--green-dk)}
.lesson-btn.done .sub{color:var(--green-dk)}
.big{position:absolute;left:0;width:1260px;text-align:center;font-weight:700;color:var(--ink)}
.stat{position:absolute;left:96px;width:1068px;height:200px;border:6px solid var(--line);border-radius:48px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px}
.stat b{font-size:72px;color:var(--yellow-ink)}
.stat span{font-size:40px;color:#777;font-weight:700}
.chip{position:absolute;height:120px;padding:0 40px;border:6px solid var(--line);border-radius:60px;display:flex;align-items:center;font-size:48px;font-weight:700;color:var(--ink)}
.chip small{font-weight:500;color:#777;margin-left:20px;font-size:40px}
