/* ============================================================================
 * Claude Code 任务监控 —— 样式表（浅色主题）
 * 全部颜色集中在 :root 变量里；不引用任何外网字体/图片（只用系统字体栈）。
 * ========================================================================== */

/* ============================ 基础 / 浅色主题 ============================ */
:root{
  /* —— 浅色配色（对比度见 README 说明：正文 #1f2937 对底 13.6:1，次要 #6b7280 对白卡 4.83:1） —— */
  --bg:#f5f7fa;            /* 页面底 */
  --card:#ffffff;          /* 卡片面 */
  --card2:#f1f3f7;         /* 次级面（按下态 / 表头） */
  --fg:#1f2937;            /* 主文本 */
  --muted:#6b7280;         /* 次要文本 */
  --line:#e5e7eb;          /* 边框 */
  --blue:#2563eb;          /* 主色 */
  --blue-soft:rgba(37,99,235,.07);
  --blue-line:rgba(37,99,235,.22);
  --blue-ink:#1e3a8a;      /* 蓝色浅底上的文字 */
  --green:#16a34a;         /* 状态：运行中 */
  --green-fg:#15803d;
  --green-soft:rgba(22,163,74,.10);
  --red:#dc2626;           /* 状态：失败 / 中断 */
  --red-fg:#dc2626;
  --red-soft:rgba(220,38,38,.08);
  --gray:#9ca3af;          /* 状态：已结束 / 中性（用于圆点、边框） */
  --gray-fg:#6b7280;       /* 灰色文字用更深一档，保证可读 */
  --gray-soft:rgba(107,114,128,.10);
  --yellow:#ca8a04;        /* 状态：未知 */
  --yellow-fg:#a16207;
  --yellow-soft:rgba(202,138,4,.12);
  --amber:#d97706;         /* 状态：超轮次（撞 --max-turns 上限，SPEC4 第 5 节） */
  --amber-bg:#fef3c7;
  --amber-line:rgba(217,119,6,.4);
  /* —— 分组块底色（#fafafa）上的文字：对比度 ≥ 4.5:1 ——
     下面几个值原是为更深的旧底色选定的，换成更浅的 #fafafa 后对比度只增不减，故保留不动 */
  --muted-2:#5f6673;       /* 对 #fafafa 5.5:1 */
  --green-ink:#146b34;     /* 对 #fafafa 6.3:1 */
  --red-ink:#b91c1c;       /* 对 #fafafa 6.2:1 */
  --grouphead:#fafafa;     /* 分组块底色（组头 + 展开区共用）：比子任务卡片(#ffffff)深一档 */
  --code-bg:#f6f8fa;       /* 代码块底 */
  --code-fg:#334155;
  --shadow:0 1px 2px rgba(16,24,40,.04),0 1px 3px rgba(16,24,40,.05);
  /* 顶栏高度的唯一来源：列表页与详情页共用，两边必须严格同高 */
  --topbar-h:56px;
  --safe-b:env(safe-area-inset-bottom,0px);
  --safe-t:env(safe-area-inset-top,0px);
  /* 顶栏的「可见总高」= 固定高 + 安全区；安全区只作顶部内边距，不混进 --topbar-h */
  --topbar-total:calc(var(--topbar-h) + var(--safe-t));
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0;background:var(--bg);color:var(--fg);
  font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  font-size:15px;line-height:1.55;-webkit-text-size-adjust:100%}
a{color:var(--blue);text-decoration:none}
button{font-family:inherit;font-size:inherit;color:inherit;background:none;border:none;cursor:pointer}
/* 长路径/长 UUID 一律允许折行，避免撑破 375px 视口 */
.uuid,.path,.fp,.kv .v{word-break:break-all}

/* ============================ 布局骨架 ============================ */
.shell{max-width:820px;margin:0 auto;padding:0 12px;padding-bottom:calc(76px + var(--safe-b))}
.shell.detail-mode{padding-bottom:calc(18px + var(--safe-b))}
/* 顶栏：固定高度（不靠内容撑开），列表页与详情页共用同一份规则，
   故两页高度、底边框、阴影、吸顶行为必然一致 */
.topbar{position:sticky;top:0;z-index:20;background:rgba(245,247,250,.94);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line);
  box-shadow:0 1px 2px rgba(16,24,40,.03);
  height:var(--topbar-total);
  padding:var(--safe-t) 12px 0;
  margin:0 -12px;display:flex;align-items:center;gap:10px;
  overflow:hidden}
.topbar .title{font-weight:600;font-size:15px;flex:1 1 auto;min-width:0;line-height:1.25;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.topbar .back{flex:0 0 auto;width:44px;height:44px;display:flex;align-items:center;justify-content:center;
  font-size:22px;margin-left:-10px;color:var(--fg);border-radius:10px;transition:background .15s}
.topbar .back:active{background:var(--card2)}
/* 详情页顶栏右侧的状态徽标：与返回按钮、任务名同一垂直基线（都在固定高度内居中） */
.topbar .tstate{flex:0 0 auto;display:flex;align-items:center;gap:5px;font-size:11.5px;
  padding:3px 9px;border-radius:999px;border:1px solid var(--line);background:var(--card2);
  color:var(--muted);white-space:nowrap}
.topbar .tstate.running{color:var(--green-fg);border-color:rgba(22,163,74,.35);background:var(--green-soft)}
.topbar .tstate.failed,.topbar .tstate.killed{color:var(--red-fg);border-color:rgba(220,38,38,.35);background:var(--red-soft)}
.topbar .tstate.overrun{color:var(--amber);border-color:var(--amber-line);background:var(--amber-bg)}
.topbar .tstate.unknown{color:var(--yellow-fg);border-color:rgba(202,138,4,.4);background:var(--yellow-soft)}
.topbar .tstate .dot{margin:0;width:8px;height:8px;margin-top:0}
/* 顶栏最右侧的「显示已隐藏 (N)」开关（SPEC4 第 3 节）。
   高度固定 36px < 56px，flex:0 0 auto，不会把顶栏撑高，列表页与详情页仍严格同高 */
.topbar .hbadge{flex:0 0 auto;display:flex;align-items:center;gap:6px;height:36px;
  padding:0 12px;border:1px solid var(--line);border-radius:999px;background:var(--card2);
  color:var(--muted);font-size:12.5px;font-variant-numeric:tabular-nums;white-space:nowrap;
  transition:color .15s,border-color .15s,background .15s}
.topbar .hbadge .hico{font-size:13px;line-height:1}
.topbar .hbadge .hcnt{font-weight:600;font-size:13px}
.topbar .hbadge:active{background:var(--line)}
.topbar .hbadge.on{color:var(--blue-ink);border-color:var(--blue-line);background:var(--blue-soft)}
.overview{display:flex;flex-wrap:wrap;gap:4px 12px;font-size:12.5px;color:var(--muted);padding:10px 2px 4px}
.overview b{font-weight:600;color:var(--fg);font-variant-numeric:tabular-nums}
.overview b.green{color:var(--green-fg)}
.overview b.red{color:var(--red-fg)}
.overview b.amber{color:var(--amber)}
/* 页面过渡容器：overflow-x:clip 只裁剪横向（不是滚动容器，故内部 sticky 仍相对视口生效），
   保证「详情从右侧滑入」这类位移不会在 375px 上产生横向滚动条 */
.view{position:relative;overflow-x:clip;overflow-y:visible}

/* ============================ 底部 tab ============================ */
.tabbar{position:fixed;left:0;right:0;bottom:0;z-index:30;display:flex;
  background:rgba(255,255,255,.96);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  border-top:1px solid var(--line);padding-bottom:var(--safe-b);
  max-width:820px;margin:0 auto;box-shadow:0 -1px 3px rgba(16,24,40,.04)}
.tabbar button{flex:1;min-width:0;min-height:56px;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:2px;font-size:11.5px;color:var(--muted);
  transition:color .15s,transform .08s}
.tabbar button .ico{font-size:18px;line-height:1}
.tabbar button.on{color:var(--blue);font-weight:600}
.tabbar button.on .ico{color:var(--blue)}
.tabbar button:active{transform:scale(.96)}

/* ============================ 任务卡片 ============================ */
.card{background:var(--card);border:1px solid var(--line);border-radius:12px;
  padding:12px;margin:10px 0;display:block;width:100%;text-align:left;min-height:44px;
  box-shadow:var(--shadow);transition:background .15s,transform .08s}
.card:active{background:var(--card2);transform:scale(.995)}
.card .row1{display:flex;align-items:flex-start;gap:9px}
.dot{width:10px;height:10px;border-radius:50%;flex:0 0 auto;margin-top:6px;background:var(--gray)}
.dot.running{background:var(--green);animation:pulse 1.5s infinite}
.dot.finished{background:var(--gray)}
.dot.failed,.dot.killed{background:var(--red)}
.dot.overrun{background:var(--amber)}
.dot.unknown{background:var(--yellow)}
@keyframes pulse{
  0%{box-shadow:0 0 0 0 rgba(22,163,74,.55)}
  70%{box-shadow:0 0 0 9px rgba(22,163,74,0)}
  100%{box-shadow:0 0 0 0 rgba(22,163,74,0)}
}
/* 标题固定单行省略号截断：不给 ⋯ 按钮让位就会压住按钮（320px 下同理） */
.card .name{font-weight:600;font-size:14.5px;flex:1 1 auto;min-width:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.badge{font-size:11px;padding:2px 7px;border-radius:999px;border:1px solid var(--line);
  color:var(--muted);white-space:nowrap;flex:0 0 auto;background:var(--card2)}
.badge.running{color:var(--green-fg);border-color:rgba(22,163,74,.35);background:var(--green-soft)}
.badge.finished{color:var(--muted)}
.badge.failed,.badge.killed{color:var(--red-fg);border-color:rgba(220,38,38,.35);background:var(--red-soft)}
/* 超轮次：琥珀色系，与「失败」的红色明确区分（SPEC4 第 5 节建议的配色） */
.badge.overrun{color:var(--amber);border-color:var(--amber-line);background:var(--amber-bg)}
.badge.unknown{color:var(--yellow-fg);border-color:rgba(202,138,4,.4);background:var(--yellow-soft)}
/* 转录里声明写过、磁盘上并不存在（未生成） */
.badge.missing{color:var(--gray-fg);border-color:var(--line);background:var(--gray-soft)}
.card .path{font-size:12px;color:var(--muted);margin-top:5px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card .path .badge{margin-left:6px}
/* 信息行：状态徽标排在最前（间距 12px ≥ 8px，不会与标题行的 ⋯ 打架） */
.card .meta{display:flex;flex-wrap:wrap;align-items:center;gap:4px 12px;font-size:12px;
  color:var(--fg);margin-top:7px;font-variant-numeric:tabular-nums}
.card .meta .k{color:var(--muted);font-style:normal}
.card .live{color:var(--green-fg)}

/* ============================ 按工作目录分组 ============================
   SPEC4 第 1/2 节：组头（父级）占满内容宽度、底色比卡片深一档；
   组内卡片（子级）四边各内缩 6px，用真实缩进表达父子层级。 */
.group{background:var(--card);border:1px solid var(--line);border-radius:12px;
  margin:10px 0;box-shadow:var(--shadow);overflow:hidden}
.group.hidden{background:var(--card2);border-style:dashed}
/* 组头是一整行可点区域，高 ≥44px；caret/dot 与项目名同一行基线。
   根元素是 div[role=button]（组头里有 ⋯ / 恢复 两个真按钮） */
.grouphead{display:flex;align-items:flex-start;gap:9px;width:100%;text-align:left;
  padding:10px 12px;min-height:44px;background:var(--grouphead);
  cursor:pointer;transition:background .15s}
.grouphead:active{background:#e2e6ee}
.grouphead .caret{flex:0 0 auto;color:var(--muted-2);font-size:12px;width:12px;margin-top:4px;
  transition:transform .18s ease}
.grouphead .caret.open{transform:rotate(90deg)}
/* 组头里的聚合状态圆点：与项目名同一行、垂直居中（覆盖 .dot 面向卡片的 margin-top）。
   底色变深后圆点也深一档，保证 ≥3:1 的可辨识度 */
.grouphead .dot{margin-top:4px;width:9px;height:9px}
.grouphead .dot.finished{background:var(--muted)}
.grouphead .dot.running{background:var(--green-ink)}
.grouphead .dot.failed,.grouphead .dot.killed{background:var(--red-ink)}
.grouphead .dot.overrun{background:var(--amber)}
.grouphead .gi{flex:1 1 auto;min-width:0}
.grouphead .gname{display:block;font-weight:600;font-size:14px;line-height:1.35;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.grouphead .gpath{display:block;font-size:11px;color:var(--muted-2);line-height:1.3;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.grouphead .gmeta{display:flex;flex-wrap:wrap;gap:1px 10px;font-size:11.5px;color:var(--muted-2);
  margin-top:2px;font-variant-numeric:tabular-nums}
.grouphead .gmeta b{color:var(--fg);font-weight:600}
.grouphead .gstate{flex:0 0 auto;display:flex;align-items:center;gap:5px;font-size:11.5px;
  color:var(--muted-2);white-space:nowrap;font-variant-numeric:tabular-nums;margin-top:2px}
.grouphead .gstate.green{color:var(--green-ink)}
.grouphead .gstate.red{color:var(--red-ink)}
.grouphead .gstate.amber{color:var(--amber)}
/* 组头最右：⋯ 菜单（命中区 ≥44px）或「已隐藏 + 恢复」 */
.grouphead .gacts{flex:0 0 auto;display:flex;align-items:center;gap:8px;margin-top:2px}
.grouphead .gmenu{width:44px;height:44px;margin:-8px -6px -8px 0;border-radius:10px;
  display:flex;align-items:center;justify-content:center;font-size:17px;line-height:1;
  color:var(--muted-2);letter-spacing:1px;transition:background .15s,color .15s}
.grouphead .gmenu:active,.grouphead .gmenu:hover{background:rgba(16,24,40,.06);color:var(--fg)}
.grouphead .gmini{min-height:34px;padding:5px 12px;border:1px solid var(--line);
  border-radius:999px;background:var(--card);color:var(--blue);font-size:12px;
  transition:background .15s}
.grouphead .gmini:active{background:var(--card2)}
/* 窄屏（320px）优先让项目名有宽度：聚合状态文字让位（圆点颜色仍可辨） */
@media (max-width:360px){.grouphead .gstate{display:none}}
/* 组内任务：卡片四边各内缩 6px 表达子级；组头与卡片之间靠 1px 边框分隔。
   类名以 GroupBlock 模板为准：真实 DOM 是 .gbody > .gbody-in > .cards > .card，
   写成 .groupbody/.groupbody-in 会静默不匹配（SPEC4 第 1 条曾因此完全失效）。 */
/* 展开区（.gbody/.gbody-in）与组头同底色，使「组头 + 展开区」是一整块 */
.gbody{display:grid;grid-template-rows:1fr;border-top:1px solid var(--line);
  background:var(--grouphead)}
.gbody-in{overflow:hidden;min-height:0;position:relative;padding:0;
  background:var(--grouphead)}
.gbody-in .cards{position:relative}
/* .card 基础规则带 width:100%，只加 margin 会让卡片比容器宽 12px 并被裁掉右缘，
   故同时把宽度交回 auto（块级自适应：容器宽 − 左右 margin − 边框内边距）。
   四边同为 6px：相邻卡片外边距合并后实际间隔 6px；.gbody-in 是 BFC（overflow:hidden），
   首卡的 6px 不会溢出到组体外，故上下留白最大就是 6px */
.gbody-in .card{margin:6px;width:auto}
.morebtn{width:calc(100% - 12px);min-height:44px;border-radius:10px;border:1px dashed var(--line);
  background:var(--card);color:var(--blue);font-size:13px;margin:6px;
  transition:background .15s}
.morebtn:active{background:var(--card2)}

/* ============================ 交付物文件树 ============================ */
.treehead{display:flex;gap:6px;margin:12px 0 8px;position:sticky;top:var(--topbar-total);
  z-index:15;background:var(--bg);padding:6px 0}
.treehead button{flex:1;min-width:0;min-height:44px;border-radius:9px;border:1px solid var(--line);
  background:var(--card);color:var(--muted);font-size:12.5px;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;transition:color .15s,border-color .15s,background .15s,transform .08s}
.treehead button:active{transform:scale(.98)}
.treehead button.on{color:var(--blue);border-color:var(--blue);background:var(--blue-soft);font-weight:600}
.treebox{background:var(--card);border:1px solid var(--line);border-radius:12px;
  padding:4px;box-shadow:var(--shadow)}
.treeroot{font-size:11.5px;color:var(--muted);padding:6px 8px 4px;
  word-break:break-all;font-family:var(--mono)}
.tnode{min-width:0}
.tchildren{margin-left:13px;border-left:1px solid var(--line);padding-left:1px}
.trow{display:flex;align-items:center;gap:7px;width:100%;text-align:left;min-height:44px;
  padding:5px 8px;border-radius:9px;transition:background .15s}
.trow:not(:disabled):active{background:var(--card2)}
.trow:disabled{cursor:default}
.trow .tcaret{flex:0 0 auto;width:12px;color:var(--muted);font-size:12px;
  transition:transform .18s ease}
.trow .tcaret.open{transform:rotate(90deg)}
.trow .tico{flex:0 0 auto;font-size:12px;color:var(--muted);width:14px;text-align:center}
.trow .tname{flex:1 1 auto;min-width:0;font-size:13px;line-height:1.35;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.trow.t-dir .tname{font-weight:600}
.trow .tmeta{flex:0 0 auto;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums;
  white-space:nowrap}
.trow .tbadges{flex:0 0 auto;display:flex;align-items:center;gap:4px}
.trow .tbadges .badge{font-size:10px;padding:1px 6px}
.badge.deliv{color:var(--blue-ink);border-color:var(--blue-line);background:var(--blue-soft)}
.badge.doc{color:var(--blue-ink);border-color:var(--blue-line);background:var(--blue-soft);
  font-weight:600}
/* 未生成（转录声明写入、磁盘不存在）：灰色、不可点 */
.trow.off .tname,.trow.off .tmeta,.trow.off .tico{color:var(--gray-fg);opacity:.8}
.trow.off .tname{text-decoration:line-through;text-decoration-color:rgba(107,114,128,.5)}
.tnode.miss>.trow{background:var(--gray-soft)}
.treelink{color:var(--blue)}
.treehint{font-size:11.5px;color:var(--muted);padding:4px 8px 8px}

/* ============================ 详情 ============================ */
.sechead{background:var(--card);border:1px solid var(--line);border-radius:12px;
  padding:14px;margin:10px 0;box-shadow:var(--shadow)}
.sechead h1{font-size:16px;margin:0 0 8px;line-height:1.4;word-break:break-word}
.statline{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--muted);flex-wrap:wrap}
.statline .st-overrun{color:var(--amber);font-weight:600}
/* 超轮次说明（SPEC4 第 5 节）：撞轮次上限不是失败，工作已产出
   类名用 overrunbox 而非裸 .overrun：裸类名会同时命中 .dot.overrun / .badge.overrun，
   把这块的 padding 与 border 注入状态圆点和徽标（圆点被撑成方块、徽标换行） */
.overrunbox{margin-top:8px;padding:9px 11px;border:1px solid var(--amber-line);
  border-radius:9px;background:var(--amber-bg);color:var(--amber);
  font-size:12.5px;line-height:1.6}
.overrunbox b{font-weight:600}
.kv{display:grid;grid-template-columns:auto 1fr;gap:5px 12px;font-size:13px;margin-top:8px}
.kv .k{color:var(--muted)}
.kv .v{text-align:right;font-variant-numeric:tabular-nums}
.kv .v.live{color:var(--green-fg)}
.kv .v.uuid{font-size:11.5px}
.subtabs{display:flex;gap:6px;margin:12px 0 4px;position:sticky;top:var(--topbar-total);z-index:15;
  background:var(--bg);padding:6px 0}
.subtabs button{flex:1;min-width:0;min-height:44px;border-radius:9px;border:1px solid var(--line);
  background:var(--card);color:var(--muted);font-size:13px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;transition:color .15s,border-color .15s,background .15s,transform .08s}
.subtabs button:active{transform:scale(.98)}
.subtabs button.on{color:var(--blue);border-color:var(--blue);background:var(--blue-soft);font-weight:600}
.subtabs button.off{color:var(--gray);cursor:default;background:var(--card2)}

/* 交付物 */
.file{display:flex;align-items:center;gap:10px;background:var(--card);
  border:1px solid var(--line);border-radius:10px;padding:10px 12px;margin:8px 0;
  width:100%;text-align:left;min-height:44px;box-shadow:var(--shadow);
  transition:background .15s,transform .08s}
.file:active{background:var(--card2);transform:scale(.995)}
.file .fi{flex:1;min-width:0}
.file .fp{font-size:13px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.file .fm{font-size:11.5px;color:var(--muted);margin-top:3px;font-variant-numeric:tabular-nums}
.file .go{color:var(--muted);font-size:16px;flex:0 0 auto}
/* 未生成的交付物：灰色、不可点击 */
.file.off{opacity:.7;cursor:default;box-shadow:none}
.file.off:active{background:var(--card);transform:none}

/* 时间线 */
.tl{margin:8px 0}
.tl .ev{border-left:2px solid var(--line);padding:0 0 14px 12px;margin-left:4px;position:relative}
.tl .ev:before{content:'';position:absolute;left:-5px;top:6px;width:8px;height:8px;
  border-radius:50%;background:var(--line)}
.tl .ev.user:before{background:var(--blue)}
.tl .ev.tool:before{background:var(--yellow)}
.tl .ev.assistant:before{background:var(--green)}
.tl .ev .h{font-size:11.5px;color:var(--muted);margin-bottom:4px;display:flex;gap:8px;flex-wrap:wrap}
.tl .ev .txt{font-size:13.5px;white-space:pre-wrap;word-break:break-word}
.tl .ev.user .txt{background:var(--blue-soft);border:1px solid var(--blue-line);
  border-radius:9px;padding:9px 11px;color:var(--blue-ink)}
.tl .ev.tool .txt{font-family:var(--mono);font-size:12.5px;background:var(--card);
  border:1px solid var(--line);border-radius:8px;padding:8px 10px;color:var(--code-fg)}
.tl .ev .tname{font-weight:600;color:var(--fg)}
.tl .ev .ok{font-size:11px;padding:1px 6px;border-radius:999px;border:1px solid var(--line);background:var(--card)}
.tl .ev .ok.y{color:var(--green-fg);border-color:rgba(22,163,74,.35);background:var(--green-soft)}
.tl .ev .ok.n{color:var(--red-fg);border-color:rgba(220,38,38,.35);background:var(--red-soft)}
.tlmeta{font-size:11.5px;color:var(--muted);margin:6px 0 2px}

/* 折叠区（实时日志） */
.logpanel{background:var(--card);border:1px solid var(--line);border-radius:10px;
  margin:10px 0;overflow:hidden;box-shadow:var(--shadow)}
.logtoggle{padding:12px;min-height:44px;display:flex;align-items:center;width:100%;
  text-align:left;font-size:13.5px;color:var(--fg)}
.logtoggle .caret{display:inline-block;margin-right:8px;color:var(--muted);
  transition:transform .15s ease}
.logtoggle .caret.open{transform:rotate(90deg)}
.logbar{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:6px 12px;border-top:1px solid var(--line);background:var(--card2);
  font-size:11.5px;color:var(--muted)}
.logbar .mini{padding:4px 10px;border:1px solid var(--line);border-radius:999px;
  background:var(--card);color:var(--muted);min-height:28px}
.logbar .mini:active{background:var(--card2)}
pre.log{margin:0;padding:12px;background:var(--code-bg);
  font-family:var(--mono);font-size:11.5px;
  line-height:1.5;color:var(--code-fg);overflow-x:auto;max-height:52vh;
  white-space:pre-wrap;word-break:break-all}

/* 空/加载/错误 */
.state{text-align:center;color:var(--muted);padding:44px 16px;font-size:13.5px}
.state .big{font-size:30px;display:block;margin-bottom:10px;opacity:.55}
.state .hint{margin-top:10px}
.state .code-hint{display:inline-block;margin-top:6px;padding:6px 10px;border-radius:8px;
  background:var(--card);border:1px solid var(--line);color:var(--fg);
  font-family:var(--mono);font-size:11.5px;word-break:break-all;max-width:100%}
.err{background:var(--red-soft);border:1px solid rgba(220,38,38,.3);color:var(--red-fg);
  border-radius:10px;padding:11px 13px;margin:10px 0;font-size:13px}

/* ============================ 文件查看浮层 ============================ */
.overlay{position:fixed;inset:0;z-index:60;background:var(--bg);display:flex;flex-direction:column}
.overlay .ovh{display:flex;align-items:center;gap:8px;padding:8px 12px;
  border-bottom:1px solid var(--line);background:var(--card);min-height:52px;
  padding-top:calc(8px + var(--safe-t))}
.overlay .ovh .p{flex:1;min-width:0;font-size:12.5px;color:var(--muted);
  word-break:break-all;max-height:38px;overflow:hidden}
.overlay .ovh button{min-width:44px;min-height:44px;font-size:15px;color:var(--fg);
  border-radius:10px;transition:background .15s}
.overlay .ovh button:active{background:var(--card2)}
.overlay .ovb{flex:1;overflow:auto;padding:12px;-webkit-overflow-scrolling:touch}
.overlay pre.plain{border:none;max-height:none;background:var(--code-bg);border-radius:10px}

/* ============================ 正文 markdown 渲染 ============================ */
.md{font-size:14px;word-break:break-word}
.md h1,.md h2,.md h3,.md h4,.md h5,.md h6{margin:18px 0 8px;line-height:1.35;font-weight:600}
.md h1{font-size:19px;border-bottom:1px solid var(--line);padding-bottom:6px}
.md h2{font-size:17px;border-bottom:1px solid var(--line);padding-bottom:5px}
.md h3{font-size:15.5px}
.md h4,.md h5,.md h6{font-size:14.5px}
.md p{margin:9px 0}
.md ul,.md ol{margin:9px 0;padding-left:22px}
.md li{margin:3px 0}
.md code{background:var(--code-bg);border:1px solid var(--line);border-radius:5px;
  padding:1px 5px;font-family:var(--mono);font-size:12.5px;color:var(--fg)}
.md pre{background:var(--code-bg);border:1px solid var(--line);border-radius:9px;
  padding:11px;overflow-x:auto;margin:10px 0}
.md pre code{background:none;border:none;padding:0;font-size:12.5px;line-height:1.5;color:var(--code-fg)}
.md blockquote{margin:10px 0;padding:8px 13px;border-left:3px solid var(--blue);
  background:var(--blue-soft);color:var(--blue-ink);border-radius:0 8px 8px 0}
.md blockquote p{margin:4px 0}
.md hr{border:none;border-top:1px solid var(--line);margin:18px 0}
.md table{border-collapse:collapse;width:100%;margin:11px 0;font-size:13px;
  display:block;overflow-x:auto}
.md th,.md td{border:1px solid var(--line);padding:6px 9px;text-align:left}
.md th{background:var(--card2);font-weight:600}
.md a{color:var(--blue);word-break:break-all}
.md strong{font-weight:600;color:var(--fg)}
.md del{color:var(--muted)}
.md img{max-width:100%}

/* ============================================================================
 * SPEC3：卡片 ⋯ 菜单 / 隐藏记录 / 仪表盘
 * ========================================================================== */

/* ---------------------------- 卡片右上角的 ⋯ 操作入口 ----------------------------
   SPEC4 第 4 节：与标题同一行 flex 排布（标题 flex:1 省略号截断，⋯ flex:0 0 auto），
   状态徽标已下移到信息行 —— 不再用绝对定位叠加，320px 下也不会与徽标重叠。 */
.card .cmenu{flex:0 0 auto;width:44px;height:44px;margin:-11px -8px -11px 0;
  border-radius:10px;display:flex;align-items:center;justify-content:center;
  font-size:17px;line-height:1;color:var(--muted);letter-spacing:1px;
  transition:background .15s,color .15s}
.card .cmenu:active,.card .cmenu:hover{background:var(--card2);color:var(--fg)}

/* 已隐藏的卡片：灰显 + 虚线边 + 「已隐藏」标签 + 恢复按钮 */
.card.hidden{opacity:.62;background:var(--card2);border-style:dashed}
.card.hidden:active{background:var(--card2)}
.badge.hiddenb{color:var(--gray-fg);border-color:var(--line);background:var(--gray-soft)}
.card .hiddenbar{display:flex;align-items:center;justify-content:space-between;gap:8px;
  margin-top:8px;padding-top:8px;border-top:1px dashed var(--line);
  font-size:11.5px;color:var(--muted)}
.card .hiddenbar .mini{min-height:32px;padding:4px 12px;border:1px solid var(--line);
  border-radius:999px;background:var(--card);color:var(--blue);font-size:12px}
.card .hiddenbar .mini:active{background:var(--card2)}

/* ---------------------------- ⋯ 菜单（渲染在根组件，fixed 定位不受裁剪） ---------------------------- */
.menulayer{position:fixed;inset:0;z-index:70}
.menubackdrop{position:absolute;inset:0}
.cardmenu{position:absolute;background:var(--card);border:1px solid var(--line);
  border-radius:11px;box-shadow:0 6px 20px rgba(16,24,40,.14);overflow:hidden;
  padding:4px;display:flex;flex-direction:column}
.cardmenu button{min-height:40px;padding:8px 11px;text-align:left;font-size:13.5px;
  border-radius:8px;color:var(--fg);transition:background .12s}
.cardmenu button:active{background:var(--card2)}
.cardmenu button.danger{color:var(--red-fg)}

/* ---------------------------- 二次确认弹窗 ---------------------------- */
.modal{position:fixed;inset:0;z-index:80;background:rgba(17,24,39,.34);
  display:flex;align-items:center;justify-content:center;padding:20px}
.modal .mbox{background:var(--card);border:1px solid var(--line);border-radius:14px;
  padding:16px;max-width:360px;width:100%;box-shadow:0 12px 34px rgba(16,24,40,.2)}
.modal .mbox h3{margin:0 0 8px;font-size:15.5px}
.modal .mbox p{margin:0 0 8px;font-size:13px;color:var(--muted);line-height:1.6}
.modal .mbtns{display:flex;gap:8px;justify-content:flex-end;margin-top:12px}
.modal .mbtns .mini{min-height:40px;padding:8px 16px;border:1px solid var(--line);
  border-radius:10px;background:var(--card);font-size:13.5px;color:var(--fg)}
.modal .mbtns .mini:active{background:var(--card2)}
.modal .mbtns .mini.danger{background:var(--red);border-color:var(--red);color:#fff;font-weight:600}
.modal .mbtns .mini.danger:active{background:#b91c1c}

/* ------------------- 「显示已隐藏」开关已移入顶栏（见 .topbar .hbadge） -------------------
   开关打开时列表顶部只留一行说明（SPEC4 第 3 节） */
.hintline{font-size:11.5px;color:var(--muted);padding:10px 2px 0;line-height:1.6}

/* ---------------------------- 已隐藏记录管理面板 ---------------------------- */
.panelnote{font-size:12px;color:var(--muted);background:var(--blue-soft);
  border:1px solid var(--blue-line);color:var(--blue-ink);border-radius:10px;
  padding:10px 12px;margin:0 0 10px;line-height:1.6}
.hrow{display:flex;align-items:center;gap:10px;background:var(--card);border:1px solid var(--line);
  border-radius:10px;padding:11px 12px;margin:8px 0;box-shadow:var(--shadow)}
.hrow .hi{flex:1;min-width:0}
.hrow .hn{font-size:13.5px;font-weight:600;word-break:break-word}
.hrow .hm{font-size:11.5px;color:var(--muted);margin-top:3px;word-break:break-all}
.hrow .mini{flex:0 0 auto;min-height:36px;padding:6px 14px;border:1px solid var(--blue-line);
  border-radius:999px;background:var(--blue-soft);color:var(--blue-ink);font-size:12.5px}
.hrow .mini:active{background:var(--card2)}

/* ---------------------------- 仪表盘 ---------------------------- */
.dashhead{padding:10px 2px 0}
.ranges{display:flex;gap:6px}
.ranges button{flex:1;min-width:0;min-height:40px;border-radius:9px;border:1px solid var(--line);
  background:var(--card);color:var(--muted);font-size:12.5px;
  transition:color .15s,border-color .15s,background .15s,transform .08s}
.ranges button:active{transform:scale(.98)}
.ranges button.on{color:var(--blue);border-color:var(--blue);background:var(--blue-soft);font-weight:600}
.rangetip{font-size:11.5px;color:var(--muted);padding:7px 2px 0}
.rangetip b{color:var(--fg)}

.dsec{background:var(--card);border:1px solid var(--line);border-radius:12px;
  padding:12px;margin:10px 0;box-shadow:var(--shadow)}
.dsec h3{margin:0 0 10px;font-size:13.5px;font-weight:600}
.dsec h3 .hunit{font-size:11.5px;color:var(--muted);font-weight:400}

/* 核心指标卡 */
.cards4{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:10px 0}
.mcard{background:var(--card);border:1px solid var(--line);border-radius:12px;
  padding:12px;box-shadow:var(--shadow);min-width:0}
.mcard .mv{font-size:21px;font-weight:600;line-height:1.2;font-variant-numeric:tabular-nums;
  color:var(--fg);word-break:break-all}
.mcard .ml{font-size:11.5px;color:var(--muted);margin-top:3px}
.mcard .ml .sub{color:var(--gray-fg)}
.cards4.avg .mv{font-size:18px}

/* Token 与代码量 */
.tokgrid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.tok{display:flex;flex-direction:column;gap:1px;background:var(--card2);border-radius:10px;
  padding:8px 10px;min-width:0}
.tok .tk{font-size:11px;color:var(--muted)}
.tok b{font-size:15px;font-weight:600;font-variant-numeric:tabular-nums}
.tok .tv{font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
.tok .adds{color:var(--green-fg)}
.tok .dels{color:var(--red-fg)}

/* 状态分布：横向堆叠占比条 */
.stackbar{display:flex;height:14px;border-radius:999px;overflow:hidden;background:var(--card2);
  border:1px solid var(--line)}
.stackbar .seg{min-width:0;transition:width .3s ease}
.stackbar .seg.running{background:var(--green)}
.stackbar .seg.finished{background:var(--gray)}
.stackbar .seg.failed,.stackbar .seg.killed{background:var(--red)}
.stackbar .seg.overrun{background:var(--amber)}
.stackbar .seg.unknown{background:var(--yellow)}
.statusrows{display:flex;flex-wrap:wrap;gap:4px 14px;margin-top:9px;font-size:12px;color:var(--muted)}
.statusrows .srow{display:flex;align-items:center;gap:5px}
.statusrows .srow b{color:var(--fg);font-variant-numeric:tabular-nums}
.statusrows .srow .dot{margin:0;width:8px;height:8px;animation:none}
.statusrows .sp{color:var(--gray-fg);font-variant-numeric:tabular-nums}

/* 趋势图（手写 SVG，viewBox 等比缩放到容器宽度） */
.trend{width:100%;height:auto;display:block;margin-top:2px;overflow:visible}
.trend .grid line{stroke:var(--line);stroke-width:1;stroke-dasharray:2 3}
.trend .axis{stroke:var(--line);stroke-width:1}
.trend .bars rect{fill:var(--blue);opacity:.75}
.trend .costline{fill:none;stroke:var(--yellow);stroke-width:1.6;
  stroke-linejoin:round;stroke-linecap:round}
.trend .costdot{fill:var(--card);stroke:var(--yellow);stroke-width:1.2}
.trend .ytick,.trend .xtick{font-size:7.5px;fill:var(--muted);font-variant-numeric:tabular-nums}
.trend .ytick.cost{fill:var(--yellow-fg)}
.legend{display:flex;gap:14px;font-size:11.5px;color:var(--muted);margin-bottom:4px}
.legend .lg{display:inline-block;width:10px;height:10px;border-radius:2px;margin-right:5px;
  vertical-align:-1px}
.legend .lg.bar{background:var(--blue);opacity:.75}
.legend .lg.line{background:var(--yellow);height:3px;border-radius:2px}
.chartnote{font-size:11px;color:var(--muted);margin-top:6px;line-height:1.5}

/* 横向占比条（费用榜 / 项目分布 / 工具分布共用） */
.barrow{display:grid;grid-template-columns:minmax(0,1fr) 84px auto;align-items:center;
  gap:8px;padding:5px 0;min-height:36px}
.barrow.clickable{cursor:pointer;border-radius:8px;padding:5px 6px;margin:0 -6px;
  transition:background .15s}
.barrow.clickable:active{background:var(--card2)}
.barrow .bl{min-width:0;display:flex;flex-direction:column;gap:1px}
.barrow .bt{font-size:12.5px;line-height:1.35;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.barrow .bs{font-size:10.5px;color:var(--muted);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.barrow .btrack{height:9px;border-radius:999px;background:var(--card2);overflow:hidden}
.barrow .bfill{height:100%;border-radius:999px;background:var(--gray);transition:width .3s ease}
.barrow .bfill.blue{background:var(--blue)}
.barrow .bfill.yellow{background:var(--yellow)}
.barrow .bfill.running{background:var(--green)}
.barrow .bfill.failed,.barrow .bfill.killed{background:var(--red)}
.barrow .bv{font-size:11.5px;color:var(--muted);text-align:right;white-space:nowrap;
  font-variant-numeric:tabular-nums}

/* 底部：未登记 / 已隐藏入口 */
.dashfoot{display:flex;flex-direction:column;gap:8px;margin:12px 0 4px}
.footrow{display:flex;align-items:center;gap:10px;min-height:48px;padding:10px 12px;
  background:var(--card);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow);
  font-size:13px;color:var(--fg);text-align:left;transition:background .15s,transform .08s}
.footrow:active{background:var(--card2);transform:scale(.995)}
.footrow b{margin-left:auto;font-weight:600;font-variant-numeric:tabular-nums}
.footrow .go{color:var(--muted);font-size:16px}
.dashnote{font-size:11px;color:var(--muted);line-height:1.6;padding:2px 2px 8px}

/* 仪表盘骨架屏（加载中占位） */
.dash-skeleton{opacity:.9}
@keyframes shimmer{0%{background-position:-160px 0}100%{background-position:160px 0}}
.sk i,.sk .sk-block,.sk-chart{display:block;border-radius:12px;
  background:linear-gradient(90deg,var(--card2) 0%,#e9edf3 50%,var(--card2) 100%);
  background-size:320px 100%;animation:shimmer 1.2s linear infinite}
.sk-cards{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:10px 0}
.sk-cards i{height:66px}
.sk-block{height:120px;margin:10px 0}
.sk-chart{height:160px;margin:10px 0}

/* 仪表盘范围切换的淡入过渡 + 数值变化时的轻微上浮 */
.dashfade-enter-active,.dashfade-leave-active{transition:opacity .2s ease,transform .2s ease}
.dashfade-enter-from{opacity:0;transform:translateY(8px)}
.dashfade-leave-to{opacity:0;transform:translateY(-6px)}

/* 更宽的屏：仪表盘两列网格，窄屏仍是单列 */
@media (min-width:640px){
  .dashpane{display:grid;grid-template-columns:1fr 1fr;gap:0 12px;align-items:start}
  .dashpane> .cards4,.dashpane> .dashfoot,.dashpane> .dashnote,
  .dashpane> .state,.dashpane> .err,.dashpane> .dash-skeleton{grid-column:1 / -1}
  .cards4{grid-template-columns:repeat(4,1fr)}
  .tokgrid{grid-template-columns:repeat(2,1fr)}
}

/* ============================================================================
 * 过渡动画（纯 CSS；prefers-reduced-motion 下全部关闭）
 * ========================================================================== */

/* —— 列表页 ↔ 详情页：前进=详情从右滑入；返回=详情向右滑出 —— */
.page-forward-enter-active,.page-forward-leave-active,
.page-back-enter-active,.page-back-leave-active{
  transition:transform .24s cubic-bezier(.4,0,.2,1),opacity .24s ease}
/* 进入的一页留在文档流里决定高度，离开的一页脱离文档流，避免切换时页面高度塌陷 */
.page-forward-leave-active,.page-back-leave-active{
  position:absolute;top:0;left:0;right:0;z-index:0}
.page-forward-enter-active,.page-back-enter-active{position:relative;z-index:1}
.page-forward-enter-from{transform:translateX(100%);opacity:.45}
.page-forward-leave-to{transform:translateX(-28%);opacity:0}
.page-back-enter-from{transform:translateX(-28%);opacity:.45}
.page-back-leave-to{transform:translateX(100%);opacity:.45}

/* —— 三个主 tab：淡入 + 轻微纵向位移 —— */
.tabfade-enter-active,.tabfade-leave-active{transition:opacity .18s ease,transform .18s ease}
.tabfade-enter-from{opacity:0;transform:translateY(8px)}
.tabfade-leave-to{opacity:0;transform:translateY(-8px)}

/* —— 卡片列表：交错淡入；新增/删除有过渡；重排用 FLIP 平滑移动 —— */
.list-enter-active{transition:opacity .3s ease,transform .3s ease;transition-delay:var(--d,0ms)}
.list-leave-active{transition:opacity .18s ease,transform .18s ease;
  position:absolute;left:0;right:0;z-index:0}
.list-enter-from{opacity:0;transform:translateY(8px)}
.list-leave-to{opacity:0;transform:scale(.98)}
.list-move{transition:transform .25s ease}
.cards{position:relative}

/* —— 详情内三个子 tab：淡入 + 轻微横向位移 —— */
.subtabfade-enter-active,.subtabfade-leave-active{transition:opacity .18s ease,transform .18s ease}
.subtabfade-enter-from{opacity:0;transform:translateX(10px)}
.subtabfade-leave-to{opacity:0;transform:translateX(-10px)}

/* —— 分组展开/折叠 与 文件树展开/折叠：grid-template-rows 0fr→1fr 的真实高度过渡
     （不支持该属性的浏览器只是瞬间展开，不影响功能） —— */
.gbody-enter-active,.gbody-leave-active,
.tkids-enter-active,.tkids-leave-active{transition:grid-template-rows .24s ease,opacity .2s ease}
.gbody-enter-from,.gbody-leave-to,
.tkids-enter-from,.tkids-leave-to{grid-template-rows:0fr;opacity:0}
.tkids{display:grid;grid-template-rows:1fr}
.tkids>.tchildren{overflow:hidden;min-height:0}

/* —— 概览条 / 文件浮层 / 日志折叠 —— */
.fade-enter-active,.fade-leave-active{transition:opacity .18s ease}
.fade-enter-from,.fade-leave-to{opacity:0}
.overlayfade-enter-active,.overlayfade-leave-active{transition:opacity .18s ease,transform .18s ease}
.overlayfade-enter-from,.overlayfade-leave-to{opacity:0;transform:translateY(14px)}
.collapse-enter-active,.collapse-leave-active{transition:opacity .16s ease}
.collapse-enter-from,.collapse-leave-to{opacity:0}

/* —— 尊重系统「减弱动态效果」—— */
@media (prefers-reduced-motion:reduce){
  *,*:before,*:after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;transition-delay:0ms !important}
  .dot.running{animation:none;box-shadow:none}
}
