/* ============================================================
   杜鸣工作室 · Python 课程 — 视觉系统
   主题与 ai-courses 全套课程统一：深色科技霓虹风
   design token 与 ai-courses/ai-*-course/style.css 保持一致，改动请同步
   ★ 布局（尺寸 / 栅格 / 层级 / 响应式）完全保留，仅替换配色、字体与光效
   ============================================================ */

:root {
  /* —— 统一主题 token（与 ai-courses 一致） —— */
  --bg: #070b1a;
  --bg-2: #0b1228;
  --panel: rgba(18, 26, 54, .72);
  --panel-solid: #101935;
  --panel-2: rgba(28, 40, 78, .60);
  --border: rgba(120, 160, 255, .16);
  --border-2: rgba(120, 160, 255, .32);
  --cyan: #21e6ff;
  --purple: #a45cff;
  --pink: #ff4ecd;
  --lime: #5cff9d;
  --gold: #ffd166;
  --text: #e8eeff;
  --text-2: #93a4cf;
  --text-3: #6f83b5;
  --accent: var(--cyan);
  --accent-2: linear-gradient(135deg, rgba(33, 230, 255, .16), rgba(164, 92, 255, .16));
  --accent-text: var(--cyan);
  --ok: #5cff9d;
  --ok-bg: rgba(92, 255, 157, .12);
  --warn: #ffd166;
  --warn-bg: rgba(255, 209, 102, .12);
  --err: #ff5c8a;
  --err-bg: rgba(255, 92, 138, .14);
  --code-bg: #0a1124;
  --brand-a: #21e6ff;
  --brand-b: #a45cff;
  --grad: linear-gradient(110deg, var(--cyan), var(--purple) 55%, var(--pink));
  --grad-soft: linear-gradient(135deg, rgba(33, 230, 255, .16), rgba(164, 92, 255, .16));
  --shadow: 0 18px 50px rgba(0, 0, 0, .45);
  --shadow-sm: 0 2px 12px rgba(0, 0, 0, .35);
  --glow: 0 0 22px rgba(33, 230, 255, .35);
  --r: 18px;
  --cm-theme: material-darker;
  --mono: "Cascadia Code", "JetBrains Mono", Consolas, "Courier New", monospace;
  --sans: "PingFang SC", "Microsoft YaHei", system-ui, -apple-system, "Segoe UI", sans-serif;
  --display: "Orbitron", "Bahnschrift", "DIN Alternate", "Rajdhani", "PingFang SC", "Microsoft YaHei", sans-serif;
}

/* 浅色分支：同一套霓虹配色的“日间版”，保证主题切换按钮仍然有意义 */
[data-theme="light"] {
  --bg: #eef2ff;
  --bg-2: #e4ebff;
  --panel: rgba(255, 255, 255, .86);
  --panel-solid: #ffffff;
  --panel-2: rgba(255, 255, 255, .74);
  --border: rgba(33, 230, 255, .30);
  --border-2: rgba(164, 92, 255, .38);
  --text: #1a2340;
  --text-2: #5b678a;
  --text-3: #8794b5;
  --accent: #0e8fb0;
  --accent-text: #0b7f9e;
  --accent-2: linear-gradient(135deg, rgba(33, 230, 255, .18), rgba(164, 92, 255, .14));
  --ok: #0f9d63;
  --ok-bg: rgba(15, 157, 99, .12);
  --warn: #a97000;
  --warn-bg: rgba(255, 209, 102, .22);
  --err: #e11d64;
  --err-bg: rgba(225, 29, 100, .10);
  --code-bg: #f2f6ff;
  --grad: linear-gradient(110deg, #0e8fb0, #7c3aed 55%, #db2777);
  --grad-soft: linear-gradient(135deg, rgba(33, 230, 255, .14), rgba(164, 92, 255, .12));
  --shadow: 0 14px 34px rgba(30, 60, 120, .14);
  --shadow-sm: 0 2px 10px rgba(30, 60, 120, .10);
  --glow: 0 0 18px rgba(33, 230, 255, .22);
}

* { box-sizing: border-box; }

/* hidden 属性优先级必须高于下面的 display:flex 等规则 */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--bg); color: var(--text);
  font-family: var(--sans);
  font-size: 16px; line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

/* 背景层（与 ai-courses 一致：网格 + 霓虹光晕），用伪元素实现，不新增 DOM */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    linear-gradient(rgba(40, 80, 160, .07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(40, 80, 160, .07) 1px, transparent 1px);
  background-size: 46px 46px;
  -webkit-mask-image: radial-gradient(circle at 50% 30%, #000 30%, transparent 80%);
  mask-image: radial-gradient(circle at 50% 30%, #000 30%, transparent 80%);
}
body::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(60% 50% at 15% 10%, rgba(164, 92, 255, .22), transparent 60%),
    radial-gradient(55% 45% at 88% 18%, rgba(33, 230, 255, .18), transparent 60%),
    radial-gradient(60% 60% at 50% 100%, rgba(255, 78, 205, .14), transparent 60%);
}
[data-theme="light"] body::before {
  background:
    linear-gradient(rgba(60, 100, 200, .06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(60, 100, 200, .06) 1px, transparent 1px);
  background-size: 46px 46px;
}
[data-theme="light"] body::after {
  background:
    radial-gradient(60% 50% at 15% 10%, rgba(164, 92, 255, .14), transparent 60%),
    radial-gradient(55% 45% at 88% 18%, rgba(33, 230, 255, .14), transparent 60%),
    radial-gradient(60% 60% at 50% 100%, rgba(255, 78, 205, .10), transparent 60%);
}

h1, h2, h3, h4 { font-family: var(--display); letter-spacing: .3px; line-height: 1.3; }
b { color: var(--accent-text); }
a { color: var(--accent-text); text-decoration: none; }

button { font-family: inherit; cursor: pointer; }
kbd {
  font-family: var(--mono); font-size: 10px; padding: 1px 4px;
  border: 1px solid var(--border-2); border-radius: 4px;
  background: var(--panel-2); color: var(--text-3); margin-left: 4px;
}

/* ---------- 加载屏 ---------- */
#boot {
  position: fixed; inset: 0; z-index: 999;
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(900px 620px at 50% 0%, #132044 0%, #070b1a 62%),
    radial-gradient(70% 60% at 80% 90%, rgba(164, 92, 255, .18), transparent 60%);
}
.boot-card { text-align: center; color: var(--text); max-width: 460px; padding: 0 24px; }
.boot-logo {
  display: flex; align-items: center; justify-content: center; gap: 16px;
  margin: 0 auto 22px; text-align: center;
}
.boot-logo-img {
  display: inline-block; height: 44px; width: calc(44px * 2.5714);
  border-radius: 10px;
  background: url("../img/logo-dark.png?v=2026110220") center / contain no-repeat;
  box-shadow: 0 12px 34px rgba(33, 230, 255, .25);
}
.boot-card h1 { font-size: 27px; margin: 0 0 8px; font-weight: 700; }
.boot-sub { margin: 0 0 30px; color: var(--text-2); font-size: 14px; }
.boot-bar { height: 6px; border-radius: 99px; background: rgba(120, 160, 255, .18); overflow: hidden; }
.boot-bar-fill { height: 100%; width: 4%; border-radius: 99px; background: var(--grad); box-shadow: var(--glow); transition: width .45s ease; }
.boot-status { margin: 16px 0 0; font-size: 14px; color: var(--text-2); min-height: 22px; }
.boot-note { margin: 8px 0 0; font-size: 12px; color: var(--text-3); }
.boot-err { color: #ff8fa8 !important; }

/* ---------- 布局 ---------- */
#app { display: flex; height: 100vh; overflow: hidden; position: relative; z-index: 1; }

.sidebar {
  position: relative; z-index: 2;
  width: 286px; flex: 0 0 286px; height: 100%;
  background: var(--panel); border-right: 1px solid var(--border);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  display: flex; flex-direction: column;
}
.side-head { padding: 18px 18px 14px; border-bottom: 1px solid var(--border); }
.brand { display: flex; align-items: center; gap: 12px; text-decoration: none; color: inherit; }
.brand-logo-img {
  display: inline-block; height: 46px; width: calc(46px * 2.5714);
  border-radius: 8px;
  background: url("../img/logo-dark.png?v=2026110220") center / contain no-repeat;
}
/* 主题化 LOGO：默认（深色主题）用 logo-dark，浅色主题切换为 logo-light（单元素 + 背景图切换） */
[data-theme="light"] .boot-logo-img,
[data-theme="light"] .brand-logo-img {
  background-image: url("../img/logo-light.png?v=2026110220");
}

.prog-wrap { display: flex; align-items: center; gap: 12px; }
.ring { width: 46px; height: 46px; flex: 0 0 46px; transform: rotate(-90deg); }
.ring circle { fill: none; stroke-width: 4.5; }
.ring-bg { stroke: var(--border); }
.ring-fg {
  stroke: var(--accent); stroke-linecap: round;
  stroke-dasharray: 119.4; stroke-dashoffset: 119.4;
  filter: drop-shadow(0 0 6px rgba(33, 230, 255, .55));
  transition: stroke-dashoffset .5s ease;
}
.prog-txt { display: flex; flex-direction: column; line-height: 1.35; }
.prog-txt b { font-size: 17px; font-family: var(--display); color: var(--cyan); }
.prog-txt span { font-size: 11.5px; color: var(--text-3); }

.side-nav { flex: 1; overflow-y: auto; padding: 10px 10px 20px; }
.nav-ch { margin-bottom: 4px; }
.nav-ch-head {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 9px 9px; border: 0; background: none; color: var(--text);
  border-radius: 9px; text-align: left; font-size: 13.5px; font-weight: 600;
}
.nav-ch-head:hover { background: var(--panel-2); }
.nav-ch-num {
  width: 21px; height: 21px; flex: 0 0 21px; border-radius: 6px;
  background: var(--accent-2); color: var(--accent-text);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--display); font-size: 11.5px; font-weight: 700;
}
.nav-ch-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-ch-meta { font-size: 11px; color: var(--text-3); font-weight: 500; }
.nav-ls { padding: 2px 0 8px 12px; margin-left: 18px; border-left: 1.5px solid var(--border); }
.nav-ls.closed { display: none; }
.nav-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 9px; margin-bottom: 1px; border: 0; background: none;
  color: var(--text-2); border-radius: 10px; text-align: left; font-size: 12.8px;
}
.nav-item:hover { background: var(--panel-2); color: var(--text); }
.nav-item.active {
  background: var(--accent-2); color: var(--cyan); font-weight: 600;
  box-shadow: inset 0 0 0 1px rgba(33, 230, 255, .30);
}
.nav-dot {
  width: 15px; height: 15px; flex: 0 0 15px; border-radius: 50%;
  border: 1.5px solid var(--border-2); display: flex; align-items: center;
  justify-content: center; font-size: 9px; color: #04122b;
}
.nav-item.done .nav-dot { background: var(--lime); border-color: var(--lime); box-shadow: 0 0 8px rgba(92, 255, 157, .45); }
.nav-item.done .nav-dot { color: #04122b; }
/* 看答案通关：对勾变黄色 */
.nav-item.done-answer .nav-dot {
  background: var(--gold); border-color: var(--gold);
  box-shadow: 0 0 10px rgba(255, 209, 102, .55); color: #2a1c00; font-weight: 700;
}
.nav-item-t { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.side-foot { padding: 10px 14px 14px; border-top: 1px solid var(--border); display: flex; gap: 8px; }
.mini {
  flex: 1; padding: 7px 8px; font-size: 12px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--panel-2); color: var(--text-2);
  transition: border-color .15s, color .15s, box-shadow .15s;
}
.mini:hover { border-color: var(--cyan); color: var(--cyan); box-shadow: var(--glow); }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; height: 100%; }
.topbar {
  height: 54px; flex: 0 0 54px; display: flex; align-items: center; gap: 12px;
  padding: 0 18px; background: var(--panel); border-bottom: 1px solid var(--border);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
}
.crumb { flex: 1; font-size: 13.5px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.top-right { display: flex; align-items: center; gap: 8px; }
.nav-btn {
  padding: 6px 12px; font-size: 12.5px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--panel-2); color: var(--text-2);
  transition: border-color .15s, color .15s, box-shadow .15s;
}
.nav-btn:hover:not(:disabled) { border-color: var(--cyan); color: var(--cyan); box-shadow: var(--glow); }
.nav-btn:disabled { opacity: .4; cursor: not-allowed; }
.icon-btn { border: 0; background: none; font-size: 19px; color: var(--text-2); padding: 4px 8px; }
.icon-btn:hover { color: var(--cyan); }
.only-mobile { display: none; }

.view { flex: 1; min-height: 0; overflow: hidden; }

/* ---------- 总览页 ---------- */
#viewHome { overflow-y: auto; }
.home-wrap { max-width: 1020px; margin: 0 auto; padding: 34px 30px 60px; }
.hero {
  position: relative; overflow: hidden;
  display: flex; gap: 30px; align-items: center; flex-wrap: wrap;
  background: linear-gradient(160deg, rgba(255, 255, 255, .07), rgba(255, 255, 255, .02));
  border: 1px solid var(--border-2); border-radius: 22px;
  padding: 34px; box-shadow: var(--shadow);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.hero::before {
  content: ""; position: absolute; inset: -40% -10% auto auto; width: 420px; height: 420px;
  background: radial-gradient(circle, rgba(164, 92, 255, .22), transparent 65%);
  pointer-events: none;
}
.hero-txt { flex: 1; min-width: 300px; position: relative; }
.tag {
  display: inline-block; font-family: var(--display); font-size: 11.5px; font-weight: 600; letter-spacing: 1px;
  padding: 4px 11px; border-radius: 99px; background: var(--accent-2); color: var(--accent-text);
  border: 1px solid rgba(33, 230, 255, .30);
}
.hero-txt h1 {
  font-size: 33px; line-height: 1.35; margin: 15px 0 12px; letter-spacing: -.3px;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 4px 26px rgba(33, 230, 255, .22));
}
.hero-txt p { color: var(--text-2); margin: 0 0 22px; font-size: 14.5px; max-width: 520px; }
.hero-btns { display: flex; gap: 10px; flex-wrap: wrap; }

/* 「继续学习」卡片：学过之后才出现，帮学生一键回到上次的位置 */
.resume {
  margin-top: 14px; padding: 12px 14px; max-width: 520px;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  background: var(--panel-2); border: 1px solid var(--border-2);
  border-left: 3px solid var(--cyan); border-radius: 12px;
}
.resume-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.resume-label { font-size: 11.5px; color: var(--text-3); letter-spacing: .5px; }
.resume-info b {
  font-size: 14.5px; color: var(--text); font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.btn.small { padding: 8px 14px; font-size: 13px; flex: 0 0 auto; }
.hero-stats {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; min-width: 230px; position: relative;
}
.hero-stats > div {
  background: var(--panel-2); border: 1px solid var(--border); border-radius: 12px;
  padding: 14px 16px; display: flex; flex-direction: column;
}
.hero-stats b { font-size: 23px; letter-spacing: -.5px; font-family: var(--display); color: var(--cyan); text-shadow: 0 0 14px rgba(33, 230, 255, .35); }
.hero-stats span { font-size: 11.5px; color: var(--text-3); }

.sec-title {
  font-size: 17px; margin: 38px 0 16px;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.ch-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 15px; }
.ch-card {
  position: relative; overflow: hidden;
  background: var(--panel); border: 1px solid var(--border); border-radius: 18px;
  padding: 19px; cursor: pointer; transition: transform .15s, border-color .15s, box-shadow .15s;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.ch-card::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: var(--grad); opacity: .08;
}
.ch-card:hover { transform: translateY(-2px); border-color: var(--cyan); box-shadow: 0 18px 40px rgba(0, 0, 0, .35), var(--glow); }
.ch-card-top { display: flex; align-items: center; gap: 10px; margin-bottom: 11px; position: relative; }
.ch-card-num {
  width: 30px; height: 30px; flex: 0 0 30px; border-radius: 9px;
  background: var(--grad); color: #04122b;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--display); font-weight: 700; font-size: 14px;
  box-shadow: 0 0 14px rgba(33, 230, 255, .30);
}
.ch-card h3 { margin: 0; font-size: 15.5px; color: var(--text); }
.ch-card .sub { font-size: 11.5px; color: var(--text-3); }
.ch-card p { margin: 0 0 15px; font-size: 13px; color: var(--text-2); position: relative; }
.ch-bar { height: 5px; border-radius: 99px; background: var(--border); overflow: hidden; margin-bottom: 7px; position: relative; }
.ch-bar > i { display: block; height: 100%; background: linear-gradient(90deg, var(--cyan), var(--lime)); border-radius: 99px; transition: width .4s; }
.ch-meta { font-size: 11.5px; color: var(--text-3); display: flex; justify-content: space-between; position: relative; }

/* ---------- 按钮 ---------- */
.btn {
  padding: 11px 22px; font-size: 14.5px; font-weight: 700; border-radius: 13px;
  border: 1px solid transparent; font-family: var(--display); letter-spacing: .3px;
  transition: filter .15s, border-color .15s, transform .12s, box-shadow .15s;
}
.btn:active { transform: translateY(1px); }
.btn.primary { background: var(--grad); color: #04122b; box-shadow: 0 10px 28px rgba(33, 230, 255, .28); }
.btn.primary:hover { filter: brightness(1.08); box-shadow: 0 14px 36px rgba(164, 92, 255, .40); }
.btn.ghost { background: var(--panel-2); color: var(--text); border-color: var(--border-2); }
.btn.ghost:hover { border-color: var(--cyan); color: var(--cyan); box-shadow: var(--glow); }
.btn:disabled { opacity: .55; cursor: not-allowed; filter: none; box-shadow: none; }
.sbtn {
  padding: 5px 10px; font-size: 12px; border-radius: 7px;
  border: 1px solid var(--border); background: var(--panel-2); color: var(--text-2);
  transition: border-color .15s, color .15s, box-shadow .15s;
}
.sbtn:hover { border-color: var(--cyan); color: var(--cyan); box-shadow: var(--glow); }

/* ---------- 关卡页 ---------- */
.split { display: flex; height: 100%; }
.pane { min-width: 0; height: 100%; display: flex; flex-direction: column; }
.pane-left { flex: 0 0 46%; border-right: 1px solid var(--border); background: var(--panel); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
.pane-right { flex: 1; background: var(--bg); }
.pane-scroll { flex: 1; overflow-y: auto; padding: 26px 30px 50px; }

.lesson-head { margin-bottom: 20px; }
.chip {
  display: inline-block; font-family: var(--display); font-size: 11.5px; font-weight: 600; padding: 3px 10px;
  border-radius: 99px; background: var(--accent-2); color: var(--accent-text);
  border: 1px solid rgba(33, 230, 255, .30);
}
.lesson-head h1 {
  font-size: 26px; margin: 12px 0 6px; letter-spacing: -.2px;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 3px 18px rgba(33, 230, 255, .20));
}
.goal { margin: 0; color: var(--text-3); font-size: 13.5px; }

.concept { font-size: 14px; color: var(--text); }
.concept h4 { font-family: var(--sans); font-size: 14.5px; margin: 24px 0 9px; color: var(--cyan); }
.concept p { margin: 0 0 13px; color: var(--text-2); }
.concept ul, .concept ol { margin: 0 0 14px; padding-left: 22px; color: var(--text-2); }
.concept li { margin-bottom: 6px; }
.concept b, .concept strong { color: var(--text); font-weight: 600; }
.concept code {
  font-family: var(--mono); font-size: 12.5px; padding: 1.5px 5px;
  border-radius: 5px; background: var(--code-bg); border: 1px solid var(--border);
  color: #7fe9ff; white-space: nowrap;
}
.concept pre {
  background: var(--code-bg); border: 1px solid var(--border); border-radius: 10px;
  padding: 13px 15px; overflow-x: auto; margin: 0 0 15px;
}
.concept pre code {
  background: none; border: 0; padding: 0; font-size: 12.8px;
  line-height: 1.75; color: var(--text); white-space: pre;
}
.concept pre.err { background: var(--err-bg); border-color: rgba(255, 92, 138, .45); }
.concept pre.err code { color: var(--err); }
.concept .cmt { color: var(--text-3); }
.concept table.dt {
  width: 100%; border-collapse: collapse; font-size: 12.8px; margin: 0 0 16px;
  border: 1px solid var(--border); border-radius: 8px; overflow: hidden;
}
.concept table.dt th {
  background: var(--panel-2); text-align: left; padding: 8px 11px;
  border-bottom: 1px solid var(--border); font-size: 12px; color: var(--cyan);
}
.concept table.dt td { padding: 8px 11px; border-bottom: 1px solid var(--border); color: var(--text-2); }
.concept table.dt tr:last-child td { border-bottom: 0; }
.concept .tip {
  background: var(--warn-bg); border-left: 3px solid var(--warn);
  padding: 11px 15px; border-radius: 0 8px 8px 0; font-size: 13px;
  color: var(--text-2); margin: 0 0 15px;
}
.concept .tip b { color: var(--warn); }

.task-box {
  margin-top: 26px; padding: 18px 20px; border-radius: 12px;
  background: var(--accent-2); border: 1px solid rgba(33, 230, 255, .28);
}
.task-box h3 { margin: 0 0 10px; font-size: 14px; color: var(--cyan); font-family: var(--display); }
.task-box ol { margin: 0; padding-left: 21px; font-size: 13.5px; }
.task-box li { margin-bottom: 8px; color: var(--text); }
.task-box code {
  font-family: var(--mono); font-size: 12.3px; padding: 1.5px 5px; border-radius: 5px;
  background: var(--panel-solid); border: 1px solid var(--border-2); color: #7fe9ff;
}

.hint-box {
  margin-top: 15px; padding: 14px 18px; border-radius: 10px;
  background: var(--warn-bg); border-left: 3px solid var(--warn);
}
.hint-box b { font-size: 13px; color: var(--warn); }
.hint-box p { margin: 6px 0 0; font-size: 13px; color: var(--text-2); font-family: var(--mono); line-height: 1.7; }

/* 编辑器 */
.ed-head {
  height: 42px; flex: 0 0 42px; display: flex; align-items: center; justify-content: space-between;
  padding: 0 14px; background: var(--panel); border-bottom: 1px solid var(--border);
}
.ed-title { font-family: var(--mono); font-size: 12.5px; color: var(--cyan); }
.ed-hint { font-size: 11px; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ed-hint kbd { margin-left: 2px; }
.ed-btns { display: flex; gap: 7px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.ed-body { flex: 1 1 auto; min-height: 0; overflow: hidden; border-bottom: 1px solid var(--border); }
.ed-body .CodeMirror { height: 100%; font-family: var(--mono); font-size: 14.5px; line-height: 1.65; }
.ed-body.big .CodeMirror { height: 100%; }
/* 深色霓虹：让编辑器底色调成与 ai-courses 一致的深蓝，而不是 CodeMirror 自带的灰 */
[data-theme="dark"] .ed-body .CodeMirror,
[data-theme="dark"] .ed-body .CodeMirror-gutters { background: #0a1124; }
[data-theme="dark"] .ed-body .CodeMirror-gutters { border-right: 1px solid var(--border); color: #55699e; }
[data-theme="dark"] .ed-body .CodeMirror-linenumber { color: #55699e; }
.CodeMirror-lines { padding: 12px 0; }
.cm-err-line { background: rgba(255, 92, 138, .16) !important; }

.ed-actions {
  flex: 0 0 auto; display: flex; gap: 10px; padding: 11px 14px;
  background: var(--panel); border-bottom: 1px solid var(--border);
}
.ed-actions .btn { flex: 1; padding: 9px 12px; }

.console-head {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
  padding: 8px 14px; font-size: 11.5px; color: var(--text-3);
  background: var(--panel-2); border-bottom: 1px solid var(--border);
}
.console-head .mini { flex: 0 0 auto; padding: 3px 9px; font-size: 11px; }

/* 符号助手：点击插入常用符号，消灭中文引号 / 全角括号等小白坑 */
.symbar {
  flex: 0 0 auto; display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  padding: 8px 12px; background: var(--panel); border-bottom: 1px solid var(--border);
}
.sym-tip { font-size: 11.5px; font-weight: 700; color: var(--text-3); margin-right: 2px; }
.sym {
  font-family: var(--mono); font-size: 13px; font-weight: 700; line-height: 1;
  padding: 5px 9px; border-radius: 8px; background: var(--panel-2);
  border: 1px solid var(--border); color: var(--text); cursor: pointer;
  transition: border-color .15s, color .15s, box-shadow .15s, transform .15s;
}
.sym:hover { border-color: var(--cyan); color: var(--cyan); transform: translateY(-1px); box-shadow: var(--glow); }
.sym:active { transform: translateY(0); }
.sym-call { color: var(--cyan); border-color: rgba(33, 230, 255, .40); }
.ch-acts { display: flex; gap: 7px; align-items: center; }

/* 快捷键帮助列表 */
.help-list { display: flex; flex-direction: column; gap: 9px; margin: 8px 0 20px; text-align: left; }
.help-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 13px; color: var(--text-2); padding: 7px 12px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 8px; }
.help-row > span:first-child { color: var(--text); }
.help-row kbd { margin: 0 2px; }

/* 图表放大覆盖层 */
.plot-zoom {
  position: fixed; inset: 0; z-index: 550; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 14px; padding: 24px;
  background: rgba(4, 7, 18, .86); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); cursor: zoom-out;
}
.plot-zoom img { max-width: 92vw; max-height: 82vh; border-radius: 12px; background: #fff; box-shadow: 0 20px 60px rgba(0, 0, 0, .6); }
.plot-zoom-tip { color: var(--text-2); font-size: 12.5px; }
.console {
  flex: 0 0 200px; overflow: auto; margin: 0; padding: 13px 16px;
  font-family: var(--mono); font-size: 12.8px; line-height: 1.7;
  background: var(--code-bg); color: var(--text); white-space: pre-wrap; word-break: break-word;
}
.console.big { flex: 1; }
.console .muted { color: var(--text-3); }
.console .cerr { color: var(--err); }
.console .cerr-cn { color: var(--warn); font-weight: 700; }
.console .chint { color: var(--warn); }
.console .cok { color: var(--ok); }
.console .plot-img {
  display: block; max-width: 100%; height: auto; margin: 10px 0 4px;
  background: #fff; border: 1px solid var(--border); border-radius: 10px; padding: 6px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .3);
}

.verdict {
  flex: 0 0 auto; padding: 13px 18px; font-size: 13.5px; font-weight: 500;
  border-top: 1px solid var(--border); display: flex; gap: 9px; align-items: flex-start;
}
.verdict.ok { background: var(--ok-bg); color: var(--lime); border-top-color: rgba(92, 255, 157, .35); }
.verdict.no { background: var(--err-bg); color: var(--err); border-top-color: rgba(255, 92, 138, .35); }
.verdict .vi { font-size: 15px; line-height: 1.4; }

/* ---------- 自由练习台 ---------- */
#viewPlay { overflow: hidden; }
.play-wrap { height: 100%; display: flex; flex-direction: column; padding: 20px 24px 24px; }
.play-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
.play-head h1 {
  margin: 0 0 4px; font-size: 20px;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.play-head p { margin: 0; font-size: 13px; color: var(--text-3); }
.play-split {
  flex: 1; min-height: 0; display: flex; gap: 14px;
}
.play-split .ed-body {
  flex: 1; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: var(--panel);
}
.play-split .console { flex: 1; border: 1px solid var(--border); border-radius: 12px; }

/* ---------- 弹窗 ---------- */
.modal {
  position: fixed; inset: 0; z-index: 500; display: flex; align-items: center;
  justify-content: center; background: rgba(4, 7, 18, .68); padding: 20px;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.modal-card {
  background: linear-gradient(160deg, rgba(24, 34, 68, .96), rgba(11, 17, 38, .96));
  border-radius: 24px; padding: 32px 34px; text-align: center; color: var(--text);
  max-width: 400px; border: 1px solid var(--border-2);
  box-shadow: 0 30px 80px rgba(0, 0, 0, .55), 0 0 0 1px rgba(33, 230, 255, .08);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
}
.modal-emoji { font-size: 52px; line-height: 1; margin-bottom: 12px; filter: drop-shadow(0 0 18px rgba(33, 230, 255, .45)); }
.modal-card h2 {
  margin: 0 0 8px; font-size: 21px;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.modal-card p { margin: 0 0 22px; color: var(--text-2); font-size: 13.5px; }
.modal-btns { display: flex; gap: 10px; justify-content: center; }
.modal-card.wide { max-width: 470px; }
.modal-card.wide .muted-sm { text-align: center; }

/* ---------- 参考答案弹窗 ---------- */
.modal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.modal-head h2 { margin: 0; font-size: 20px; background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.modal-x { width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--border-2); background: rgba(255,255,255,.04); color: var(--text-2); font-size: 20px; line-height: 1; cursor: pointer; }
.modal-x:hover { color: var(--text); border-color: var(--cyan); }
.sol-warn { text-align: left; font-size: 12.8px; line-height: 1.6; color: var(--gold);
  background: rgba(255, 209, 102, .10); border: 1px solid rgba(255, 209, 102, .35); border-radius: 12px; padding: 10px 12px; margin-bottom: 14px; }
.sol-yellow { color: var(--gold); font-weight: 700; }
.sol-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; text-align: left; }
.sol-col { display: flex; flex-direction: column; gap: 8px; }
.sol-sub { font-size: 12.5px; color: var(--cyan); font-weight: 600; letter-spacing: .3px; }
.sol-code { margin: 0; padding: 12px 14px; border-radius: 12px; background: #0a1124; border: 1px solid var(--border);
  font-family: var(--mono); font-size: 12.5px; line-height: 1.55; color: var(--text); overflow: auto; max-height: 320px; white-space: pre; }
.sol-code code { font-family: inherit; }
.sol-explain { color: #cfe3ff; }
.sol-fill { align-self: flex-start; }
@media (max-width: 560px) { .sol-grid { grid-template-columns: 1fr; } }

/* ---------- 侧边栏工具（搜索 / 连续闯关 / 错题本 / 进度） ---------- */
.side-search { margin-top: 13px; }
.side-search input {
  width: 100%; padding: 7px 11px; font-size: 12.5px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--panel-2); color: var(--text);
}
.side-search input::placeholder { color: var(--text-3); }
.side-search input:focus { outline: none; border-color: var(--cyan); box-shadow: var(--glow); }
.side-tools {
  padding: 12px 14px; border-top: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 11px;
}
.tool-row { display: flex; gap: 8px; }
.tool-row .mini { position: relative; }
.toggle { display: flex; align-items: center; gap: 9px; font-size: 12.3px; color: var(--text-2); cursor: pointer; }
.toggle input { display: none; }
.toggle-box {
  width: 34px; height: 19px; flex: 0 0 34px; border-radius: 99px;
  background: var(--border-2); position: relative; transition: background .2s;
}
.toggle-box::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 15px; height: 15px;
  border-radius: 50%; background: #fff; transition: transform .2s; box-shadow: 0 1px 2px rgba(0, 0, 0, .25);
}
.toggle input:checked + .toggle-box { background: var(--grad); box-shadow: var(--glow); }
.toggle input:checked + .toggle-box::after { transform: translateX(15px); }
.toggle-label { line-height: 1.3; }

.verdict-act {
  margin-left: auto; padding: 4px 11px; font-size: 12px; border-radius: 7px;
  border: 1px solid var(--err); background: var(--panel); color: var(--err); white-space: nowrap;
}
.verdict-act:hover:not(:disabled) { background: var(--err-bg); }
.verdict-act:disabled { opacity: .6; cursor: default; }

.muted-sm { color: var(--text-3); font-size: 12.5px; line-height: 1.6; }

/* 通关撒花画布 */
#fx { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 600; }

/* ---------- 响应式 ---------- */
@media (max-width: 1080px) {
  .pane-left { flex: 0 0 44%; }
}
@media (max-width: 900px) {
  .only-mobile { display: block; }
  .sidebar {
    position: fixed; z-index: 200; left: 0; top: 0; bottom: 0;
    transform: translateX(-100%); transition: transform .25s; box-shadow: var(--shadow);
  }
  .sidebar.open { transform: none; }
  .split { flex-direction: column; }
  .pane-left { flex: 0 0 auto; max-height: 46vh; border-right: 0; border-bottom: 1px solid var(--border); }
  .pane-right { flex: 1; }
  .play-split { flex-direction: column; }
  .hero { padding: 24px; }
  .hero-txt h1 { font-size: 24px; }
}

/* 滚动条 */
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(120, 160, 255, .30); border-radius: 99px; }
::-webkit-scrollbar-thumb:hover { background: rgba(33, 230, 255, .55); }

/* ---------- Turtle 画图关（左右分栏：左代码 右画布） ---------- */
.turtle-wrap { margin: 0 0 10px; }
.turtle-split {
  display: flex; gap: 10px; height: 380px;
}
.turtle-code {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  overflow: hidden;
}
.turtle-code .ed-head { border-bottom: 1px solid var(--border); border-radius: 11px 11px 0 0; }
.turtle-code .ed-body { flex: 1; min-height: 0; }
.turtle-canvas {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column;
}
.turtle-label { font-size: 12.5px; color: var(--text-2); margin: 2px 2px 6px; font-weight: 600; }
.turtle-stage {
  position: relative; flex: 1; min-height: 0;
  /* 海龟默认笔色是深色，画布保持浅色（相当于 ai-courses 里的白色内容卡） */
  background: #f6f9ff; border: 1px solid var(--border-2); border-radius: 14px;
  overflow: hidden; box-shadow: var(--shadow-sm), 0 0 0 1px rgba(33, 230, 255, .12);
}
.turtle-stage canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.turtle-stage .turtle-overlay { pointer-events: none; }

/* 非 turtle 关卡时显示普通编辑器 */
#normalEditor { display: block; }
.turtle-wrap:not([hidden]) ~ #normalEditor { display: none; }

/* ---- 关卡讲解视频 ---- */
.lesson-video {
  margin: 18px 0 6px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--panel);
}
.lesson-video video {
  display: block;
  width: 100%;
  max-width: 640px;
  aspect-ratio: 16 / 9;
  border-radius: 10px;
  background: #070b1a;
  outline: none;
}

/* ---- 本课单词板块 ---- */
.word-board {
  margin: 18px 0 6px;
  padding: 14px 14px 16px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--panel);
}
.wb-head {
  font-size: 14px;
  font-weight: 700;
  color: var(--cyan);
  margin-bottom: 12px;
  font-family: var(--display, inherit);
  letter-spacing: .3px;
}
.wb-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
}
.word-chip {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 7px 12px;
  min-width: 78px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: rgba(33, 230, 255, .06);
  color: var(--text);
  cursor: pointer;
  text-align: left;
  line-height: 1.2;
  transition: transform .12s ease, border-color .12s ease, background .12s ease, box-shadow .12s ease;
}
.word-chip:hover {
  border-color: var(--cyan);
  background: rgba(33, 230, 255, .14);
  transform: translateY(-1px);
}
.word-chip:active { transform: translateY(0); }
.word-chip.speaking {
  border-color: var(--purple);
  box-shadow: 0 0 0 2px rgba(164, 92, 255, .35);
  background: rgba(164, 92, 255, .16);
}
.wc-en {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
}
.wc-zh {
  font-size: 12px;
  color: var(--muted, #9fb0d8);
}

/* ============================================================
   键盘可达性：所有可交互元素都要有清晰的焦点圈。
   之前完全没有 :focus 样式，习惯用 Tab 键操作的学生
   根本看不出焦点在哪一个按钮上。
   ============================================================ */
:where(button, a, input, textarea, select, [tabindex]):focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
  border-radius: 6px;
}
/* 输入框本身已有聚焦态，去掉多余的外框避免双线 */
.side-search input:focus-visible,
.console:focus-visible { outline: none; }

/* 尊重系统的「减少动态效果」设置：
   前庭功能敏感的学生开启动画会不适，甚至会诱发眩晕。 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* 高对比度需求：加强正文与次要文字的对比 */
@media (prefers-contrast: more) {
  :root { --text-2: #c3d0f0; --text-3: #a6b6dd; }
  [data-theme="light"] { --text-2: #33406b; --text-3: #4a5780; }
}

/* ---------- 帮助弹窗里的使用小贴士 ---------- */
.help-sub {
  font-family: var(--sans); font-size: 14px; color: var(--cyan);
  margin: 18px 0 10px; text-align: left;
}
.help-tips {
  margin: 0 0 18px; padding-left: 20px; text-align: left;
  font-size: 13px; line-height: 1.85; color: var(--text-2);
}
.help-tips li { margin-bottom: 5px; }
.help-tips b { color: var(--text); font-weight: 600; }
.help-tips code {
  font-family: var(--mono); font-size: 12px; padding: 1px 5px;
  background: var(--code-bg); border: 1px solid var(--border);
  border-radius: 4px; color: var(--cyan);
}

/* ---------- Python 代码补全弹窗（自绘，不依赖 show-hint） ---------- */
.py-hint-box {
  position: fixed; z-index: 900; max-height: 210px; overflow-y: auto;
  min-width: 130px; padding: 4px 0; margin: 0;
  list-style: none; background: var(--panel-solid);
  border: 1px solid var(--border-2); border-radius: 10px;
  box-shadow: var(--shadow), 0 0 0 1px rgba(33, 230, 255, .12);
  font-family: var(--mono); font-size: 13px;
}
.py-hint-box li {
  padding: 5px 14px; cursor: pointer; color: var(--text-2); white-space: nowrap;
}
.py-hint-box li:hover { background: var(--panel-2); color: var(--text); }
.py-hint-box li.on {
  background: var(--grad); color: #04122b; font-weight: 700;
}

/* ---------- 云端同步 / 账号 ---------- */
.cloud-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 5px 11px; border-radius: 20px; cursor: pointer;
  font-size: 12.5px; font-weight: 600; color: var(--text-2);
  background: var(--panel-2); border: 1px solid var(--border-2);
}
.cloud-chip:hover { border-color: var(--cyan); color: var(--cyan); box-shadow: var(--glow); }
.cloud-chip.on { color: var(--cyan); border-color: rgba(33, 230, 255, .5); }

.acct-tabs { display: flex; gap: 6px; margin: 0 0 16px; }
.acct-tab {
  flex: 1; padding: 9px 0; border-radius: 10px; cursor: pointer;
  font-size: 13.5px; font-weight: 600; color: var(--text-2);
  background: var(--panel-2); border: 1px solid var(--border-2);
}
.acct-tab.active { background: var(--grad); color: #04122b; border: 0; box-shadow: 0 8px 22px rgba(33, 230, 255, .25); }

.acct-label { display: block; margin-bottom: 12px; font-size: 12.5px; color: var(--text-2); }
.acct-label input {
  width: 100%; margin-top: 6px; padding: 11px 13px; border-radius: 10px;
  font-size: 14px; color: var(--text); background: var(--code-bg);
  border: 1px solid var(--border-2); box-sizing: border-box;
}
.acct-label input:focus { outline: none; border-color: var(--cyan); box-shadow: var(--glow); }

.acct-otp { margin: -4px 0 12px; }
.acct-otp .acct-label { margin-bottom: 0; }

.acct-msg { min-height: 18px; margin: 2px 0 12px; font-size: 12.5px; line-height: 1.5; }
.acct-msg.err { color: #ff7a8a; }
.acct-msg.ok { color: var(--ok); }

.acct-form .modal-btns { flex-wrap: wrap; }
.acct-user { font-size: 15px; font-weight: 700; color: var(--cyan); margin: 4px 0 10px; word-break: break-all; }
.acct-note { margin-top: 14px; text-align: center; }

/* 访客锁定（未登录仅可学习前三节：初识Python 1-1～1-3） */
.nav-item.locked { opacity: .5; cursor: not-allowed; }
.nav-item.locked:hover { background: none; }
.nav-item.locked .nav-item-t { color: var(--text-3); }
.ch-card.locked { opacity: .55; cursor: not-allowed; }
.ch-card.locked:hover { transform: none; border-color: var(--border); box-shadow: none; }
.guest-banner {
  margin: 16px 0 0; padding: 12px 15px; border-radius: 12px;
  background: var(--panel-2); border: 1px dashed var(--border-2);
  color: var(--text-2); font-size: 13px; line-height: 1.6;
}
.guest-banner .link-btn {
  margin-left: 6px; padding: 0; border: 0; background: none; cursor: pointer;
  color: var(--cyan); font-size: 13px; font-weight: 600; text-decoration: underline;
}
.guest-banner .link-btn:hover { color: var(--pink); }

/* ============================================================
   阶梯拆解（ladder） + 代码动画演示（demo）
   目标：让每一关充分理解、零障碍——
   ladder 把概念从零拆到能写答案；demo 把抽象代码变直观。
   ============================================================ */

/* —— 阶梯拆解：每一步是一级台阶 —— */
.ladder-box {
  margin: 18px 0 6px; padding: 16px 16px 6px; border-radius: 16px;
  background: var(--panel-2); border: 1px solid var(--border);
}
.ladder-head {
  font-size: 13.5px; font-weight: 700; color: var(--cyan);
  font-family: var(--display); letter-spacing: .3px; margin-bottom: 12px;
}
.ladder-steps { display: flex; flex-direction: column; gap: 12px; }
.ladder-step { display: flex; gap: 12px; align-items: flex-start; }
.ladder-num {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 9px;
  display: grid; place-items: center; font-size: 13px; font-weight: 800; color: #04122a;
  background: var(--grad); box-shadow: var(--glow);
}
.ladder-body { flex: 1; min-width: 0; }
.ladder-ask { font-size: 13.5px; font-weight: 700; color: var(--text); margin-bottom: 6px; line-height: 1.55; }
.ladder-ask::before { content: "❓ "; color: var(--gold); }
.ladder-code {
  margin: 0 0 6px; padding: 9px 12px; border-radius: 10px;
  background: var(--code-bg); border: 1px solid var(--border-2);
  font-family: var(--mono); font-size: 13px; line-height: 1.6; color: var(--text);
  overflow-x: auto; white-space: pre;
}
.ladder-code code { font-family: var(--mono); }
.ladder-out {
  font-family: var(--mono); font-size: 12.5px; color: var(--ok); margin: 0 0 4px;
  padding: 3px 10px; border-radius: 8px; background: var(--ok-bg); display: inline-block;
}
.ladder-out::before { content: "↳ 预期输出 "; color: var(--text-3); font-family: var(--sans); }
.ladder-note { font-size: 13px; color: var(--text-2); line-height: 1.65; }
.ladder-note::before { content: "💡 "; }

/* 阶梯每步的「运行」按钮 + 实时终端输出 */
.ladder-coderow { display: flex; align-items: stretch; gap: 10px; margin: 0 0 4px; }
.ladder-coderow .ladder-code { flex: 1; min-width: 0; margin: 0; }
.ladder-run {
  flex: 0 0 auto; align-self: flex-start; cursor: pointer;
  padding: 8px 14px; border-radius: 10px; border: 0;
  font-size: 13px; font-weight: 700; color: #04122a;
  background: var(--grad); box-shadow: var(--glow); transition: transform .12s;
}
.ladder-run:hover { transform: translateY(-1px); }
.ladder-run:active { transform: translateY(0); }
.ladder-run:disabled { opacity: .6; cursor: default; transform: none; }
.ladder-live {
  font-family: var(--mono); font-size: 12.5px; line-height: 1.6; color: var(--text);
  margin: 2px 0 8px; padding: 8px 12px; border-radius: 10px;
  background: #06121f; border: 1px solid var(--border-2);
  white-space: pre-wrap; word-break: break-word; max-height: 240px; overflow: auto;
}
.ladder-live:not([hidden]) { animation: demoFade .35s ease; }
.ladder-live .cerr { color: var(--err); }
.ladder-live .cerr-cn { color: var(--warn); font-weight: 700; }
.ladder-live .chint { color: var(--warn); }
.ladder-live .cok { color: var(--ok); }
.ladder-live .muted { color: var(--text-3); }

/* 阶梯每步的「可视化运行」按钮 + 内联逐行动画 */
.ladder-btns { display: flex; flex-direction: column; gap: 8px; flex: 0 0 auto; align-self: flex-start; }
.ladder-viz {
  flex: 0 0 auto; cursor: pointer; padding: 8px 14px; border-radius: 10px;
  border: 1px solid rgba(164, 92, 255, .5); font-size: 13px; font-weight: 700;
  color: var(--purple); background: rgba(164, 92, 255, .14);
  transition: transform .12s, background .12s;
}
.ladder-viz:hover { transform: translateY(-1px); background: rgba(164, 92, 255, .24); }
.ladder-viz:active { transform: translateY(0); }
.ladder-viz:disabled { opacity: .6; cursor: default; transform: none; }
.ladder-vizwrap {
  margin: 6px 0 10px; padding: 12px; border-radius: 14px;
  background: var(--panel-2); border: 1px solid var(--border);
}
.ladder-vizcode {
  margin: 0; padding: 10px 12px; border-radius: 10px;
  background: var(--code-bg); border: 1px solid var(--border-2);
  font-family: var(--mono); font-size: 13px; line-height: 1.65; color: var(--text);
  overflow-x: auto; white-space: pre;
}
.ladder-vizvars {
  margin-top: 10px; padding: 10px 12px; border-radius: 12px;
  background: rgba(164, 92, 255, .10); border: 1px solid rgba(164, 92, 255, .26);
}
.ladder-vizout {
  margin-top: 10px; padding: 10px 12px; border-radius: 12px; min-height: 18px;
  background: var(--code-bg); border: 1px solid var(--border-2);
  font-family: var(--mono); font-size: 13px; line-height: 1.65; color: var(--ok);
  white-space: pre-wrap; word-break: break-word;
}
.ladder-vizout:not([hidden]) { animation: demoFade .4s ease; }
.ladder-vizerr { color: var(--err); }

/* —— 代码动画演示：打字浮出 / 逐行执行器 —— */
.demo-box { margin: 16px 0 4px; }
.demo-head {
  font-size: 13.5px; font-weight: 700; color: var(--pink);
  font-family: var(--display); letter-spacing: .3px; margin-bottom: 10px;
}
.demo-card {
  border-radius: 16px; padding: 14px; background: var(--panel-2);
  border: 1px solid var(--border);
}
.demo-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.demo-play {
  flex: 0 0 auto; padding: 8px 16px; border-radius: 10px; cursor: pointer;
  font-size: 13.5px; font-weight: 700; color: #04122a; border: 0;
  background: var(--grad); box-shadow: var(--glow); transition: transform .12s;
}
.demo-play:hover { transform: translateY(-1px); }
.demo-play:active { transform: translateY(0); }
.demo-label { font-size: 12.5px; color: var(--text-2); line-height: 1.5; }
.demo-step, .demo-reset {
  flex: 0 0 auto; padding: 8px 16px; border-radius: 10px; cursor: pointer;
  font-size: 13.5px; font-weight: 700; color: var(--text);
  background: transparent; border: 1px solid var(--border-2); transition: transform .12s;
}
.demo-step:hover:not(:disabled), .demo-reset:hover:not(:disabled) { transform: translateY(-1px); }
.demo-step:disabled, .demo-reset:disabled { opacity: .4; cursor: not-allowed; }
.demo-code {
  margin: 0; padding: 12px 14px; border-radius: 12px; min-height: 40px;
  background: var(--code-bg); border: 1px solid var(--border-2);
  font-family: var(--mono); font-size: 13.5px; line-height: 1.7; color: var(--text);
  overflow-x: auto; white-space: pre;
}
.demo-code.typing::after {
  content: "▋"; color: var(--cyan); margin-left: 1px; animation: demoBlink 1s steps(1) infinite;
}
@keyframes demoBlink { 50% { opacity: 0; } }
.demo-line { display: block; padding: 1px 8px; border-radius: 5px; white-space: pre; transition: background .25s; }
.demo-line.active { background: rgba(33, 230, 255, .18); box-shadow: inset 3px 0 0 var(--cyan); }
.demo-vars {
  margin-top: 12px; padding: 11px 13px; border-radius: 12px;
  background: rgba(164, 92, 255, .10); border: 1px solid rgba(164, 92, 255, .26);
}
.demo-vars-title { font-size: 12px; color: var(--purple); font-weight: 700; margin-bottom: 8px; }
.vars-list { display: flex; flex-wrap: wrap; gap: 8px; }
.var-chip {
  font-family: var(--mono); font-size: 12.5px; padding: 4px 10px; border-radius: 8px;
  background: var(--panel-solid); border: 1px solid var(--border-2); color: var(--text);
}
.var-chip b { color: var(--cyan); }
.vars-empty { font-size: 12.5px; color: var(--text-3); }
.demo-out {
  margin-top: 12px; padding: 11px 13px; border-radius: 12px; min-height: 20px;
  background: var(--code-bg); border: 1px solid var(--border-2);
  font-family: var(--mono); font-size: 13px; line-height: 1.7; color: var(--ok);
  white-space: pre-wrap; word-break: break-word;
}
.demo-out:not([hidden]) { animation: demoFade .4s ease; }
@keyframes demoFade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* —— 电脑新手必看 —— */
.novice-box {
  margin: 16px 0 6px; padding: 16px 16px 8px; border-radius: 16px;
  background: linear-gradient(180deg, rgba(255, 209, 102, .10), var(--panel-2));
  border: 1px solid rgba(255, 209, 102, .34);
}
.novice-head {
  font-size: 13.5px; font-weight: 700; color: var(--gold);
  font-family: var(--display); letter-spacing: .3px; margin-bottom: 12px;
}
.novice-list { display: flex; flex-direction: column; gap: 14px; }
.novice-item { line-height: 1.5; }
.novice-t { font-size: 13.5px; font-weight: 700; color: var(--text); margin-bottom: 5px; }
.novice-t::before { content: "\1F527  "; }
.novice-d { font-size: 13px; color: var(--text-2); line-height: 1.7; margin-bottom: 6px; }
.novice-cmp { display: flex; flex-wrap: wrap; gap: 10px; }
.novice-bad, .novice-good { flex: 1 1 240px; min-width: 0; }
.novice-tag { display: inline-block; font-size: 11.5px; font-weight: 700; margin-bottom: 4px; }
.novice-tag.bad { color: var(--err); }
.novice-tag.good { color: var(--ok); }
.novice-bad pre, .novice-good pre {
  margin: 0; padding: 8px 11px; border-radius: 9px;
  font-family: var(--mono); font-size: 12.5px; line-height: 1.6; color: var(--text);
  background: var(--code-bg); overflow-x: auto; white-space: pre-wrap; word-break: break-word;
}
.novice-bad pre { border: 1px solid rgba(255, 92, 138, .42); }
.novice-good pre { border: 1px solid var(--border-2); }

/* ============================================================
   执行洞察（insight.js）· 知识点检索（knowledge.js）
   2026-11-01 新增：错因归因 / 分叉对比 / 执行回放 / 视频知识点检索
   设计沿用上方 token，类名统一 iz- 前缀，避免与既有样式冲突
   ============================================================ */

.iz-sbtn { border-color: rgba(164, 92, 255, .42); color: #c9b3ff; }
.iz-sbtn:hover { border-color: var(--purple); color: var(--purple); box-shadow: 0 0 18px rgba(164, 92, 255, .35); }

/* ---------- 错因卡片 ---------- */
.iz-pitfall {
  margin-top: 10px; padding: 12px 14px; border-radius: 12px; font-size: 13px; line-height: 1.65;
  color: var(--text); background: linear-gradient(150deg, rgba(255, 92, 138, .10), rgba(255, 209, 102, .05));
  border: 1px solid rgba(255, 92, 138, .32);
}
.iz-pf-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; font-size: 13.5px; }
.iz-pf-tag {
  flex: 0 0 auto; padding: 2px 7px; border-radius: 6px; font-size: 11px; font-weight: 700;
  background: rgba(255, 92, 138, .18); color: #ff8fa8; border: 1px solid rgba(255, 92, 138, .4);
}
.iz-pf-why { margin: 0 0 8px; color: var(--text-2); }
.iz-pf-detail {
  margin: 0 0 8px; padding: 8px 10px; border-radius: 8px; font-family: var(--mono); font-size: 12px;
  color: var(--gold); background: rgba(10, 17, 36, .6); border-left: 2px solid var(--gold);
}
.iz-pf-fix { margin: 0 0 4px; color: var(--text); }
.iz-pf-novice { margin: 8px 0 0; font-size: 12.5px; color: var(--text-2); }
.iz-pf-acts { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }

.iz-btn {
  padding: 6px 12px; font-size: 12.5px; border-radius: 8px; cursor: pointer; transition: .15s;
  border: 1px solid var(--border-2); background: var(--panel-2); color: var(--text-2);
}
.iz-btn:hover { border-color: var(--cyan); color: var(--cyan); }
.iz-btn.primary { border-color: rgba(33, 230, 255, .55); color: var(--cyan); background: rgba(33, 230, 255, .10); }

/* ---------- 弹窗 ---------- */
.iz-modal {
  position: fixed; inset: 0; z-index: 620; display: flex; align-items: center; justify-content: center;
  padding: 24px; background: rgba(4, 7, 18, .72);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.iz-modal-card {
  width: min(1080px, 96vw); max-height: 88vh; display: flex; flex-direction: column; overflow: hidden;
  border-radius: 20px; border: 1px solid var(--border-2);
  background: linear-gradient(160deg, rgba(24, 34, 68, .98), rgba(11, 17, 38, .98));
  box-shadow: 0 30px 80px rgba(0, 0, 0, .6);
}
.iz-modal-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--border); }
.iz-modal-title {
  font-size: 15px; font-weight: 700; letter-spacing: .5px;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.iz-modal-x {
  width: 30px; height: 30px; border-radius: 50%; font-size: 18px; line-height: 1; cursor: pointer;
  border: 1px solid var(--border-2); background: rgba(255, 255, 255, .04); color: var(--text-2);
}
.iz-modal-x:hover { color: var(--text); border-color: var(--cyan); }
.iz-modal-body { padding: 16px 18px 20px; overflow: auto; }
.iz-loading { padding: 30px; text-align: center; font-size: 13.5px; color: var(--text-2); }
.iz-warn {
  margin-top: 10px; padding: 10px 12px; border-radius: 10px; font-size: 12.5px;
  color: var(--gold); background: var(--warn-bg); border: 1px solid rgba(255, 209, 102, .35);
}

/* ---------- 分叉对比 ---------- */
.iz-diff-head {
  padding: 12px 14px; margin-bottom: 14px; border-radius: 12px; font-size: 13.5px; line-height: 1.7;
  color: var(--text); background: var(--grad-soft); border: 1px solid var(--border-2);
}
.iz-diff-head.ok { background: var(--ok-bg); border-color: rgba(92, 255, 157, .4); }
.iz-fork-list { display: block; margin-top: 8px; font-size: 12.5px; line-height: 1.75; color: var(--text-2); }
.iz-fork-var { margin-right: 6px; font-family: var(--mono); font-weight: 700; color: var(--cyan); }
.iz-bad { font-family: var(--mono); color: #ff8fa8; }
.iz-good { font-family: var(--mono); color: var(--ok); }
.iz-diff-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 820px) { .iz-diff-cols { grid-template-columns: 1fr; } }
.iz-diff-col { min-width: 0; }
.iz-diff-title { margin-bottom: 6px; font-size: 12.5px; letter-spacing: .5px; color: var(--text-3); }
.iz-code {
  margin: 0; padding: 10px 0; max-height: 38vh; overflow: auto; border-radius: 10px;
  background: var(--code-bg); border: 1px solid var(--border);
  font-family: var(--mono); font-size: 12.5px; line-height: 1.85;
}
.iz-cl { padding: 0 12px; white-space: pre; color: var(--text); }
.iz-cl.hot { background: rgba(255, 92, 138, .16); box-shadow: inset 3px 0 0 #ff5c8a; }
.iz-cl.active { background: rgba(33, 230, 255, .14); box-shadow: inset 3px 0 0 var(--cyan); }
.iz-ln { display: inline-block; width: 26px; margin-right: 10px; text-align: right; color: var(--text-3); user-select: none; }
.iz-step-vars { margin-top: 8px; }
.iz-sv-title { display: block; margin-bottom: 5px; font-size: 11.5px; color: var(--text-3); }
.iz-chip {
  display: inline-block; margin: 0 6px 6px 0; padding: 3px 9px; border-radius: 7px;
  background: var(--panel-2); border: 1px solid var(--border);
  font-family: var(--mono); font-size: 12px; color: var(--text);
}
.iz-chip b { font-weight: 700; color: var(--cyan); }
.iz-empty { font-size: 12px; color: var(--text-3); }
.iz-step-out pre {
  margin: 4px 0 0; padding: 8px 10px; max-height: 16vh; overflow: auto; border-radius: 8px;
  background: var(--code-bg); border: 1px solid var(--border);
  font-family: var(--mono); font-size: 12px; color: var(--text-2);
}

/* ---------- 执行回放 ---------- */
.iz-replay { display: grid; grid-template-columns: 1.15fr 1fr; gap: 14px; }
@media (max-width: 820px) { .iz-replay { grid-template-columns: 1fr; } }
.iz-rp-left .iz-code { max-height: 52vh; }
.iz-rp-right { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.iz-rp-vars {
  min-height: 90px; padding: 10px 12px; border-radius: 10px;
  background: rgba(10, 17, 36, .55); border: 1px solid var(--border);
}
.iz-sv-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; font-size: 12.5px; color: var(--text); }
.iz-sv-sub { font-size: 11.5px; color: var(--text-3); }
.iz-var-list { display: flex; flex-direction: column; gap: 6px; }
.iz-var-row {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 5px 8px; border-radius: 7px;
  background: rgba(255, 255, 255, .025); border-left: 2px solid transparent; transition: .18s;
}
.iz-var-row.changed { background: rgba(33, 230, 255, .08); border-left-color: var(--cyan); }
.iz-var-name { flex: 0 0 auto; font-family: var(--mono); font-size: 12.5px; font-weight: 700; color: var(--cyan); }
.iz-new { font-style: normal; font-size: 10px; padding: 0 4px; margin-left: 4px; border-radius: 4px; background: rgba(92, 255, 157, .2); color: var(--ok); }
.iz-var-val { font-family: var(--mono); font-size: 12.5px; color: var(--text); }
.iz-var-was { font-family: var(--mono); font-size: 11px; color: var(--text-3); }
.iz-rp-out { padding: 10px 12px; border-radius: 10px; background: rgba(10, 17, 36, .55); border: 1px solid var(--border); }
.iz-rp-out pre {
  margin: 0; max-height: 22vh; overflow: auto; font-family: var(--mono); font-size: 12px;
  color: var(--text-2); white-space: pre-wrap;
}
.iz-timeline {
  display: flex; align-items: center; gap: 10px; margin-top: 14px; padding: 10px 12px;
  border-radius: 10px; background: rgba(10, 17, 36, .55); border: 1px solid var(--border);
}
.iz-timeline input[type=range] { flex: 1; accent-color: var(--cyan); }
.iz-rp-count { min-width: 62px; text-align: right; font-family: var(--mono); font-size: 12px; color: var(--text-2); }

/* ---------- 容器可视化 ---------- */
.iz-box-wrap { display: inline-flex; flex-wrap: wrap; gap: 4px; align-items: center; vertical-align: middle; }
.iz-box {
  display: inline-block; padding: 2px 7px; border-radius: 5px;
  background: rgba(33, 230, 255, .12); border: 1px solid rgba(33, 230, 255, .35);
  font-family: var(--mono); font-size: 11.5px; color: var(--text);
}
.iz-box-more { font-size: 11px; color: var(--text-3); }
.iz-box-empty { font-size: 11.5px; color: var(--text-3); }
.iz-dict-wrap { display: inline-flex; flex-wrap: wrap; gap: 5px; }
.iz-kv {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px 7px; border-radius: 5px;
  background: rgba(164, 92, 255, .12); border: 1px solid rgba(164, 92, 255, .35);
  font-family: var(--mono); font-size: 11.5px;
}
.iz-k { color: #c9b3ff; }
.iz-kv-sep { color: var(--text-3); }
.iz-v { color: var(--text); }
.iz-str { color: var(--lime); }
.iz-str-len { margin-left: 6px; font-size: 10px; color: var(--text-3); }
.iz-plain { font-family: var(--mono); }

/* ---------- 视频知识点检索 ---------- */
.iz-kb {
  position: fixed; z-index: 480; padding: 8px; max-height: 46vh; overflow: auto; border-radius: 10px;
  background: rgba(10, 17, 36, .97); border: 1px solid var(--border-2);
  box-shadow: 0 18px 50px rgba(0, 0, 0, .55);
}
.iz-kb-head { display: flex; justify-content: space-between; gap: 8px; padding: 2px 4px 8px; font-size: 11.5px; color: var(--text-3); }
.iz-kb-n { color: var(--cyan); }
.iz-kb-list { display: flex; flex-direction: column; gap: 4px; }
.iz-kb-item {
  display: grid; grid-template-columns: auto auto 1fr; gap: 8px; align-items: baseline; width: 100%;
  padding: 6px 8px; border-radius: 7px; cursor: pointer; text-align: left;
  border: 1px solid transparent; background: rgba(255, 255, 255, .03); color: var(--text-2); font-size: 12px;
}
.iz-kb-item:hover { border-color: rgba(33, 230, 255, .4); background: rgba(33, 230, 255, .08); color: var(--text); }
.iz-kb-id { font-family: var(--mono); font-size: 11.5px; color: var(--cyan); }
.iz-kb-time { font-family: var(--mono); font-size: 11px; color: var(--gold); }
.iz-kb-txt { line-height: 1.5; }
.iz-kb-txt mark { padding: 0 2px; border-radius: 3px; background: rgba(255, 209, 102, .28); color: var(--gold); }
.iz-kb-more, .iz-kb-empty { padding: 8px 4px 2px; font-size: 11.5px; color: var(--text-3); }

/* ---------- 跟打模式（ladder-demo.js） ---------- */
.demo-kbd {
  flex: 0 0 auto; padding: 8px 16px; border-radius: 10px; cursor: pointer;
  font-size: 13.5px; font-weight: 700; color: #c9b3ff;
  background: transparent; border: 1px solid rgba(164, 92, 255, .45); transition: transform .12s;
}
.demo-kbd:hover { transform: translateY(-1px); border-color: var(--purple); }
.demo-typing { position: relative; }
.demo-type-input {
  position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0;
  border: 0; background: transparent; resize: none; z-index: 2; cursor: text;
}
.demo-type-view { position: relative; z-index: 1; max-height: 40vh; overflow: auto; }
.demo-type-view span { transition: color .12s; }
.demo-type-view span.ok { color: var(--lime); }
.demo-type-view span.cur {
  color: #04122a; background: var(--cyan); border-radius: 3px;
  box-shadow: 0 0 12px rgba(33, 230, 255, .55);
}
.demo-type-view span.cur:empty::after { content: " "; }
.demo-typing.shake { animation: demoShake .26s; }
@keyframes demoShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}
.demo-type-at { color: var(--text-3); font-family: var(--mono); font-size: 11.5px; margin-left: 6px; }
.demo-write, .demo-exit {
  margin-left: 8px; padding: 4px 12px; border-radius: 8px; cursor: pointer;
  font-size: 12.5px; font-weight: 700;
  border: 1px solid rgba(33, 230, 255, .5); background: rgba(33, 230, 255, .12); color: var(--cyan);
}
.demo-exit { border-color: var(--border-2); background: transparent; color: var(--text-2); }

/* ============================================================
   运行时状态角标（app.js 的 ensureRuntime）
   ────────────────────────────────────────────────────────────
   Python 解释器改成后台加载后，进度不再用整屏遮罩挡住课程内容，
   而是缩成顶栏右侧一个小药丸：加载中呼吸、就绪变绿、失败变红可悬停看原因。
   ============================================================ */
.rt-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 12px;
  line-height: 1.4;
  font-family: var(--mono, ui-monospace, monospace);
  border: 1px solid var(--border);
  color: var(--text-3);
  background: rgba(255, 255, 255, .03);
  white-space: nowrap;
  transition: color .25s, border-color .25s, background .25s;
}
.rt-badge.rt-loading {
  color: var(--gold);
  border-color: rgba(255, 200, 80, .35);
  background: rgba(255, 200, 80, .06);
}
.rt-badge.rt-loading::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentColor;
  animation: rtPulse 1.1s ease-in-out infinite;
}
.rt-badge.rt-ready {
  color: var(--lime);
  border-color: rgba(140, 240, 120, .28);
  background: rgba(140, 240, 120, .05);
}
.rt-badge.rt-ready::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentColor;
  opacity: .85;
}
.rt-badge.rt-error {
  color: var(--pink);
  border-color: rgba(255, 120, 180, .4);
  background: rgba(255, 120, 180, .07);
  cursor: help;
}
@keyframes rtPulse {
  0%, 100% { opacity: .3; transform: scale(.8); }
  50%      { opacity: 1;  transform: scale(1); }
}
/* 浅色主题：白底上淡白背景会消失，换成淡黑底，边框颜色已随变量自适应 */
[data-theme="light"] .rt-badge {
  background: rgba(20, 30, 60, .04);
}
[data-theme="light"] .rt-badge.rt-loading { background: rgba(190, 140, 0, .08); }
[data-theme="light"] .rt-badge.rt-ready   { background: rgba(20, 160, 80, .08); }
[data-theme="light"] .rt-badge.rt-error   { background: rgba(200, 30, 150, .07); }
/* 手机顶栏空间有限：只留状态点，文字收窄 */
@media (max-width: 760px) {
  .rt-badge {
    padding: 3px 8px;
    font-size: 11px;
    max-width: 104px;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}
