/* ============================================================
   达观交付工作台 ·「项目协作」— 外壳与原子 app.css
   设计系统：浅色多彩（冷灰白底 · 白卡 · 1px 浅线 + 柔影 · 靛蓝强调）
   约束：分隔一律 1px；层级靠 --sh-1/2，不叠第三层；字重 400 / 500 / 600；
        CJK 不加字距；全站同一时刻至多一个实心靛蓝主按钮；
        彩色只上小元素（图标砖 / 序号徽标 / 数字 / 色点），卡片本体恒白。
   分工：本文件 = 基础 + 三栏骨架 + 左栏 + 顶行 + 按钮 + 徽标 + 头像
        + 内联表单 + 分组标签 + 响应式护栏（所有页面共用）。
        各页面自己的视图样式（右栏面板 / 动态流 / 项目列表 / 任务详情 /
        项目资料 / 对话 / 任务卡 / 任务分组 / 工具箱 / 空态 / 样张页）见 views.css。
        加载顺序：theme.css（内含 tokens.css）→ app.css → views.css。
   ============================================================ */

/* ============ 0. 基础 ============ */
/* 禁用/主按钮的色值已由设计系统专家收进 :root（--disabled-bg / --disabled-fg / --accent-fg，
   见 DESIGN §3.5 与 §8.1），此处不再另起组件级局部变量（§8.3 第 13 条）。 */

*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg-page);
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4, p, figure, ul, ol { margin: 0; padding: 0; }
ul, ol { list-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
input { font: inherit; }
svg { display: block; }
/* 聚焦环：全站唯一允许的「光晕」，用 outline 实现。三条理由，主因是可访问性：
   ① forced-colors / 强制高对比模式（Windows）下，框阴影属性被强制为 none、聚焦环会整圈消失；
      outline 是浏览器聚焦指示的原生属性，在该模式下被系统重着色并保留。焦点必须始终可见。
   ② outline 自动跟随元素自身的 border-radius，故此处不得再声明 border-radius —— 多写会把
      .project-card 的 6px 圆角在聚焦瞬间改成 4px；且 outline 不参与布局、开销更低。
   ③ 副产品：全站框阴影计数恒为 0，硬禁 #1 可被 grep 一次机械判定。
   附注（勿再误传）：outline 与框阴影一样**都会被祖先 overflow 裁剪**，二者在这一点上无差异，
   因此「outline 不受祖先裁剪」不是理由（已由四组对照实验证伪：无内边距时两种环都消失，
   有内边距时两种环都完整）。本项目滚动容器内边距 12–16px ≥ 环 4px，故两种写法实际都不越界；
   若将来某容器改成零内边距，两种环会一起被裁，正解是保留内边距或改用负 outline-offset 的内嵌环。 */
:focus-visible { outline: 3px solid var(--accent-ring); outline-offset: 1px; }

/* ============ 1. 三栏骨架 ============ */
/* 浅色版：左栏用次级底与中栏分开（不再只靠一条 1px 线），右栏仍走线分隔 */
.app { display: flex; height: 100vh; overflow: hidden; background: var(--bg-page); }
.rail {
  width: var(--rail-w); flex: none;
  background: var(--bg-subtle);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  overflow-y: auto;
}
.main { flex: 1; min-width: 480px; display: flex; flex-direction: column; min-height: 0; background: var(--bg-page); }
.panel {
  width: var(--panel-w); flex: none;
  border-left: 1px solid var(--border);   /* 右栏与中栏之间：只有这一条 1px 线 */
  background: var(--card);
  display: flex; flex-direction: column; min-height: 0;
  transition: width .15s ease;
}
.panel.is-collapsed { width: var(--panel-w-collapsed); }

/* ============ 2. 左栏 ============ */
/* 品牌区是指回顶层工作台（index.html）的链接：内页都从这里退出工作台 */
.rail-head { padding: var(--space-4); border-bottom: 1px solid var(--border); }
.rail-brand { display: flex; align-items: center; }
.rail-logo {
  display: inline-block; font-size: var(--fs-label); font-weight: 600;
  color: var(--accent-fg); background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm); padding: 2px 7px; margin-right: var(--space-2);
  vertical-align: 1px; box-shadow: var(--accent-glow);
}
.rail-workbench { font-size: var(--fs-body); font-weight: 600; color: var(--text-primary); }

/* 一级恒为三项（工具箱 / 项目资料 / 项目管理），当前页的那一项带 .is-current */
.rail-group { padding: var(--space-3) var(--space-2); }
.rail-group + .rail-group { border-top: 1px solid var(--border); }
.rail-group-title {
  font-size: var(--fs-label); color: var(--text-tertiary);
  padding: 0 var(--space-2) var(--space-2);
}
.rail-project {
  display: flex; align-items: center;
  padding: var(--space-2); border-radius: var(--radius-sm);
  font-size: var(--fs-body); color: var(--text-secondary);
}
.rail-project:hover { background: var(--bg-hover); }
/* 选中项：白卡 + 左缘一条同色竖条（参考图左栏那一枚），不靠换字色撑焦点 */
.rail-project.is-current {
  color: var(--text-primary); font-weight: 600; background: var(--card);
  border-left: 3px solid var(--h); box-shadow: var(--sh-1);
}
.rail-project-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 第二组「当前项目」只在进入某个项目内部时出现，二级只有一项「资料」 */
.rail-sub {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2); border-radius: var(--radius-sm);
  font-size: var(--fs-body); color: var(--text-secondary);
}
.rail-sub:hover { background: var(--bg-hover); }
.rail-sub.is-active { color: var(--h); font-weight: 600; background: var(--h-soft); }

/* ============ 3. 中栏顶行（只放上下文 + 操作，不放大标题） ============ */
.main-head {
  flex: none; display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  min-height: 52px;
}
.crumb { font-size: var(--fs-subtitle); color: var(--text-secondary); }
.crumb .here { color: var(--text-primary); font-weight: 500; }
.crumb .sep { color: var(--text-tertiary); padding: 0 var(--space-1); }
.head-actions { margin-left: auto; display: flex; align-items: center; gap: var(--space-2); }

.main-scroll { flex: 1; min-height: 0; overflow-y: auto; }

/* ============ 4. 按钮 ============ */
/* 尺寸采用 DESIGN §8.2 的按钮片段：高 36px，与输入框同高（邀请页 §5.1 规格）。 */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1);
  height: 36px; padding: 0 var(--space-4); border-radius: var(--radius-sm);
  font-size: var(--fs-body-strong); font-weight: 600;
  border: 1px solid transparent; white-space: nowrap;
  transition: background-color .12s, border-color .12s, color .12s, box-shadow .12s, transform .12s;
}
/* 主按钮：全站唯一实心靛蓝，分时归属（见 project.html 说明）；柔影把它从白底上抬起来 */
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); box-shadow: var(--accent-glow); }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); transform: translateY(-1px); }
.btn-primary:active { background: var(--accent-active); border-color: var(--accent-active); transform: none; box-shadow: none; }
/* 禁用态：非实心强调，不占稀缺额度（§3.5） */
.btn-primary:disabled,
.btn-primary.is-disabled {
  background: var(--disabled-bg); border-color: var(--disabled-bg);
  color: var(--disabled-fg); cursor: not-allowed; box-shadow: none; transform: none;
}
/* 次级按钮 */
.btn-secondary { background: var(--card); border-color: var(--border-strong); color: var(--text-secondary); box-shadow: var(--sh-1); }
.btn-secondary:hover { background: var(--bg-hover); color: var(--text-primary); border-color: var(--accent-ring); }
.btn-secondary:disabled,
.btn-secondary.is-disabled { color: var(--text-disabled); border-color: var(--border); cursor: not-allowed; background: var(--bg-subtle); box-shadow: none; }
/* 幽灵按钮（无描边的工具按钮） */
.btn-ghost { background: transparent; border-color: transparent; color: var(--text-secondary); }
.btn-ghost:hover { background: var(--bg-hover); color: var(--text-primary); }
/* 文本链接式行内动作。规格与既有工作台「邀请管理」§5.5 同源（--fs-body / --text-secondary）。
   默认色是「次级文字」而非强调色 —— 行内动作往往同类重复（资料行的「打开」、右栏的「查看」），
   若全部上强调色就构成「动作同色」缺陷：重点与非重点不分、强调色被稀释。层级由「形态」承担，
   不靠颜色；强调色只留给页面级 / 区域级的唯一实心动作（.btn-primary）与品牌标识（.rail-logo）。 */
.btn-link { color: var(--text-secondary); font-size: var(--fs-body); font-weight: 400; padding: 2px 0; }
.btn-link:hover { color: var(--accent); }                   /* 悬停才转强调，作为「可点」反馈 */
.btn-link--muted { color: var(--text-tertiary); }           /* 更次级：可省的行内动作 */
.btn-link--muted:hover { color: var(--text-secondary); }
/* 注：DESIGN §8.2 另定义了 .btn-link--danger:hover（破坏性行内动作，沿用邀请页 §5.5 的
   --danger + --danger-tint 底）。本模块（项目协作）不含「作废 / 删除 / 移除」类动作
   （--danger 令牌在本模块无使用点），故此处不定义该规则，以免留下无引用的死代码。 */

/* ============ 5. 状态徽标（颜色 + 文字 + 图标 三重信号） ============ */
/* 徽标内只放「图标 + 文字」，不叠圆点（§8.3 第 5 条）：图标与圆点是同一槽位的二选一，
   本产品 5 状态各配一枚语义不同的线形图标，信息量高于纯色圆点，故取图标。
   --tst-*-dot 五枚令牌仍保留，唯一允许用途是列表视图行内极窄位退回「圆点 + 文字」（与图标不得同现）。 */
.badge {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: var(--fs-label); font-weight: 600; line-height: 1.4;
  padding: 2px 8px; border-radius: 999px; flex: none;
}
/* JS 渲染与手写徽标两条路径统一：图标即 .badge 的直接子 svg */
.badge > svg { flex: none; }
.badge.todo   { color: var(--tst-todo-fg);   background: var(--tst-todo-bg); }
.badge.doing  { color: var(--tst-doing-fg);  background: var(--tst-doing-bg); }
.badge.review { color: var(--tst-review-fg); background: var(--tst-review-bg); }
.badge.done   { color: var(--tst-done-fg);   background: var(--tst-done-bg); }
.badge.stuck  { color: var(--tst-stuck-fg);  background: var(--tst-stuck-bg); }

/* ============ 6. 身份徽标与头像 ============ */
.idtag {
  display: inline-flex; align-items: center; gap: var(--space-1);
  font-size: var(--fs-label); font-weight: 500; line-height: 1.4;
  padding: 1px 6px; border-radius: var(--radius-sm); border: 1px solid var(--border);
  flex: none;
}
.idtag .dot { width: 6px; height: 6px; border-radius: 50%; flex: none; }
.idtag.human  { color: var(--id-human-fg);  background: var(--id-human-bg); }
.idtag.human .dot  { background: var(--id-human-dot); }
.idtag.butler { color: var(--id-butler-fg); background: var(--id-butler-bg); }
.idtag.butler .dot { background: var(--id-butler-dot); }
.idtag.worker { color: var(--id-worker-fg); background: var(--id-worker-bg); }
.idtag.worker .dot { background: var(--id-worker-dot); }

.avatar {
  width: 24px; height: 24px; border-radius: 50%;
  border: 1px solid var(--border-strong); flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--fs-label); font-weight: 600; color: var(--text-secondary);
  background: var(--card);
}
.avatar.sm { width: 18px; height: 18px; }
.avatar.xs { width: 20px; height: 20px; }
.avatar.butler { background: var(--id-butler-bg); color: var(--id-butler-fg); }
.avatar.worker { background: var(--id-worker-bg); color: var(--id-worker-fg); }

/* 任务卡负责人处：人的微徽标不出现，Agent 追加「管 / 工」单字微徽标 */
.idmini {
  display: inline-flex; align-items: center; gap: 2px;
  font-size: var(--fs-label); font-weight: 500; line-height: 1;
  padding: 1px 4px; border-radius: var(--radius-sm); border: 1px solid var(--border);
}
.idmini.butler { color: var(--id-butler-fg); background: var(--id-butler-bg); border-color: var(--id-butler-dot); }
.idmini.worker { color: var(--id-worker-fg); background: var(--id-worker-bg); border-color: var(--id-worker-dot); }

/* 成员行（人和 Agent 同行并排，不分组、不加分隔标题） */
.member-row {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
}
.member-row:hover { background: var(--bg-hover); }
.member-name { font-size: var(--fs-body); font-weight: 500; color: var(--text-primary); }
.member-info { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.member-role { font-size: var(--fs-caption); color: var(--text-tertiary); }
.member-note { font-size: var(--fs-caption); color: var(--text-tertiary); }
.member-right { margin-left: auto; display: flex; align-items: center; gap: var(--space-3); }

/* ============ 7. 列表里的两处安静文本 ============ */
/* 「未指派」需 nowrap：CJK 之间默认可断行，若不锁住，窄位下它会被逐字拆成两行（「未指 / 派」）。 */
.assignee--none { font-size: var(--fs-caption); color: var(--text-tertiary); white-space: nowrap; }
/* 空列表 / 空产出的一行说明（任务详情的「产出」区用到） */
.col-empty { font-size: var(--fs-caption); color: var(--text-tertiary); padding: var(--space-2) 0; }

/* ============ 8. 内联表单（就地展开，不弹窗） ============ */
/* 仅用于「新建项目」（projects.html）。本产品不提供任何手动新建任务的入口。 */
.inline-form {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
}
.inline-form[hidden] { display: none; }
.input {
  height: 36px; padding: 0 var(--space-3);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--card); color: var(--text-primary); font-size: var(--fs-body);
  outline: none;
}
.input::placeholder { color: var(--text-placeholder); }
.input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.inline-form .input { flex: 1; }

/* ============ 11. 分组标签 ============ */
.group-label { font-size: var(--fs-label); color: var(--text-tertiary); padding: var(--space-4) var(--space-4) var(--space-2); }

/* ============ 12. 响应式护栏（主战场 ≥1180px；窄屏只保证不错位） ============ */
/* 三栏骨架在窄屏收窄两栏宽度，给中栏（对话 / 内容）留出可排宽。
   1264px 这个断点是照「中栏最小排宽」定的：视口 1265–1440 用默认宽度，
   进入 1264 及以下左右栏各收 24–40px。全区间（1440 / 1280 / 1180）
   实测无横向溢出，下界 = 1180px。核算见 DESIGN §4.1、§9。 */
@media (max-width: 1264px) {
  .rail { width: 200px; }
  .panel { width: 280px; }
}
