:root {
  font-family: Inter, "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
  font-synthesis: none;
}

/* Unified business sections and independent AI view */
.ai-sidebar-entry { width: 100%; margin: 10px 0 12px; padding: 10px 11px; border: 1px solid color-mix(in srgb, #04685b 50%, var(--line)); border-radius: 12px; background: color-mix(in srgb, #87c9c3 18%, var(--surface)); color: #04685b; display: flex; align-items: center; gap: 9px; font-weight: 750; cursor: pointer; }
.ai-sidebar-entry[aria-current="page"] { box-shadow: inset 0 0 0 2px #04685b; }
.ai-sidebar-mark { width: 27px; height: 27px; display: grid; place-items: center; border-radius: 8px; background: #04685b; color: #fff; font-size: 11px; }
.ai-mode .person-actions > * { display: none; }
.ai-mode .business-panel, .ai-mode #custom-business-sections { display: none !important; }
.content-area > .ai-panel { display: none; }
.ai-mode .content-area > .ai-panel { display: block; }

/* ══ 推送管理视图（仅管理员） ══
   与 ai-mode 同一套「进入视图」机制：进入推送视图时隐藏业务面板与 AI 面板，
   反之亦然（JS 侧保证两者互斥）。 */
.content-area > .push-panel { display: none; }
.push-mode .content-area > .push-panel { display: block; }
/* 互斥必须是**双向**的：JS 里两个 setXxxMode 各自退出对方，这里再加一道 CSS 兜底。
   少了这条，只要有任何一条 JS 路径漏了移除 push-mode，两个面板就会同时显示。 */
.ai-mode .content-area > .push-panel { display: none !important; }
.push-mode .person-actions > * { display: none; }
.push-mode .business-panel,
.push-mode #custom-business-sections,
.push-mode .ai-panel { display: none !important; }

.push-sidebar-entry { width: 100%; margin: 0 0 12px; padding: 10px 11px; border: 1px solid color-mix(in srgb, #185fa5 50%, var(--line)); border-radius: 12px; background: color-mix(in srgb, #85b7eb 18%, var(--surface)); color: #185fa5; display: flex; align-items: center; gap: 9px; font-weight: 750; cursor: pointer; }
.push-sidebar-entry[aria-current="page"] { box-shadow: inset 0 0 0 2px #185fa5; }
.push-sidebar-mark { width: 27px; height: 27px; display: grid; place-items: center; border-radius: 8px; background: #185fa5; color: #fff; font-size: 11px; }
/* ★ [hidden] 不等于隐藏：作者样式里的 display:flex 会盖掉 UA 的 [hidden] 规则，
   必须显式补一条，否则「仅管理员可见」的入口会对所有人显示。 */
.push-sidebar-entry[hidden] { display: none; }

.push-workspace[hidden], .push-denied[hidden], .push-pane[hidden] { display: none; }
.push-denied { padding: 16px 18px; border-radius: 12px; background: color-mix(in srgb, #e24b4a 12%, var(--surface)); color: #791f1f; }

.push-tabs { display: flex; gap: 8px; margin: 0 0 14px; flex-wrap: wrap; }
.push-tab { padding: 7px 14px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--ink); cursor: pointer; font-weight: 650; }
.push-tab.is-current { border-color: #185fa5; color: #185fa5; box-shadow: inset 0 0 0 1px #185fa5; }

.push-compose { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(260px, 0.85fr); gap: 18px; align-items: start; }
.push-form, .push-target-form { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.push-field { display: flex; flex-direction: column; gap: 6px; font-weight: 650; }
.push-field input, .push-field select, .push-field textarea { font: inherit; font-weight: 400; padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--ink); }
.push-field textarea { resize: vertical; min-height: 150px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.push-form-note, .push-form-hint, .push-history-meta, .push-target-meta, .push-empty { font-weight: 400; color: color-mix(in srgb, var(--ink) 62%, transparent); }
.push-form-note { margin: 0; }

.push-picker { border: 1px solid var(--line); border-radius: 12px; padding: 8px 12px 12px; }
.push-picker legend { font-weight: 650; padding: 0 6px; }
.push-target-options, .push-tag-options { display: flex; flex-wrap: wrap; gap: 8px; }
.push-chip { display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--ink); cursor: pointer; font-weight: 500; }
.push-chip.is-on { border-color: #185fa5; color: #185fa5; background: color-mix(in srgb, #85b7eb 16%, var(--surface)); }
.push-chip input { margin: 0; }

.push-form-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.push-target-form { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line); }

.push-preview { border: 1px solid var(--line); border-radius: 12px; padding: 12px; background: color-mix(in srgb, var(--ink) 3%, var(--surface)); position: sticky; top: 12px; min-width: 0; }
.push-preview-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.push-preview-body { white-space: pre-wrap; word-break: break-word; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; line-height: 1.6; max-height: 440px; overflow: auto; }
.push-preview-body table { border-collapse: collapse; width: 100%; /* 容器是 pre-wrap，表格里必须还原，否则每格文字会带着源文本缩进错行 */ white-space: normal; font-family: inherit; }
.push-preview-body th, .push-preview-body td { border: 1px solid var(--line); padding: 4px 8px; text-align: left; vertical-align: top; }
.push-preview-body th { background: color-mix(in srgb, var(--ink) 6%, var(--surface)); font-weight: 650; }

.push-history-item, .push-target-item { border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; margin-bottom: 10px; }
.push-history-head, .push-target-head { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.push-history-results { margin-top: 8px; font-weight: 400; }
.push-status { padding: 2px 8px; border-radius: 999px; font-size: 12px; font-weight: 650; }
.push-status.is-sent { background: color-mix(in srgb, #1d9e75 18%, var(--surface)); color: #0f6e56; }
.push-status.is-failed { background: color-mix(in srgb, #e24b4a 16%, var(--surface)); color: #791f1f; }
.push-status.is-pending { background: color-mix(in srgb, #ef9f27 20%, var(--surface)); color: #854f0b; }

/* 「引用成员周报」 */
.push-ref-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.push-ref-bar input[type="search"] { flex: 1 1 160px; min-width: 0; font: inherit; font-weight: 400; padding: 6px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--ink); }
.push-mini { padding: 5px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink); cursor: pointer; font-weight: 600; }
/* 名单可能上百人，限高滚动避免把整个表单撑长 */
.push-ref-list { display: flex; flex-wrap: wrap; gap: 8px; max-height: 180px; overflow: auto; }
.push-ref-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
/* 模块勾选区：每个周报模块（本周 / 下周 / 待支援 / 自定义）一个开关，
   由 JS 依据当周实际板块动态生成 —— 自定义板块因此能自动出现，无需改代码。 */
.push-ref-fields { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; flex: 1 1 100%; }
.push-ref-field { display: inline-flex; align-items: center; gap: 6px; font-weight: 500; }
.push-ref-field input { margin: 0; }
/* 无数据的模块：仍然可见（用户要能看出「这个板块存在但这周没人填」），
   但明确置灰并说明原因，而不是静默消失让人以为功能漏了板块。 */
.push-ref-field.is-empty { color: #8a8f98; font-weight: 400; }
.push-ref-field .push-ref-empty-note { font-size: 12px; opacity: 0.85; }
.push-ref-fields-empty { color: #8a8f98; font-size: 13px; }
/* 引用图片预览（插入后即时展示，用户能确认真实效果而不是盲发） */
.push-ref-image-preview { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.push-ref-image-item { border: 1px solid #e3e6ea; border-radius: 6px; padding: 8px; background: #fafbfc; }
.push-ref-image-item[hidden] { display: none; }
.push-ref-image-item img { max-width: 100%; height: auto; display: block; border: 1px solid #eceef1; }
.push-ref-image-caption { font-size: 12px; color: #5c6270; margin-bottom: 6px; }

/* 周期推送 */
.push-rec-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.push-rec-row + .push-rec-row { margin-top: 10px; }
.push-rec-row select,
.push-rec-row input[type="time"] { font: inherit; font-weight: 400; padding: 5px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink); }

/* 周报「填写提醒」配置面板 */
.push-reminder { display: flex; flex-direction: column; gap: 12px; }
.push-reminder-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.push-reminder-bar .push-form-hint { margin: 0; }
.push-switch { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.push-switch input { width: 16px; height: 16px; margin: 0; }
/* 星期是 7 个复选框，横向排布在窄屏会挤成两行 —— 允许换行而不是压缩到看不清 */
.push-weekday-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.push-reminder-status-box { padding: 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); display: flex; flex-direction: column; gap: 4px; }
.push-reminder-status-box p { margin: 0; }
/* 未提交名单可能很长：限高滚动 + 允许长词换行，避免一串姓名把布局撑破 */
.push-reminder-pending { max-height: 120px; overflow: auto; line-height: 1.7; overflow-wrap: anywhere; }
#push-reminder-mention-hint { margin: 6px 0 0; }

@media (max-width: 980px) {
  .push-compose { grid-template-columns: minmax(0, 1fr); }
  .push-preview { position: static; }
}
.business-panel { --section-color: #87c9c3; --section-ink: #202020; --section-soft-color: color-mix(in srgb, var(--section-color) 34%, var(--surface)); position: relative; }
.panel.business-panel { overflow: hidden; }
.business-panel[hidden] { display: none !important; }
/* 主色竖条：必须低于表格 sticky 列（z-index 2），否则横向滚动时会盖住首列 */
.business-panel::before { content: ""; position: absolute; z-index: 1; left: 0; top: 0; bottom: 0; width: 8px; background: var(--section-color); pointer-events: none; }
.business-panel .panel-topbar { display: flex; align-items: center; background: var(--surface); transition: background-color .18s ease; }
.business-panel .panel-head { flex: 1 1 auto; min-width: 0; width: auto; padding-left: 18px; background: transparent; color: inherit; }
.business-panel .panel-topbar > .table-tools { flex: 0 0 auto; padding: 8px 11px 8px 4px; background: transparent; border: 0; }
.business-panel .panel-topbar .edit-hint { display: none; }
.business-panel:not(.open) .panel-topbar > .table-tools { display: none; }
.business-panel:not(.open) .panel-topbar { width: 100% !important; max-width: 100% !important; }
.business-panel.open .panel-topbar { background: var(--section-color); color: var(--section-ink); }
.business-panel.open .panel-count,
.business-panel.open .panel-tip,
.business-panel.open .panel-retention,
.business-panel.open .chevron { color: color-mix(in srgb, var(--section-ink) 72%, transparent); }
.business-panel.open .panel-topbar .tool-button { color: var(--section-ink); background: color-mix(in srgb, var(--surface) 78%, var(--section-color)); border-color: color-mix(in srgb, var(--section-ink) 24%, transparent); }
.business-panel.open .panel-topbar .tool-button:hover { background: color-mix(in srgb, var(--surface) 90%, var(--section-color)); }
.business-panel .group-heading { background: var(--section-color) !important; color: var(--section-ink) !important; }
.business-panel .field-heading, .business-panel .project-column-row th { background: var(--section-soft-color) !important; color: var(--ink) !important; }
.business-panel.is-dragging { opacity: .45; }
.is-editing .business-panel .panel-head { cursor: grab; }
.is-editing .business-panel .panel-title, .is-editing .business-panel .group-heading, .is-editing .business-panel .field-heading { cursor: text; }
.inline-title-editor { min-width: 90px; padding: 4px 6px; border: 2px solid #04685b; border-radius: 6px; background: var(--surface); color: var(--ink); font: inherit; }
.column-resize-handle { position: absolute; z-index: 8; top: 0; right: -5px; width: 10px; height: 100%; cursor: col-resize; touch-action: none; }
.column-resize-handle::after { content: none; }
/* 行高拖拽手柄 .field-height-handle 已整体删除。
   ── 为什么要删，而不是修它的定位 ─────────────────────────────────
   它靠一个 ::after 画指示条：
     .field-height-handle        { position: absolute; left: 8px; right: 8px;
                                   bottom: -5px; height: 10px; cursor: row-resize }
     .field-height-handle::after { left: 30%; right: 30%; top: 4px; height: 2px;
                                   background: color-mix(in srgb, var(--ink) 30%, transparent) }
   手柄是绝对定位，它的参照物应当是「自己所在的那一格」。但编辑态的 <td> 由
   app.js 的 createInputCell 产出，是不带任何类的裸 td（position: static）；
   非编辑态走 createEditableCell 才有 .editable-cell（position: relative）。
   于是**只有编辑态**参照物会退化成最近的可定位祖先 —— 整张滚动盒（宽约 1135px），
   而不是约 150px 的单元格。三个后果叠在一起，就是用户看到的那条黑线：

     1) left:30%; right:30% 会按 1135px 解析 → 指示条宽 454px，横跨约 3 列，
        且与列边界完全不对齐（实测线跨 具体需求→负责部门，而列宽只有 150px）；
     2) 同一模板里 6 行 × 2 个多行字段 = 12 个手柄全部落在同一位置，
        每层 30% 的 --ink 反复叠加，alpha 收敛到接近 1，
        颜色从预期的浅灰 #b4b4b4 变成实心 #111111；
     3) 手柄位于滚动盒内，于是这条线随内容上下滚动而漂移，位置不断偏移。

   实测佐证（对用户截图做像素级 PNG 解码）：
     线为 #111111 不透明、908×4 图像 px（DPR 2 → 454×2 CSS px），实心无断点，
     恰等于 40% × 1135 —— 与上面的 left/right 30% 规则唯一对应。

   删除后：行高仍会从已保存的数据应用（app.js applyCellSizing 里的 --field-height），
   只是不再提供「拖动改行高」的入口。若日后要恢复该能力，手柄必须落在
   一个明确 position: relative 的单元格里，且指示条不要用整表尺度的 30%/30%。 */
.table-textarea { resize: none; min-height: var(--field-height, 72px); }
.editable-cell { position: relative; }
.business-section-dialog { width: min(720px, calc(100vw - 32px)); }
.business-section-list { padding: 10px 18px; max-height: 58vh; overflow: auto; }
.business-section-item { display: grid; grid-template-columns: auto 28px minmax(0,1fr) auto auto auto; gap: 9px; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--line); }
.business-section-drag { cursor: grab; color: var(--muted); }
.business-section-swatch { width: 26px; height: 26px; border-radius: 8px; border: 1px solid color-mix(in srgb, var(--ink) 18%, transparent); }
.business-section-item small { display: block; color: var(--muted); margin-top: 2px; }
/* N4 · 导入 CSV 弹窗 */
.import-dialog { width: min(720px, calc(100vw - 32px)); }
.import-toolbar { display: flex; flex-wrap: wrap; gap: 10px; align-items: end; padding: 0 18px 12px; }
.import-target-control { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }
.import-target-control select,
.import-mapping-row select { padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink); font: inherit; }
.import-mapping { max-height: 40vh; overflow: auto; padding: 0 18px; display: grid; gap: 8px; }
.import-mapping-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); gap: 10px; align-items: center; font-size: 13px; }
.import-summary { margin: 12px 18px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 9px; background: var(--soft); color: var(--ink); font-size: 12px; line-height: 1.7; white-space: pre-wrap; }
.import-format-hint { align-self: center; font-size: 12px; color: var(--muted); }
.import-target-bar { display: flex; flex-wrap: wrap; gap: 12px; align-items: end; padding: 4px 18px 12px; border-bottom: 1px solid var(--line); }
.import-mode-control, .import-existing-control { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }
.import-mode-control select,
.import-existing-control select,
.import-existing-control input { padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink); font: inherit; }
.import-existing-control { flex: 1 1 260px; }
/* 目标回显：单独一行且加底色，确保「要导到哪个模块」不会被下面的校验信息淹没 */
.import-target-echo { margin: 10px 18px 0; padding: 8px 11px; border-radius: 8px; background: color-mix(in srgb, var(--surface) 88%, #87c9c3); color: var(--ink); font-size: 12px; font-weight: 500; }
.import-target-echo:empty { display: none; }
.import-field-row { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) auto; gap: 10px; align-items: center; }
.import-field-row select, .import-field-row input { padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink); font: inherit; }
.import-source-name { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* [hidden] 必须显式声明：下面的 display:flex 是作者样式，会盖掉浏览器默认的
   [hidden]{display:none}，导致新建模式下这根条也一直显示。 */
.import-ai-bar { display: flex; align-items: center; gap: 10px; margin: 8px 18px 0; }
.import-ai-bar[hidden] { display: none; }
.import-ai-bar .button { padding: 5px 10px; font-size: 12px; }
.import-ai-status { font-size: 12px; color: var(--muted); }
.import-ai-status[data-level="ok"] { color: #04685b; }
.import-ai-status[data-level="warn"] { color: #b73508; }
.import-confidence { font-size: 11px; padding: 2px 7px; border-radius: 999px; border: 1px solid var(--line); background: var(--soft); color: var(--muted); white-space: nowrap; }
.import-confidence[data-level="high"] { color: #04685b; border-color: color-mix(in srgb, #04685b 40%, var(--line)); }
.import-confidence[data-level="medium"] { color: #8a6d1f; border-color: color-mix(in srgb, #8a6d1f 40%, var(--line)); }
.import-confidence[data-level="low"] { color: #b73508; border-color: color-mix(in srgb, #b73508 45%, var(--line)); }
.import-confidence[data-level="manual"] { color: var(--ink); }

.business-section-actions { display: flex; gap: 7px; justify-content: flex-end; }
.business-section-fixed { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; cursor: pointer; }
.business-section-fixed input { width: 16px; height: 16px; margin: 0; accent-color: var(--inverse); }
.business-section-create { padding: 14px 18px 18px; display: flex; gap: 9px; border-top: 1px solid var(--line); }
.business-section-create input { flex: 1; min-width: 0; border: 1px solid var(--line); border-radius: 9px; background: var(--surface); color: var(--ink); padding: 9px 10px; }
.custom-business-empty { padding: 22px; color: var(--muted); text-align: center; }
.template-header-colors, .template-field-color-control { display: none !important; }
@media (max-width: 720px) {
  .column-resize-handle { display: none !important; }
  .business-section-item { grid-template-columns: 24px minmax(0,1fr) auto auto; }
  .business-section-drag, .business-section-item .business-section-swatch { display: none; }
  .business-section-create { flex-direction: column; }
}

* {
  box-sizing: border-box;
}

html,
body {
  min-width: 320px;
  min-height: 100%;
  margin: 0;
}

body {
  background: #efefef;
}

button {
  font: inherit;
}

button:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

#weekly-app {
  --page: #f3f3f3;
  --surface: #ffffff;
  --raised: #ffffff;
  --ink: #111111;
  --muted: #686868;
  --line: #dedede;
  --soft: #f6f6f6;
  --inverse: #111111;
  --inverse-ink: #ffffff;
  --hover: #eeeeee;
  --shadow: rgb(0 0 0 / 11%);
  min-height: 100vh;
  padding: 12px;
  color: var(--ink);
  background: var(--page);
  color-scheme: light;
}

#weekly-app[data-authenticated="false"] .app-window {
  visibility: hidden;
}

#weekly-app[data-authenticated="true"] .login-screen {
  display: none;
}

.login-screen {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  /* 上下两行：上格放登录卡片并保持垂直居中，下格放页脚；不给行高，
     否则卡片会被页脚压偏。 */
  grid-template-rows: 1fr auto;
  padding: 24px 24px 0;
  color: #111111;
  background: #f3f3f3;
}

/* 登录页配色固定为浅色（不受 data-theme 影响），且作为 grid 项需自行撑满整行 */
.login-site-footer {
  justify-self: stretch;
  align-self: end;
  margin-bottom: 20px;
  color: #858585;
  background: transparent;
  border-top-color: #dcdcdc;
}

.login-site-footer .site-record-link:hover {
  color: #111111;
}

.login-site-footer .site-record-sep {
  color: #b0b0b0;
}

/* 矮屏：登录卡 + 页脚可能超出视口，允许整屏滚动而不是把页脚挤没 */
@media (max-height: 640px) {
  .login-screen {
    place-items: start center;
    align-content: start;
    overflow-y: auto;
  }

  .login-card {
    margin: auto 0;
  }
}

.login-card {
  width: min(410px, 100%);
  padding: 34px;
  background: #ffffff;
  border: 1px solid #d8d8d8;
  border-radius: 12px;
  box-shadow: 0 24px 70px rgb(0 0 0 / 12%);
}

.login-logo {
  height: 30px;
  margin-bottom: 28px;
  filter: invert(1);
}

.login-eyebrow {
  margin: 0 0 8px;
  color: #686868;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
}

.login-card h1 {
  margin: 0;
  font-size: 25px;
}

.auth-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  margin-bottom: 18px;
  padding: 4px;
  background: #f1f1f1;
  border-radius: 7px;
}

.auth-tab {
  padding: 8px 10px;
  color: #666666;
  background: transparent;
  border: 0;
  border-radius: 5px;
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
}

.auth-tab.active {
  color: #111111;
  background: #ffffff;
  box-shadow: 0 1px 4px rgb(0 0 0 / 10%);
}

.auth-form {
  display: grid;
  gap: 12px;
}

.auth-form[hidden] {
  display: none;
}

.login-description {
  margin: 10px 0 24px;
  color: #686868;
  font-size: 13px;
}

.login-field {
  display: grid;
  gap: 7px;
  font-size: 12px;
  font-weight: 600;
}

.login-field input {
  width: 100%;
  padding: 11px 12px;
  color: #111111;
  background: #ffffff;
  border: 1px solid #bdbdbd;
  border-radius: 6px;
  outline: 0;
  font: inherit;
}

.login-field input:focus {
  border-color: #111111;
  box-shadow: 0 0 0 1px #111111;
}

.login-submit {
  width: 100%;
  margin-top: 2px;
  padding: 11px 14px;
  color: #ffffff;
  background: #111111;
  border: 1px solid #111111;
  border-radius: 6px;
  cursor: pointer;
  font-weight: 600;
}

.login-submit:disabled {
  cursor: wait;
  opacity: 0.6;
}

.login-error {
  margin: 10px 0 0;
  color: #b52626;
  font-size: 11px;
}

.login-note {
  margin: 14px 0 0;
  color: #858585;
  font-size: 10px;
  line-height: 1.5;
  text-align: center;
}

.cloud-state {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: #b8dfc6;
  font-size: 10px;
  white-space: nowrap;
}

.cloud-state::before {
  width: 6px;
  height: 6px;
  background: #42b66d;
  border-radius: 50%;
  content: "";
}

.cloud-state.offline {
  color: #ffb2b2;
}

.cloud-state.offline::before {
  background: #d85050;
}

#weekly-app[data-theme="dark"] {
  --page: #070707;
  --surface: #0d0d0d;
  --raised: #171717;
  --ink: #f7f7f7;
  --muted: #a8a8a8;
  --line: #303030;
  --soft: #151515;
  --inverse: #f5f5f5;
  --inverse-ink: #111111;
  --hover: #202020;
  --shadow: rgb(0 0 0 / 50%);
  color-scheme: dark;
}

.app-window {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: calc(100vh - 24px);
  min-height: 640px;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 16px 44px var(--shadow);
}

/* ── 站点页脚（版权 + 公安备案 / ICP 备案） ──
   作为 .app-window flex 列的最后一个子元素，天然贴底并随主题切换配色；
   不用 fixed，避免遮住表格最后一行。 */
.site-footer {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 6px 18px;
  padding: 10px 20px;
  color: var(--muted);
  background: var(--surface);
  border-top: 1px solid var(--line);
  font-size: 11px;
  line-height: 1.6;
}

.site-footer p {
  margin: 0;
}

.site-footer-records {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}

.site-record {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}

.site-record-icon {
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
}

.site-record-sep {
  color: color-mix(in srgb, var(--muted) 60%, transparent);
}

.site-record-link {
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}

.site-record-link:hover {
  color: var(--ink);
  text-decoration: underline;
}

@media (max-width: 640px) {
  .site-footer {
    justify-content: center;
    text-align: center;
    padding: 9px 12px;
  }
}

.global-bar {
  display: flex;
  min-height: 52px;
  align-items: center;
  gap: 14px;
  padding: 8px 14px;
  color: #ffffff;
  background: #111111;
  border-bottom: 1px solid #292929;
}

.global-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-right: auto;
  font-weight: 600;
  white-space: nowrap;
}

.brand-logo {
  display: block;
  width: auto;
  height: 28px;
  object-fit: contain;
}

.global-actions,
.person-actions,
.table-tools {
  display: flex;
  align-items: center;
  gap: 7px;
}

.global-actions {
  flex-wrap: wrap;
  justify-content: flex-end;
}

.top-button {
  padding: 7px 10px;
  color: #ffffff;
  background: #1d1d1d;
  border: 1px solid #3d3d3d;
  border-radius: 5px;
  cursor: pointer;
  font-size: 12px;
}

.top-button:hover {
  background: #303030;
}

.top-button.strong {
  color: #111111;
  background: #ffffff;
  border-color: #ffffff;
}

.theme-button {
  min-width: 84px;
}

.tab-bar {
  display: flex;
  min-height: 37px;
  align-items: flex-end;
  gap: 5px;
  padding: 5px 10px 0;
  color: #c8c8c8;
  background: #1a1a1a;
  border-bottom: 1px solid #303030;
}

.page-tab {
  padding: 7px 13px;
  color: #c8c8c8;
  background: transparent;
  border: 0;
  border-radius: 7px 7px 0 0;
  cursor: pointer;
  font-size: 12px;
}

/* 单一面板的静态位置标签：不是可交互控件，不显示 pointer 光标 */
.page-tab.is-current {
  cursor: default;
  color: #111111;
  background: #ffffff;
}

#weekly-app[data-theme="dark"] .page-tab.is-current {
  color: #ffffff;
  background: #0d0d0d;
}

.page-tab[aria-selected="true"] {
  color: #111111;
  background: #ffffff;
}

#weekly-app[data-theme="dark"] .page-tab[aria-selected="true"] {
  color: #ffffff;
  background: #0d0d0d;
}

.workspace {
  --sidebar-width: 220px;
  display: grid;
  flex: 1;
  min-height: 0;
  grid-template-columns: var(--sidebar-width) 10px minmax(0, 1fr);
  background: var(--page);
}

.sidebar {
  display: flex;
  min-height: 0;
  flex-direction: column;
  padding: 18px 12px 14px;
  background: var(--surface);
}

.sidebar-resizer {
  position: relative;
  z-index: 9;
  min-height: 0;
  background: var(--surface);
  border-right: 1px solid var(--line);
  border-left: 1px solid transparent;
  cursor: col-resize;
  touch-action: none;
}

.sidebar-resizer::after {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 3px;
  height: 38px;
  background: var(--muted);
  border-radius: 999px;
  content: "";
  opacity: 0;
  transform: translate(-50%, -50%);
  transition: opacity 150ms ease;
}

.sidebar-resizer:hover::after,
.sidebar-resizer:focus-visible::after,
.workspace.is-resizing .sidebar-resizer::after {
  opacity: 1;
}

.workspace.is-resizing {
  cursor: col-resize;
  user-select: none;
}

.side-title {
  margin: 0 8px 12px;
  color: var(--muted);
  font-size: 12px;
}

.side-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.staff-panel-toggle {
  display: none;
  width: 34px;
  height: 34px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
}

.staff-management {
  display: grid;
  gap: 7px;
  margin-bottom: 10px;
}

.staff-search {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  padding: 7px 9px;
  color: var(--muted);
  background: var(--soft);
  border: 1px solid var(--line);
  border-radius: 6px;
}

.staff-search:focus-within {
  border-color: var(--ink);
}

.staff-search input {
  width: 100%;
  min-width: 0;
  padding: 0;
  color: var(--ink);
  background: transparent;
  border: 0;
  outline: 0;
  font: inherit;
  font-size: 11px;
}

.add-staff-button {
  width: 100%;
  padding: 8px;
  color: var(--ink);
  background: var(--surface);
  border: 1px dashed var(--muted);
  border-radius: 6px;
  cursor: pointer;
  font-size: 11px;
}

.add-staff-button:hover {
  background: var(--hover);
}

.add-staff-button:disabled,
.remove-person:disabled {
  cursor: not-allowed;
  opacity: 0.4;
}

.staff-list {
  min-height: 0;
  overflow-y: auto;
}

/* 排序栏：进入「自定义排序」前只占一行小按钮，不挤压列表 */
.staff-sort-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px 0;
}

.staff-sort-toggle,
.staff-sort-reset {
  font-size: 11px;
  padding: 4px 8px;
  color: var(--ink);
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
}

.staff-sort-toggle[aria-pressed="true"] {
  color: #fff;
  background: #2f6bd8;
  border-color: #2f6bd8;
}

.staff-sort-toggle:disabled,
.staff-sort-reset:disabled {
  cursor: not-allowed;
  opacity: 0.4;
}

.person-row {
  position: relative;
  display: flex;
  width: 100%;
  min-width: 0;
  align-items: center;
  gap: 4px;
}

/* 自定义排序模式：排序子组独占一行并缩进到名称起始位置，跟管理员操作同一套
   视觉语言；行可拖拽，拖影要看得见。 */
.person-row.sorting {
  flex-wrap: wrap;
  align-items: center;
  row-gap: 6px;
}

.person-row.dragging {
  opacity: 0.6;
}

.sort-actions {
  display: flex;
  flex: 1 1 100%;
  flex-wrap: wrap;
  min-width: 0;
  align-items: center;
  gap: 6px;
  padding-left: 50px;
  position: relative;
}

.sort-actions::before {
  content: "";
  position: absolute;
  left: 39px;
  top: 5px;
  bottom: 5px;
  width: 2px;
  background: var(--line);
  border-radius: 1px;
}

.sort-handle {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: 12px;
  cursor: grab;
  border-radius: 4px;
  user-select: none;
}

.person-row.dragging .sort-handle {
  cursor: grabbing;
  color: var(--ink);
}

.sort-actions .admin-action {
  padding: 2px 8px;
  font-size: 11px;
}

/* 带管理员操作（移除/重置码/设为管理员）的行：「名称 + 移除」作为整体单元
   保持同行；名称过长时允许换行，移除按钮垂直居中；管理操作作为该条目的
   子组缩进对齐到名称起始位置，避免视觉漂移。 */
.person-row.has-admin-actions {
  flex-wrap: wrap;
  align-items: center;
  row-gap: 6px;
}

.person-row.has-admin-actions .person {
  /* 注意：basis 只能是 0%。改成 auto 时 .person 以内容宽起算 → 超出侧栏剩余空间，
     「移除」按钮会被换行掉到名称下方（verify-person-layout R1 会红）。 */
  flex: 1 1 0%;
  min-width: 0;
}

.person {
  display: flex;
  width: auto;
  min-width: 0;
  flex: 1 1 auto;
  align-items: center;
  gap: 10px;
  margin: 2px 0;
  padding: 10px;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
  text-align: left;
}

.person-details {
  display: flex;
  min-width: 0;
  flex: 1;
  flex-direction: column;
  gap: 2px;
  overflow: hidden;
}

.person-details small {
  overflow: hidden;
  color: var(--muted);
  font-size: 9px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.person[aria-selected="true"] .person-details small {
  color: currentColor;
  opacity: 0.72;
}

.person:hover {
  background: var(--hover);
}

.person[aria-selected="true"] {
  color: var(--inverse-ink);
  background: var(--inverse);
}

.avatar {
  display: grid;
  width: 30px;
  height: 30px;
  flex: 0 0 30px;
  place-items: center;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-size: 12px;
}

.person-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.updated-dot {
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  background: currentColor;
  border-radius: 50%;
  opacity: 0.7;
}

.remove-person {
  width: auto;
  min-width: 36px;
  height: 27px;
  flex: 0 0 auto;
  padding: 0 5px;
  margin-left: auto;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 5px;
  cursor: pointer;
  font-size: 10px;
}

.remove-person:hover {
  color: #b52626;
  background: #fde9e9;
  border-color: #e6a1a1;
}

#weekly-app[data-theme="dark"] .remove-person:hover {
  color: #ff9a9a;
  background: #4a2222;
  border-color: #8c4545;
}

/* 「＋ 添加」：搜索态下把同事放进「我的周会空间」的唯一入口。
   与 .remove-person 共用同一套几何（同高、同 margin-left:auto），
   保证加了按钮之后名称窄度和「移除」时完全一致，不会把姓名挤到换行。 */
.add-person {
  width: auto;
  min-width: 36px;
  height: 27px;
  flex: 0 0 auto;
  padding: 0 5px;
  margin-left: auto;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 5px;
  cursor: pointer;
  font-size: 10px;
}

.add-person:hover {
  color: #1a6fb5;
  background: #eaf3fd;
  border-color: #a9cbf0;
}

#weekly-app[data-theme="dark"] .add-person:hover {
  color: #9ecbff;
  background: #17293c;
  border-color: #3c5f85;
}

.add-person:disabled {
  cursor: not-allowed;
  opacity: 0.4;
}

.staff-empty {
  margin: 12px 4px;
  color: var(--muted);
  font-size: 11px;
  text-align: center;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.side-foot {
  margin-top: auto;
  padding: 12px 8px 0;
  color: var(--muted);
  border-top: 1px solid var(--line);
  font-size: 11px;
  line-height: 1.7;
}

.main-content {
  min-width: 0;
  overflow: auto;
  background: var(--page);
}

/* 顶栏允许换行：空间不足时按钮组整体换到姓名下方，而不是把姓名挤扁。
   （修复前按钮不换行 + identity 无 min-width:0，按钮文字竖排成
   「设/置/分/组」字塔、角色说明折成多行堆叠。） */
.person-bar {
  position: sticky;
  top: 0;
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  
  align-items: center;
  justify-content: space-between;
  gap: 8px 15px;
  padding: 15px 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

.identity {
  flex: 1 1 260px;
  min-width: 0;
}

.identity-title {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.identity-title h1 {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.identity-title .read-only-badge {
  flex: 0 0 auto;
}

.identity h1 {
  margin: 0 0 3px;
  font-size: 18px;
  font-weight: 600;
}

.read-only-badge {
  padding: 3px 7px;
  color: #2563a8;
  background: #e8f3ff;
  border: 1px solid #a9cef4;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 600;
}

#weekly-app[data-theme="dark"] .read-only-badge {
  color: #a8d2ff;
  background: #173452;
  border-color: #35638e;
}

.identity p {
  margin: 0;
  min-width: 0;
  overflow: hidden;
  color: var(--muted);
  font-size: 11px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 按钮永不内部换行（防「设/置/分/组」竖排字塔），空间不足时整组换行 */
.person-actions {
  flex: 0 1 auto;
  flex-wrap: wrap;
  justify-content: flex-end;
  row-gap: 8px;
}

.person-actions .button {
  flex: 0 0 auto;
  white-space: nowrap;
}

.button,
.tool-button {
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
}

.button {
  padding: 8px 11px;
}

.tool-button {
  padding: 6px 9px;
  font-size: 11px;
}

.button:hover,
.tool-button:hover {
  background: var(--hover);
}

.button:disabled,
.tool-button:disabled,
.top-button:disabled,
.arrow-button:disabled,
.add-plan:disabled,
.attachment-button:disabled,
.status-select:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

.button.primary {
  color: var(--inverse-ink);
  background: var(--inverse);
  border-color: var(--inverse);
}

.content-area {
  padding: 17px 20px 28px;
}

.week-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.week-picker {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  flex-wrap: wrap;
}

.week-jump-separator { width: 1px; height: 22px; margin-left: 4px; background: var(--line); }
.week-jump-control { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: 11px; font-weight: 500; }
.week-jump-control input { min-height: 30px; padding: 4px 7px; color: var(--ink); background: var(--surface); border: 1px solid var(--line); border-radius: 5px; font: inherit; font-variant-numeric: tabular-nums; }
.week-jump-button { min-height: 30px; padding: 4px 10px; }

.arrow-button {
  width: 28px;
  height: 28px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 5px;
  cursor: pointer;
}

@media (max-width: 760px) {
  .business-panel .panel-topbar { align-items: stretch; flex-wrap: wrap; }
  .business-panel.open .panel-topbar > .table-tools { width: 100%; justify-content: flex-end; padding: 0 11px 9px 18px; }
  .week-line { align-items: flex-start; }
  .week-picker { row-gap: 7px; }
  .week-jump-separator { display: none; }
  .week-jump-control { width: 100%; }
}

.save-state {
  color: var(--muted);
  font-size: 11px;
}

.panel {
  margin-bottom: 11px;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 8px;
}

.panel-head {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 9px;
  padding: 13px 14px;
  color: var(--ink);
  background: var(--surface);
  border: 0;
  cursor: pointer;
  text-align: left;
}

.chevron {
  color: var(--muted);
  transition: transform 0.2s ease;
}

.panel.open .chevron {
  transform: rotate(90deg);
}

.panel-title {
  font-weight: 600;
}

.panel-count,
.panel-tip {
  color: var(--muted);
  font-size: 11px;
}

.panel-tip {
  margin-left: auto;
}

.panel-retention {
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}

/* 「每周清空」需与「跨周固定」形成明确区分，避免被误读为数据丢失 */
.panel-retention.is-clearing {
  padding: 1px 6px;
  color: #8a5a00;
  background: color-mix(in srgb, #f5d44b 22%, var(--surface));
  border: 1px solid color-mix(in srgb, #f5d44b 55%, var(--line));
  border-radius: 4px;
  cursor: help;
}

.business-panel.open .panel-retention.is-clearing {
  color: #6b4600;
  background: color-mix(in srgb, var(--surface) 78%, #f5d44b);
  border-color: color-mix(in srgb, #b8860b 40%, transparent);
}

/* 面板内「下周将清空」提示条 */
.retention-notice {
  margin: 0;
  padding: 7px 12px 7px 14px;
  color: #7a4a00;
  background: color-mix(in srgb, #f5d44b 16%, var(--surface));
  border-bottom: 1px solid color-mix(in srgb, #f5d44b 40%, var(--line));
  font-size: 11px;
  line-height: 1.6;
}

.support-panel {
  margin-bottom: 8px;
}

.panel-body {
  display: none;
  border-top: 1px solid var(--line);
}

.panel.open .panel-body {
  display: block;
}

.table-tools {
  padding: 9px 11px;
  background: var(--soft);
  border-bottom: 1px solid var(--line);
}

/* 窄窗/移动端：面板顶部工具条改为换行堆叠，避免按钮溢出到表格之上造成重叠 */
@media (max-width: 760px) {
  .business-panel.open .panel-topbar {
    flex-wrap: wrap;
    height: auto;
    min-height: 0;
    align-items: stretch;
  }
  .business-panel.open .panel-topbar > .panel-head {
    flex: 1 1 100%;
    width: 100%;
  }
}

.edit-hint {
  margin-left: auto;
  color: var(--muted);
  font-size: 11px;
}

/* 表格滚动容器：横竖两个方向都在这一层滚动，是表头 sticky 的唯一参照物。
   ── 为什么必须有 max-height ──────────────────────────────────────
   position: sticky 的参照物是「最近的可滚动祖先」。此前这里只写
   overflow-x: auto —— 按 CSS 规则，当一轴为 auto、另一轴为 visible 时，
   visible 会计算成 auto，所以纵向其实也成了滚动容器，但元素高度由内容撑开，
   纵向永远没有可滚动量，表头实际上「钉在一个不会滚的盒子里」，等于没钉。
   于是整页滚动（.main-content）时，表头连同 .table-wrap 一起被卷走 ——
   这正是「单模板内上下滑动时 UI 重叠」。

   给一个 max-height 之后，表格内容超出时由本层产生纵向滚动条，表头钉在
   本层顶部不再滚走；同时横向吸附列也仍然以本层为参照，两个方向共用同一个
   滚动盒，行为天然一致。
   max-height 用 min() 表达：既不超过视口的 70vh，也不超过 720px，
   避免小窗口下被压成一条缝。 */
.table-wrap {
  position: relative;
  /* 高于 .table-scroll-shell::after（z-index 1）与 .business-panel::before（z-index 1），
     保证右侧渐隐遮罩只作用于表格之外、不覆盖 sticky 首列 */
  z-index: 2;
  overflow: auto;
  max-height: min(70vh, 720px);
  scrollbar-width: auto;
  scrollbar-color: auto;
  /* 隔离表格内部的层叠上下文，避免 sticky 列与下方吸附滚动条互相穿透 */
  isolation: isolate;
}

/* 外层壳：只负责右侧渐隐遮罩与滑动提示，自身不滚动 */
.table-scroll-shell {
  position: relative;
  width: 100%;
  overflow: hidden;
  /* 面板装饰层独立于表格的 sticky 层 */
  isolation: isolate;
}

/* 右侧渐隐遮罩：置于滚动容器之外、表格 sticky 层之下，横向滚动时不遮挡 sticky 首列 */
.table-scroll-shell::after {
  content: "";
  position: absolute;
  z-index: 1;
  top: 0;
  /* 收在横向滚动条上方：滚动条在 Windows 上实高约 15px，
     若只留 14px 遮罩会压住滚动条 1px，拖动时表现为边缘错位/重叠。
     这里留 17px 并允许在无滚动条时略高，确保绝不压住滚动条。 */
  bottom: 17px;
  right: 0;
  width: 34px;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(to right, transparent, color-mix(in srgb, var(--surface) 88%, transparent));
  transition: opacity .16s ease;
}

.table-scroll-shell.is-scrollable:not(.at-scroll-end)::after {
  opacity: 1;
}

/* 滑动提示气泡：浮在表格之上，但不拦截指针事件 */
.table-scroll-shell::before {
  content: "可左右滑动查看更多列";
  position: absolute;
  z-index: 9;
  right: 12px;
  /* 抬到滚动条之上：滚动条实高约 15px，再留 8px 呼吸位。
     原来 24px 时气泡下沿会压在滚动条与最后一行操作按钮上，
     拖动时看起来像「提示文字与附件按钮叠在一起」。 */
  bottom: 23px;
  padding: 5px 8px;
  border: 1px solid var(--line);
  border-radius: 5px;
  color: var(--ink);
  background: var(--surface);
  box-shadow: 0 4px 14px var(--shadow);
  font-size: 11px;
  pointer-events: none;
  opacity: 0;
  transform: translateY(3px);
  transition: opacity .16s ease, transform .16s ease;
}

.table-scroll-shell.is-scrollable:hover::before {
  opacity: 1;
  transform: translateY(0);
}

.project-table {
  width: 2820px;
  min-width: 2820px;
  table-layout: fixed;
}

.weekly-table {
  min-width: 1280px;
  table-layout: fixed;
}

.next-week-table {
  min-width: 1080px;
}

.project-table th,
.project-table td,
.weekly-table th,
.weekly-table td {
  border-right: 1px solid var(--line);
}

.project-table th:last-child,
.project-table td:last-child,
.weekly-table th:last-child,
.weekly-table td:last-child {
  border-right: 0;
}

.project-table .group-heading {
  color: var(--ink);
  background: color-mix(in srgb, var(--soft) 70%, #9ac9f8 30%);
  text-align: center;
}

.business-panel .project-table {
  table-layout: fixed;
}

/* 表头设置进行中的「实时预览」：给表头打一层虚线内框，
   让用户明确知道这是「尚未保存的草稿投影」，与已生效表头区分。
   同时保证预览态的横向吸附列仍按 sticky-column 规则工作。 */
table[data-header-preview] > thead th[data-preview="true"] {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--line) 60%, transparent);
}

table[data-header-preview] > thead th.sticky-column[data-preview="true"] {
  z-index: 5;
}

.business-panel .group-heading-grouped {
  text-align: center !important;
}

.business-panel td.editable-cell,
.business-panel .table-textarea {
  overflow-wrap: anywhere;
  word-break: break-word;
  white-space: pre-wrap;
}

.empty-fields-heading {
  text-align: center;
}

/* ── 表头层叠分级 ────────────────────────────────────────────────
   表头分为两层，各用一个显式 z-index：

   TIER-BASE = 1  —— 所有表头单元格。横向滚动时它们滑出容器左边界即可，
                     不需要盖住谁。但仍必须显式声明 z-index：auto 不产生层叠
                     层级，绘制顺序会被 DOM 顺序支配（越靠右画得越晚），
                     邻列的左边缘就会压住吸附首列。

   TIER-PIN  = 4  —— 承担横向吸附的首列（.sticky-column）。高于 BASE 与
                     表体吸附列（3），横滚时永远压住滚出边界的邻居。

   ⚠ 真正决定「首个子表头会不会压住后续 UI」的不是层级高低，而是
   **它有没有被标记 .sticky-column**。整行表头都是 position: sticky，
   若覆盖第 0 列的那一格没有 left: 0，横向滚动时它就整体滑出容器左缘；
   而 border-collapse: collapse 下 Chromium 不把单元格背景裁剪到格内，
   于是它会在已经滚出视野的邻列上继续画背景色块 —— 看起来就是首列表头
   和下表格「压住」了后面的内容。判据见 app.js 的 ownsFirstColumn。

   历史教训：曾把第一行分组表头单独设为更高层级（5）来压第二行子表头，
   这个方向是错的 —— 两者本就分别占第 0 列的两行，边界完全重合；层级不同
   反而会让 collapse 模式下的边框渲染顺序错开，凭空制造出一条 1px 接缝。 */

/* 表头基础层级：所有表头单元格 */
.project-table thead th,
.weekly-table thead th {
  position: sticky;
  z-index: 1;
}

/* ── 表头纵向吸附：按「行」分配吸附线，两行各有一条，互不重叠 ────────────
   规则顺序即优先级（后写的、特异度高的胜出），这里刻意按行分层：

     第一行（总表头，含 rowSpan 贯穿格的顶段）  → top: 0
     第二行（子表头）                          → top: var(--group-heading-h)

   两条线的差值必须恒等于第一行实测高度，否则就会出现「第二行被第一行盖住」
   的叠字（差值偏小）或「两行之间裂开一条缝」（差值偏大）。第一行高度随字体、
   缩放、是否带操作列变化，所以由 JS 实测后写进 --group-heading-h，
   下面的 34px 只是脚本执行前的兜底值。

   ⚠ 任何针对表头的规则都不要再统一写 top —— 一条 `thead th { top: X }`
   会把两行压到同一条线上，这正是此前「单模板上下滑动时子表头与总表头重叠」
   的成因。纵向偏移永远按行给。 */

/* 第一行（总表头）钉在滚动盒顶部 */
.project-table thead .group-heading-row,
.weekly-table thead .group-heading-row {
  top: 0;
}

/* 贯穿两行表头的单元格（操作列）：
   它同时属于第一行和第二行，纵向吸附线只能取一条 —— 给 0（贴齐第一行）。
   若给第二行的值，它会被第一行表头盖住。 */
.project-table thead th[rowspan="2"],
.weekly-table thead th[rowspan="2"] {
  top: 0;
}

/* 第二行（子表头）紧贴总表头下方 —— 必须排在最后，才能压过上面的通用规则 */
.project-table thead .project-column-row th,
.weekly-table thead .project-column-row th {
  top: var(--group-heading-h, 34px);
}

/* 表头吸附首列。与表体吸附列严格区分（td / th）：表体首列是 z=3，
   表头首列是 z=4。多级表头下第 0 列跨两行、两个单元格都带 .sticky-column，
   二者 left 相同、共用同一条横向吸附线。 */
.project-table thead th.sticky-column,
.weekly-table thead th.sticky-column {
  left: 0;
  /* ⚠ 这里绝对不能写 top。写 top 会覆盖掉上方那条按行分配纵向偏移的规则：
     .project-column-row th 想拿 var(--group-heading-h)，却因为本条特异度更高
     （0,3,1 > 0,3,0）而被压成 0 —— 于是两行表头的纵向吸附线都落在 0，
     第一行正好完整盖住第二行，表现为「上下滑动时子表头被总表头吞掉」，
     两行文字叠成一片。纵向偏移必须由「行」决定，横向吸附由本条决定，
     两个维度各自独立，不要混在同一个选择器里。 */
  z-index: 4;
  /* 吸附列必须自身不透明：它要遮住从左侧滚过的所有邻居内容。
     背景用 --soft（与表头底色一致），并补一条右侧分隔线替代被遮住的边框。 */
  background: var(--soft);
  box-shadow: 1px 0 0 var(--line);
}

/* 表体 sticky 首列：严格以 .sticky-column 为准（由 JS 显式标注）。
   不再依赖 :first-child —— 在 colspan/rowspan 组合表头下 :first-child 会命中
   多个不同列的单元格，导致多个单元格同时吸附到 left:0 而文字互相压叠。 */
.project-table td.sticky-column,
.weekly-table td.sticky-column {
  position: sticky;
  left: 0;
  /* 高于底部吸附的横向滚动条，防止首列滚到底时被滚动条盖住 */
  z-index: 3;
  background: var(--surface);
  box-shadow: 1px 0 0 var(--line);
  /* 单元格内部是输入框/下拉/文本域，它们自己会形成绘制层。
     首列吸附时必须把这些子元素一并抬到同层，否则其边框会越过首列背景
     透到左侧，视觉上表现为「输入框叠在首列文字上」。 */
  isolation: isolate;
}

/* 首列内部可交互控件不得产生新的层叠穿透 */
.project-table td.sticky-column > *,
.weekly-table td.sticky-column > * {
  position: relative;
  z-index: 1;
}

/* 表头 sticky 首列：必须高于表体 sticky 列，否则横向滚动时表体文字会盖住表头。 */
.project-table thead th.sticky-column,
.weekly-table thead th.sticky-column {
  left: 0;
  /* TIER-PIN：吸附列统一层级。高于表头非吸附列（1）与表体吸附列（3），
     保证横滚时吸附列永远压住滚出边界的邻居。同样不设 top，理由见上方注释。 */
  z-index: 4;
  background: var(--soft);
}

/* 分组表头的一级表头承担吸附职责时，背景需与分组色一致 */
.project-table thead .group-heading.sticky-column,
.weekly-table thead .group-heading.sticky-column {
  background: color-mix(in srgb, var(--soft) 70%, #9ac9f8 30%);
}

/* 组合表头的第二行（子表头）默认不参与横向吸附，避免与一级表头争抢 left:0。
   唯一例外是「首分组只占 1 列」的情况 —— 此时吸附线就在子表头自身所在列，
   由 JS 显式打上 .sticky-column，其 left:0 与上方 top:34px 同时生效。 */
.project-table thead .project-column-row th:not(.sticky-column),
.weekly-table thead .project-column-row th:not(.sticky-column) {
  left: auto;
}

/* ── 表头响应式排版：窄列换行 / 逐字堆叠，杜绝溢出压邻列 ────────────
   缺陷背景：全局 `th { white-space: nowrap }` + 列宽可拖到 100px，
   文字既不换行也不裁切，直接溢出到相邻单元格上（表现为表头与邻区重叠）。
   修法：给每个表头单元格塞一个 .th-cell（容器）+ .th-label（被查询对象），
   用 CSS 容器查询按「单元格自身可用宽度」分级降级，JS 不参与测量。

   分级（阈值 = th 内容盒宽度，padding 已从 th 移到 .th-cell 内部）：
     ≥ 160px  单行 nowrap（超过则省略号）
     112–160px 换行，最多 2 行
      84–112px 换行，最多 3 行 + 左右内边距收窄
     <  84px  逐字堆叠，最多 4 行 + 字号降一档（极窄列兜底）
   优先级：容器查询只依赖自身宽度，故从宽到窄逐条覆盖、窄的胜出；
   任何一档都不写死高度，行高由内容撑开，两行表头的纵向吸附偏移
   由 app.js 实测 --group-heading-h 保证一致。 */
.project-table thead th,
.weekly-table thead th {
  padding: 0;                 /* 内边距交给 .th-cell，才能随宽度收窄 */
  overflow: hidden;           /* 兜底：任何残余溢出都不越出本格 */
  vertical-align: middle;
  white-space: normal;
}

/* 容器：宽度恒等于表头格的内容宽度。
   ⚠ 必须是 display:block —— container-type: inline-size 对 inline 元素不产生
   有效的尺寸容器，.th-cell 会退回「由内容撑宽」，于是文字既不换行也不收缩，
   直接溢出压邻列（实测 th 宽 90px 时 label 被撑到 89px，溢出 22px）。 */
.project-table thead .th-cell,
.weekly-table thead .th-cell {
  display: block;
  container-type: inline-size;
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  padding: 9px 11px;
  font: inherit;
  text-align: inherit;
}

.project-table thead .th-label,
.weekly-table thead .th-label {
  display: block;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  overflow-wrap: anywhere;    /* 长英文/URL/无空格文本也断行 */
  word-break: normal;
  line-height: 1.35;
}

/* 档 1：≥160px 单行 */
@container (min-width: 160px) {
  .project-table thead .th-label,
  .weekly-table thead .th-label {
    display: block;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
}

/* 档 2：112–159px 两行 */
@container (max-width: 159px) {
  .project-table thead .th-label,
  .weekly-table thead .th-label {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    word-break: break-word;
  }
}

/* 档 3：84–111px 三行 + 收紧内边距 */
@container (max-width: 111px) {
  .project-table thead .th-cell,
  .weekly-table thead .th-cell { padding: 7px 6px; }
  .project-table thead .th-label,
  .weekly-table thead .th-label {
    -webkit-line-clamp: 3;
    line-clamp: 3;
    text-align: center;
  }
}

/* 档 4：<84px 逐字堆叠（四行封顶 + 降一档字号），仍溢出则省略号 + title 提示 */
@container (max-width: 83px) {
  .project-table thead .th-cell,
  .weekly-table thead .th-cell { padding: 6px 3px; }
  .project-table thead .th-label,
  .weekly-table thead .th-label {
    -webkit-line-clamp: 4;
    line-clamp: 4;
    font-size: 11px;
    line-height: 1.25;
    letter-spacing: 0;
    text-align: center;
    word-break: break-all;   /* CJK 逐字；西文按 anywhere 断，不溢出 */
  }
}

/* 表头里的下拉也必须受格子宽度约束，否则会被内容撑出格子压到邻列。 */
.project-table th .table-select,
.weekly-table th .table-select {
  min-width: 0;
  max-width: 100%;
}

/* 空态行跨列显示，不应参与 sticky 首列吸附 */
.weekly-table td.empty-table,
.project-table td.empty-table {
  position: static;
  box-shadow: none;
}

.project-table .task-name {
  width: 210px;
  min-width: 210px;
}

.project-table th,
.project-table td {
  min-width: 125px;
}

.project-table .field-type-multiline {
  min-width: 190px;
}

.project-table .field-type-people { min-width: 155px; }
.project-table .field-type-attachment { min-width: 145px; }
.project-table .field-type-number,
.project-table .field-type-date,
.project-table .field-type-status { min-width: 145px; }

.weekly-table th:nth-child(1),
.weekly-table td:nth-child(1) { width: 210px; }
.weekly-table th:nth-child(2),
.weekly-table td:nth-child(2) { width: 330px; }
.weekly-table th:nth-child(3),
.weekly-table td:nth-child(3) { width: 220px; }
.weekly-table th:nth-child(4),
.weekly-table td:nth-child(4) { width: 280px; }

.table-input,
.table-select,
.people-input {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px;
  font: inherit;
}

.table-input,
.table-select {
  min-height: 32px;
  padding: 6px 7px;
}

.table-textarea {
  min-height: 58px;
  resize: vertical;
}

.table-input[type="date"] {
  min-width: 142px;
  padding-inline: 8px;
  font-variant-numeric: tabular-nums;
}

.table-select:disabled {
  color: var(--ink);
  background: transparent;
  border-color: transparent;
  opacity: 1;
  -webkit-appearance: none;
  appearance: none;
}

.money-cell {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.money-input {
  text-align: right;
}

.people-editor {
  display: flex;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  align-items: center;
  gap: 5px;
  flex-wrap: wrap;
  overflow: hidden;
}

.person-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 3px 6px;
  color: var(--ink);
  background: var(--soft);
  border: 1px solid var(--line);
  border-radius: 5px;
  white-space: nowrap;
}

.person-chip-remove {
  width: 18px;
  height: 18px;
  padding: 0;
  color: var(--muted);
  background: transparent;
  border: 0;
  cursor: pointer;
}

.people-input {
  min-width: 0;
  flex: 1 1 110px;
  padding: 5px 6px;
}

table {
  width: 100%;
  min-width: 930px;
  border-collapse: collapse;
  color: var(--ink);
  font-size: 12px;
}

th {
  padding: 10px 11px;
  color: var(--muted);
  background: var(--soft);
  border-bottom: 1px solid var(--line);
  font-weight: 600;
  text-align: left;
  white-space: nowrap;
}

.custom-header {
  min-width: 132px;
}

.custom-header-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.custom-header-label {
  min-width: 72px;
  padding: 2px 3px;
  color: var(--ink);
  border-radius: 3px;
}

.custom-header-input {
  width: 100%;
  min-width: 82px;
  padding: 4px 5px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px;
  font: inherit;
  font-weight: 600;
}

.custom-header-input:disabled {
  color: var(--muted);
  background: transparent;
  border-color: transparent;
  opacity: 1;
}

.remove-column {
  width: 22px;
  height: 22px;
  padding: 0;
  color: var(--muted);
  background: transparent;
  border: 0;
  border-radius: 4px;
  cursor: pointer;
}

.remove-column:hover {
  color: var(--ink);
  background: var(--hover);
}

td {
  padding: 9px 11px;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}

tbody tr:last-child td {
  border-bottom: 0;
}

tbody tr:hover {
  background: var(--soft);
}

.task-name {
  min-width: 235px;
  font-weight: 600;
}

.editable-cell[contenteditable="true"] {
  cursor: text;
}

.editable-cell[contenteditable="true"]:hover {
  background: var(--hover);
}

.editable-cell:focus,
.custom-header-label:focus {
  background: var(--surface);
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}

.status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 7px;
  border: 1px solid var(--line);
  border-radius: 999px;
  white-space: nowrap;
}

.status::before {
  width: 6px;
  height: 6px;
  background: currentColor;
  border-radius: 50%;
  content: "";
}

.status[data-status="进行中"],
.status-select[data-status="进行中"] {
  color: #117a43;
  background: #e4f6eb;
  border-color: #96d5ae;
}

.status[data-status="已完成"],
.status-select[data-status="已完成"] {
  color: #1769a8;
  background: #e6f1fb;
  border-color: #9cc4e7;
}

.status[data-status="已延期"],
.status-select[data-status="已延期"] {
  color: #b52626;
  background: #fde9e9;
  border-color: #e6a1a1;
}

.status[data-status="待开始"],
.status-select[data-status="待开始"] {
  color: #646464;
  background: #eeeeee;
  border-color: #c9c9c9;
}

#weekly-app[data-theme="dark"] .status[data-status="进行中"],
#weekly-app[data-theme="dark"] .status-select[data-status="进行中"] {
  color: #73d99f;
  background: #173b28;
  border-color: #347955;
}

#weekly-app[data-theme="dark"] .status[data-status="已完成"],
#weekly-app[data-theme="dark"] .status-select[data-status="已完成"] {
  color: #82bee9;
  background: #18364c;
  border-color: #326b93;
}

#weekly-app[data-theme="dark"] .status[data-status="已延期"],
#weekly-app[data-theme="dark"] .status-select[data-status="已延期"] {
  color: #ff9a9a;
  background: #4a2222;
  border-color: #8c4545;
}

#weekly-app[data-theme="dark"] .status[data-status="待开始"],
#weekly-app[data-theme="dark"] .status-select[data-status="待开始"] {
  color: #c5c5c5;
  background: #2a2a2a;
  border-color: #555555;
}

.status-select {
  min-width: 88px;
  padding: 5px 26px 5px 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  font: inherit;
  font-weight: 600;
}

.status-select:disabled {
  opacity: 1;
  appearance: none;
  background-image: none;
}

/* ── 状态气泡（业务表格内的排期区域） ─────────────────────────────
   目标：气泡沿水平方向完整覆盖其所属排期区域，且在不同屏宽下都对齐。

   实现要点：
   1. 单元格取消内边距并作为定位参照，让气泡能贴满左右内缘（真正的"满覆盖"）；
   2. 气泡用 absolute 撑满整个单元格 —— td 是 table-cell，子元素 height:100%
      在这里不可靠（会塌回内容高度），必须靠 inset 定位才能纵向铺满；
   3. 文本过长时省略，避免撑破列宽导致横向错位；
   4. 状态切换时由 data-status 驱动配色，浅色/深色主题各自适配。 */
.status-cell {
  /* 抵消业务表格 td 的 padding: 9px 11px —— 气泡需要完整覆盖排期区域 */
  padding: 0;
  /* 作为气泡的定位参照 */
  position: relative;
  /* 气泡铺满后由气泡自身承担高度，单元格保持表格行高 */
  overflow: hidden;
}

.table-select.status-bubble-select {
  /* inset 四边归零 = 完整覆盖整个单元格，横向纵向都不留缝 */
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  min-width: 0;
  margin: 0;
  box-sizing: border-box;
  /* 直角贴边，横向完整覆盖；圆角会让左右边缘露出底色 */
  border-radius: 0;
  border-width: 0;
  border-left-width: 3px;
  border-left-style: solid;
  /* 为下拉箭头预留空间，文本不与其重叠 */
  padding: 6px 24px 6px 10px;
  font-weight: 600;
  /* 单行显示 + 溢出省略，防止长文案撑开列宽 */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  /* 让原生下拉箭头在铺满状态下仍可见 */
  background-repeat: no-repeat;
  background-position: right 7px center;
  background-size: 10px 6px;
}

/* 气泡配色：与 .status-select 共用同一套 data-status 语义色 */
.table-select.status-bubble-select[data-status="进行中"] {
  color: #117a43;
  background-color: #e4f6eb;
  border-left-color: #117a43;
}

.table-select.status-bubble-select[data-status="已完成"] {
  color: #1769a8;
  background-color: #e6f1fb;
  border-left-color: #1769a8;
}

.table-select.status-bubble-select[data-status="已延期"] {
  color: #b52626;
  background-color: #fde9e9;
  border-left-color: #b52626;
}

.table-select.status-bubble-select[data-status="待开始"] {
  color: #646464;
  background-color: #eeeeee;
  border-left-color: #9a9a9a;
}

/* 未命中内置色板的自定义状态：中性描边，保证不会出现无底色裸框 */
.table-select.status-bubble-select:not([data-status="进行中"]):not([data-status="已完成"]):not([data-status="已延期"]):not([data-status="待开始"]) {
  color: var(--ink);
  background-color: var(--soft);
  border-left-color: var(--line);
}

/* 用户自定义色板优先，且不覆盖左侧强调条 */
.table-select.status-bubble-select[data-custom-bubble="true"] {
  border-left-color: currentColor;
}

/* 深色主题下的气泡配色 */
#weekly-app[data-theme="dark"] .table-select.status-bubble-select[data-status="进行中"] {
  color: #73d99f; background-color: #173b28; border-left-color: #73d99f;
}
#weekly-app[data-theme="dark"] .table-select.status-bubble-select[data-status="已完成"] {
  color: #82bee9; background-color: #18364c; border-left-color: #82bee9;
}
#weekly-app[data-theme="dark"] .table-select.status-bubble-select[data-status="已延期"] {
  color: #ff9a9a; background-color: #4a2222; border-left-color: #ff9a9a;
}
#weekly-app[data-theme="dark"] .table-select.status-bubble-select[data-status="待开始"] {
  color: #c5c5c5; background-color: #2a2a2a; border-left-color: #6e6e6e;
}
#weekly-app[data-theme="dark"] .table-select.status-bubble-select:not([data-status="进行中"]):not([data-status="已完成"]):not([data-status="已延期"]):not([data-status="待开始"]) {
  color: var(--ink); background-color: var(--soft); border-left-color: var(--line);
}

/* 只读态：气泡保持满覆盖与配色，不显示可点击暗示 */
.table-select.status-bubble-select:disabled {
  opacity: 1;
  appearance: none;
  -webkit-appearance: none;
  cursor: default;
  /* 只读时隐藏下拉箭头（无交互） */
  background-image: none;
  padding-right: 10px;
}

/* 窄屏：气泡内边距与字号收紧，仍保持横向满覆盖与文本省略 */
@media (max-width: 760px) {
  .table-select.status-bubble-select {
    padding: 5px 20px 5px 8px;
    font-size: 12px;
  }
  .table-select.status-bubble-select:disabled {
    padding-right: 8px;
  }
}

/* 超窄屏：进一步压缩左侧强调条，避免挤压文本 */
@media (max-width: 520px) {
  .table-select.status-bubble-select {
    border-left-width: 2px;
    padding: 5px 16px 5px 6px;
  }
  .table-select.status-bubble-select:disabled {
    padding-right: 6px;
  }
}

.priority {
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.attachment-button {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 7px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 5px;
  cursor: pointer;
  white-space: nowrap;
}

.attachment-button:hover {
  background: var(--hover);
}

.delete-button {
  padding: 5px 7px;
  color: var(--muted);
  background: transparent;
  border: 0;
  cursor: pointer;
}

.delete-button:hover {
  color: var(--ink);
  text-decoration: underline;
}

.plan-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 9px;
  padding: 12px;
}

.plan-card {
  position: relative;
  min-height: 105px;
  padding: 12px;
  color: var(--ink);
  background: var(--soft);
  border: 1px solid var(--line);
  border-radius: 7px;
}

.plan-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.plan-card-top .delete-button {
  margin-left: auto;
}

.plan-title-field {
  margin-top: 9px;
  font-weight: 600;
}

.plan-edit-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(118px, 0.7fr);
  gap: 8px;
  margin: 9px 0;
}

.plan-field {
  width: 100%;
  min-width: 0;
  padding: 7px 8px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 5px;
  font: inherit;
}

.plan-field:disabled {
  padding-right: 0;
  padding-left: 0;
  color: var(--ink);
  background: transparent;
  border-color: transparent;
  opacity: 1;
  -webkit-text-fill-color: var(--ink);
}

.plan-card > .attachment-button {
  margin-top: 2px;
}

.plan-card strong {
  display: block;
  margin: 8px 0 12px;
  font-size: 12px;
  line-height: 1.5;
}

.plan-meta {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  color: var(--muted);
  font-size: 11px;
}

.add-plan {
  min-height: 105px;
  color: var(--muted);
  background: transparent;
  border: 1px dashed var(--muted);
  border-radius: 7px;
  cursor: pointer;
}

.add-plan:disabled {
  border-color: var(--line);
}

.empty-table {
  padding: 28px 14px;
  color: var(--muted);
  text-align: center;
}

.navigation-locked {
  cursor: not-allowed;
  opacity: 0.58;
}

.ai-mark {
  display: grid;
  width: 27px;
  height: 27px;
  flex: 0 0 27px;
  place-items: center;
  color: var(--inverse-ink);
  background: var(--inverse);
  border-radius: 5px;
  font-size: 10px;
  font-weight: 800;
}

.ai-panel {
  margin-bottom: 0;
}

.ai-toolbar,
.ai-result-head,
.ai-confirm-bar,
.ai-history-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.ai-toolbar {
  padding: 13px 14px;
  background: var(--soft);
  border-bottom: 1px solid var(--line);
}

/* 「重新检测」与「生成全员总结」并排。
   重检按钮平时 hidden（配置正常时无需打扰用户），只在 AI 配置状态
   不是 ready 时出现 —— 它是「bootstrap 那次检测失败后自愈」的入口。 */
.ai-toolbar-actions {
  display: flex;
  flex: none;
  align-items: center;
  gap: 8px;
}

.ai-toolbar p,
.ai-result-head p {
  margin: 3px 0 0;
  color: var(--muted);
  font-size: 11px;
}

.ai-progress,
.ai-empty {
  padding: 20px 14px;
  color: var(--muted);
  text-align: center;
}

.ai-progress {
  color: var(--ink);
  background: repeating-linear-gradient(-45deg, var(--soft), var(--soft) 8px, var(--surface) 8px, var(--surface) 16px);
  border-bottom: 1px solid var(--line);
  font-weight: 600;
}

.ai-result {
  border-top: 1px solid var(--line);
}

.ai-result-head {
  padding: 12px 14px;
  background: var(--surface);
}

.ai-draft-badge {
  padding: 4px 8px;
  color: var(--inverse-ink);
  background: var(--inverse);
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
}

.ai-draft-badge.confirmed {
  color: var(--ink);
  background: var(--soft);
  border: 1px solid var(--line);
}

.ai-table-wrap {
  border-block: 1px solid var(--line);
}

.ai-summary-table {
  width: 1640px;
  min-width: 1640px;
  table-layout: fixed;
  border-collapse: collapse;
  font-size: 11px;
}

.ai-summary-table th,
.ai-summary-table td {
  padding: 9px;
  vertical-align: top;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  text-align: left;
}

.ai-summary-table th {
  color: var(--inverse-ink);
  background: var(--inverse);
  font-weight: 600;
}

.ai-summary-table th:first-child,
.ai-summary-table td:first-child {
  width: 130px;
}

.ai-summary-table th:last-child,
.ai-summary-table td:last-child {
  width: 100px;
  border-right: 0;
}

.ai-summary-table textarea {
  width: 100%;
  min-height: 104px;
  resize: vertical;
  padding: 8px;
  color: var(--ink);
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: 4px;
  font: inherit;
  line-height: 1.55;
}

.ai-summary-table textarea[readonly] {
  resize: none;
  background: var(--soft);
  border-color: transparent;
}

.ai-employee-cell strong,
.ai-employee-cell span {
  display: block;
}

.ai-employee-cell span {
  margin-top: 4px;
  color: var(--muted);
}

.ai-source-button,
.ai-version-button {
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px;
  cursor: pointer;
}

.ai-source-button {
  padding: 6px 8px;
}

.ai-confirm-bar {
  padding: 12px 14px;
  color: var(--muted);
  font-size: 11px;
}

.ai-history {
  padding: 13px 14px;
  background: var(--soft);
  border-top: 1px solid var(--line);
}

.ai-history-head span,
.ai-history-empty {
  color: var(--muted);
  font-size: 11px;
}

.ai-version-list {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 10px;
}

.ai-version-button {
  padding: 7px 9px;
}

.ai-version-button.active,
.ai-version-button:hover,
.ai-source-button:hover {
  color: var(--inverse-ink);
  background: var(--inverse);
  border-color: var(--inverse);
}

.ai-source-dialog {
  width: min(960px, 100%);
}

.ai-source-content {
  display: grid;
  gap: 12px;
  padding: 14px;
}

.ai-source-section {
  padding: 12px;
  background: var(--soft);
  border: 1px solid var(--line);
  border-radius: 6px;
}

.ai-source-section h3 {
  margin: 0 0 8px;
  font-size: 12px;
}

.ai-source-section pre {
  margin: 0;
  overflow-wrap: anywhere;
  color: var(--ink);
  white-space: pre-wrap;
  font: 11px/1.6 inherit;
}

.modal {
  position: absolute;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 30px;
  background: rgb(0 0 0 / 68%);
}

.modal[hidden],
.toast[hidden] {
  display: none;
}
/* 找回密码弹窗在未登录时也要能弹出：它已移到 .app-window 之外（那里未登录是
   visibility:hidden + inert，弹窗会既看不见又点不动），且必须盖过
   .login-screen 的 z-index 100，否则会被登录遮罩压住。 */
#reset-modal {
  position: fixed;
  z-index: 110;
}

.modal-dialog {
  width: min(650px, 100%);
  max-height: 84%;
  overflow: auto;
  color: var(--ink);
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 20px 60px rgb(0 0 0 / 35%);
}

.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
}

.modal-head h2 {
  margin: 0;
  font-size: 15px;
}

.modal-head p {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 11px;
}

/* 修改密码弹窗的「作用域行」：把「改的是谁的密码」写在标题下方，
   避免用户在他人周报页点该按钮时误以为改的是对方密码。 */
.modal-scope {
  color: var(--ink) !important;
  font-weight: 600;
}

.modal-note {
  margin: 10px 0 0;
  padding: 8px 10px;
  font-size: 11px;
  line-height: 1.5;
  color: #8a5a00;
  background: #fff8e6;
  border: 1px solid #f0d9a8;
  border-radius: 6px;
}

/* 作者样式的 display 会盖掉 UA 默认的 [hidden]，必须显式补一条。 */
.modal-note[hidden] {
  display: none;
}

.employee-dialog,
.confirm-dialog {
  width: min(460px, 100%);
}

.employee-form-fields {
  display: grid;
  gap: 13px;
  padding: 18px 16px;
}

.employee-form-fields label {
  display: grid;
  gap: 6px;
  color: var(--ink);
  font-size: 12px;
}

.employee-form-fields input {
  width: 100%;
  padding: 9px 10px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 6px;
  outline: 0;
  font: inherit;
}

.employee-form-fields input:focus {
  border-color: var(--ink);
  box-shadow: 0 0 0 1px var(--ink);
}

.confirm-body {
  padding: 18px 16px;
  font-size: 12px;
  line-height: 1.6;
}

.confirm-body p {
  margin: 0 0 12px;
  color: var(--muted);
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 16px;
  background: var(--soft);
  border-top: 1px solid var(--line);
}

.button.danger {
  color: #ffffff;
  background: #b52626;
  border-color: #b52626;
}

.button.danger:hover {
  background: #941f1f;
}

.modal-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.close-button {
  width: 30px;
  height: 30px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 5px;
  cursor: pointer;
}

.preview-area {
  display: grid;
  min-height: 230px;
  place-items: center;
  margin: 16px;
  padding: 28px;
  color: var(--muted);
  background: repeating-linear-gradient(45deg, var(--soft), var(--soft) 10px, var(--surface) 10px, var(--surface) 20px);
  border: 1px solid var(--line);
  border-radius: 7px;
  text-align: center;
}

.preview-art {
  display: grid;
  width: 160px;
  height: 125px;
  place-items: center;
  margin: 0 auto 12px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--ink);
  font-size: 24px;
}

.preview-image {
  display: block;
  max-width: min(460px, 100%);
  max-height: 250px;
  margin: 0 auto 12px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 5px;
}

.preview-image[hidden] {
  display: none;
}

.preview-download {
  display: inline-block;
  margin-top: 10px;
  padding: 6px 10px;
  color: var(--inverse-ink);
  background: var(--inverse);
  border-radius: 5px;
  font-size: 11px;
  text-decoration: none;
}

.preview-download[hidden] {
  display: none;
}

.file-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  padding: 0 16px 16px;
}

.file-item {
  position: relative;
  min-width: 0;
}

.empty-files {
  grid-column: 1 / -1;
  margin: 0;
  padding: 18px;
  color: var(--muted);
  background: var(--soft);
  border: 1px dashed var(--line);
  border-radius: 6px;
  text-align: center;
}

.file-button {
  width: 100%;
  min-height: 62px;
  padding: 10px;
  padding-right: 30px;
  color: var(--ink);
  background: var(--soft);
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
  text-align: left;
}

.delete-file {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 24px;
  height: 24px;
  padding: 0;
  color: var(--muted);
  background: transparent;
  border: 0;
  border-radius: 4px;
  cursor: pointer;
}

.delete-file:hover {
  color: var(--ink);
  background: var(--hover);
}

.template-dialog {
  width: min(920px, 100%);
  max-height: min(820px, calc(100vh - 32px));
  overflow-y: auto;
}

.template-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}

.template-toolbar > span {
  margin-left: auto;
  color: var(--muted);
  font-size: 11px;
}

.template-position-control {
  display: flex;
  align-items: center;
  gap: 7px;
  color: var(--muted);
  font-size: 11px;
}

.template-position-control span {
  margin: 0;
  white-space: nowrap;
}

.template-position-control select {
  min-height: 32px;
  max-width: 220px;
  padding: 5px 28px 5px 8px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px;
  font: inherit;
}

.template-groups {
  display: grid;
  gap: 10px;
  padding: 14px 16px;
}

.template-group-editor {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 6px;
}

.template-group-row {
  display: grid;
  grid-template-columns: minmax(150px, 1fr) auto minmax(145px, .75fr) auto;
  align-items: center;
  gap: 8px;
  padding: 10px;
  background: var(--soft);
  border-radius: 6px 6px 0 0;
}

.template-group-name,
.template-field-name,
.template-field-type,
.template-field-group,
.template-group-mode,
.template-status-option {
  width: 100%;
  min-height: 32px;
  padding: 6px 7px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px;
  font: inherit;
}

.template-group-color {
  width: 44px;
  height: 32px;
  padding: 2px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px;
}

.template-header-colors,
.template-status-color-control {
  display: flex;
  align-items: center;
  gap: 5px;
  color: var(--muted);
  font-size: 10px;
}

.template-field-color-control {
  display: flex;
  align-items: center;
  grid-column: 1 / -1;
  flex-wrap: wrap;
  gap: 5px;
  color: var(--muted);
  font-size: 10px;
}

.template-field-color-control[hidden],
.template-field-actions[hidden] {
  display: none;
}

.template-field-color {
  width: 38px;
  height: 32px;
  padding: 2px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px;
}

.template-group-actions,
.template-field-actions,
.template-option-actions {
  display: flex;
  gap: 5px;
}

.template-mini-button {
  min-width: 30px;
  min-height: 30px;
  padding: 3px 7px;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px;
  cursor: pointer;
}

.template-mini-button:hover {
  color: var(--ink);
  background: var(--hover);
}

.template-mini-button.danger:hover { color: #b52626; }

.template-fields {
  display: grid;
  gap: 7px;
  padding: 10px;
}

.template-field-row {
  display: grid;
  grid-template-columns: minmax(145px, 1.35fr) minmax(105px, .75fr) minmax(125px, .95fr) auto;
  gap: 7px;
  align-items: start;
}

.template-field-actions {
  grid-column: 4;
  grid-row: 1;
}

.template-field-main {
  display: grid;
  gap: 5px;
}

.template-field-note,
.template-empty {
  color: var(--muted);
  font-size: 11px;
}

.template-status-options {
  grid-column: 1 / -1;
  display: grid;
  gap: 6px;
  margin-left: 14px;
  padding: 8px 0 2px 10px;
  border-left: 2px solid var(--line);
}

.template-status-option-row {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) auto auto;
  gap: 6px;
}

.template-status-color {
  width: 38px;
  height: 32px;
  padding: 2px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px;
}

.template-add-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding: 0 10px 10px;
}

.project-table .group-heading[data-custom-color] {
  color: var(--group-heading-ink, var(--ink));
  background: var(--group-heading-color);
}

.project-table thead .group-heading.sticky-column[data-custom-color] {
  color: var(--group-heading-ink, var(--ink));
  background: var(--group-heading-color);
}

.project-table .field-heading[data-custom-color] {
  color: var(--field-heading-ink, var(--ink));
  background: var(--field-heading-color);
}

.field-value-warning {
  display: block;
  margin-top: 4px;
  color: #b52626;
  font-size: 10px;
}

.file-button[aria-pressed="true"] {
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}

.file-button small {
  display: block;
  margin-top: 3px;
  color: var(--muted);
}

.upload-status {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  color: var(--muted);
  font-size: 10px;
}

.upload-status[data-state="uploading"] {
  color: #9a6400;
}

.upload-status[data-state="pending"] {
  color: #18733a;
}

.upload-status[data-state="failed"] {
  color: #b52626;
}

.upload-progress {
  width: 68px;
  height: 4px;
  overflow: hidden;
  background: var(--line);
  border-radius: 999px;
}

.upload-progress > span {
  display: block;
  height: 100%;
  background: currentColor;
  transition: width 160ms ease;
}

.retry-file {
  padding: 0;
  color: inherit;
  background: transparent;
  border: 0;
  cursor: pointer;
  font: inherit;
  text-decoration: underline;
}

.storage-dialog {
  width: min(560px, 100%);
}

.storage-health-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  padding: 18px 16px 12px;
}

.storage-health-card {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 104px;
  padding: 15px;
  background: var(--soft);
  border: 1px solid var(--line);
  border-radius: 8px;
}

.storage-health-card strong {
  font-size: 13px;
}

.storage-health-card p {
  margin: 7px 0 0;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.55;
}

.health-dot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  margin-top: 4px;
  background: #9c9c9c;
  border-radius: 50%;
}

.storage-health-card[data-state="checking"] .health-dot {
  background: #d79a24;
}

.storage-health-card[data-state="ok"] .health-dot {
  background: #42b66d;
}

.storage-health-card[data-state="error"] .health-dot,
.storage-health-card[data-state="missing"] .health-dot {
  background: #d85050;
}

.health-time {
  margin: 0;
  padding: 0 16px 16px;
  color: var(--muted);
  font-size: 11px;
}

.storage-note {
  margin: 0;
  padding: 0 16px 16px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.5;
}

.toast {
  position: absolute;
  left: 50%;
  bottom: 20px;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  color: var(--inverse-ink);
  background: var(--inverse);
  border-radius: 6px;
  box-shadow: 0 8px 28px var(--shadow);
  font-size: 12px;
  transform: translateX(-50%);
}

.undo-button {
  color: inherit;
  background: transparent;
  border: 0;
  cursor: pointer;
  text-decoration: underline;
}

@media (max-width: 760px) {
  .template-toolbar > span { width: 100%; margin-left: 0; }
  .template-position-control { align-items: stretch; flex-direction: column; width: 100%; }
  .template-position-control select { width: 100%; max-width: none; }
  .template-add-row { align-items: stretch; flex-direction: column; }
  .template-field-row { grid-template-columns: 1fr; }
  .template-field-actions { grid-column: 1; grid-row: auto; }
  .template-header-colors { grid-column: 1 / -1; flex-wrap: wrap; }
  .template-status-option-row { grid-template-columns: 1fr; }
  .template-status-options { grid-column: 1; margin-left: 0; }
  .template-group-row { grid-template-columns: minmax(120px, 1fr) 44px; }
  .template-group-mode { grid-column: 1 / -1; }
  .template-group-actions { grid-column: 1 / -1; }
  .storage-health-grid {
    grid-template-columns: 1fr;
  }
  #weekly-app {
    padding: 6px;
  }

  .app-window {
    height: calc(100vh - 12px);
    min-height: 620px;
  }

  .global-brand span:last-child,
  .global-actions .top-button:not(.theme-button):not(.strong) {
    display: none;
  }

  .workspace {
    --sidebar-width: 64px;
    grid-template-columns: var(--sidebar-width) 10px minmax(0, 1fr);
  }

  .sidebar-resizer::after {
    opacity: 0.45;
  }

  .sidebar {
    position: relative;
    z-index: 8;
    padding-inline: 7px;
  }

  .side-title,
  .person-details,
  .updated-dot,
  .side-foot,
  .staff-management,
  .remove-person {
    display: none;
  }

  .staff-panel-toggle {
    display: block;
    margin: 0 auto 8px;
  }

  .side-heading {
    display: block;
  }

  .staff-list {
    overflow: visible;
  }

  .person {
    justify-content: center;
    padding-inline: 0;
  }

  /* 侧栏折叠成 64px 图标列时，管理员操作按钮必然溢出，直接收起；
     展开面板（management-open）后再以「姓名行 + 操作行」两行式展示 */
  .sidebar:not(.management-open) .admin-row-actions {
    display: none;
  }

  .sidebar.management-open {
    position: relative;
    width: auto;
    padding: 14px 12px;
    box-shadow: 8px 0 20px rgb(0 0 0 / 12%);
  }

  .sidebar.management-open .side-heading {
    display: flex;
  }

  .sidebar.management-open .side-title,
  .sidebar.management-open .staff-management,
  .sidebar.management-open .person-details,
  .sidebar.management-open .updated-dot,
  .sidebar.management-open .side-foot,
  .sidebar.management-open .remove-person {
    display: flex;
  }

  .sidebar.management-open .side-title {
    margin-bottom: 10px;
  }

  .sidebar.management-open .staff-management {
    display: grid;
  }

  .sidebar.management-open .staff-list {
    overflow-y: auto;
  }

  .sidebar.management-open .person {
    justify-content: flex-start;
    overflow: hidden;
    padding-inline: 10px;
  }

  .sidebar.management-open .remove-person {
    position: relative;
    z-index: 2;
    display: block;
  }

  .person-bar,
  .content-area {
    padding-right: 12px;
    padding-left: 12px;
  }

  .person-actions .button:first-child {
    display: none;
  }

  .panel-tip {
    display: none;
  }

  .plan-grid {
    grid-template-columns: 1fr;
  }

  .plan-edit-grid {
    grid-template-columns: 1fr;
  }

  .modal {
    padding: 14px;
  }

  .file-list {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 430px) {
  .global-bar {
    gap: 8px;
    padding-inline: 9px;
  }

  .theme-button {
    min-width: auto;
  }

  .brand-logo {
    height: 22px;
  }

  .top-button {
    padding-inline: 8px;
  }

  .person-bar {
    align-items: flex-start;
  }

  /* 角色说明改为省略号截断（由 .identity p 的 nowrap+ellipsis 统一处理），
     不再限制 max-width —— 那会让长文本在窄屏上折成多行堆叠 */

  .week-line {
    align-items: flex-start;
    flex-direction: column;
  }

  .ai-toolbar,
  .ai-result-head,
  .ai-confirm-bar,
  .ai-history-head {
    align-items: stretch;
    flex-direction: column;
  }

  .ai-toolbar .button,
  .ai-confirm-bar .button {
    width: 100%;
  }

  /* 窄屏下工具条已改为纵向，两个按钮也随之各占一行 */
  .ai-toolbar-actions {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }
}

/* ── 找回密码 / 管理员功能 ── */
.login-link {
  display: block;
  width: 100%;
  margin-top: 10px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 13px;
  text-align: center;
  cursor: pointer;
}
.login-link:hover { color: var(--ink); text-decoration: underline; }

.admin-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: color-mix(in srgb, #04685b 14%, var(--surface));
  border-bottom: 1px solid color-mix(in srgb, #04685b 36%, var(--line));
  color: var(--ink);
  font-size: 13px;
}
/* 必须显式声明：上面的 display:flex 是作者样式，会盖掉浏览器默认的
   [hidden]{display:none}，导致「非管理员也一直显示管理员横幅」。 */
.admin-banner[hidden] { display: none; }
.admin-banner-mark {
  flex: none;
  padding: 2px 8px;
  border-radius: 999px;
  background: #04685b;
  color: #fff;
  font-weight: 700;
  font-size: 12px;
}
.admin-banner #admin-banner-text { flex: 1; }

/* 管理员操作子组：独占一整行并缩进对齐到名称起始位置（头像 30px + 头像与名称间距 10px + .person 内边距 10px = 50px），
   左侧加一条 subtle 竖线作为分组容器，让用户一眼看出操作作用于该条目。 */
.admin-row-actions {
  display: flex;
  flex: 1 1 100%;
  flex-wrap: wrap;
  min-width: 0;
  gap: 6px;
  padding-left: 50px;
  position: relative;
}
.admin-row-actions::before {
  content: "";
  position: absolute;
  left: 39px;
  top: 5px;
  bottom: 5px;
  width: 2px;
  background: var(--line);
  border-radius: 1px;
}
.person-row.has-admin-actions {
  column-gap: 6px;
}
/* 与「名称」同行的移除按钮不能再用 margin-left:auto，否则 auto margin 会吸走
   剩余空间，导致 .person 缩成最小内容宽（名称被压到 38px）。 */
.person-row.has-admin-actions .remove-person {
  margin-left: 0;
}
.admin-action {
  flex: none;
  padding: 3px 9px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.admin-action:hover { background: var(--hover); }
.admin-action.audit-delete { color: #b3261e; border-color: color-mix(in srgb, #b3261e 40%, var(--line)); }
/* 「删除账号」是不可逆操作，比其它管理操作给更高的视觉权重 */
.admin-action.danger { color: #b3261e; font-weight: 650; border-color: color-mix(in srgb, #b3261e 45%, var(--line)); }
.admin-action.danger:hover { background: color-mix(in srgb, #b3261e 12%, var(--surface)); }

.audit-dialog { max-width: 560px; }
.audit-list {
  list-style: none;
  margin: 4px 0;
  padding: 0;
  max-height: 52vh;
  overflow: auto;
}
.audit-item {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "meta del" "summary del";
  gap: 2px 12px;
  padding: 10px 2px;
  border-bottom: 1px solid var(--line);
}
.audit-meta { grid-area: meta; color: var(--muted); font-size: 12px; }
.audit-summary { grid-area: summary; margin: 0; color: var(--ink); font-size: 14px; }
.audit-delete { grid-area: del; align-self: center; }
.audit-empty { padding: 18px; color: var(--muted); text-align: center; }

