/* 教学平台统一视觉。设计取向：安静、克制、信息优先——
   课堂上界面不该抢注意力，颜色只用来区分"角色"（教师内容 / 学生动作 / 状态）。

   约定：页面只写布局，视觉一律走这里的 token 与组件类。
   深色模式下语义色必须单独给值——把浅色用的深蓝深棕直接搬到深底上会糊成一团。 */

:root {
  color-scheme: light dark;

  /* ---- 中性色：界面骨架 ---- */
  --bg: #f4f6fa;             /* 白卡片要浮起来，底就不能也接近白——原先与 #fff
                                只差一点，整页读作一大片白，像还没做完 */
  --surface: #ffffff;
  --surface-2: #f0f3f9;
  --surface-3: #e9edf5;
  --line: #e1e5ee;           /* 边框只做分隔，不参与"画框"——层次交给间距与阴影 */
  --line-strong: #cbd2e1;
  --text: #0f1724;           /* 正文压深：13/1b/25 在白底上偏灰，长时间读着累 */
  --text-dim: #56637a;
  --text-faint: #68758a;

  /* ---- 语义色：每种只有一个用途，不混用 ---- */
  --brand: #4059a6;          /* 主操作 */
  --brand-deep: #344984;     /* 品牌标记的渐变末端 */
  --brand-hover: #334a91;
  --brand-soft: #eaf0ff;
  --on-brand: #ffffff;
  --teach: #b45309;          /* 教师板书/笔记 */
  --teach-soft: #fff8e8;
  --mark: #7c3aed;           /* 知识点、点名 */
  --mark-soft: #f4f1ff;
  --ok: #15803d;
  --ok-soft: #edfbf1;
  --warn: #b91c1c;
  --warn-soft: #fef1f1;

  /* ---- 字号阶梯：只用这几档，页面不要另写 px ---- */
  --t-xs: 12px;
  --t-sm: 13px;
  --t-md: 14px;
  --t-base: 14.5px;          /* 中文字形比拉丁字母"矮"，同号数看着更小 */
  --t-lg: 17px;
  --t-xl: 21px;
  --t-2xl: 28px;             /* 页面主标题要够大，否则整页没有视觉落点 */

  /* ---- 间距节奏：4 的倍数 ---- */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px;

  --r: 16px;
  --r-sm: 10px;
  --r-lg: 20px;
  --shadow-sm: 0 1px 2px rgba(15,23,36,.04), 0 1px 1px rgba(15,23,36,.03);
  --shadow: 0 1px 3px rgba(15,23,36,.05), 0 8px 24px -8px rgba(15,23,36,.10);
  --shadow-lg: 0 16px 48px -12px rgba(15,23,36,.24);
  --ring: 0 0 0 3px var(--brand-soft);

  /* 批注笔色：语义键存进事件日志，各端按自己的主题解析——
     直接存 #000 的话，深色板上就是一片看不见的黑。 */
  /* 播放器的黑边：深浅主题下都是黑的——这是视频的惯例，不是配色的一部分。
     写成 token 只为让"页面里不许出现硬编码颜色"这条规矩没有例外。 */
  --video-mat: #000;

  /* 浮在内容之上的深色蒙层（弹窗背景、字幕条、投影上的角标）。两种主题下都是
     深色——它盖的是画面而不是页面，跟着主题翻白会看不清下面的内容。 */
  --scrim: #18203866;
  --scrim-solid: #142036e8;
  --stage: #eef1f6;          /* 投影/课件台的底色，深色模式下跟着变深 */

  --ink:       #1f2937;
  --ink-red:   #dc2626;
  --ink-blue:  #2563eb;
  --ink-green: #16a34a;
  --ink-amber: #d97706;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
          "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0b0f14; --surface: #151b23; --surface-2: #1b222b; --surface-3: #232b36;
    --line: #232b35; --line-strong: #36404d;
    --text: #eaeff6; --text-dim: #9dabbd; --text-faint: #6d7a8c;
    /* 语义色整体提亮：深色底上原来的深蓝/深棕几乎不可读 */
    --brand: #5b9bff; --brand-deep: #2f5fb8; --brand-hover: #7db0ff; --brand-soft: #16233a; --on-brand: #0b1220;
    --teach: #e2a33c; --teach-soft: #2a2214;
    --mark: #b795ff; --mark-soft: #221b34;
    --stage: #0e141c;
    --ok: #4ade80; --ok-soft: #12251a;
    --warn: #f87171; --warn-soft: #2a1616;
    --ink:       #e8edf5;
    --ink-red:   #f87171;
    --ink-blue:  #60a5fa;
    --ink-green: #4ade80;
    --ink-amber: #fbbf24;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.35);
    --shadow: 0 1px 2px rgba(0,0,0,.3), 0 4px 16px rgba(0,0,0,.35);
    --shadow-lg: 0 12px 40px rgba(0,0,0,.55);
  }
}

* { box-sizing: border-box; }

body {
  margin: 0; background: var(--bg); color: var(--text);
  font-family: var(--font); font-size: var(--t-base); line-height: 1.6;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}
a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4 { line-height: 1.3; letter-spacing: -.015em; }
h1 { font-size: var(--t-2xl); font-weight: 680; margin: 0 0 var(--s3); }
h2 { font-size: var(--t-lg); font-weight: 650; margin: 0 0 var(--s3); }
h3 { font-size: var(--t-base); font-weight: 650; margin: 0 0 var(--s2); }
code, kbd { font-family: var(--mono); font-size: .92em; }

/* 键盘可见焦点——鼠标点击不出现方框，Tab 导航时必须出现 */
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* ---- 应用栏 ---- */
.appbar {
  display: flex; align-items: center; gap: var(--s3);
  padding: 0 var(--s5); height: 56px; position: sticky; top: 0; z-index: 10;
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
  /* 顶上一条品牌色细线：最省的一处标识，页面一眼有归属 */
  box-shadow: none;
}
.brand { display: flex; align-items: center; gap: var(--s2); font-weight: 650;
         font-size: var(--t-lg); letter-spacing: -.01em; color: var(--text); }
.brand:hover { text-decoration: none; }
/* 品牌名 + 功能名：老师在授权页看到的应用名要和站点上的对得上，
   对不上他就会犹豫——这种一致性本身就是信任信号。功能名弱化，
   因为一眼要先认出"这是哪个东西"，再看"我在它的哪一页"。 */
.brand .where { font-weight: 500; color: var(--text-dim); }
.brand .where::before { content: "·"; margin: 0 var(--s2); color: var(--text-faint); }
/* 品牌标记：一个 7px 的小圆点当不了标识——它在任何地方都读作"一个状态点"。
   给一块有形的色块：白底页面上这是唯一一处饱和色，页面因此有了归属，
   而不是"一个表单浮在白底上"。 */
.brand .dot { width: 22px; height: 22px; border-radius: 7px; flex: none;
              background: linear-gradient(160deg, var(--brand), var(--brand-deep));
              box-shadow: 0 1px 3px rgba(64,89,166,.20);
              display: grid; place-items: center; }
.brand .dot::after { content: "随"; color: #fff; font-size: 13px; font-weight: 700;
                     line-height: 1; }
.navlink { font-size: var(--t-md); color: var(--text-dim); padding: 5px 10px;
           border-radius: var(--r-sm); }
.navlink:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.navlink.on { background: var(--brand-soft); color: var(--brand); font-weight: 600; }

/* 旧版顶栏（授课台/教室仍在用） */
.topbar {
  display: flex; align-items: center; gap: var(--s3);
  padding: 9px var(--s4); background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.topbar h1 { margin: 0; font-size: var(--t-lg); font-weight: 650; letter-spacing: -.01em; }
.topbar .sub { font-size: var(--t-sm); color: var(--text-dim); }
.spacer { flex: 1; }

/* ---- 按钮 ---- */
button, .btn {
  font: inherit; font-size: var(--t-md); font-weight: 500;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 6px 12px; cursor: pointer; white-space: nowrap;
  background: var(--surface); color: var(--text);
  transition: background .12s ease, border-color .12s ease, transform .06s ease;
}
button:hover:not(:disabled), .btn:hover { background: var(--surface-2);
                                          border-color: var(--line-strong); }
button:active:not(:disabled) { transform: translateY(.5px); }
button:disabled { opacity: .45; cursor: not-allowed; }
/* 变体一律同时写 button 与 .btn：链接当按钮用（<a class="btn pri">）非常常见，
   只写 button.pri 会让它悄悄退化成一个普通白按钮——而这类"没报错、只是不对"
   的样式问题，不截图根本发现不了。 */
button.pri, .btn.pri { background: var(--brand); color: var(--on-brand);
                       border-color: transparent; box-shadow: var(--shadow-sm); }
button.pri:hover:not(:disabled), .btn.pri:hover { background: var(--brand-hover);
                                                  color: var(--on-brand); }
button.warn, button.danger, .btn.warn, .btn.danger {
  background: var(--surface); color: var(--warn); border-color: var(--line); }
button.warn:hover:not(:disabled), button.danger:hover:not(:disabled),
.btn.warn:hover, .btn.danger:hover { background: var(--warn-soft); border-color: var(--warn); }
button.ghost, .btn.ghost { background: transparent; border-color: transparent;
                           color: var(--text-dim); }
button.ghost:hover:not(:disabled), .btn.ghost:hover { background: var(--surface-2);
                                                      color: var(--text); }
button.sm, .btn.sm { font-size: var(--t-sm); padding: 3px 9px; }
/* 链接当按钮用时：去掉下划线，行内块以便对齐 */
a.btn { display: inline-block; text-decoration: none; }
a.btn:not(.pri) { color: var(--text); }
a.btn:hover { text-decoration: none; }
button.block { width: 100%; padding: 9px; font-size: var(--t-base); }

/* 分段控件（互斥选择，比一排按钮更清楚"只能选一个"）*/
.seg { display: inline-flex; background: var(--surface-2); border: 1px solid var(--line);
       border-radius: var(--r-sm); padding: 2px; gap: 2px; }
.seg button { border: 0; background: transparent; padding: 4px 11px; font-size: var(--t-sm);
              border-radius: 5px; color: var(--text-dim); }
.seg button:hover:not(:disabled) { background: var(--surface); border-color: transparent; }
.seg button.on { background: var(--surface); color: var(--text); font-weight: 600;
                 box-shadow: var(--shadow-sm); }

/* ---- 输入 ---- */
input, textarea, select {
  font: inherit; font-size: var(--t-md); color: var(--text);
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r-sm); padding: 8px 10px; width: 100%;
  transition: border-color .12s, box-shadow .12s;
}
input::placeholder, textarea::placeholder { color: var(--text-faint); }
input:focus, textarea:focus, select:focus {
  outline: none; border-color: var(--brand); box-shadow: var(--ring);
}
label { font-size: var(--t-sm); color: var(--text-dim); display: block; margin-bottom: var(--s1); }
.field { margin-bottom: var(--s3); }

/* ---- 卡片 / 面板 ---- */
/* 卡片：浅色下不描边——一页上七八个 1px 灰框会把版面切碎，层次交给
   底色差与一层极淡的阴影；深色下反过来，暗底上阴影读不出来，得留边。 */
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--shadow-sm); padding: var(--s5);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .card { border-color: var(--line); box-shadow: none; }
}
:root[data-theme="dark"] .card { border-color: var(--line); box-shadow: none; }
.card.pad-lg { padding: var(--s6); }
.panel { background: var(--surface); border-left: 1px solid var(--line); overflow: auto; }
.panel h4, .sectitle {
  margin: 0 0 var(--s2); font-size: var(--t-xs); font-weight: 650; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: .07em;
}
.muted { color: var(--text-faint); font-size: var(--t-sm); }
.hint { color: var(--text-dim); font-size: var(--t-md); line-height: 1.65; }
.empty { color: var(--text-faint); font-size: var(--t-md); padding: var(--s5) var(--s2);
         text-align: center; }

/* ---- 胶囊 / 标签 ---- */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--t-sm); padding: 4px 10px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--line); color: var(--text-dim);
}
.chip.alert { background: var(--warn-soft); border-color: transparent; color: var(--warn);
              font-weight: 600; }
.chip.live { background: var(--ok-soft); color: var(--ok); border-color: transparent;
             font-weight: 600; }
.chip.live::before { content: ""; width: 6px; height: 6px; border-radius: 50%;
                     background: var(--ok); animation: pulse 2s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
.tag { display: inline-block; font-size: var(--t-xs); padding: 2px 7px; border-radius: 5px;
       background: var(--surface-3); color: var(--text-dim); font-weight: 500; }
.tag.brand { background: var(--brand-soft); color: var(--brand); }
.tag.teach { background: var(--teach-soft); color: var(--teach); }
.tag.mark  { background: var(--mark-soft);  color: var(--mark); }
.tag.ok    { background: var(--ok-soft);    color: var(--ok); }
.tag.warn  { background: var(--warn-soft);  color: var(--warn); }

/* ---- 表格 ---- */
table { width: 100%; border-collapse: collapse; font-size: var(--t-md); }
th, td { padding: 9px 10px; text-align: left; border-bottom: 1px solid var(--line); }
th { font-weight: 650; color: var(--text-faint); font-size: var(--t-xs);
     text-transform: uppercase; letter-spacing: .06em; }
tbody tr:hover td { background: var(--surface-2); }
tbody tr:last-child td { border-bottom: 0; }

/* ---- 白板 ---- */
.board {
  position: relative; background: var(--surface); border-radius: var(--r);
  box-shadow: var(--shadow); overflow: auto; margin: var(--s3);
  border: 1px solid var(--line);
}
.board-lines { padding: 30px 36px 140px; min-height: 100%; }
.bline { margin: 12px 0; font-size: 20px; overflow-x: auto; border-radius: var(--r-sm);
         padding: 3px 8px; }
.note-line {                        /* 教师板书笔记 */
  background: var(--teach-soft); border-left: 3px solid var(--teach);
  border-radius: var(--r-sm); padding: 10px 13px; margin: var(--s4) 0; font-size: 15px;
}
.mkr {                              /* 知识点标记（仅教师端可见） */
  color: var(--mark); font-weight: 650; font-size: var(--t-base); margin: 22px 0 var(--s2);
  border-top: 1px dashed var(--line); padding-top: var(--s4);
}

/* ---- 字幕 ---- */
.caption {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 18px;
  background: rgba(10,15,22,.85); color: #fff; padding: 9px 18px;
  border-radius: var(--r); font-size: 15px; max-width: 58%; text-align: center;
  z-index: 15; backdrop-filter: blur(8px); box-shadow: var(--shadow-lg);
}

/* ---- 浮层 ---- */
.overlay {
  position: fixed; inset: 0; background: rgba(10,15,22,.45);
  display: flex; align-items: center; justify-content: center; z-index: 30;
  backdrop-filter: blur(3px);
}
.sheet {
  background: var(--surface); border-radius: var(--r-lg); padding: var(--s5);
  width: 380px; max-height: 76vh; overflow: auto; box-shadow: var(--shadow-lg);
  border: 1px solid var(--line); animation: rise .16s ease-out;
}
@keyframes rise { from { opacity: 0; transform: translateY(8px); } }
.floatcard {
  position: fixed; right: 22px; bottom: 22px; width: 330px;
  background: var(--surface); border-radius: var(--r); padding: var(--s4);
  box-shadow: var(--shadow-lg); z-index: 20; border: 1px solid var(--line);
  animation: rise .16s ease-out;
}
.menu {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow-lg); padding: var(--s1); min-width: 176px;
  animation: rise .12s ease-out;
}
.menu button { display: block; width: 100%; text-align: left; border: 0;
               background: transparent; padding: 7px 10px; border-radius: var(--r-sm); }
.menu button:hover:not(:disabled) { background: var(--surface-2); }
.menu hr { border: 0; border-top: 1px solid var(--line); margin: var(--s1) 0; }

/* ---- 对话 ---- */
.msg, .m { margin-bottom: var(--s3); font-size: var(--t-md); line-height: 1.65;
           white-space: pre-wrap; }
.msg.user, .m.user { text-align: right; }
.msg.user > span, .m.user > span { background: var(--brand); color: var(--on-brand);
                 padding: 8px 13px; border-radius: 13px 13px 4px 13px;
                 display: inline-block; max-width: 88%; text-align: left; }
.msg.bot > span, .m.bot > span { background: var(--surface-2); padding: 8px 13px;
                border: 1px solid var(--line);
                border-radius: 13px 13px 13px 4px; display: inline-block; max-width: 92%; }
.cite { color: var(--brand); font-weight: 600; cursor: pointer; }

/* ---- 进度条 ---- */
.bar { height: 6px; border-radius: 3px; background: var(--surface-3); overflow: hidden; }
.bar > * { display: block; height: 100%; background: var(--brand); transition: width .3s ease; }
.bar.ok > * { background: var(--ok); }

/* ---- 列表项（名单等）---- */
.row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 10px; border-radius: var(--r-sm); margin-bottom: 3px;
  background: var(--surface-2); cursor: pointer; font-size: var(--t-md);
  border: 1px solid transparent; transition: background .12s, border-color .12s;
}
.row:hover { background: var(--brand-soft); border-color: var(--line); }
.row.off { opacity: .45; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 6px;
                            border: 3px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--text-faint); background-clip: content-box; }
::-webkit-scrollbar-track { background: transparent; }

/* ---- 对话框（ui.js）：替代浏览器原生 alert/confirm/prompt ---- */
.ui-dlg { animation: fade .14s ease-out; }
.ui-dlg.out { animation: fade .12s ease-in reverse; }
@keyframes fade { from { opacity: 0; } }
.ui-dlg .sheet { width: min(420px, calc(100vw - 32px)); }
.ui-dlg-t { margin: 0 0 var(--s2); font-size: var(--t-lg); font-weight: 650; }
.ui-dlg-t.danger { color: var(--warn); }
.ui-dlg-d { margin: 0 0 var(--s4); color: var(--text-dim); font-size: var(--t-md);
            line-height: 1.65; white-space: pre-wrap; }
.ui-dlg label { margin-bottom: var(--s1); }
.ui-dlg-h { font-size: var(--t-sm); color: var(--warn); min-height: 17px;
            margin-top: var(--s1); }
.ui-dlg-a { display: flex; justify-content: flex-end; gap: var(--s2); margin-top: var(--s4); }
button.danger-solid { background: var(--warn); color: #fff; border-color: transparent; }
button.danger-solid:hover:not(:disabled) { background: var(--warn); filter: brightness(1.12); }

/* ---- 轻提示 ---- */
.ui-toasts { position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);
             display: flex; flex-direction: column; gap: var(--s2);
             z-index: 60; pointer-events: none; }
.ui-toast { background: var(--text); color: var(--bg); padding: 9px 16px;
            border-radius: 999px; font-size: var(--t-md); font-weight: 500;
            box-shadow: var(--shadow-lg); animation: rise .16s ease-out;
            max-width: 78vw; }
.ui-toast.out { animation: fade .2s ease-in reverse; }
.ui-toast.ok   { background: var(--ok);   color: #fff; }
.ui-toast.warn { background: var(--warn); color: #fff; }

/* ---- 批注工具条（教师端）---- */
/* 统一的工作区行：左栏、主区、AI 区、辅助区都是这一行里的列。
   列不互相压，也不需要谁给谁留位置——"浮层盖住正文"那一整类问题就没有了。 */
/* 分屏：N 块等分，中间是可拖的分割线。grid-auto-columns 用 --stage-sizes
   覆盖，老师拖完分割线把比例一并广播给学生，两端排法才一致。 */
#stageGrid{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;min-width:0;min-height:100%;height:100%;box-sizing:border-box;--stage-sizes:repeat(auto-fit,minmax(0,1fr))}
#stageGrid.split{grid-template-columns:var(--stage-sizes)}
#stageGrid>.stage{position:relative;min-width:0;min-height:100%;overflow:auto}
/* 第 2–4 块屏的三层要和第 0 块长一样：墨迹层绝对定位盖在课件上，否则它会
   留在文档流里、默认 300x150，指针根本落不到它身上。 */
.stage-deck{text-align:center;padding:8px}
.stage-ink{z-index:3;position:absolute;top:0;left:0;touch-action:none}

#stageGrid>.stage+.stage{border-left:1px solid var(--line)}
#stageGrid>.stage-gutter{cursor:col-resize;background:transparent;position:relative}
#stageGrid>.stage-gutter::after{content:"";position:absolute;inset:0 calc(50% - 1px);background:var(--line)}
#stageGrid>.stage-gutter:hover::after{background:var(--brand)}
#stageGrid>.stage.on{outline:2px solid var(--brand-soft);outline-offset:-2px}
/* 每块屏右上角的 ×，只在分屏时显示 */
.stage-close{position:absolute;top:6px;right:6px;z-index:6;width:28px;height:28px;padding:0;border-radius:8px;background:var(--surface);border:1px solid var(--line);opacity:.75}
.stage-close:hover{opacity:1}
#stageGrid:not(.split) .stage-close{display:none}
.inkbar { position: relative; flex-wrap: wrap; justify-content: center; margin: 8px;
  display: flex; align-items: center; gap: var(--s2); z-index: 12;
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px;
  padding: 5px 9px; box-shadow: var(--shadow); }
/* 工具条固定在板的顶端：板是可滚动的，不钉住的话往下看课件时工具条就滚没了，
   想改个笔色还得先滚回去。 */
.inkbar { position: sticky; top: 0; }
/* 小巧些：这一条上十几个控件，默认的内边距和字号会把它顶成两三行，
   占掉课件的垂直空间——而课件才是这块板的主角。 */
.inkbar { margin: 6px 8px; padding: 2px 8px; gap: 4px;
  flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden;
  scrollbar-width: thin; justify-content: flex-start; }
.inkbar > * { flex: none; }
.inkbar #lessonDeckBar { flex-wrap: nowrap; padding: 0; gap: 6px; }
.inkbar #lessonDeckBar > * { flex: none; }
.inkbar #lessonDeckBar select { max-width: 150px; }
.inkbar button { padding: 3px 6px; font-size: var(--t-sm); }
.inkbar select { width: auto; flex: none; max-width: 92px; padding: 2px 4px;
  font-size: var(--t-sm); height: 26px; }
.inkbar .sw { width: 17px; height: 17px; }
.inkbar .wd { width: 21px; height: 21px; }
.inkbar .sep { height: 15px; }
.inkbar .sep { width: 1px; height: 18px; background: var(--line); }
.inkbar button { border: 0; background: transparent; padding: 4px 8px; border-radius: 999px;
  font-size: var(--t-md); line-height: 1; }
.inkbar button:hover:not(:disabled) { background: var(--surface-2); }
.inkbar button.on { background: var(--brand-soft); color: var(--brand); font-weight: 600; }
.inkbar .sw { width: 20px; height: 20px; border-radius: 50%; padding: 0;
  border: 2px solid transparent; }
.inkbar .sw.on { border-color: var(--text); }
.inkbar .wd { width: 24px; height: 24px; padding: 0; display: grid; place-items: center; }
.inkbar .wd i { display: block; border-radius: 999px; background: var(--text-dim); }
.inkbar .wd.on { background: var(--brand-soft); }
.inkbar .wd.on i { background: var(--brand); }

/* 课件页的背景是白纸，跟深浅主题无关。深色主题下 --ink 是近白色，画在
   幻灯片上等于隐形——老师圈了一个词，学生什么也没看见，而且两边都不会
   察觉。所以只要当前显示的是课件，墨色就切回"纸上"的那一套。 */
body.on-paper {
  /* 播放器的黑边：深浅主题下都是黑的——这是视频的惯例，不是配色的一部分。
     写成 token 只为让"页面里不许出现硬编码颜色"这条规矩没有例外。 */
  --video-mat: #000;

  --ink:       #1f2937;
  --ink-red:   #dc2626;
  --ink-blue:  #2563eb;
  --ink-green: #16a34a;
  --ink-amber: #d97706;
}

/* ---- 页头：每页要有一个视觉落点 ----
   原先课程主页一进来就是四个大数字盒，而它们多半是 0——最响的位置给了最没
   信息量的东西，页面于是没有"我在哪儿"。标题在前，数字退成一行注解。 */
.pagehead { margin: var(--s5) 0 var(--s4); }
.pagehead h1 { margin: 0 0 var(--s2); }
.pagehead .meta { display: flex; flex-wrap: wrap; align-items: center;
                  gap: var(--s2) var(--s4); color: var(--text-dim);
                  font-size: var(--t-md); }
.pagehead .meta b { color: var(--text); font-weight: 650; font-variant-numeric: tabular-nums; }
.pagehead .meta .sep { color: var(--line-strong); }

/* 进度条：细、安静，只在有进展时才有颜色 */
.bar { height: 6px; border-radius: 999px; background: var(--surface-3); overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--brand); border-radius: 999px; }

/* 区块标题：和正文拉开距离，但别用大字号抢戏 */
section { margin-bottom: var(--s6); }
section > h2 { display: flex; align-items: center; gap: var(--s3);
               margin: 0 0 var(--s3); font-size: var(--t-base); font-weight: 650; }
/* 行内元素给不了宽高——.maphead 里的 h2 不是 flex 容器，写 width 会静默失效。
   这类"没报错、只是不显示"的样式问题，只有截图能发现。 */
section > h2::before, .maphead h2::before {
  content: ""; display: inline-block; vertical-align: -2px;
  width: 3px; height: 14px; border-radius: 2px; flex: none;
  background: var(--brand); margin-right: var(--s2);
}

/* 空态要像"这里本来就该是这样"，而不是"内容没加载出来"：一块有边界的浅底、
   一个小标题、两句说清能做什么。原先是两行灰字浮在白底中间，占着大片位置
   却什么都没说。 */
.blank { background: var(--surface-2); border-radius: var(--r); padding: var(--s5);
         color: var(--text-dim); font-size: var(--t-md); line-height: 1.7; }
.blank-t { font-weight: 650; color: var(--text); font-size: var(--t-base);
           margin-bottom: var(--s2); }
.blank p { margin: 0 0 var(--s2); }
.blank p:last-child { margin-bottom: 0; }

/* ---- 独立页面的底 ----
   一张卡片浮在纯白上，看起来永远像"还没做完"。给一层极淡的品牌色晕染：
   不抢内容，但让页面有方向感——人一眼能看出这是谁家的页面。 */
.standalone {
  min-height: 100vh; display: grid; place-items: center; padding: var(--s5);
  background:
    radial-gradient(48rem 26rem at 50% -6rem, var(--brand-soft), transparent 72%),
    radial-gradient(30rem 20rem at 88% 105%, var(--mark-soft), transparent 70%),
    var(--bg);
}

/* ---- 随堂思维导图 ----
   一条从上往下长的脉络：讲过的留在上面，正在讲的在最下面高亮。
   竖线把它们串起来——学生扫一眼就知道"走到哪儿了、之前讲过什么"。 */
.mm { overflow: auto; padding: var(--s3) var(--s4); }
.mm-empty { color: var(--text-faint); font-size: var(--t-sm); padding: var(--s3) 0; }
.mm-mod { font-size: var(--t-xs); font-weight: 650; color: var(--text-faint);
          letter-spacing: .06em; margin: var(--s3) 0 var(--s1); }
.mm-mod:first-child { margin-top: 0; }
.mm-node { position: relative; padding: 5px 0 5px var(--s4); font-size: var(--t-md);
           color: var(--text-dim); line-height: 1.5; }
.mm-node::before { content: ""; position: absolute; left: 4px; top: 0; bottom: 0;
                   width: 2px; background: var(--line); }
.mm-node:last-child::before { bottom: 50%; }        /* 最后一个不再往下拖线 */
.mm-dot { position: absolute; left: 0; top: 11px; width: 10px; height: 10px;
          border-radius: 50%; background: var(--surface);
          border: 2px solid var(--line-strong); }
.mm-node.on { color: var(--text); font-weight: 600; }
/* 出完笔记对账：讲过但笔记没覆盖的那几个要显眼——它们正是跳着看漏掉的 */
.mm-node.miss { color: var(--text); }
.mm-node.miss .mm-dot { background: var(--warn); }
.mm-node.mm-jump { cursor: pointer; }
.mm-node.mm-jump:hover { color: var(--brand); }
.mm-node.on .mm-dot { border-color: var(--brand); background: var(--brand); }
.mm-via { margin-left: var(--s2); font-size: var(--t-xs); color: var(--text-faint);
          font-weight: 400; }

/* 分栏默认宽度。写在这里而不是各页自己藏一个数：拖条会用同名变量覆盖它们，
   默认值散在三个文件里的话，改一次要找三处。运行时由 ui.resizable 改写。 */
:root {
  --chatw: 380px;      /* 教室：随堂提问栏 */
  --matw: 430px;       /* 教室：教材栏 */
  --sidew: 430px;      /* 工作台：右侧详情+对话 */
  --scriptw: 264px;    /* 授课台：讲稿栏 */
  --panelw: 300px;     /* 授课台：出题/名单侧栏 */
  --detailh: 46%;      /* 工作台：详情区高度上限（下面是对话） */
  --mmh: 38%;          /* 教室：随堂导图高度上限（下面是提问） */
  --page-notes-height: 220px; /* 学生逐页笔记与课件之间的可拖动分隔 */
  --noteh: 52%;        /* 教室：课后笔记面板高度上限（上面是提问） */
  /* 弹幕配色按钮的颜色，由 seminar-social.js 逐个写进 style。给个默认值兜底：
     JS 没跑到时按钮至少不是透明的。 */
  --swatch: var(--brand);
}

/* 分栏拖条。6px 够手指也够鼠标；平时看不见，指上去才显出来——它是工具，
   不是装饰，不该在每一屏里都占一条线 */
.gutter { position: absolute; z-index: 6; touch-action: none; }
.gutter.left, .gutter.right { top: 0; bottom: 0; width: 7px; cursor: col-resize; }
.gutter.top, .gutter.bottom { left: 0; right: 0; height: 7px; cursor: row-resize; }
.gutter.left { left: -4px; }
.gutter.right { right: -4px; }
.gutter.top { top: -4px; }
.gutter.bottom { bottom: -4px; }
.gutter::after { content: ""; position: absolute; background: var(--brand);
                 opacity: 0; transition: opacity .15s ease; }
.gutter.left::after, .gutter.right::after { top: 0; bottom: 0; left: 3px; width: 1px; }
.gutter.top::after, .gutter.bottom::after { left: 0; right: 0; top: 3px; height: 1px; }
.gutter:hover::after { opacity: .55; }

/* The application frame stays in place; only the active tab changes. */
.workspace-shell{height:56px;min-height:56px;flex-shrink:0;position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:28px;padding:0 24px;background:var(--surface);border-bottom:1px solid var(--line)}
.workspace-shell>.brand{flex-shrink:0;min-width:90px}
.workspace-tabs{display:flex;align-items:stretch;gap:8px;height:100%;overflow-x:auto;min-width:0;scrollbar-width:thin}
.workspace-tab{display:flex;align-items:center;position:relative;flex-shrink:0;padding:0 16px;color:var(--text-dim);font-size:14px;font-weight:500;border-bottom:3px solid transparent}
.workspace-tab:hover{text-decoration:none;background:var(--surface-2);color:var(--text)}
.workspace-tab.active{color:var(--brand);background:var(--brand-soft);border-bottom-color:var(--brand);font-weight:700}
.has-workspace-shell .workspace-context{top:56px;min-height:44px;height:auto;flex-shrink:0;padding:8px 24px;box-shadow:none;background:var(--bg);backdrop-filter:none;z-index:10}
.workspace-context[hidden]{display:none!important}
.workspace-context>.brand,.workspace-context>#teachentry,.workspace-context>#libraryentry,.workspace-context>a.navlink:not([id]),.workspace-context>a[href="/teach"]:not([id]),.workspace-context>a[href="/"]:not([id]){display:none!important}
.has-workspace-shell #workspace>.toolbar{top:100px}
.has-workspace-shell .prep-sources{top:120px}
.has-workspace-shell #usermenu{top:106px}
@media(max-width:760px){.workspace-shell{gap:8px;padding:0 12px}.workspace-shell>.brand{min-width:62px}.workspace-tab{padding:0 12px}.has-workspace-shell .workspace-context{padding:8px 12px}.has-workspace-shell #workspace>.toolbar,.has-workspace-shell .prep-sources{position:static}}
body.has-workspace-shell:has(>#main){grid-template-rows:56px auto minmax(0,1fr)}

/* Common top-right account controls. */
.workspace-tabs{flex:1}.workspace-tabs>*,.workspace-back{flex:none;white-space:nowrap}
.workspace-account{display:flex;align-items:center;gap:4px;flex-shrink:0;position:relative;margin-left:auto}
.workspace-account[hidden]{display:none}
.workspace-account>#ubtn{max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.workspace-account>#paymentStatus{white-space:nowrap;font-size:12px}
.has-workspace-shell .workspace-account>#usermenu{position:absolute;top:calc(100% + 8px);right:0;min-width:190px;z-index:50}
body.has-workspace-shell.workspace-home:has(>#main){grid-template-rows:56px minmax(0,1fr)}
@media(max-width:1000px){.workspace-shell{gap:12px}.workspace-tab{padding:0 10px}.workspace-account>#ubtn{max-width:175px}}
@media(max-width:600px){.workspace-shell{flex-wrap:wrap;height:96px;min-height:96px;gap:0 8px}.workspace-shell>.brand{height:48px}.workspace-account{height:48px;flex:1 1 0;min-width:0;max-width:none;justify-content:flex-end;overflow:hidden}.workspace-account>#ubtn{max-width:120px;padding:4px;overflow:hidden;text-overflow:ellipsis}.workspace-account>#paymentStatus{max-width:130px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:4px}.workspace-tabs{order:3;flex-basis:100%;height:48px}.has-workspace-shell .workspace-context{top:96px}body.has-workspace-shell.workspace-home:has(>#main){grid-template-rows:96px minmax(0,1fr)}}

/* Library-style local navigation; collapse leaves only an opening handle. */
.has-page-rail{--outline-width:210px;--outline-space:calc(var(--outline-width) + 28px)}
.has-page-rail.rail-closed{--outline-space:52px}
.page-rail{position:fixed;left:14px;top:116px;bottom:16px;width:var(--outline-width);box-sizing:border-box;border:1px solid var(--line);border-radius:20px;background:var(--surface);z-index:9;display:flex;flex-direction:column;padding:14px;box-shadow:var(--shadow-sm)}
.page-rail-head{display:flex;align-items:center;gap:8px;margin-bottom:12px;flex-shrink:0}.page-rail-head strong{flex:1;font-size:14px}.page-rail-head button{border:0;background:var(--surface-2);padding:5px 10px;border-radius:12px}
.page-rail nav{overflow:auto;min-height:0;flex:1;scrollbar-width:thin}.page-rail nav button{display:block;width:100%;text-align:left;border:0;background:transparent;padding:10px 14px;border-radius:18px;margin:4px 0;white-space:normal;overflow-wrap:anywhere;color:var(--text-dim)}
.page-rail nav button.on{background:var(--brand-soft);color:var(--brand);font-weight:650}.page-rail summary{padding:12px 4px;font-weight:600;cursor:pointer;overflow-wrap:anywhere}.page-rail details>button{padding-left:22px}
.has-page-rail .rail-main{margin-left:var(--outline-space)!important;min-width:0}.has-page-rail>#pick{margin-right:24px}.has-page-rail>main.wrap,.has-page-rail>div.wrap{max-width:none;margin-right:24px}
.rail-closed .page-rail{width:36px;padding:7px 2px}.rail-closed .page-rail-head strong,.rail-closed .page-rail nav,.rail-closed .page-rail>.prep-sources,.rail-closed .page-rail>.gutter{display:none}.rail-closed .page-rail-head{margin:0;justify-content:center}
.has-page-rail .prep-columns{display:block}.page-rail>.prep-sources{position:static!important;flex:0 1 auto;max-height:42%;overflow:auto;border:0;border-top:1px solid var(--line);border-radius:0;padding:12px 0 0;margin-top:12px}.page-rail>.prep-sources summary{font-size:14px}.page-rail>.prep-sources .hint{font-size:12px}.page-rail>.prep-sources button{font-size:12px}
.workspace-home .page-rail{top:72px}.has-page-rail h2,.has-page-rail .lrow{scroll-margin-top:125px}
@media(max-width:1000px){.has-page-rail #main{grid-template-columns:minmax(0,1fr) minmax(240px,34%)}.has-page-rail .setup-grid{grid-template-columns:minmax(0,1fr)}.has-page-rail #room.withoutai{min-width:0}}
@media(max-width:760px){.page-rail{left:8px;top:158px;bottom:8px}.workspace-home .page-rail{top:108px}.has-page-rail:not(.rail-closed) .page-rail{z-index:25;box-shadow:var(--shadow)}.has-page-rail{--outline-space:48px}.has-page-rail>#main{grid-template-columns:minmax(0,1fr)}.has-page-rail>main.wrap,.has-page-rail>div.wrap{margin-right:8px}.has-page-rail #left{padding:12px}}

.has-page-rail #workspace>section>h2{scroll-margin-top:180px}

/* Installed windows: keep navigation and touch controls clear of device cutouts. */
@media (display-mode:standalone){
 body{padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px)}
 .workspace-shell{top:env(safe-area-inset-top,0px);padding-left:max(12px,env(safe-area-inset-left,0px));padding-right:max(12px,env(safe-area-inset-right,0px))}
 .has-workspace-shell .workspace-context{top:calc(56px + env(safe-area-inset-top,0px))}
}
@media (display-mode:standalone) and (max-width:600px){.has-workspace-shell .workspace-context{top:calc(96px + env(safe-area-inset-top,0px))}}
@media(pointer:coarse){.workspace-tab{min-height:44px}.ui-dlg button{min-height:44px}input,textarea,select{font-size:max(16px,1em)}}

/* Content slots in the shared page rail (seminar resources, approvals and roles). */
.page-rail>.page-rail-content{flex:1;min-height:0;overflow:auto;scrollbar-width:thin;overscroll-behavior:contain}
.page-rail>.page-rail-content[hidden],.rail-closed .page-rail>.page-rail-content{display:none!important}
.workspace-columns{display:grid;gap:18px;align-items:start;min-width:0}
.workspace-columns>.workspace-stage{background:var(--surface);border:1px solid var(--line);border-radius:20px;min-width:0}
.page-rail>.gutter.right{width:12px;right:-6px}

/* Visible, keyboard-accessible splitters shared by all workspaces. */
.page-rail{overflow:visible!important;max-height:none!important}
.page-rail>.gutter.right{right:0;width:12px;z-index:30}
.page-rail>.gutter.right::after{left:8px;opacity:.25;width:2px}
.gutter:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}
.gutter:hover::after,.gutter:focus-visible::after{opacity:.9}
button.icon-button{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:36px;height:36px;min-height:36px;padding:7px;border-radius:10px;color:var(--text-dim);background:transparent;border:1px solid transparent}
button.icon-button:hover,button.icon-button[aria-expanded=true]{background:var(--brand-soft);color:var(--brand)}
button.icon-button:focus-visible{outline:2px solid var(--brand)}
.rail-closed .page-rail-head button.icon-button{width:30px;padding:4px}

button.icon-button[hidden]{display:none!important}

button.icon-button[aria-pressed=true]{background:var(--brand-soft);color:var(--brand)}
#seminarMic[aria-pressed=true]{color:#b42318;background:#fee4e2}

/* Shared quiet workspace: soft tabs, light separators, independent sections. */
.workspace-tabs{align-items:center;gap:4px}
.workspace-tab{height:38px;box-sizing:border-box;border-bottom:0;border-radius:12px}
.workspace-tab.active{border-bottom:0;background:var(--brand-soft);color:var(--brand)}
.page-rail,.workspace-columns>.workspace-stage{box-shadow:none;border-color:var(--line);border-radius:20px}
.workspace-section>summary{font-weight:600;color:var(--text);cursor:pointer}
.workspace-section>summary small{font-weight:400;color:var(--text-dim)}
.workspace-section>summary:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:8px}

/* Teacher and student rooms share the same panel surfaces and split boundaries. */
body.workspace-classroom{background:var(--bg)}
body.workspace-classroom #room{gap:12px;padding:12px;box-sizing:border-box}
body.workspace-classroom #room>#boardwrap,body.workspace-classroom #room>#boardcolumn,body.workspace-classroom #room>#script,body.workspace-classroom #room>#side,body.workspace-classroom #room>#matpane,body.workspace-classroom #room>#interact{border:1px solid var(--line);border-radius:20px;background:var(--surface);box-shadow:none;min-width:0}
body.workspace-classroom #room>#boardwrap{margin:0}
body.workspace-classroom #room>#side{overflow:visible}
body.workspace-classroom #mmpane.section-closed{height:auto!important;min-height:0;flex:none}
body.workspace-classroom #mmpane.section-closed>.gutter{display:none}
body.workspace-classroom #room>.sized>.gutter.left,body.workspace-classroom #room>.sized>.gutter.right,body.workspace-classroom #room>#side>.gutter,body.workspace-classroom #room>#script>.gutter,body.workspace-classroom #room>#matpane>.gutter,body.workspace-classroom #room>#interact>.gutter{width:12px;z-index:12}
body.workspace-classroom #room>.gutter::after,body.workspace-classroom #room>*>.gutter::after{opacity:.25}
body.workspace-classroom #mmhead,body.workspace-classroom #askhead,body.workspace-classroom .speaker-heading{font-weight:600;background:var(--surface);border-bottom:1px solid var(--line)}
body.workspace-classroom #classToolbar{border-radius:16px 16px 0 0;background:var(--surface)}
@media(max-width:760px){body.workspace-classroom #room{gap:8px;padding:8px}body.workspace-classroom #room>#side{overflow:visible}}

body.workspace-classroom #mmpane,body.workspace-classroom #mmhead{border-radius:20px 20px 0 0}
body.workspace-classroom #chat,body.workspace-classroom #inbar{border-radius:0 0 20px 20px}

/* Shared panel frame: same edge, corner and header rhythm on both sides. */
.page-rail,#seminarAI,body.workspace-classroom #room>#side{border:1px solid var(--line);border-radius:20px;background:var(--surface);box-shadow:none;box-sizing:border-box}
#seminarAI{padding:14px!important}
#seminarAI>.ai-heading{min-height:40px;margin-bottom:12px;gap:8px;align-items:center}
#seminarAI>.ai-heading strong,.page-rail-head strong{font-size:14px;font-weight:650}
#seminarAI>.ai-heading button.icon-button,.page-rail-head button.icon-button{width:36px;height:36px;border-radius:12px;background:var(--brand-soft);color:var(--brand)}
#seminarAI>.gutter.left{left:0;width:12px;z-index:30}
#seminarAI>.gutter.left::after{left:1px;width:2px;opacity:.25}
.workspace-settings{max-height:88dvh;overflow:auto;box-sizing:border-box}
.workspace-settings>h2{margin:0 0 22px}
.workspace-settings>label:not(.workspace-switch-row){display:block;margin-bottom:16px}
.workspace-settings>label>select{display:block;width:100%;margin-top:8px}
.workspace-settings .workspace-switch-row{display:flex!important;align-items:center;justify-content:space-between;gap:20px;min-height:56px;margin:0;border-bottom:1px solid var(--line)}
.workspace-switch-row>span{flex:1;line-height:1.5;color:var(--text)}
input.workspace-switch{appearance:none;-webkit-appearance:none;display:block;position:relative;flex:0 0 44px;width:44px!important;min-width:44px;height:26px;margin:0;padding:0;border:1px solid var(--line-strong);border-radius:999px;background:var(--surface-3);cursor:pointer;transition:background .15s}
input.workspace-switch::before{content:'';display:block;position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:var(--surface);box-shadow:0 1px 3px #0003;transition:transform .15s}
input.workspace-switch:checked{background:var(--brand);border-color:var(--brand)}
input.workspace-switch:checked::before{transform:translateX(18px);background:white}
input.workspace-switch:focus-visible{outline:2px solid var(--brand);outline-offset:3px}
.workspace-settings-actions{display:flex;justify-content:flex-end;align-items:center;gap:12px;margin-top:20px}
.workspace-settings>.hint{line-height:1.7;margin-top:18px}
@media(prefers-reduced-motion:reduce){input.workspace-switch,input.workspace-switch::before{transition:none}}

/* Side panels share the rail's vertical bounds, independently of center toolbars. */

/* Live communication is shared between classroom and seminar adapters. */
.classroom-communication-bar{display:flex;align-items:center;gap:6px;padding:4px 12px;flex-shrink:0;
  flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin}
.classroom-communication-bar>*{flex:none}
/* 课堂里的横条一律一行、横向可滚：折行是课件区被压小的主因 */
#classToolbar,#studentPaging{flex-wrap:nowrap!important;overflow-x:auto;overflow-y:hidden;
  scrollbar-width:thin}
#classToolbar>*,#studentPaging>*{flex:none}
#classToolbar{padding-top:4px;padding-bottom:4px;gap:6px}
#classToolbar button,#studentPaging button{padding:4px 8px}
.classroom-communication-bar[hidden]{display:none!important}
.classroom-communication-bar #seminarSocial{display:flex;align-items:center;gap:6px;flex:1;min-width:260px;position:relative;margin:0}
.classroom-communication-bar #danmakuText{flex:1;min-width:80px;width:auto}.classroom-communication-bar #danmakuStatus{font-size:12px}
#classroomParticipants{flex:none;max-height:32%;overflow:auto;padding-top:10px;border-top:1px solid var(--line)}
.rail-closed #classroomParticipants{display:none}
#classroomOnlineMembers .member-row{display:flex;align-items:center;gap:6px;padding:8px 0;border-bottom:1px solid var(--line)}
#classroomOnlineMembers .member-row>span{flex:1;min-width:0;overflow-wrap:anywhere;font-size:12px}#classroomOnlineMembers .member-role{display:block;font-size:11px;color:var(--text-dim)}
#seminarDanmaku{position:absolute;inset:0;z-index:8;pointer-events:none;overflow:hidden}
.danmaku-message{position:absolute;left:100%;white-space:pre;padding:4px 10px;border-radius:8px;color:white;background:#18233bd9;font-size:18px;pointer-events:none}
#danmakuFaceList{position:absolute;bottom:100%;right:0;max-width:300px;padding:10px;background:var(--surface);border:1px solid var(--line);border-radius:12px;z-index:15;box-shadow:var(--shadow)}#danmakuFaceList button{margin:4px;padding:6px}
#seminarCaptions{position:absolute;bottom:12px;left:8%;right:8%;z-index:9;pointer-events:none;background:#142036e8;color:white;padding:10px 16px;border-radius:12px;text-align:center;font-size:18px;white-space:pre-wrap}
#seminarCaptions[hidden],#seminarDanmaku[hidden],#danmakuFaceList[hidden],#classroomParticipants[hidden]{display:none!important}
#classroomTools #seminarMic[aria-pressed=true]{color:#b42318;background:#fee4e2}
#classroomTools #seminarHand[aria-pressed=true]{background:#fff2ca;color:#845600}

.deck-uploader{display:block;margin-top:4px;color:var(--text-dim);font-size:12px;overflow-wrap:anywhere}

#seminarMic[data-muted=true] .audio-slash,#seminarSpeaker[data-muted=true] .audio-slash{stroke:var(--warn)}
#seminarMic[aria-busy=true],#seminarSpeaker[aria-busy=true]{background:var(--surface-2)}

/* Compact slide tools share one baseline without oversized form controls. */
.workspace-tools.group-toolbar{display:flex;align-items:center;flex-wrap:nowrap;gap:6px;margin:0 0 8px;padding:0;min-height:36px;overflow-x:auto;scrollbar-width:thin}
.workspace-tools>button.icon-button{width:32px;height:32px;min-height:32px;padding:6px;flex:0 0 32px}
.workspace-tools .zoom-control{display:flex;align-items:center;margin:0;flex:0 0 auto}
.workspace-tools select{width:76px!important;min-width:76px;height:32px;min-height:32px;padding:3px 6px;margin:0;font-size:13px;box-sizing:border-box}
.workspace-tools #page{min-width:44px;text-align:center;white-space:nowrap;font-size:13px;font-variant-numeric:tabular-nums}
@media(pointer:coarse){.workspace-tools>button.icon-button{width:38px;height:38px;min-height:38px;flex-basis:38px}.workspace-tools select{height:38px;min-height:38px}}

.workspace-tools>input[hidden]{display:none!important}

.member-action-menu{position:fixed;inset:auto;min-width:180px;margin:0;padding:6px;background:var(--surface);color:var(--text);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow);z-index:100}
.member-action-menu button{display:block;width:100%;text-align:left;border:0;background:transparent;padding:10px;border-radius:8px}
.member-action-menu button:hover{background:var(--brand-soft)}
.member-row[data-online=false]{opacity:.75}

#danmakuFaceList.danmaku-composer{width:min(390px,85vw);max-width:390px;max-height:360px;overflow:auto}
.danmaku-face-tabs,.danmaku-palette{display:flex;gap:4px;flex-wrap:wrap;padding-bottom:8px;border-bottom:1px solid var(--line)}
.danmaku-face-tabs button[aria-pressed=true]{color:var(--brand);background:var(--brand-soft)}
/* emoji 一个一格，密网格排；颜文字和短语长短不一，还是两列 */
/* 随堂导图：一棵会分叉的树。主干竖在左边，讲到一个知识点就从所在模块那一节
   分出一条枝——"讲到哪儿了""这几点同属一块"排成列表时得靠读字，画成枝就一眼
   看得出来。 */
.mm-tree{display:block;max-width:100%;overflow:visible}
.mm-tree .mm-trunk{stroke:var(--line-strong);stroke-width:2;fill:none;stroke-linecap:round}
.mm-tree .mm-branch{stroke:var(--line);stroke-width:1.5;fill:none}
.mm-tree .mm-trunk-dot{fill:var(--brand)}
.mm-tree text{font-size:12.5px;fill:var(--text);dominant-baseline:auto}
.mm-tree text.mm-mod{font-size:12px;font-weight:600;fill:var(--text-dim)}
.mm-tree text.mm-via{font-size:10.5px;fill:var(--text-dim)}
.mm-tree .mm-dot{fill:var(--text-dim)}
.mm-tree .mm-node.on .mm-dot{fill:var(--brand)}
.mm-tree .mm-node.on text{font-weight:600;fill:var(--brand)}
.mm-tree .mm-node.miss .mm-dot{fill:var(--warn)}
.mm-tree .mm-node.mm-jump{cursor:pointer}
.mm-tree .mm-node.mm-jump:hover text{fill:var(--brand)}
.danmaku-emoji-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(38px,1fr));gap:2px;margin:8px 0}
.danmaku-emoji-grid:empty{display:none}
#danmakuFaceList .danmaku-emoji-grid button{margin:0;padding:4px 0;font-size:20px;line-height:1.2;min-height:34px}
/* 装了开源的 Noto Color Emoji 就优先用它，各端看到的才是同一个字形；没装就退回
   设备自带的那套（都有）。不额外下发字体——完整的 Noto Color Emoji 有 10MB，
   弹幕不值得为此多拉这么多。CJK 不在 emoji 字体里，会自动落到后面的 --font。 */
.danmaku-emoji-grid button,.danmaku-message{
  font-family:"Noto Color Emoji","Twemoji Mozilla","Apple Color Emoji","Segoe UI Emoji","Noto Emoji",var(--font)}
.danmaku-face-choices{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px;margin:8px 0}.danmaku-face-choices button{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#danmakuFaceList .danmaku-palette button{width:30px;min-height:30px;height:30px;padding:0;border:3px solid var(--surface);border-radius:50%;background:var(--swatch);box-shadow:0 0 0 1px var(--line-strong)}
#danmakuFaceList .danmaku-palette button[aria-pressed=true]{box-shadow:0 0 0 2px var(--brand)}
.danmaku-anonymous{display:flex;align-items:center;gap:8px;margin-top:10px;font-size:12px}.danmaku-anonymous[hidden]{display:none!important}.danmaku-anonymous input{width:16px!important;flex:0 0 16px;margin:0}

/* Explicit dark selection also works when the operating system is light. */
  :root[data-theme="dark"] {
    --bg: #0b0f14; --surface: #151b23; --surface-2: #1b222b; --surface-3: #232b36;
    --line: #232b35; --line-strong: #36404d;
    --text: #eaeff6; --text-dim: #9dabbd; --text-faint: #6d7a8c;
    /* 语义色整体提亮：深色底上原来的深蓝/深棕几乎不可读 */
    --brand: #5b9bff; --brand-deep: #2f5fb8; --brand-hover: #7db0ff; --brand-soft: #16233a; --on-brand: #0b1220;
    --teach: #e2a33c; --teach-soft: #2a2214;
    --mark: #b795ff; --mark-soft: #221b34;
    --stage: #0e141c;
    --ok: #4ade80; --ok-soft: #12251a;
    --warn: #f87171; --warn-soft: #2a1616;
    --ink:       #e8edf5;
    --ink-red:   #f87171;
    --ink-blue:  #60a5fa;
    --ink-green: #4ade80;
    --ink-amber: #fbbf24;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.35);
    --shadow: 0 1px 2px rgba(0,0,0,.3), 0 4px 16px rgba(0,0,0,.35);
    --shadow-lg: 0 12px 40px rgba(0,0,0,.55);
  }

.danmaku-anonymous input.workspace-switch{width:44px!important;flex-basis:44px;min-width:44px}



/* Shared page chrome and bounded content for catalog/admin/read-only pages. */
.standard-page main,.standard-page .wrap,.standard-page #body,.standard-page section,.standard-page .card{min-width:0;box-sizing:border-box}
.standard-page .table-scroll{width:100%;max-width:100%;overflow:auto;overscroll-behavior:contain}
.standard-page .workspace-context{border-bottom:1px solid var(--line)}
.standard-page input,.standard-page select,.standard-page textarea{max-width:100%;box-sizing:border-box}
.standard-page .lrow{flex-wrap:wrap}.standard-page .lrow .ltitle{flex:1 1 150px;white-space:normal;overflow-wrap:anywhere}
.standard-page .actions,.standard-page .acts{flex-wrap:wrap}
.standard-page button,.standard-page a.btn{max-width:100%}
.standard-page[data-page="/assistants"] main{width:auto;min-width:0}.standard-page #assistant .grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
.standard-page[data-page="/admin"] .wrap{max-width:1120px}.standard-page[data-page="/device-check"] pre{overflow-wrap:anywhere}
@media(max-width:760px){.standard-page #assistant .grid{grid-template-columns:minmax(0,1fr)}.standard-page .wrap{padding-left:12px;padding-right:12px}.standard-page .lrow>button,.standard-page .lrow>a.btn{white-space:normal}.standard-page #body .toolbar{flex-wrap:wrap}.standard-page .library-grid{grid-template-columns:minmax(0,1fr)}}
@media print{.workspace-shell,.page-rail,.workspace-context{display:none!important}.standard-page .rail-main{margin-left:0!important}.standard-page .table-scroll{overflow:visible}}

.ui-document{width:min(900px,94vw)!important;max-width:94vw!important}.ui-document-body{max-height:65vh;overflow:auto;overflow-wrap:anywhere;line-height:1.8}.ui-document-body .katex-display{overflow:auto}.ui-document-body pre{white-space:pre-wrap}

/* Containment: shrink/wrap controls; scroll wide data inside its own region. */
.standard-page button,.standard-page a.btn{min-width:0;white-space:normal;overflow-wrap:anywhere}
.standard-page .row,.standard-page .toolbar,.standard-page .group-toolbar,.standard-page .library-actions{min-width:0;max-width:100%;overflow-wrap:anywhere}
.standard-page .row>span,.standard-page label,.standard-page .library-actions>strong{min-width:0;max-width:100%;overflow-wrap:anywhere}
.standard-page .library-actions>strong{flex:1}.standard-page .library-search>*{min-width:0}
.standard-page audio,.standard-page video,.standard-page iframe,.standard-page img{max-width:100%}
.standard-page .workspace-account button{white-space:nowrap}
.workspace-col input,.workspace-col select,.workspace-col textarea{min-width:0;max-width:100%;box-sizing:border-box}
.workspace-col button,.workspace-col .btn{max-width:100%;overflow-wrap:anywhere}
.ui-dlg .sheet,.ui-dlg .sheet>*{min-width:0;max-width:100%;box-sizing:border-box}
.ui-dlg .ui-dlg-a{flex-wrap:wrap}.ui-dlg .ui-dlg-d{overflow-wrap:anywhere}

.standard-page #assistant .row{flex-wrap:wrap}.standard-page #assistant .row>div{min-width:0;max-width:100%;flex:1 1 100%;overflow-wrap:anywhere}.standard-page #assistant .group-toolbar{flex-wrap:wrap}.standard-page #assistant .group-toolbar>label{max-width:100%;min-width:0;flex:1 1 160px}.standard-page #assistant input[type=datetime-local]{min-width:0;width:100%}

.workspace-col button,.workspace-col .btn{white-space:normal}

.standard-page :is(h1,h2,h3,p,.material-card,.ccard,.source-label){overflow-wrap:anywhere}.standard-page .workspace-context>*{min-width:0;max-width:100%}.standard-page .workspace-context #ctitle{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.standard-page .install-hero>div{min-width:0}

.standard-page .table-scroll td{overflow-wrap:anywhere;white-space:normal;max-width:340px}

.workspace-back{white-space:nowrap;min-width:68px;font-size:13px}
