/* 波波乐园 · 原理实验室（看懂原理）
   Same cartoon rules as game.css: dark ink outline, rounded shapes, a solid drop shadow, bright but calm colours.
   Landscape (iPad 1180×820): picture left, words and controls right. Phone: picture on top, then words, then controls. */
.tl-open{position:relative;margin-left:auto;flex:none;display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:8px 20px;border:3px solid var(--ink,#2b1d14);border-radius:999px;background:linear-gradient(180deg,#fffce8,#ffe27a 52%,#ffc93a);box-shadow:0 4px 0 var(--ink,#2b1d14),0 0 14px 3px #ffb84a88;font:800 16px/1 var(--f-body);color:var(--ink,#2b1d14);cursor:pointer;white-space:nowrap;overflow:hidden;isolation:isolate;animation:tlGlow 1.45s ease-in-out infinite}
.tl-open-label{position:relative;z-index:1;font:800 16px/1 var(--f-body);letter-spacing:.02em}
.tl-open-short{display:none;font-style:normal}
.tl-open-sheen{position:absolute;inset:-30% -50%;z-index:0;pointer-events:none;background:linear-gradient(115deg,transparent 38%,#ffffffcc 50%,transparent 62%);transform:translateX(-65%);animation:tlSheen 2.1s ease-in-out infinite}
@keyframes tlGlow{0%,100%{box-shadow:0 4px 0 var(--ink,#2b1d14),0 0 10px 2px #ffcf5066}50%{box-shadow:0 4px 0 var(--ink,#2b1d14),0 0 22px 7px #ff9a2add}}
@keyframes tlSheen{0%,50%{transform:translateX(-75%)}100%{transform:translateX(75%)}}
.tl-demo-cue{margin:0;padding:10px 12px;border-left:4px solid #ef762d;background:#fff4e4;font:700 15px/1.45 var(--f-body);color:#8a3a12}
.tl-demo-text{margin:8px 0 0;font:600 16px/1.55 var(--f-body)}
.tl-open:active{transform:translateY(3px);box-shadow:0 1px 0 var(--ink,#2b1d14),0 0 12px 3px #ffb84acc;animation:none}
@media (max-width:520px){.tl-open{padding:8px 14px;min-width:46px}.tl-open-label{display:none}.tl-open-short{display:inline;font:800 15px/1 var(--f-body)}}
@media(prefers-reduced-motion:reduce){.tl-open,.tl-open-sheen{animation:none}}

.tl-overlay{position:fixed;inset:0;z-index:1200;display:grid;place-items:center;background:rgba(43,29,20,.42);opacity:0;transition:opacity .2s;padding:max(10px,env(safe-area-inset-top)) max(10px,env(safe-area-inset-right)) max(10px,env(safe-area-inset-bottom)) max(10px,env(safe-area-inset-left))}
.tl-overlay.in{opacity:1}
.tl-card{width:min(1120px,100%);height:min(780px,100%);display:flex;flex-direction:column;background:var(--paper,#fffaf0);border:4px solid var(--ink,#2b1d14);border-radius:26px;box-shadow:0 8px 0 var(--ink,#2b1d14);overflow:hidden;-webkit-user-select:none;user-select:none}
.tl-lab{--tl-ink:var(--ink,#2b1d14);color:var(--tl-ink)}
.tl-head{display:flex;align-items:center;gap:12px;padding:10px 14px 6px 18px}
.tl-head>div{flex:1;min-width:0}
.tl-title{display:block;font:400 clamp(20px,2.4vw,27px)/1.2 var(--f-display)}
.tl-goal{display:block;font:600 14px/1.35 var(--f-body);opacity:.75}
.tl-badge{flex:none;padding:5px 12px;border-radius:999px;border:2.5px solid var(--tl-ink);font:800 13px/1.2 var(--f-body);background:#e6f5ff}
.tl-badge[data-kind=question]{background:#fff0c4}
.tl-badge[data-kind=explore]{background:#e3f7e1}
.tl-badge[data-kind=transfer]{background:#efe5ff}
.tl-x{flex:none;width:48px;height:48px;border-radius:50%;border:3px solid var(--tl-ink);background:#fff;font:900 26px/1 var(--f-body);cursor:pointer;box-shadow:0 3px 0 var(--tl-ink)}
.tl-stages{display:flex;gap:6px;padding:2px 16px 8px;overflow-x:auto;scrollbar-width:none}
.tl-chip{flex:none;min-height:44px;padding:4px 14px;border-radius:14px;border:2.5px solid var(--tl-ink);background:#fff;font:800 14px var(--f-body);cursor:pointer;opacity:.78}
.tl-chip.on{background:#ffd34a;opacity:1;box-shadow:0 3px 0 var(--tl-ink)}
.tl-parts{display:flex;gap:6px;padding:0 16px 6px}
.tl-part-btn{min-height:44px;padding:4px 14px;border-radius:12px;border:2.5px solid var(--tl-ink);background:#fff;font:800 14px var(--f-body);cursor:pointer}
.tl-part-btn.on{background:#c9e7ff}
.tl-body{flex:1;min-height:0;display:grid;grid-template-columns:minmax(0,1.55fr) minmax(280px,1fr);gap:12px;padding:0 14px}
.tl-scene{min-height:0;display:flex;align-items:center;justify-content:center;background:#fffdf6;border:3px solid var(--tl-ink);border-radius:20px;overflow:hidden;touch-action:pan-y}
.tl-svg{width:100%;height:100%;max-height:100%;display:block}
.tl-side{min-height:0;overflow:auto;display:flex;flex-direction:column;gap:10px;padding:2px 2px 8px;overscroll-behavior:contain}
.tl-formula{font:800 clamp(22px,2.6vw,30px)/1.25 var(--f-num);text-align:center;padding:8px 10px;border:3px solid var(--tl-ink);border-radius:16px;background:#fff;min-height:52px}
.tl-formula:empty{display:none}
.tl-formula.long{font-size:clamp(16px,1.7vw,19px);text-align:left;line-height:1.5}
.tl-caption{background:#fff;border:3px solid var(--tl-ink);border-radius:16px;padding:10px 14px}
.tl-say{margin:0;font:800 clamp(17px,1.8vw,20px)/1.5 var(--f-body)}
.tl-why{margin:6px 0 0;font:600 15px/1.5 var(--f-body);color:#6b4b2e}
.tl-try,.tl-gate,.tl-explore,.tl-transfer{background:#fff7d8;border:3px dashed var(--tl-ink);border-radius:16px;padding:10px 12px;display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.tl-try p,.tl-gate p,.tl-explore p,.tl-transfer p{flex-basis:100%;margin:0;font:700 15px/1.5 var(--f-body)}
.tl-gate{background:#ffe9dd;border-style:solid}
.tl-explore{background:#e9f8e6}
.tl-transfer{background:#f1e9ff}
.tl-act{min-height:46px;min-width:46px;padding:6px 16px;border-radius:14px;border:3px solid var(--tl-ink);background:#fff;font:800 16px var(--f-body);cursor:pointer;box-shadow:0 3px 0 var(--tl-ink)}
.tl-act.main{background:#ffd34a}
.tl-act:active{transform:translateY(2px);box-shadow:0 1px 0 var(--tl-ink)}
.tl-act.nope{animation:tl-shake .4s}
.tl-skip{min-height:44px;padding:4px 10px;border:none;background:none;font:700 14px var(--f-body);text-decoration:underline;cursor:pointer;color:#6b4b2e}
.tl-msg{margin:0;font:700 15px/1.5 var(--f-body);color:#9a3412;min-height:0}
.tl-msg:empty{display:none}
.tl-knob{display:flex;align-items:center;gap:6px;flex-wrap:wrap;flex-basis:100%}
.tl-knob span{min-width:6em;font:800 15px var(--f-body)}
.tl-knob button{width:46px;height:46px;border-radius:12px;border:3px solid var(--tl-ink);background:#fff;font:900 22px/1 var(--f-num);cursor:pointer}
.tl-knob button.big{width:auto;padding:0 10px;font-size:15px}
.tl-knob output{min-width:3.4em;text-align:center;font:800 22px var(--f-num)}
.tl-tin{display:flex;align-items:center;gap:8px;font:800 16px var(--f-body)}
.tl-tin input{width:7em;height:46px;border:3px solid var(--tl-ink);border-radius:12px;font:800 22px var(--f-num);text-align:center;background:#fff}
.tl-tq{font:800 17px/1.5 var(--f-body)!important}
.tl-tmsg{font-weight:800!important}
.tl-ctrl{display:flex;align-items:center;gap:8px;padding:10px 14px 12px;flex-wrap:wrap}
.tl-btn{display:inline-flex;align-items:center;gap:6px;min-height:48px;min-width:48px;padding:6px 14px;border-radius:16px;border:3px solid var(--tl-ink);background:#fff;font:800 15px var(--f-body);cursor:pointer;box-shadow:0 4px 0 var(--tl-ink)}
.tl-btn.main{background:#7fd67a}
.tl-btn:disabled{opacity:.4;cursor:default;box-shadow:none;transform:translateY(3px)}
.tl-btn:not(:disabled):active{transform:translateY(3px);box-shadow:0 1px 0 var(--tl-ink)}
.tl-btn.wide{background:#e6f5ff}
.tl-btn[aria-pressed=true]{background:#7fd67a}
.tl-count{font:800 15px var(--f-num);opacity:.7;margin-right:auto}

/* the column form, digit for digit with the blocks */
.tl-colform{display:grid;grid-template-columns:repeat(var(--n),minmax(30px,46px));justify-content:center;gap:2px 4px;padding:10px 12px;background:#fff;border:3px solid var(--tl-ink);border-radius:16px;font:800 clamp(24px,2.6vw,32px)/1.15 var(--f-num)}
.tl-cc{text-align:center;position:relative;border-radius:8px;min-height:1.15em}
.tl-cc.mark{font-size:.55em;line-height:1.4;color:#c0392b;min-height:1.4em}
.tl-cc.mark.carry{color:#1e6fd9}
.tl-cc.crossed{color:#9b8b7a;text-decoration:line-through;text-decoration-thickness:3px;text-decoration-color:#c0392b}
.tl-cc.focus{background:#fff2a8}
.tl-cc.op{color:#7a3b12}
.tl-cc.res{color:#1e7a46}
.tl-rule{grid-column:1/-1;height:4px;background:var(--tl-ink);border-radius:2px;margin:2px 0}

/* SVG pieces */
.tl-svg .tl-shadow{fill:rgba(43,29,20,.16)}
.tl-svg .tl-drop{fill:transparent;stroke:none;transition:fill .15s}
.tl-svg .tl-drop.target{fill:rgba(255,211,74,.18);stroke:#e0a400;stroke-width:3;stroke-dasharray:8 6}
.tl-svg .tl-drop.hot{fill:rgba(127,214,122,.32);stroke:#2f9e44}
.tl-svg .tl-col.focus .tl-place{fill:#c0392b}
.tl-svg .tl-frame{fill:#fff;stroke:#c9b79c;stroke-width:2;stroke-dasharray:5 4}
.tl-svg .tl-frame.full{stroke:#e0a400;stroke-width:2.6;stroke-dasharray:none}
.tl-svg [data-drag]{cursor:grab;touch-action:none}
.tl-svg [data-drag].lifted{opacity:.35}
.tl-svg .can-drag{filter:drop-shadow(0 0 4px #ffb400)}
.tl-pending .tl-svg .can-drag{animation:tl-glow 1.1s ease-in-out infinite alternate}
.tl-svg .tl-taken{opacity:.55}.tl-svg .tl-taken.on{opacity:1}
.tl-svg .tl-bar.unknown rect{stroke-dasharray:7 5}
.tl-svg .tl-bar.focus rect,.tl-svg .tl-diff.focus rect{stroke:#c0392b;stroke-width:3.6}
.tl-svg .tl-part{cursor:pointer}
.tl-ghost{position:fixed;left:0;top:0;z-index:1300;pointer-events:none;filter:drop-shadow(0 10px 6px rgba(43,29,20,.35));will-change:transform}
.tl-pending .tl-drop.target{animation:tl-glow 1.2s ease-in-out infinite alternate}
.tl-still{display:flex;flex-direction:column;gap:6px}.tl-still svg{width:100%;max-height:240px}.tl-still p{margin:0;font:700 15px/1.5 var(--f-body)}

/* change is shown gently: new pieces pop in, nothing keeps shaking */
.tl-scene.animate .tl-new{animation:tl-pop .45s cubic-bezier(.2,1.6,.4,1) both;transform-box:fill-box;transform-origin:50% 100%}
.tl-scene.animate .tl-bar{animation:tl-grow .5s ease-out both;transform-box:fill-box;transform-origin:0 50%}
@keyframes tl-pop{from{transform:scale(.3) translateY(-14px);opacity:0}to{transform:none;opacity:1}}
@keyframes tl-grow{from{transform:scaleX(.2)}to{transform:none}}
@keyframes tl-glow{from{opacity:.55}to{opacity:1}}
@keyframes tl-shake{25%{transform:translateX(-5px)}75%{transform:translateX(5px)}}
@media (prefers-reduced-motion:reduce){.tl-lab *{animation:none!important;transition:none!important}.tl-overlay{transition:none}}

/* compact player inside the explanation sheet */
.tl-lab.compact{display:flex;flex-direction:column;gap:8px}
.tl-lab.compact .tl-body{display:flex;flex-direction:column;padding:0}
.tl-lab.compact .tl-scene{max-height:260px}
.tl-lab.compact .tl-formula{font-size:22px;min-height:0}
.tl-lab.compact .tl-say{font-size:16px}
.tl-lab.compact .tl-ctrl{padding:4px 0}
.tl-lab.compact .tl-btn span{display:none}
.tl-lab.compact .tl-btn.wide span{display:inline}

/* phone and portrait: picture on top, everything else scrolls under it */
@media (max-width:760px),(orientation:portrait) and (max-width:900px){
  .tl-overlay{padding:0}
  .tl-card{width:100%;height:100%;border-radius:0;border:none;box-shadow:none}
  .tl-body{display:flex;flex-direction:column;overflow:auto;padding:0 10px}
  .tl-scene{flex:none;height:min(46vh,330px)}
  .tl-side{overflow:visible}
  .tl-head{padding:8px 10px 4px 12px}
  .tl-goal{display:none}
  .tl-ctrl{gap:6px;padding:8px 10px calc(10px + env(safe-area-inset-bottom))}
  .tl-btn{padding:6px 10px}
  .tl-btn span{display:none}
  .tl-btn.wide span{display:inline}
  .tl-count{order:-1;flex-basis:100%;text-align:center;margin:0}
}
/* question tabs that open a model: a small yellow corner mark, kept inside the tab because the tab row scrolls and would clip it */
.qprog button.tl-has::after{content:"";position:absolute;top:2px;right:2px;width:11px;height:11px;border-radius:50%;background:#ffc93a;border:2px solid var(--ink,#2b1d14);box-sizing:border-box;pointer-events:none}
.qprog button.tl-has.now::after{background:#ff9f1c}
/* bookshelf cards: "N 题有动画讲解", sitting on the card's top edge like the orange "下一关" tag (moved left of it when both show) */
.lib-row>.tl-shelf{position:absolute;z-index:2;top:-11px;right:12px;display:inline-flex;align-items:center;gap:4px;padding:0 9px 0 5px;background:#fff6c9;color:var(--ink,#2b1d14);border:2px solid var(--ink,#2b1d14);border-radius:999px;font:800 12px/20px var(--f-body);white-space:nowrap;pointer-events:none}
.lib-row>.tl-shelf i{width:11px;height:11px;border-radius:50%;background:#ffc93a;border:2px solid var(--ink,#2b1d14);box-sizing:border-box}
.lib-row.next>.tl-shelf{right:96px}
/* hand-painted pictures (teach-paint.js): the painted sprite shows, its original shape stays as an invisible hit area */
.tl-svg .tl-sprite{pointer-events:none}
.tl-svg .tl-ghosted{fill:transparent!important;stroke:transparent!important}
.tl-svg :is(rect,circle,ellipse,path,polygon,line).tl-ghosted{transition:fill .25s,stroke .25s}
.tl-svg .tl-sprite:not(.now){animation:tl-paint-in .25s ease-out both}
.tl-svg .tl-ghosted.now{transition:none}
@keyframes tl-paint-in{from{opacity:0}to{opacity:1}}
.tl-painted-ok .tl-scene.tl-paper{background-image:var(--tl-paper,none);background-size:192px 192px}
.tl-ghost .tl-svg{width:auto;height:auto;max-height:none}
/* Focus portal: “● N” on each lesson button (top-right corner), and the chapter total under its title */
.fx-go{position:relative}
.fx-go>.tl-fx{position:absolute;z-index:2;top:-10px;right:-8px;display:inline-flex;align-items:center;gap:3px;padding:0 6px 0 4px;background:#fff6c9;color:var(--ink,#2b1d14);border:2px solid var(--ink,#2b1d14);border-radius:999px;font:800 12px/18px "Baloo 2",var(--f-body),sans-serif;pointer-events:none}
.fx-go>.tl-fx i,.tl-fx-sum i{width:10px;height:10px;border-radius:50%;background:#ffc93a;border:2px solid var(--ink,#2b1d14);box-sizing:border-box;flex:none}
.tl-fx .tl-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.tl-fx-sum{display:inline-flex;align-items:center;gap:4px;margin-top:3px;padding:0 8px 0 5px;background:#fff6c9;border:2px solid var(--ink,#2b1d14);border-radius:999px;font:800 12px/18px "Baloo 2",var(--f-body),sans-serif;width:max-content;max-width:100%}
