/* workbench.css —— /opc/workbench「我的任务工作台」专属样式
 * 移植自原站 OPC 办公室内联 <style>（1:1 像素级复刻）。
 * 共享 chrome（.theme-btn / .lang-wrap / .lang-menu / .lang-opt / .logo / .toast 等）
 * 来自 opc.css；本文件覆盖 .wrap 宽度（1080px）并定义 workbench 专属组件。
 * 改文件请同步升版本戳：workbench.css?v=<版本>。 */

/* 防闪烁门控（与原站内联一致；i18n-core 亦会注入同效规则，重复无害） */
html.i18n-pending body { visibility: hidden; }

/* 本页不重声明任何基础 token —— 全部来自 opc.css（内含 tokens.css 唯一源）；见 DESIGN-SYSTEM.md §4#1。 */

/* ── 层级标尺（本页浮层 z-index 的唯一事实源；加浮层先看这张表）─────────────────────────
 *  120  .drawer-mask   抽屉遮罩
 *  121  .drawer        详情抽屉（**必须** > 页眉的 100，见下方注释：否则抽屉从页眉下穿过）
 *  140  .confirm-mask  页面内确认浮层（**必须** > 抽屉：否则「批准/驳回」弹窗被抽屉盖住，点不到）
 *  160  .toast         轻提示（最高：错误提示常在抽屉开着时弹出，不能被抽屉吃掉）
 *
 * ⚠️ 三条浮层的 DOM 都在 `body` 直系（workbench.html 尾部，与 .wrap 平级），祖先链上没有
 *    transform / filter / opacity / will-change ⇒ 不会新建 stacking context，这里的 z-index
 *    直接参与 body 根上下文的比较，不会被「局部层级」吃掉。
 *    2026-10-01 修复：.confirm-mask 原为 z-index:70（照抄原站抽屉 61 的旧口径），而本页抽屉已抬到
 *    121 ⇒ 弹窗恒在抽屉之下，老板实测「必须关掉右侧卡才能点」。现按上表定档。
 *    改动后请同步升 workbench.css 版本戳（见 workbench.html 的 ?v=）。 */

* { box-sizing: border-box; margin: 0; padding: 0; }
body { background: var(--bg); color: var(--fg); font-family: -apple-system, "Segoe UI", Roboto, "PingFang SC", "Microsoft YaHei", sans-serif; }
.wrap { max-width: 1080px; margin: 0 auto; padding: 8px 24px 40px; }
header { display: flex; align-items: center; justify-content: space-between; padding: 12px 0; border-bottom: 1px solid var(--border); margin-bottom: 20px; }
.logo { display: flex; align-items: center; gap: 10px; font-weight: 600; }
.logo svg { width: 26px; height: 26px; color: var(--accent); }
.logo .sub { color: var(--muted); font-weight: 400; font-size: 13px; margin-left: 4px; }
.hdr-actions { display: flex; align-items: center; gap: 12px; }
.back { font-size: 13px; color: var(--muted); text-decoration: none; display: inline-flex; align-items: center; gap: 5px; }
.back:hover { color: var(--fg); }
.theme-btn:disabled { opacity: .55; cursor: default; }
/* 点击反馈：按钮内 loading 转圈（中性 SVG，currentColor） */
.theme-btn .spin { width: 13px; height: 13px; animation: wb-spin .9s linear infinite; flex-shrink: 0; }
@keyframes wb-spin { to { transform: rotate(360deg); } }

.hero { padding: 8px 0 4px; }
.hero-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.hero-title { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; flex: 1 1 auto; min-width: 0; }
.hero h1 { font-size: 26px; font-weight: 700; letter-spacing: .01em; }
.hero .en { font-family: ui-monospace, Menlo, monospace; font-size: 12px; color: var(--muted); font-weight: 500; }
.hero p { color: var(--muted); font-size: 14px; margin-top: 10px; line-height: 1.7; overflow-wrap: break-word; max-width: none; }
.hero .hero-actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.hero .hero-actions .theme-btn { display: inline-flex; align-items: center; gap: 7px; }
.hero .hero-actions .act-ico { width: 14px; height: 14px; flex-shrink: 0; }
.hero .ts { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; margin-top: 8px; }
/* 本地活数据标识：**只在活数据模式显示**（线上演示数据下 JS 把它 hidden 掉，1:1 外观不受影响）。
   用途＝让「这页现在吃的是真数据还是演示数据」一眼可见，是活/演示隔离的可视证据。
   文字色按 DESIGN-SYSTEM.md §1.3.1「语义色文字档」：就地混 --fg，一条声明同覆盖亮/暗两态
   （原来直用 var(--green)，亮态实测 2.79:1 < AA 4.5；改后见 §6 变更记录 t_4824cfc7）。 */
.hero .live-badge { display: inline-block; margin-left: 8px; padding: 1px 8px; border-radius: var(--radius-pill); font-size: 11px; font-weight: 600; color: color-mix(in srgb, var(--green) 65%, var(--fg)); background: var(--accent-soft); border: 1px solid var(--border); vertical-align: 1px; }
.hero .live-badge[hidden] { display: none; }

/* 登录横幅（写操作门禁；读公开） */
.login-banner { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 12px 16px; margin-top: 16px; }
.login-banner .lb-ico { width: 18px; height: 18px; color: var(--amber); flex-shrink: 0; }
.login-banner .lb-txt { font-size: 13px; color: var(--muted); flex: 1; min-width: 200px; line-height: 1.6; }
.login-banner input { border: 1px solid var(--border); background: var(--bg); color: var(--fg); border-radius: var(--radius-sm); padding: 8px 12px; font-size: 13px; min-width: 180px; }
.login-banner .lb-err { color: color-mix(in srgb, var(--danger) 65%, var(--fg)); font-size: 12.5px; }

/* KPI */
.kpis { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 18px 0 6px; }
.kpi { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 14px 16px; }
.kpi .k-label { font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 6px; }
.kpi .k-label svg { width: 13px; height: 13px; stroke: currentColor; flex-shrink: 0; }
.kpi .k-num { font-size: 22px; font-weight: 700; margin-top: 8px; font-variant-numeric: tabular-nums; letter-spacing: .01em; }

/* 区块 */
.section { margin-top: 26px; }
.section-title { display: flex; align-items: baseline; gap: 10px; margin-bottom: 12px; }
.section-title h2 { font-size: 17px; font-weight: 700; }
.section-title .tag { font-family: ui-monospace, Menlo, monospace; font-size: 11px; color: var(--muted); font-weight: 500; }
/* 分区说明行（知情分区用：讲清「这不是要你动手的事」） */
.sec-hint { font-size: 12px; line-height: 1.55; color: var(--muted); margin: -4px 0 12px; }

/* 卡片列表 */
.task-list { display: flex; flex-direction: column; gap: 10px; }
.task-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 12px 16px; cursor: pointer; transition: border-color .15s; }
.task-card:hover { border-color: var(--accent); }
.task-card .row1 { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.task-card .tt { font-weight: 600; font-size: 14px; line-height: 1.5; flex: 1; min-width: 220px; }
.task-card .meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 14px; margin-top: 8px; font-size: 12px; color: var(--muted); }
.task-card .meta .id { font-family: ui-monospace, Menlo, monospace; font-size: 11px; }
.task-card .meta .who { font-weight: 600; color: var(--fg); }
.task-card .meta .tm { font-variant-numeric: tabular-nums; }
.badge { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600; padding: 2px 10px; border-radius: var(--radius-pill); border: 1px solid var(--border); color: var(--muted); background: var(--card); white-space: nowrap; }
.badge.b-blocked { color: color-mix(in srgb, var(--amber) 65%, var(--fg)); border-color: rgba(180,83,9,.4); background: rgba(180,83,9,.08); }
.badge.b-running { color: color-mix(in srgb, var(--green) 65%, var(--fg)); border-color: rgba(22,163,74,.4); background: rgba(22,163,74,.08); }
/* 退让态：**不用 opacity** —— `opacity` 会把文字连同自身底色/描边整体按 alpha 合成到祖先底上，
   实测（像素口径 probe_contrast_px.cjs）亮 2.53 / 暗 3.72（.65）、亮 2.00 / 暗 2.72（.5），远低于 AA 4.5:1。
   改用 §1.3.1「文字档」：muted 80%/90% + var(--fg)，mode-agnostic 一条覆盖亮暗两态；
   弱化语义交给**灰度文字 + 更浅描边**（已归档比已完成再轻一档）。t_fb5569b9 */
.badge.b-done { color: color-mix(in srgb, var(--muted) 80%, var(--fg)); border-color: color-mix(in srgb, var(--border) 70%, transparent); }
.badge.b-todo { color: var(--fg); border-color: var(--border); background: var(--accent-soft); }
.badge.b-ready { color: color-mix(in srgb, var(--green) 65%, var(--fg)); border-color: rgba(22,163,74,.4); }
.badge.b-review { color: color-mix(in srgb, #7c3aed 65%, var(--fg)); border-color: rgba(124,58,237,.4); background: rgba(124,58,237,.08); }
.badge.b-archived { color: color-mix(in srgb, var(--muted) 90%, var(--fg)); border-color: color-mix(in srgb, var(--border) 45%, transparent); }
.badge.pri { background: var(--border); color: color-mix(in srgb, var(--muted) 80%, var(--fg)); font-weight: 600; }
.empty { padding: 30px 16px; text-align: center; color: var(--muted); font-size: 13px; background: var(--card); border: 1px dashed var(--border); border-radius: var(--radius-lg); }

/* 详情抽屉 */
body.drawer-open { overflow: hidden; overscroll-behavior: none; }
/* ⚠️ 遮罩/抽屉的层级必须高于页眉：style.css 给 `header` 定了 `position:relative; z-index:100`，
   而页眉本身没有背景色 ⇒ 若层级低于它，抽屉会从页眉“底下”穿过，看起来就是「顶部导航栏变透明」。
   （页眉无背景是 style.css 的设计，故此处用抬高层级来解，不动页眉本身。） */
.drawer-mask { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 120; display: none; }
.drawer-mask.open { display: block; }
.drawer { position: fixed; top: 0; bottom: 0; inset-inline-end: 0; width: min(560px, 94vw); background: var(--bg); border-inline-start: 1px solid var(--border); z-index: 121; transform: translateX(102%); transition: transform .22s ease; display: flex; flex-direction: column; }
[dir="rtl"] .drawer { transform: translateX(-102%); }
.drawer.open { transform: translateX(0); }
.drawer-head { display: flex; align-items: center; gap: 10px; padding: 16px 20px; border-bottom: 1px solid var(--border); background: var(--card); }
.drawer-head h3 { font-size: 15px; font-weight: 700; flex: 1; line-height: 1.5; }
.drawer-body { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 18px 20px 28px; }
.drawer-body h4 { font-size: 13px; font-weight: 700; margin: 18px 0 8px; display: flex; align-items: baseline; gap: 8px; }
.drawer-body h4 .n { font-family: ui-monospace, Menlo, monospace; font-size: 11px; color: var(--muted); font-weight: 500; }
.meta-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 14px; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 12px 14px; font-size: 12.5px; }
.meta-grid .m-item { min-width: 0; }
.meta-grid .m-item .mk { font-size: 11px; color: var(--muted); }
.meta-grid .m-item .mv { margin-top: 2px; word-break: break-word; font-variant-numeric: tabular-nums; }
.body-box { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 14px 16px; font-size: 13px; line-height: 1.75; word-break: break-word; }
.body-box h1, .body-box h2, .body-box h3, .cmt .c-body h1, .cmt .c-body h2, .cmt .c-body h3 { font-size: 15px; font-weight: 700; margin: 14px 0 6px; line-height: 1.45; }
.body-box h2, .cmt .c-body h2 { font-size: 14px; }
.body-box h3, .cmt .c-body h3 { font-size: 13.5px; }
.body-box p, .cmt .c-body p { margin: 0 0 8px; }
.body-box p:last-child, .cmt .c-body p:last-child { margin-bottom: 0; }
.body-box ul, .body-box ol, .cmt .c-body ul, .cmt .c-body ol { margin: 4px 0 8px; padding-inline-start: 22px; }
.body-box li, .cmt .c-body li { margin: 3px 0; }
.body-box code, .cmt .c-body code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 1px 5px; word-break: break-all; }
.body-box pre, .cmt .c-body pre { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 10px 12px; overflow-x: auto; margin: 8px 0; }
.body-box pre code, .cmt .c-body pre code { background: none; border: none; padding: 0; word-break: normal; white-space: pre; }
.body-box a, .cmt .c-body a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; word-break: break-all; }
.body-box strong, .cmt .c-body strong { font-weight: 700; }
.body-box em, .cmt .c-body em { font-style: italic; }
.body-box .tbl-wrap, .cmt .c-body .tbl-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 8px 0; }
.body-box table, .cmt .c-body table { border-collapse: collapse; width: max-content; min-width: 100%; font-size: 12.5px; }
.body-box th, .body-box td, .cmt .c-body th, .cmt .c-body td { border: 1px solid var(--border); padding: 5px 9px; text-align: left; white-space: nowrap; }
.body-box td.wrap, .cmt .c-body td.wrap { max-width: 34em; overflow-wrap: anywhere; white-space: normal; }
.body-box th, .cmt .c-body th { background: var(--bg); font-weight: 600; }
.body-box blockquote, .cmt .c-body blockquote { border-left: 3px solid var(--border); padding-left: 10px; color: var(--muted); margin: 8px 0; }
.body-box hr, .cmt .c-body hr { border: none; border-top: 1px solid var(--border); margin: 12px 0; }
.body-box img, .cmt .c-body img { max-width: 100%; height: auto; border-radius: var(--radius-md); border: 1px solid var(--border); display: block; margin: 8px auto; }
.cmt { border-inline-start: 2px solid var(--border); padding: 4px 0 4px 12px; margin-bottom: 12px; }
.cmt .c-head { display: flex; align-items: baseline; gap: 8px; font-size: 12px; color: var(--muted); }
.cmt .c-head b { color: var(--fg); font-weight: 600; }
.cmt .c-body { font-size: 13px; margin-top: 4px; word-break: break-word; line-height: 1.65; }
.evt { display: flex; gap: 8px; align-items: baseline; font-size: 12px; margin-bottom: 8px; }
.evt .e-toggle { flex-shrink: 0; width: 12px; color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; }
.evt .e-toggle svg { width: 10px; height: 10px; transition: transform .15s ease; }
.evt.open .e-toggle svg { transform: rotate(90deg); }
.evt-x { cursor: pointer; border-radius: var(--radius-sm); }
.evt-x:hover .e-p { color: var(--fg); }
.evt .e-time { font-family: ui-monospace, Menlo, monospace; font-size: 11px; color: var(--muted); flex-shrink: 0; font-variant-numeric: tabular-nums; }
.evt .e-kind { font-family: ui-monospace, Menlo, monospace; font-size: 11px; font-weight: 600; color: var(--fg); flex-shrink: 0; min-width: 84px; }
.evt .e-p { color: var(--muted); word-break: break-word; }
.evt-json { margin: -2px 0 10px 20px; }
.evt-json pre { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 10px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 11px; line-height: 1.55; overflow-x: auto; margin: 0; white-space: pre; }

/* 详情未加载 / 取数失败的可见提示（卡 t_abdf06c5）：抽屉打开时按 id 补取实时详情，
   取不到（需登录 / 后端不可达）必须明说 —— 不让「不可见」看起来像「不存在」。
   语义色走 DESIGN-SYSTEM.md §1.3.1「文字档」（amber 65% + var(--fg)），mode-agnostic。 */
.drawer-note { font-size: 12.5px; line-height: 1.6; color: var(--muted); background: var(--card); border: 1px dashed var(--border); border-radius: var(--radius-md); padding: 10px 12px; margin: 12px 0 0; word-break: break-word; }
.drawer-note.warn { color: color-mix(in srgb, var(--amber) 65%, var(--fg)); border-color: rgba(180,83,9,.4); background: rgba(180,83,9,.08); }
.drawer-note .link-btn { background: none; border: none; padding: 0; margin-inline-start: 6px; color: var(--accent); font: inherit; font-weight: 600; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.drawer-note .link-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-sm); }

/* ---- 任务卡「动作区 + 确认浮层」：已搬到 opc.css（卡 t_ba16e830, 2026-10-05）--------
   原因：这套标记现在**两页都有**（看板 tab 的详情弹窗 + 本页抽屉都能处理卡，实现同一份
   kanban-actions.js）⇒ 样式落在两页都加载的 opc.css，避免两份副本漂移。
   搬走的规则（值一个没改）：.drawer-close / .fb-form / .fb-actions / .fb-btn* / .fb-hint /
   .fb-login / .confirm-mask / .confirm-box / .confirm-head / .confirm-body / .confirm-actions。
   本页层级口径仍见上方「层级标尺」：确认浮层 140（opc.css 里定义）> 抽屉 121 > 页眉 100。 */

.err-bar { display: none; background: var(--danger); color: #fff; font-size: 13px; padding: 10px 16px; border-radius: var(--radius-md); margin: 14px 0; }
/* toast：按顶部「层级标尺」取 160 —— 最高层。原为 80（低于抽屉 121）⇒ 抽屉开着时的
   「操作失败」提示会被抽屉吃掉，看不到。 */
.toast { position: fixed; bottom: 28px; left: 50%; transform: translateX(-50%); background: var(--fg); color: var(--bg); font-size: 13px; padding: 10px 18px; border-radius: var(--radius-pill); z-index: 160; opacity: 0; pointer-events: none; transition: opacity .25s; max-width: 88vw; text-align: center; }
.toast.show { opacity: 1; }
.toast.err { background: var(--danger); color: #fff; }

footer { margin-top: 34px; padding-top: 16px; border-top: 1px solid var(--border); font-size: 12px; color: var(--muted); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; }
footer a { color: var(--muted); text-decoration: none; }
footer a:hover { color: var(--fg); }

@media (max-width: 640px) {
  .wrap { padding: 8px 14px 32px; }
  .hero h1 { font-size: 22px; }
  .kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .kpi { padding: 12px 10px; }
  .kpi .k-num { font-size: 16px; }
  .back { min-height: 44px; }
  .back span { display: none; }
  .back { min-width: 44px; justify-content: center; }
  .logo .sub { display: none; }
  .hdr-actions { gap: 8px; }
  header { flex-wrap: wrap; gap: 4px 12px; }
  .hdr-actions { margin-left: auto; }
  .meta-grid { grid-template-columns: 1fr; }
}

/* ---- 暗色态语义色覆写：已删除（t_58117aba, 2026-10-02）------------------------
   历史（t_6ec7528c）：.badge.b-blocked 曾在暗色态挂一条 [data-theme="dark"] 覆写（amber 72%）。
   t_58117aba 把「语义色承载文字」全量统一为 mode-agnostic 文字档（amber 65% + var(--fg)）
   后，该覆写成冗余（且 65% 的余量更大）⇒ 删除。当前值见上面 .badge.b-blocked 的主规则。 */

/* 名册外标识的展示名标记（卡 t_6e397924）：与 opc.css 的 .who-unknown 同款（琥珀 + 点线下划，
   扫一眼就能发现同类脏数据）。本页原先没有这条 —— 加了 whoHtml() 之后标记要有样式，不然
   与 opc 看板页两副面孔。 */
.who-unknown { color: var(--state-yellow); border-bottom: 1px dotted var(--state-yellow); cursor: help; }
