/* Labels share the image coordinate system, independent of viewport size. */
.basket .basket-body>span {
  left:50%; top:60%; width:30%; height:20%;
  transform:translate(-50%,-50%);
  display:flex; align-items:center; justify-content:center;
  padding:0; line-height:1; overflow:hidden;
}
.basket .basket-body>span .item-icon {width:auto;height:100%;max-width:100%;}
.destination-icon {color:#175239;font-size:14px;font-weight:900;text-shadow:none;}
.basket .basket-body>span .destination-icon {background:none;padding:0;border-radius:0;font-size:clamp(14px,1.7vw,24px);line-height:1.15;}
.basket .basket-body>span:has(.destination-icon) {width:40%;}
@media(max-width:580px){.destination-icon,.basket .basket-body>span .destination-icon {font-size:13px;}}
.demo-frame>span {left:50%;top:calc(100% - 16px);bottom:auto;transform:translateX(-50%);height:14px;display:flex;align-items:center;justify-content:center;}
.demo-frame>span .item-icon {width:auto;height:100%;}
.belt {
  background:url('../assets/conveyor.webp') center 48% / 100% 285% no-repeat;
  border:0; box-shadow:none; border-radius:0;
}
.belt:before,.belt:after {display:none;}
.two-lanes .lane.lit .belt {border:0;box-shadow:none;filter:drop-shadow(0 0 7px #ffdc78);}
.demo-track {background:url('../assets/conveyor.webp') center 48% / 100% 285% no-repeat;border:0;box-shadow:none;}
.demo-parcel {top:calc(52px + 24px * .52 - 67px * .89);}
.demo-parcel>img {filter:drop-shadow(0 2px 1px #10271c66);}

/* Anchor the visible parcel base (89% down its PNG) to the rubber surface,
   above the conveyor's front wooden rail. Both lanes share this geometry. */
.lane {--belt-top:73px;--belt-height:86px;--parcel-size:95px;}
.lane>.belt {top:var(--belt-top);height:var(--belt-height);}
.lane>.parcel {top:calc(var(--belt-top) + var(--belt-height) * .52 - var(--parcel-size) * .89);}
.parcel .box>img {filter:drop-shadow(0 3px 2px #10271c66);}
@media(max-width:580px){
  .lane {--belt-top:92px;--belt-height:65px;--parcel-size:71px;}
  .two-lanes .lane {--belt-top:79px;}
}

/* Taller baskets enlarge the actual illustrated nameplate with its symbol. */
.lane {height:350px;}
.basket .basket-body {top:90px;bottom:auto;height:210px;}
.two-lanes .lane {height:320px;}
.two-lanes .basket .basket-body {top:90px;bottom:auto;height:180px;}
@media(max-width:850px) and (min-width:581px){
  .basket .basket-body {height:185px;}
  .two-lanes .basket .basket-body {height:170px;}
}
@media(max-width:580px){
  .lane {height:285px;}
  .basket .basket-body {top:78px;bottom:auto;height:125px;}
  .two-lanes .lane {height:270px;}
  .two-lanes .basket .basket-body {top:85px;bottom:auto;height:125px;}
}

/* Keep essential text off the detailed artwork and out of tiny type sizes. */
.result-knowledge {display:flex;align-items:center;gap:18px;background:#f2dfaa;border:1px solid #b99b5d;border-radius:14px;padding:14px;margin:18px 0;text-align:left;}
.result-knowledge .city-art {flex:0 0 130px;width:130px;border-radius:12px;}
.result-knowledge p {margin:8px 0 0;}
@media(max-width:580px){
  .result-knowledge {gap:12px;padding:12px;}
  .result-knowledge .city-art {flex-basis:85px;width:85px;}
  .result-knowledge p {font-size:14px;line-height:1.65;}
}
.game-heading {
  background:#173d2e; border:1px solid #91a77b;
  border-radius:14px; padding:14px 18px; gap:16px;
}
.game-heading .eyebrow {
  color:#fff1c8; font-size:14px; font-weight:700;
  letter-spacing:1px; line-height:1.6; text-shadow:none;
}
.game-heading h1 {color:#fff5d9;font-size:28px;line-height:1.4;text-shadow:none;margin:5px 0 0;}
.game-tools .quiet {background:#28553d;border-radius:9px;color:#fff6df;font-weight:700;}
.stats {background:#173d2e;border-color:#91a77b;padding:14px 20px;gap:28px;}
.stat {color:#fff1cd;font-size:15px;font-weight:600;line-height:1.5;white-space:nowrap;}
.stat strong {color:#fff6d8;font-size:28px;font-weight:800;line-height:1.2;margin-top:6px;}
.warehouse-top,.lane-name {font-size:14px;font-weight:600;letter-spacing:0;}
.warehouse-top>span,.lane-name {background:#173d2e;color:#fff1cd;padding:4px 8px;border-radius:6px;line-height:1.5;}
.feedback {background:#173d2e;color:#fff4ca;line-height:1.6;}
.feedback.bad {color:#ffdfbc;}
.rule-reject small,.rule-pictures small {font-size:14px;font-weight:600;}
.overlay .eyebrow,.overlay .rule-detail {font-size:14px;font-weight:600;}
.overlay .eyebrow {color:#365a36;}
.small-note,.score-details {font-size:14px;line-height:1.7;color:#43573b;}
dialog p {color:#3d563c;font-size:16px;line-height:1.8;}
.result-metrics div {color:#354d2e;font-size:14px;font-weight:600;}
nav .quiet {font-size:14px;font-weight:600;color:#fff5d7;}
@media(max-width:580px){
  .game-heading {padding:11px 12px;gap:8px;align-items:center;}
  .game-heading .eyebrow {font-size:12px;letter-spacing:.5px;}
  .game-heading h1 {font-size:22px;}
  .game-tools {gap:6px;}
  .game-tools .quiet,.game-tools .secondary {font-size:13px;padding:10px;}
  .stats {padding:12px;gap:19px;}
  .stat {font-size:14px;}
  .stat strong {font-size:25px;}
  .warehouse-top,.lane-name {font-size:13px;}
  .feedback {font-size:14px;}
  .rule-reject small,.rule-pictures small {font-size:12px;}
  nav .quiet {font-size:13px;}
  .result-metrics div {font-size:12px;}
}

/* Initial result focus announces the heading without selecting a control. */
.result-title:focus {outline:none;}
.knowledge-zoom {position:relative;float:right;width:85px;margin:10px 0 4px 12px;padding:0;border-radius:12px;background:#f2dfaa;cursor:zoom-in;}
.panda-knowledge .knowledge-zoom .city-art {float:none;width:100%;margin:0;}
.knowledge-zoom>span:last-child {position:absolute;right:3px;bottom:3px;background:#173d2e;color:#fff4cf;border-radius:5px;width:23px;height:23px;font-size:21px;line-height:23px;}
dialog.city-viewer {width:min(640px,calc(100vw - 28px));max-height:94dvh;padding:14px;overflow:auto;}
.city-viewer .city-art {width:min(100%,calc(94dvh - 125px));margin:auto;border-radius:12px;}
.city-viewer-close {display:block;margin:0 0 14px auto;min-height:44px;}
.city-viewer-caption {text-align:center;font-weight:700;padding-top:12px;}
@media(max-width:580px){.knowledge-zoom {float:none;display:block;width:76px;margin:8px 0;}}
.panda-knowledge {align-items:center;padding:12px 0;background:none;border:0;gap:10px;}
.knowledge-panda {width:125px;flex:0 0 125px;object-fit:contain;filter:drop-shadow(0 5px 4px #25492c30);}
.knowledge-bubble {position:relative;flex:1;min-width:0;padding:18px;background:#fff8e4;border:2px solid #c4a269;border-radius:20px;}
.knowledge-bubble:before {content:"";position:absolute;left:-10px;top:45%;width:16px;height:16px;background:#fff8e4;border-left:2px solid #c4a269;border-bottom:2px solid #c4a269;transform:rotate(45deg);}
.knowledge-bubble .eyebrow {display:block;color:#41653e;letter-spacing:1px;line-height:1.6;}
.panda-knowledge .city-art {float:right;width:85px;margin:10px 0 4px 12px;}
.knowledge-bubble:after {content:"";display:block;clear:both;}
/* 咚咚那句“没关系，再试一次吧。”：气泡跟着字的长短，和咚咚一起站在中间；要折成两行时在逗号后面折 */
.retry-knowledge {justify-content:center;}
.retry-knowledge .knowledge-bubble {flex:0 1 auto;}
.retry-knowledge .knowledge-bubble>p {margin:0;word-break:keep-all;overflow-wrap:anywhere;}
@media(max-width:580px){
  .panda-knowledge {gap:6px;align-items:flex-start;}
  .knowledge-panda {width:70px;flex-basis:70px;margin-top:24px;}
  .knowledge-bubble {padding:12px;border-radius:15px;}
  .knowledge-bubble:before {top:46px;}
  .panda-knowledge .city-art {float:none;width:76px;margin:8px 0;}
}
.stats + .warehouse {margin-top:28px;}
.game-tools .back-home {font-size:16px;padding:11px 18px;white-space:nowrap;}
@media(max-width:580px){
  .game-heading {flex-wrap:wrap;}
  .game-tools {width:100%;justify-content:space-between;}
  .game-tools .back-home {font-size:15px;padding:11px 14px;}
}

/* Keep the journey visual, with short labels and optional rule details. */
.journey-counts {display:flex;align-items:center;gap:20px;}
.journey-counts b {font-variant-numeric:tabular-nums;color:#fff5d5;}
/* Nothing that can be tapped is smaller than 44px; the keys used during a round are 48px. */
.primary,.secondary,.quiet,.chapter,.brand {min-height:44px;touch-action:manipulation;}
nav .quiet {min-width:44px;}
.game-tools button {min-height:48px;}
.overlay .rule-detail {min-height:44px;padding:8px 12px;border-radius:8px;}
.primary:active:not(:disabled),.secondary:active:not(:disabled) {transform:translateY(1px);}
nav .quiet {border-radius:10px;}
nav .quiet:hover,.game-tools .quiet:hover {background:#41674a;}
button:focus-visible,summary:focus-visible {outline:3px solid #ffd982;outline-offset:4px;}
dialog button:focus-visible,dialog summary:focus-visible,.overlay button:focus-visible {outline-color:#386640;}
/* 焦点框只给用键盘的人看：没按过键（或刚点过屏幕）时，弹窗自己挪过去的焦点不画框（iPhone 上会画，app.js 的 keys） */
html:not(.keys) :focus-visible {outline:none;}
#modal h2:focus {outline:none;}
.score-details summary {min-height:44px;padding:10px 0;border-radius:5px;}
dialog {max-height:calc(100dvh - 40px);overflow-y:auto;}
dialog .modal-note,dialog .collection-summary {background:#eee3c4;border:1px solid #d4c292;border-radius:10px;padding:12px 15px;color:#3e5734;font-size:14px;}
.collection-summary strong {font-variant-numeric:tabular-nums;color:#265e42;}
dialog .collection-empty {padding:26px 14px;text-align:center;border:1px dashed #baa66f;border-radius:12px;background:#fff7e5;color:#49603d;}
.modal-actions {align-items:center;}
@media(max-width:580px){
  /* Keep the mascot and its gentle rotation inside the viewport gutter. */
  .courier-art {right:-8px;}
  .section-top {gap:10px;flex-wrap:wrap;}
  .journey-counts {gap:12px;}
  .journey-counts span {font-size:13px;}
  /* The rule key grew to 44px; a slightly tighter stack keeps the card the same height. */
  .overlay {gap:8px;}
  .overlay .actions {gap:10px;}
  .tutorial-art {max-width:100%;}
  dialog {padding:20px;max-height:calc(100dvh - 28px);}
  .modal-actions {gap:10px;}
  .modal-actions button {flex:1 1 auto;}
}
@media(max-width:360px){
  header {gap:8px;}
  .brand {font-size:15px;gap:5px;}
  nav {padding:0 3px;}
  nav .quiet {font-size:13px;padding:8px 6px;}
}

.feedback:empty {visibility:hidden;}
.result-metrics {grid-template-columns:minmax(0,1fr);max-width:260px;margin:18px auto;text-align:center;}

/* The outer response leaves the existing image breathing animation running. */
.courier-button {display:block;width:100%;min-width:0;padding:0;border:0;background:none;border-radius:24px;line-height:0;touch-action:manipulation;-webkit-tap-highlight-color:transparent;}
.courier-reaction {display:block;pointer-events:none;}
.courier-button .courier-art {display:block;user-select:none;}
@media(max-width:580px){
  .courier-button {position:absolute;width:210px;height:285px;right:-8px;top:65px;z-index:1;}
  .courier-button .courier-art {position:static;width:100%;height:285px;}
  .hero>div:first-child {pointer-events:none;}
  .hero>div:first-child button {pointer-events:auto;}
}

/* Keep both sorting lanes and the action button together on laptop screens. */
.two-lanes .lane {height:210px;--belt-top:48px;--belt-height:62px;--parcel-size:80px;}
.two-lanes .lane+.lane {margin-top:6px;}
.two-lanes .basket {top:24px;height:150px;}
.two-lanes .basket .basket-body {top:72px;height:125px;}
.two-lanes .lane-name {top:0;}
@media(min-width:581px) and (max-height:850px){
 body:has(.two-lanes) header {height:52px;}
 body:has(.two-lanes) .game-heading {margin:8px 0;padding:8px 14px;}
 body:has(.two-lanes) .game-heading h1 {font-size:23px;margin:0;}
 body:has(.two-lanes) .stats {padding:8px 16px;}
 body:has(.two-lanes) .stat strong {font-size:24px;margin-top:2px;}
 .stats + .two-lanes {margin-top:16px;}
 .two-lanes.warehouse {padding:12px 18px;}
 .two-lanes .lane {height:clamp(140px,calc((100svh - 340px)/2),210px);--belt-top:35px;--belt-height:52px;--parcel-size:68px;}
 .two-lanes .basket {top:16px;height:112px;}
 .two-lanes .basket .basket-body {top:60px;height:100px;}
 .two-lanes .game-bottom {min-height:44px;padding:0;margin-top:0;}
 .two-lanes .spacekey {padding:8px 22px;}
}
@media(max-width:580px){
 .two-lanes .lane {height:195px;--belt-top:54px;--belt-height:55px;--parcel-size:65px;}
 .two-lanes .basket {top:30px;height:125px;}
 .two-lanes .basket .basket-body {top:68px;height:115px;}
 .two-lanes .game-bottom {margin-top:4px;}
}

.two-lanes .parcel .box {width:var(--parcel-size);height:var(--parcel-size);}
.two-lanes .parcel .label .item-icon {width:85%;height:85%;}
@media(min-width:581px) and (max-height:650px){
 .two-lanes .basket .basket-body {top:48px;height:85px;}
}

.knowledge-bubble ruby,.collection ruby {ruby-align:center;ruby-position:over;}
.knowledge-bubble rt,.collection rt {font-family:"Microsoft YaHei",sans-serif;font-size:13px;font-weight:600;color:#315c3c;letter-spacing:0;}
.knowledge-bubble:has(ruby) .eyebrow,.collection h3:has(ruby) {line-height:2.3;}
.knowledge-bubble p:has(ruby),.collection p:has(ruby) {line-height:2.2;}

/* Parcel selection uses the basket highlight, not a keyboard outline. */
.parcel:focus,.parcel:focus-visible {outline:none;}

/* Keep rapid taps and drags inside the game from selecting its artwork. */
.warehouse,.warehouse *,.game-heading,.game-heading *,.stats,.stats *,button,button * {-webkit-user-select:none;user-select:none;}
.warehouse img,button img {-webkit-user-drag:none;}
.parcel {touch-action:manipulation;-webkit-tap-highlight-color:transparent;}

/* Readings in the dark game header remain independent of the knowledge card. */
.game-heading .game-city {white-space:nowrap;}
.game-heading ruby {ruby-align:center;ruby-position:over;}
.game-heading rt {font-family:"Microsoft YaHei",sans-serif;font-size:14px;font-weight:600;color:#ffe4a0;letter-spacing:0;line-height:1.2;text-shadow:none;}
.game-heading h1:has(ruby) {line-height:1.8;}
@media(max-width:580px){.game-heading rt {font-size:13px;}}

/* Leave a visible gap between the reading and the character below it. */
.game-heading .pinyin-reading {display:inline-block;transform:translateY(-5px);font-style:normal;}
.game-heading h1:has(ruby) {padding-top:5px;}
.knowledge-bubble .pinyin-reading,.collection .pinyin-reading {display:inline-block;transform:translateY(-3px);font-style:normal;}
.knowledge-bubble:has(ruby) .eyebrow,.collection h3:has(ruby) {padding-top:3px;}

/* Point from beside the parcel so the category label remains visible. */
.demo-hand {left:248px;top:24px;font-size:34px;line-height:1;animation-name:demo-point;pointer-events:none;}
.demo-spark {left:244px;top:8px;font-size:16px;pointer-events:none;}
@keyframes demo-point {
  0%,47%,85%,100% {opacity:0;transform:translateX(8px);}
  55%,65% {opacity:1;transform:translateX(0);}
  75% {opacity:0;transform:translateX(8px);}
}

@media(max-width:360px){.tutorial-art {width:300px;max-width:none;transform:scale(.8);transform-origin:center;}}

/* City names must fit the shallower nameplates in compact dual-line layouts. */
.two-lanes .basket .basket-body>span .destination-icon {font-size:clamp(13px,1.9vw,17px);line-height:1;}

/* Two independent deliveries introduce the final chapter without extra copy. */
.tutorial-pair {width:320px;max-width:100%;height:226px;flex-shrink:0;}
.tutorial-pair .demo-lane {height:113px;}
.tutorial-pair .tutorial-art {width:320px;max-width:none;transform:scale(.78);transform-origin:top center;}
.tutorial-pair .demo-lane:last-child .demo-frame {left:25%;}
.tutorial-pair .demo-lane:last-child .demo-parcel {animation-name:demo-deliver-lower;}
.tutorial-pair .demo-lane:last-child .demo-hand {left:168px;}
.tutorial-pair .demo-lane:last-child .demo-spark {left:164px;}
@keyframes demo-deliver-lower {
 0%,10% {transform:translateX(0);opacity:1;}
 50%,65% {transform:translateX(84px);opacity:1;}
 80%,100% {transform:translate(84px,52px) scale(.35);opacity:0;}
}

@media(min-width:581px) and (max-height:650px){
 .two-lanes .overlay:has(.tutorial-pair) {gap:4px;}
 .two-lanes .overlay:has(.tutorial-pair) h2 {font-size:24px;}
 .two-lanes .tutorial-pair {height:160px;}
 .two-lanes .tutorial-pair .demo-lane {height:80px;}
 .two-lanes .tutorial-pair .tutorial-art {transform:scale(.55);}
 .two-lanes .overlay:has(.tutorial-pair) .practice-dots {font-size:26px;margin:4px;}
}

/* Invisible pointer margin leaves artwork and belt alignment unchanged. */
.lane>.parcel:not(.done):not(:disabled)::before {content:"";position:absolute;inset:-14px;background:transparent;border:0;border-radius:12px;}
/* 练习的三个圈一样大，练过的涂满（原来是“●”“○”两个字，不同的字体画出来大小不一样） */
.practice-dots {display:flex;justify-content:center;align-items:center;gap:.42em;letter-spacing:0;line-height:1;}
.practice-dots span {flex:none;width:.62em;height:.62em;box-sizing:border-box;border:.1em solid currentColor;border-radius:50%;}
.practice-dots span.is-done {background:currentColor;}
/* 双击不再放大页面（他说“取消双击放大功能”）；两指缩放照旧 */
html,body,body *{touch-action:manipulation;}
