/* ============================================================
   LoomRoom · base.css
   设计令牌 / 排版 / 顶栏 / 操作坞 / 通用控件 / 浮层 / 抽屉 / 纪要排版
   视觉语言 v4「INK & LAMP · 墨与灯」：默认纸色阅览室；深色是可选主题。字用系统栈。
   ============================================================ */

:root {
  /* ── v4「INK & LAMP · 墨与灯」设计令牌 ─────────────────────────────
     默认：纸色阅览室（浅色）。深色不跟系统走——默认必须是亮的；
     需要深色时给 <html data-theme="dark">（见下方同名选择器）。
     纪律：一个强调色 / 三个圆角 / 两层阴影 / 辉光归零。 */
  --bg:            #f7f5f0;
  --bg-2:          #f2efe7;
  --panel:         #ffffff;
  --panel-2:       #f4f1e9;
  --panel-3:       #ebe6da;
  --line:          #dcd5c6;
  --line-soft:     #e9e3d6;

  --text:          #1b1a17;
  --text-2:        #4c4841;
  --muted:         #6e695e;
  --faint:         #8c8678;

  /* 唯一强调色：台灯的暖琥珀（纸上要压深，才够对比度） */
  --lamp:          #a96a22;
  --lamp-soft:     rgba(168,48,30, .10);
  --lamp-line:     rgba(168,48,30, .30);
  /* 次级：音频 / 来源 */
  --cool:          #4f7a70;
  --user:          #55688c;
  --user-soft:     rgba(85, 104, 140, .10);
  --danger:        #b24a42;
  --danger-soft:   rgba(178, 74, 66, .10);
  --ok:            #45795a;
  --warn:          #8f6320;
  --violet:        #6f5f9e;

  /* 组件专用（浅色下需要一层"纸面"而不是"墨面"） */
  --avatar-bg:     #e9e4d8;
  --bar-bg:        rgba(23,20,15, .88);
  --hairline:      rgba(23,26,31, .10);
  --hairline-strong: rgba(23,26,31, .18);
  --tint:          rgba(23,26,31, .035);
  --tint-2:        rgba(23,26,31, .06);
  --scrim:         rgba(27, 25, 20, .38);

  /* 旧 HUD 令牌：保留名字（历史样式仍在引用），值全部归零 */
  --hud:           transparent;
  --hud-dim:       transparent;
  --halo:          none;
  --halo-strong:   none;
  --chamfer:       0;
  --grid-line:     transparent;

  /* 供应商色标：降饱和，只做小圆点 */
  --p-ark:         #4a6fa5;
  --p-deepseek:    #6a72a8;
  --p-minimax:     #a9685a;

  --r-sm: 4px;
  --r:    8px;
  --r-lg: 12px;

  --shadow-1: 0 1px 2px rgba(43,48,58, .12);
  --shadow-2: 0 12px 32px rgba(43,48,58, .16);
  --shadow-3: 0 32px 80px rgba(43,48,58, .20);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
          "Noto Sans SC", "HarmonyOS Sans SC", "Microsoft YaHei", sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  --dock-h: 84px;
  --head-h: 58px;
}

/* ── 可选深色主题：给 <html data-theme="dark">。默认不启用。 ──────── */
:root[data-theme="dark"] {
  --bg:            #0b0b0c;
  --bg-2:          #0e0e10;
  --panel:         #121214;
  --panel-2:       #17171a;
  --panel-3:       #1e1e22;
  --line:          #26262b;
  --line-soft:     #1c1c20;

  --text:          #ededef;
  --text-2:        #b6b6bd;
  --muted:         #8c8c94;
  --faint:         #6f6f77;

  --lamp:          #e3a15e;
  --lamp-soft:     rgba(200,68,42, .10);
  --lamp-line:     rgba(200,68,42, .32);
  --cool:          #9cb8ae;
  --user:          #9ba8c4;
  --user-soft:     rgba(155, 168, 196, .12);
  --danger:        #d9716b;
  --danger-soft:   rgba(217, 113, 107, .12);
  --ok:            #86b98f;
  --warn:          #d9a860;
  --violet:        #a79bc6;

  --avatar-bg:     #1a1a1e;
  /*
   * 2026-10-21 修：这三行原本写成「--hairline: var(--hairline)」这样的**自引用**，
   * CSS 自定义属性一旦形成依赖环就变成 guaranteed-invalid，于是深色主题里
   * 所有 hairline 边框 / tint 底色 / 顶栏背景 **全部消失**（不是"变淡"，是没有）。
   * 必须给深色主题自己的具体值。
   */
  --bar-bg:        rgba(11, 11, 12, .88);
  --hairline:      rgba(237, 237, 239, .10);
  --hairline-strong: rgba(237, 237, 239, .18);
  --tint:          rgba(237, 237, 239, .035);
  --tint-2:        rgba(237, 237, 239, .06);
  --scrim:         rgba(0, 0, 0, .55);

  --p-ark:         #6f8fbf;
  --p-deepseek:    #8b93c9;
  --p-minimax:     #c98974;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, .45);
  --shadow-2: 0 12px 32px rgba(0, 0, 0, .55);
  --shadow-3: 0 32px 80px rgba(0, 0, 0, .65);
}

* { box-sizing: border-box; }

/* hidden 属性必须永远赢过 class 上的 display（.overlay{display:flex} 会盖掉 UA 的 [hidden]） */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--fs-4);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overscroll-behavior: none;
}

body::before {
  /* 唯一的环境光：一盏灯从上方照下来，几乎看不见，但让纯黑不"死" */
  content: "";
  position: fixed; inset: 0;
  pointer-events: none;
  background: radial-gradient(1100px 520px at 50% -12%, rgba(168,48,30, .05), transparent 70%);
  z-index: 0;
}

h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: 0; }
p { margin: 0; }
button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }
kbd {
  font-family: var(--mono); font-size: var(--fs-1);
  padding: 1px 6px; border-radius: 4px;
  background: var(--panel-2); border: 1px solid var(--line);
  border-bottom-width: 2px; color: var(--muted);
}
::selection { background: rgba(168,48,30, .22); color: var(--text); }
.flex-spacer { flex: 1; }
.muted { color: var(--muted); }

/* 滚动条 */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 10px; border: 3px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--muted); background-clip: content-box; }

/* ══════════════ 骨架 ══════════════ */
.app {
  position: relative; z-index: 1;
  display: grid;
  /* 顶栏允许换行（两行式）：行高至少 --head-h，内容多时自动长高，避免子元素溢出 header 盒 */
  grid-template-rows: minmax(var(--head-h), auto) minmax(0, 1fr) auto;
  /* 显式列：否则隐式列按 max-content 撑开，窄屏会把整页顶宽 */
  grid-template-columns: minmax(0, 1fr);
  height: 100dvh;
  overflow-x: hidden;
}

/* ══════════════ 顶栏 ══════════════ */
.header {
  position: relative;
  display: flex; align-items: center; flex-wrap: wrap; gap: 12px;
  row-gap: 6px;
  padding: 0 20px;
  background: var(--bg);
  border-bottom: 1px solid var(--line-soft);
  z-index: 30;
}
.brand { display: flex; align-items: center; gap: 8px; flex: none; }
/* 主操作区（新会议 / 邀请）：DOM 顺序紧跟品牌，Tab 第一站就是它。
   这里只负责视觉间距，不用 order 改位置——位置由 DOM 决定（C12）。 */
.head-primary { display: flex; align-items: center; gap: 8px; flex: none; }
.brand-lamp {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--lamp);
}
.brand-name { font-weight: 600; letter-spacing: .02em; font-size: var(--fs-3); }
.mock-badge {
  font-size: var(--fs-1); padding: 2px 8px; border-radius: 999px;
  color: var(--muted); background: var(--panel-2); border: 1px solid var(--line-soft);
  white-space: nowrap;
}

.head-meeting { display: flex; max-width: min(560px, 42vw); min-width: 0; align-items: center; gap: 10px; min-width: 0; flex: 1; }
.meeting-title {
  font-size: var(--fs-4); font-weight: 600; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 34ch;
}
.status-badge, .round-badge {
  font-size: var(--fs-1); padding: 2px 9px; border-radius: 999px; flex: none;
  border: 1px solid var(--line-soft); color: var(--muted); background: transparent;
}
.status-badge[data-status="running"] { color: var(--lamp); border-color: var(--lamp-line); background: var(--lamp-soft); }
.status-badge[data-status="paused"]  { color: var(--warn); border-color: var(--line); background: var(--panel-2); }
.status-badge[data-status="clarifying"] { color: var(--cool); border-color: var(--line); background: var(--panel-2); }
.status-badge[data-status="ended"]   { color: var(--faint); }

.seg {
  display: flex; gap: 2px; padding: 2px; flex: none;
  background: var(--panel); border: 1px solid var(--line-soft); border-radius: var(--r);
}
.seg-btn {
  border: 0; background: transparent; color: var(--muted);
  padding: 4px 10px; border-radius: 6px; font-size: var(--fs-2);
  transition: background .15s, color .15s;
}
.seg-btn:hover { color: var(--text); background: var(--panel-2); }
.seg-btn.active { background: var(--panel-3); color: var(--text); box-shadow: none; }

.head-actions { display: flex; align-items: center; gap: 8px; flex: 1 1 100%; min-width: 0; flex-wrap: wrap; row-gap: 6px; justify-content: flex-end; }
.audio-ctl { display: flex; align-items: center; gap: 6px; padding-right: 4px; }
.volume { width: 70px; accent-color: var(--lamp); }

/*
 * 横向可滑的按钮排：左右两端各一层渐隐遮罩，滚到边缘时对应一侧淡出。
 * data-fade 由 header.js 按真实 scrollLeft 写；不依赖 CSS 猜滚动位置。
 * 用 #000 作为 alpha 通道：mask 只看透明度，颜色本身不参与渲染。
 */
.head-actions { -webkit-mask-image: none; mask-image: none; }
.head-actions[data-fade="start"] {
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 18px), transparent 100%);
  mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 18px), transparent 100%);
}
.head-actions[data-fade="end"] {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 18px, #000 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 18px, #000 100%);
}
.head-actions[data-fade="middle"] {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 18px, #000 calc(100% - 18px), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 18px, #000 calc(100% - 18px), transparent 100%);
}

/* ══════════════ 按钮 ══════════════ */
.ghost-btn, .primary-btn, .icon-btn {
  border-radius: 6px; border: 1px solid var(--line-soft);
  background: transparent; color: var(--text-2);
  padding: 6px 12px; font-size: var(--fs-2);
  transition: background .15s, color .15s, border-color .15s, transform .06s;
  white-space: nowrap;
}
.ghost-btn:hover, .icon-btn:hover { background: var(--panel-2); color: var(--text); border-color: var(--line); }
.ghost-btn:active, .primary-btn:active, .icon-btn:active { transform: translateY(1px); }
.ghost-btn.wide { width: 100%; }
.ghost-btn.danger { color: var(--danger); border-color: rgba(217,113,107,.32); }
.ghost-btn.danger:hover { background: var(--danger-soft); color: var(--danger); }
.primary-btn {
  background: var(--lamp); border-color: transparent; color: #fff; font-weight: 600;
}
.primary-btn:hover { background: var(--lamp-strong); filter: none; }
.primary-btn.big { padding: 10px 22px; font-size: var(--fs-4); letter-spacing: .02em; }
.icon-btn { padding: 5px 9px; font-size: var(--fs-3); line-height: 1.2; }
.icon-btn[aria-pressed="true"] { color: var(--lamp); border-color: var(--lamp-line); background: var(--lamp-soft); }
button:disabled { opacity: .38; cursor: not-allowed; }
.primary-btn:disabled { filter: none; }
/*
 * 键盘可用性：全站默认只有浏览器自带 1px 黑圈（深色顶栏上几乎看不见）。
 * 统一给一个 2px 主题色焦点环；局部有定制的组件（.seat / .mat-attach）优先级更高，不受影响。
 */
:focus-visible { outline: 2px solid var(--lamp); outline-offset: 2px; }

/* ══════════════ 操作坞（打断 + 插话） ══════════════ */
.dock {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--bg);
  border-top: 1px solid var(--line-soft);
  z-index: 30;
}
.interrupt-btn {
  display: flex; align-items: center; gap: 9px;
  padding: 11px 18px; flex: none;
  border-radius: var(--r); border: 1px solid rgba(217, 113, 107, .30);
  background: transparent;
  color: var(--danger); font-size: var(--fs-4); font-weight: 600;
  transition: background .15s, border-color .15s, transform .06s;
}
.interrupt-btn:hover { background: rgba(217, 113, 107, .08); border-color: rgba(217, 113, 107, .5); }
.interrupt-btn:active { transform: translateY(1px); }
.interrupt-btn.live { border-color: rgba(217, 113, 107, .6); background: rgba(217, 113, 107, .07); }
.interrupt-btn .int-icon { font-size: var(--fs-5); }
.interrupt-btn .int-kbd { opacity: .55; }

.interject-form {
  display: flex; align-items: flex-end; gap: 8px; flex: 1; min-width: 0;
  background: var(--panel); border: 1px solid var(--line-soft); border-radius: var(--r);
  padding: 6px 6px 6px 12px;
  transition: border-color .15s;
}
.interject-form:focus-within { border-color: var(--lamp-line); }
.interject-input {
  flex: 1; min-width: 0; resize: none; border: 0; background: transparent;
  outline: none; padding: 7px 0; max-height: 120px; line-height: 1.5;
}
.interject-input::placeholder { color: var(--faint); }
.send-btn {
  flex: none; border: 1px solid var(--lamp-line); border-radius: 6px;
  background: transparent; color: var(--lamp); padding: 7px 16px; font-weight: 600;
}
.send-btn:hover { background: var(--lamp-soft); }
.dock-right { display: flex; align-items: center; gap: 8px; flex: none; }

/* ══════════════ 浮层 / 模态 ══════════════ */
.overlay {
  position: fixed; inset: 0; z-index: 90;
  /*
   * 2026-10-25：align-items 从 center 改成 flex-start + 卡片 margin:auto。
   * 原因：flex 垂直居中在"卡片比视口高"时会把**上下两端同时裁掉**——
   * 用户看到的就是「标题没了、底部按钮点不到」（真机 1167×643 截图复现）。
   * margin:auto 在空间够时照样居中，空间不够时从顶部开始、整层可滚动，
   * 任何屏高都不会再把按钮顶出屏幕。
   */
  display: flex; align-items: flex-start; justify-content: center;
  overflow: auto; overscroll-behavior: contain;
  padding: 24px;
  /*
   * 窄屏（手机）时顶栏会折成 3–4 行、高度可达 ~120px，而浮层是按**视口**居中的，
   * 于是弹窗上半部分会落到顶栏底下：真机 430px 实测 #btn-nm-clarify 被 #app-header 盖住、
   * 点不到（test-zoom 因此红过一次）。这里让窄屏浮层从顶栏下方开始，并且不留滚动空隙。
   */
  /*
   * 让位给顶栏：--header-h 由 header.js 实测写入（窄屏折行后会自动变高）。
   * 必须封顶：万一测量异常（或顶栏在某些状态下异常高），过大的 padding 会把弹窗推出视口，
   * 变成"按钮在屏幕外"——比被顶栏盖住更难查。30dvh 是安全上限。
   */
  padding-top: min(calc(var(--header-h, 72px) + 12px), 30dvh);
  background: var(--scrim);
  animation: fadein .18s ease-out;
}
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
@keyframes rise { from { opacity: 0; transform: translateY(14px) scale(.985); } to { opacity: 1; transform: none; } }
.modal-card, .clarify-card {
  width: min(720px, 100%);
  max-height: min(88dvh, 900px);
  margin: auto;
  flex: 0 0 auto;
  overflow: auto;
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
  padding: 24px 26px;
  animation: rise .22s cubic-bezier(.2,.8,.3,1);
}
/*
 * 窄屏：顶栏会折行变高（430px 时约 110–130px），浮层必须从它下面开始，
 * 否则弹窗顶部的按钮会被顶栏压住、点不到（真机实测 #btn-nm-clarify）。
 * 用 dvh + 明确的让位高度，避免"居中后一半在顶栏底下"。
 */
@media (max-width: 640px) {
  .modal-card, .clarify-card { max-height: calc(100dvh - min(calc(var(--header-h, 96px) + 12px), 30dvh) - 24px); }
}
/* 程序化聚焦到容器（dialog 自身）时不要画焦点环：环只属于可交互元素 */
.clarify-card:focus,
.modal-card:focus,
.clarify-card:focus-visible,
.modal-card:focus-visible,
#v5-panel:focus,
#v5-panel:focus-visible { outline: none; }
.modal-card.small { width: min(420px, 100%); }
.modal-card h2, .clarify-card h2 { font-size: var(--fs-6); margin-bottom: 4px; }
.modal-foot { display: flex; align-items: center; gap: 10px; margin-top: 20px; }

/* ══════════════ 表单 ══════════════ */
.field { display: flex; flex-direction: column; gap: 6px; margin-top: 14px; }
.field-label { font-size: var(--fs-2); color: var(--text-2); display: flex; align-items: center; gap: 6px; }
.field-label .req { color: var(--lamp); font-style: normal; font-size: var(--fs-1); }
.field-label .hint { color: var(--faint); font-size: var(--fs-1); font-style: normal; }
.field-row { display: flex; gap: 12px; }
.field-row > .field { flex: 1; }
.input {
  background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 6px;
  padding: 9px 11px; outline: none; width: 100%;
  transition: border-color .15s;
}
.input:focus { border-color: var(--lamp-line); }
textarea.input, textarea.textarea { resize: vertical; line-height: 1.6; font-family: inherit; }
select.input { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%); background-position: calc(100% - 16px) 52%, calc(100% - 11px) 52%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 30px; }
.inline-form { display: flex; gap: 8px; align-items: center; }
.inline-form .input { flex: 1; }
.stack-form { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }
/* C6：登录 / 改密的错误行。用 --danger 而不是红块，不抢镜但看得见；
   role=alert 已在 DOM 上，读屏用户同样能听到（不依赖颜色）。 */
.auth-error { color: var(--danger); font-size: var(--fs-2); line-height: 1.5; margin: 0; }
.radio { display: flex; align-items: center; gap: 6px; font-size: var(--fs-3); color: var(--text-2); }
.range-row { display: flex; align-items: center; gap: 10px; }
.range-row input[type=range] { flex: 1; accent-color: var(--lamp); }
.range-row .val { font-family: var(--mono); font-size: var(--fs-2); color: var(--muted); min-width: 4ch; text-align: right; }
.check-list { display: flex; flex-wrap: wrap; gap: 6px 12px; }
.check-list label { display: flex; align-items: center; gap: 6px; font-size: var(--fs-3); color: var(--text-2); }
input[type=checkbox] { accent-color: var(--lamp); }

/* ══════════════ 抽屉 ══════════════ */
.drawer-scrim { position: fixed; inset: 0; z-index: 70; background: var(--scrim); animation: fadein .16s; }
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 80;
  width: min(520px, 94vw);
  display: flex; flex-direction: column;
  background: var(--bg);
  border-left: 1px solid var(--line-soft);
  box-shadow: -24px 0 60px rgba(0, 0, 0, .55);
  animation: slidein .22s cubic-bezier(.2,.8,.3,1);
}
@keyframes slidein { from { transform: translateX(24px); opacity: .4; } to { transform: none; opacity: 1; } }
.drawer-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 16px 20px; border-bottom: 1px solid var(--line-soft); flex: none;
}
/*
 * 标题不许被右侧按钮挤成"竖排"：375px 实测「会议纪要」+ 复制/下载/打印/会议包/关闭
 * 五个控件时，h2 被压到 ~20px，四个字各占一行（截图）。给一个最小宽度，
 * 空间不够就让 actions 整体换到下一行（actions 自己也能再换行）。
 */
.drawer-head h2 { font-size: var(--fs-4); font-weight: 600; flex: 1 1 auto; min-width: 7em; }
.drawer-head-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* 换行后关闭按钮仍靠右（375px：操作按钮排两行时 ✕ 掉到左下角，很难找） */
.drawer-head-actions .drawer-close { margin-left: auto; }
.drawer-body { flex: 1; overflow: auto; padding: 20px; }
.panel-sep { height: 1px; background: var(--line-soft); margin: 18px 0; }

/* ══════════════ Toast ══════════════ */
/* 2026-10-21：挪到左下角。原来底部居中，会盖住弹窗页脚的主按钮（实测遮挡「开始会议」）。 */
.toasts {
  position: fixed; left: 24px; bottom: calc(var(--dock-h) + 18px);
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  max-width: min(420px, calc(100vw - 48px));
  z-index: 200; pointer-events: none;
}
.toast {
  background: var(--panel-3); border: 1px solid var(--line-soft); color: var(--text);
  padding: 9px 16px; border-radius: 8px; font-size: var(--fs-3);
  box-shadow: var(--shadow-2); animation: toastin .2s ease-out;
  max-width: 70vw;
}
/* 2026-10-28：三种 toast 原来直接用状态色当文字（--ok #16A34A 在白底只有 3.4:1，--lamp 压暖底更低），
   改用各自的「文字级」加深色；旧主题没有 *-strong 时回落到原色。 */
.toast[data-kind="warn"] { border-color: rgba(168,48,30, .30); color: var(--warn-strong, var(--warn, var(--lamp))); background: rgba(168,48,30, .12); }
.toast[data-kind="error"] { border-color: rgba(217, 113, 107, .32); color: var(--danger); background: rgba(178, 74, 66, .12); }
.toast[data-kind="ok"] { border-color: rgba(69, 121, 90, .30); color: var(--ok-strong, var(--ok)); background: rgba(69, 121, 90, .10); }
.toast.out { animation: toastout .25s ease-in forwards; }
@keyframes toastin { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes toastout { to { opacity: 0; transform: translateY(8px); } }

/* ══════════════ 极简 markdown 渲染 ══════════════ */
.md-body { font-size: var(--fs-4); line-height: 1.75; color: var(--text-2); }
.md-body h1 { font-size: var(--fs-6); margin: 4px 0 10px; color: var(--text); }
.md-body h2 { font-size: var(--fs-5); margin: 20px 0 8px; color: var(--text); border-left: 3px solid var(--lamp); padding-left: 9px; }
.md-body h3 { font-size: var(--fs-4); margin: 16px 0 6px; color: var(--muted); }
.md-body p { margin: 8px 0; }
.md-body ul, .md-body ol { margin: 8px 0; padding-left: 22px; }
.md-body li { margin: 3px 0; }
.md-body li::marker { color: var(--lamp); }
.md-body strong { color: var(--text); }
.md-body em { color: var(--text-2); }
.md-body code { font-family: var(--mono); font-size: var(--fs-2); background: var(--panel); border: 1px solid var(--line-soft); padding: 1px 5px; border-radius: 5px; color: var(--lamp); }
.md-body pre { background: var(--panel); border: 1px solid var(--line-soft); border-radius: var(--r-sm); padding: 12px; overflow: auto; }
.md-body pre code { border: 0; background: transparent; color: var(--text-2); padding: 0; }
.md-body blockquote { margin: 10px 0; padding: 6px 12px; border-left: 3px solid var(--line); color: var(--muted); background: var(--tint); }
.md-body hr { border: 0; border-top: 1px solid var(--line-soft); margin: 16px 0; }
.md-body a { color: var(--cool); }
.md-body table { border-collapse: collapse; width: 100%; margin: 10px 0; font-size: var(--fs-3); }
.md-body th, .md-body td { border: 1px solid var(--line-soft); padding: 6px 9px; text-align: left; }
.md-body th { background: var(--panel-2); color: var(--text); }

.keys { list-style: none; padding: 0; margin: 14px 0 0; display: flex; flex-direction: column; gap: 10px; }
.keys li { display: flex; align-items: center; gap: 12px; font-size: var(--fs-3); color: var(--text-2); }
.keys kbd { min-width: 52px; text-align: center; }

.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* ══════════════ 响应式：窄屏圆桌退化为列表 ══════════════ */
@media (max-width: 1080px) {
  .mode-hint { display: none; }
  .meeting-title { max-width: 20ch; }
}
@media (max-width: 900px) {
  .app { grid-template-rows: auto minmax(0, 1fr) auto; }
  .header { flex-wrap: wrap; height: auto; padding: 6px 10px; gap: 6px; }
  /* 手机顶栏太占屏（审计 C10：191px / 47% 被 chrome 吃掉）：
     模式选择在底部 dock 的「模式」弹层里仍有，所以顶栏的模式分段在窄屏隐藏。 */
  #mode-seg { display: none !important; }
  .head-meeting { order: 3; flex-basis: 100%; }
  .seg { order: 4; flex-basis: 100%; overflow-x: auto; }
  .head-actions { margin-left: auto; }
  /* 顶栏按钮在窄屏是横向可滑的；左右两端的渐隐提示由 header.js 按**真实 scrollLeft**切换
     （data-fade=start / middle / end）：滚到哪一端，哪一端的遮罩就消失。
     纯 CSS 的固定单边遮罩会在已经滚到底时继续暗示"还有内容"，是假线索。
     可滑容器本身在文件末尾的 @media (max-width:900px) 里统一声明，这里不重复。 */
  .dock { flex-wrap: wrap; gap: 8px; }
  .interject-form { order: 3; flex-basis: 100%; }
  .interrupt-btn { flex: 1; justify-content: center; }
  .dock-right { flex: 1; justify-content: flex-end; }
  .meeting-title { max-width: none; }
}
@media (max-width: 640px) {
  .head-actions { flex-wrap: wrap; justify-content: flex-end; row-gap: 4px; }
  /*
   * 触控目标：iOS HIG / Material 都要求 ≥44px，而窄屏顶栏原来只有 ~32px（实测 430px 下
   * 连 11 个按钮挤在一起，手指极容易点错 —— 这是交接文档里的 P1）。
   * 只提高度/getBoundingClientRect 可量；宽度靠 padding 自然变宽，不硬撑。
   */
  .head-actions .ghost-btn, .head-actions .primary-btn,
  .head-primary .ghost-btn, .head-primary .primary-btn { min-height: 44px; padding: 10px 11px; font-size: var(--fs-2); }
  .head-actions .icon-btn, .head-primary .icon-btn, #mute-toggle { min-width: 44px; min-height: 44px; }
  .head-actions .volume { width: 46px; height: 44px; }
  #mode-seg .seg-btn { min-height: 44px; padding: 10px 12px; }
  /* 抽屉关闭按钮同理（窄屏上点 ✕ 也不该靠运气） */
  .drawer-close { min-width: 44px; min-height: 44px; }
  .meeting-title { font-size: var(--fs-4); }
  .int-kbd { display: none; }
  .int-text { white-space: nowrap; }
  .seat-actions { font-size: var(--fs-2); padding: 6px 8px; gap: 6px; }
  .clarify-card, .modal-card { padding: 16px 14px; }
  .dock { padding: 10px 12px calc(10px + env(safe-area-inset-bottom, 0px)); }
}

@media (max-width: 420px) {
  /*
   * 375：品牌 + 主操作必须挤在同一行 —— 主操作一旦被挤到下一行，44px 就直接从
   * 发言流里扣（375×812 实测 transcript 只剩 30px）。品牌允许被压缩：
   * 生产环境没有「演示模式」徽标，本来就放得下；只有 mock 徽标会占掉 ~110px。
   */
  .brand { flex: 0 1 auto; min-width: 0; max-width: 185px; overflow: hidden; }
  .brand-name, .brand .mock-badge { white-space: nowrap; }
  /* mock 徽标缩一号，正好不撑破 185px（生产环境没有它，不受影响） */
  .brand .mock-badge { font-size: var(--fs-1); padding: 1px 6px; }
  .head-primary { flex: none; }
}

/* ══════════════ 会中「发资料」══════════════
   入口放在插话框里（📎）而不是底部控制条：窄屏 dock 已经挤到极限，
   再加一格会把「打断/举手/结束」挤出去。资料模态复用 .modal-card 基线样式。 */
.mat-attach {
  /* 触控目标 ≥44px：这是用户明确提过的 P1（手指在 430px 上点不中） */
  flex: none; align-self: center; border: 0; background: transparent;
  color: var(--muted); font-size: var(--fs-4); line-height: 1;
  min-width: 44px; min-height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px; cursor: pointer;
  transition: background .15s, color .15s, opacity .15s;
}
.mat-attach:hover, .mat-attach:focus-visible { background: rgba(200,68,42,.14); color: var(--lamp); outline: none; }
.mat-attach[disabled] { opacity: .4; cursor: default; background: transparent; }

#table-hub .hub-materials {
  font-size: var(--fs-1); line-height: 1.6; padding: 1px 8px 2px; border-radius: 999px;
  color: var(--lamp); background: rgba(200,68,42,.12);
  border: 1px solid rgba(200,68,42,.34);
  white-space: nowrap; max-width: 108px; overflow: hidden; text-overflow: ellipsis;
}

.mat-card { width: min(620px, 100%); }
.mat-file-row { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.mat-file-name { font-size: var(--fs-2); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mat-status {
  margin-top: 12px; padding: 9px 11px; border-radius: var(--r-sm);
  font-size: var(--fs-2); line-height: 1.6;
  border: 1px solid var(--line); background: var(--tint); color: var(--text-2);
}
.mat-status[data-kind="ok"] { border-color: rgba(70,245,170,.4); background: rgba(70,245,170,.09); color: var(--ok); }
.mat-status[data-kind="warn"] { border-color: rgba(80,235,255,.45); background: rgba(80,235,255,.1); color: var(--lamp); }
.mat-status[data-kind="error"] { border-color: rgba(255,77,109,.45); background: rgba(255,77,109,.1); color: var(--danger); }
.mat-status .mat-warn-list { margin: 6px 0 0; padding-left: 18px; }

/* ══════════════ 澄清卡片：会前背景/资料（可选，不拷问用户）══════════════ */
.clarify-bg {
  margin: 12px 0 4px;
  padding: 10px 12px;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
  background: var(--tint);
}
.clarify-bg-label {
  display: flex; align-items: baseline; gap: 8px;
  font-size: var(--fs-2); color: var(--text-2); margin-bottom: 6px;
}
.clarify-bg-label em { font-style: normal; font-size: var(--fs-1); color: var(--muted); }
.clarify-bg .input { width: 100%; }
.clarify-bg-actions { display: flex; align-items: center; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.clarify-bg-hint { font-size: var(--fs-1); color: var(--faint); }
.clarify-bg-actions .ghost-btn { min-height: 36px; }

/* 首屏连接提示（P1-3）：探测后端期间不要"页面像坏了" */
#boot-hint {
  position: fixed; left: 50%; top: 12px; transform: translateX(-50%);
  z-index: 400; padding: 6px 14px; border-radius: 999px;
  font-size: var(--fs-2); color: var(--text-2);
  background: var(--panel); border: 1px solid var(--line-soft);
}
#boot-hint::after { content: ''; display: inline-block; width: 6px; height: 6px; margin-left: 8px; border-radius: 50%; background: var(--accent); animation: boot-blink 1s ease-in-out infinite; }
@keyframes boot-blink { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }

/* ══════════════ 顶栏「更多」菜单（审计 C01：901–1463px 顶栏溢出被裁）══════════════ */
.head-more-menu {
  /* 顶栏现在是两行式，菜单必须相对 header 定位；用 --head-h 会压在操作行上（点不到按钮） */
  position: absolute; top: calc(100% + 4px); right: 16px; z-index: 60;
  display: flex; flex-direction: column; gap: 4px;
  padding: 8px; min-width: 132px;
  border: 1px solid var(--line-soft); border-radius: var(--r-sm, 10px);
  background: var(--panel-2); box-shadow: 0 16px 40px rgba(0, 0, 0, .55);
}
.head-more-menu[hidden] { display: none !important; }
.head-more-menu .ghost-btn { justify-content: flex-start; min-height: 40px; padding: 8px 12px; font-size: var(--fs-2); }
@media (max-width: 900px) {
  .head-more-menu { right: 12px; top: auto; margin-top: 0; position: fixed; top: 8px; right: 12px; }
  /* 窄屏：顶栏与模式行允许横向滑动，保证每个入口都"够得着"（审计 C10） */
  .header { overflow: visible; }
  .head-actions { overflow-x: auto; flex-wrap: nowrap; max-width: 100%; padding-bottom: 2px; scrollbar-width: none; }
  .head-actions::-webkit-scrollbar { display: none; }
  .head-actions > * { flex: none; }
}

/* W1：产出页反馈（👍/👎 + 原因 chips + 漏点）——一屏一票，不弹表单 */
.outcome-feedback {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 12px; padding-top: 10px; border-top: 1px dashed rgba(0, 0, 0, .12);
  font-size: var(--fs-3);
}
.outcome-feedback .fb-q { color: #666; }
.outcome-feedback .fb-btn,
.outcome-feedback .fb-chip,
.outcome-feedback .fb-missed {
  cursor: pointer; border: 1px solid #d9d9e0; background: #fff; color: #222;
  border-radius: 14px; padding: 4px 11px; font-size: var(--fs-3); line-height: 1.3;
}
.outcome-feedback .fb-btn:hover,
.outcome-feedback .fb-chip:hover,
.outcome-feedback .fb-missed:hover { border-color: var(--user); background: var(--text); }
.outcome-feedback .fb-btn.is-active { background: var(--text-2); border-color: var(--user); }
.outcome-feedback .fb-btn:disabled,
.outcome-feedback .fb-missed:disabled { opacity: .72; cursor: default; }
.outcome-feedback .fb-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.outcome-feedback .fb-chip.is-ghost { border-style: dashed; color: #888; }
.outcome-feedback .fb-missed { border-style: dashed; }
.outcome-feedback .fb-missed.is-done { border-color: var(--user); color: var(--user); }
.outcome-feedback .fb-thanks { color: #666; font-size: var(--fs-2); }

/*
 * B3 反馈闸门：一行、贴底、不遮正文。
 * 只用一行是因为它要"顺手可答"——一旦变成一块面板，就等于把底部的评价块搬了个家。
 */
.fb-gate {
  position: fixed;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: calc(100vw - 24px);
  padding: 8px 10px 8px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--panel);
  box-shadow: var(--shadow);
}
.fb-gate-q { white-space: nowrap; color: var(--text-2); font-size: var(--fs-2); }
.fb-gate .fb-btn { padding: 4px 10px; white-space: nowrap; }
.fb-gate-x {
  margin-left: 2px;
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--faint);
  cursor: pointer;
  line-height: 1;
}
.fb-gate-x:hover { background: var(--panel-2); color: var(--text-2); }
@media (max-width: 520px) {
  .fb-gate { gap: 6px; padding: 7px 8px 7px 12px; }
  .fb-gate-q { font-size: var(--fs-1); }
}

/* W2：新会议浮层「听会模式」开关（v5.1 起默认开；取消勾选才是纯文字） */
.nm-listen-field .nm-listen-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--fs-3);
  color: var(--fg-2, var(--text-2));
}
.nm-listen-field .nm-listen-row input[type='checkbox'] {
  width: 16px;
  height: 16px;
  accent-color: var(--accent, var(--lamp));
}
.nm-listen-hint {
  display: block;
  margin: 3px 0 0 24px;
  font-size: var(--fs-1);
  line-height: 1.5;
  color: var(--faint);
}

/* W3：新建会议「场景」选择（三段模板）
   2026-10-23：场景增到 7 个后，横向不换行会把「认识一下」挤出可视区（真机踩到）。
   场景是选择器，不是轮播：允许换行，让第 7 个也看得见。 */
#nm-scenarios { flex-wrap: wrap; max-width: 100%; }
#nm-scenarios .seg-btn { min-width: 96px; }
@media (max-width: 640px) {
  #nm-scenarios .seg-btn { min-width: 0; flex: 1 1 30%; }
}
#nm-scenario-hint { min-height: 1.2em; }

/* W4：决策档案 + 7 天回访（纪要面板） */
.decision-archive {
  margin: 12px 0 4px;
  padding: 10px 12px;
  border: 1px solid rgba(200,68,42,.22);
  border-radius: 10px;
  background: var(--panel-2);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.decision-archive .dec-head { font-size: var(--fs-2); color: var(--lamp); width: 100%; }
.decision-archive .dec-hint { font-size: var(--fs-2); }
.decision-archive .dec-revisit { font-size: var(--fs-2); }
.decision-archive .dec-revisit.ok { color: var(--ok); }
.decision-archive .dec-revisit.dropped { color: var(--danger); }

/* W4：记忆面板「我的记忆（三容器）」 */
.mem-modebar { display: flex; gap: 8px; padding: 8px 12px 4px; flex-wrap: wrap; }
.owner-sec-head { margin: 14px 0 6px; font-size: var(--fs-3); font-weight: 600; color: var(--lamp); }
.owner-sec-head .muted { font-weight: 400; font-size: var(--fs-1); }
.mem-type[data-t="profile"] { color: var(--lamp); }
.mem-type[data-t="topic"] { color: #8ab4e0; }
.mem-type[data-t="session"] { color: #9fd0a0; }
.mem-type[data-t="decision"] { color: var(--violet); }
.mem-ok { color: var(--ok); }
.mem-dropped { color: var(--danger); }
/* ══════════════ 键盘焦点（可访问性） ══════════════ */
/*
 * 2026-10-21：全站此前几乎只有 :hover、没有 :focus-visible —— 键盘/读屏用户
 * 看不出焦点在哪（.input / .interject-input 还显式 outline:none）。
 *
 * 基础描边由上面第 264 行的全局 :focus-visible 统一给（那一处是并行 QA 分支加的，
 * 覆盖面更广，保留）；这里只补两件它管不到的事：
 *   ① 输入框改用软环，避免和 1px 边框叠加成双线；
 *   ② 深色主题下灯色更亮，环要更淡，否则像一块光斑。
 */
.input:focus-visible, .dc-input:focus-visible, textarea.input:focus-visible, .interject-input:focus-visible {
  outline: none;
  border-color: var(--lamp-line);
  box-shadow: 0 0 0 3px var(--lamp-soft);
}
/* 深色主题下灯色更亮，软环要跟着变淡，否则像一块光斑 */
:root[data-theme="dark"] .input:focus-visible,
:root[data-theme="dark"] .dc-input:focus-visible,
:root[data-theme="dark"] .interject-input:focus-visible {
  box-shadow: 0 0 0 3px rgba(200,68,42, .18);
}
