/* work.css —— 工作台四块（机器人、工作链、排程、运行记录，D073）和侧栏「资源」四页（技能、去重表、变量、目标池，D203）自己的几样零件。
 * 只写布局和 var(--…)，值在 tokens.css。
 * 一行一项的列表沿用设置里的 .set-list / .set-row（同一种行，不另造）。 */

/* 页头：标题、说明在左，这一页的主按钮在右；底下一条线隔开内容（照 OpenLucy 页头下界那条线，颜色用我们的分隔线，D084） */
.page-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-7);
  padding-bottom: var(--space-7); margin-bottom: var(--space-7); border-bottom: var(--border-w) solid var(--border); }
.page-top .page-head { flex: 1; min-width: 0; margin-bottom: 0; }
/* 下面紧跟标签排的：标签排那条线就是页头的下界，不画两条 */
.page-top:has(+ .tab-bar) { padding-bottom: 0; margin-bottom: var(--space-6); border-bottom: 0; }

/* 粘任务的大框：等宽字、能往下拉 */
.input.code {
  height: auto;
  min-height: calc(var(--h-lg) * 10);
  padding: var(--space-5);
  line-height: var(--lh-base);
  resize: vertical;
  white-space: pre;
}

/* 校验出的问题：一条一行，位置等宽、红字 */
.issue-list { display: flex; flex-direction: column; gap: var(--space-2); font-size: var(--fs-sm); line-height: var(--lh-base); }
.issue-list:empty { display: none; }
.issue-path { font-family: var(--font-mono); color: var(--danger); }
.issue-msg { color: var(--text-2); }

.editor-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-4); }

/* 一趟的每一步：在那一趟的行下面展开 */
.run-steps { display: flex; flex-direction: column; gap: var(--space-2); padding: 0 0 var(--space-5) var(--space-6); font-size: var(--fs-sm); }
.run-step { display: flex; gap: var(--space-4); color: var(--text-2); }
.run-step-seq { font-family: var(--font-mono); color: var(--text-dim); min-width: calc(var(--space-8) + var(--space-2)); }
.run-reason { color: var(--text-2); }

/* ── Schedule 页的今日时间轴（app.js 的 renderTimeline，照 _OpenLucy/timeline/timeline.css）：左开关 + 名字 · 中间 0–24 点的轨道 · 右一句话；
   点的位置是 JS 算的百分比 ── */
/* 最上面一行：总闸（跟下面每行的开关同一列）+「All on / All off · 停了多久」，今天几处、几个机器人有活，数据几点到的 */
.tl-status { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-7); font-size: var(--fs-note); color: var(--text-dim); }
.tl-gateline { display: inline-flex; align-items: center; gap: var(--space-4); }
.tl-gate { font-family: var(--font-mono); color: var(--success); white-space: nowrap; }
.tl-gate.susp { color: var(--warning); font-weight: var(--fw-semibold); }
.tl-num { color: var(--accent); font-weight: var(--fw-medium); }

.tl-grid { position: relative; display: flex; flex-direction: column; --tl-band: calc(var(--fs-note) + var(--space-3)); }   /* 刻度上面一层标签的高 */
.tl-row {
  display: grid;
  grid-template-columns: var(--tl-name-w) 1fr var(--tl-end-w);
  align-items: center;
  gap: var(--space-6);
  height: var(--tl-row-h);
}
.tl-name { display: flex; align-items: center; gap: var(--space-4); min-width: 0; font-size: var(--fs-sm); }
/* 名字平时正文色，压上去才亮：机器人多了一列全青会糊成一片 */
.tl-name-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-2); text-decoration: none; }
.tl-name-text:hover { color: var(--accent); }
.tl-row.paused .tl-name-text { color: var(--text-dim); }
/* 行尾两列（用户 10-07：一句话长短不一、靠右排就歪）：今天几次、下一次（几点 / Done / 停着多久，黄）。
   轨道尾到 Runs 中线、Runs 到 Next 中线两段一样长（= 一列宽），字各自居中；表头在轴那一行，跟轴上的数一样高 */
.tl-end {
  display: grid;
  grid-template-columns: var(--tl-col-w) var(--tl-col-w);
  margin-left: calc(var(--tl-col-w) / 2 - var(--space-6));
  align-items: baseline;
  justify-items: center;
  font-family: var(--font-mono);
  font-size: var(--fs-note);
  color: var(--text-2);
  white-space: nowrap;
}
.tl-runs { font-variant-numeric: tabular-nums; }
.tl-runs.zero, .tl-next.done { color: var(--text-dim); }
.tl-next.susp { color: var(--warning); }
.tl-end-head { align-self: end; padding-bottom: calc(var(--space-5) + var(--space-2)); font-family: var(--font-sans); color: var(--text-dim); }   /* 底下让出轴线那一截（.tl-line 高 + .tl-axis 间距） */
.tl-fold { align-self: flex-start; }
/* 还没有机器人、今天一处都没排：轴底下一句指路的话（去建机器人、去排程），链接青色 */
.tl-hint { font-size: var(--fs-note); color: var(--text-dim); }
.tl-hint a { color: var(--accent); }
.tl-hint a:hover { text-decoration: underline; }

/* 顶上一条独立的时间轴（用户 10-07 看样稿定的；OpenLucy 只有一排数）：左边今天几号；中间每 2 小时一个数，全是同一个灰、不加亮，
   底下一根干净的轴线，线上不带刻度点，只落今天每个机器人排的每一处（青点）；机器人一个一行直接摆在下面，不加分隔线。
   上面留两层标签：上层「NOW」、下层蓝线的时刻，两个碰在一起也都看得见（OpenLucy 是同一层、蓝的盖住红的）。
   这一行往下滚时钉在顶上（照 OpenLucy .mtl-ruler），底色跟卡一样，不然底下的行透上来 */
.tl-row.tl-axis-row { position: sticky; top: 0; z-index: 1; height: auto; align-items: end; padding-top: calc(2 * var(--tl-band)); background: var(--bg-card); }
.tl-axis-row + .tl-row { margin-top: var(--space-6); }
.tl-day { display: flex; flex-direction: column; gap: var(--space-1); }
.tl-today { font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--text); }
.tl-date { font-family: var(--font-mono); font-size: var(--fs-note); color: var(--text-dim); }
.tl-axis { display: flex; flex-direction: column; gap: var(--space-2); }
.tl-hours { position: relative; height: calc(var(--fs-note) * var(--lh-tight)); }
.tl-tick {
  position: absolute;
  bottom: 0;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: var(--fs-note);
  color: var(--text-dim);
  white-space: nowrap;
}
.tl-tick.at-0 { left: 0; transform: none; }
.tl-tick.at-24 { right: 0; transform: none; }
.tl-line { position: relative; height: var(--space-5); }
.tl-line::before { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: calc(2 * var(--border-w)); background: var(--border-strong); }
.tl-dot {
  position: absolute;
  bottom: calc(var(--border-w) - var(--space-4) / 2);
  width: var(--space-4);
  height: var(--space-4);
  border-radius: 50%;
  transform: translateX(-50%);
  background: var(--accent);
  box-shadow: var(--tl-mark-glow);
}
.tl-dot.paused { opacity: 0.35; }   /* 跟行里停着的刻度一样压暗 */

/* 轨道：一条底色条，每 2 小时一条暗线、每 6 小时一条亮线（照 OpenLucy .mtl-track / .mtl-grid）；点压在条上 */
.tl-track {
  position: relative;
  height: var(--tl-track-h);
  border-radius: var(--radius-sm);
  background-color: var(--bg-row);
  background-image:
    repeating-linear-gradient(to right, var(--border-strong) 0 var(--border-w), transparent var(--border-w) calc(100% / 4)),
    repeating-linear-gradient(to right, var(--border-soft) 0 var(--border-w), transparent var(--border-w) calc(100% / 12));
}
/* 今天没排期的、停着的：条退成淡底、不画网格；停着的刻度压暗（停了却看着跟平常一样才危险，OpenLucy 同） */
.tl-row.idle .tl-track, .tl-row.paused .tl-track { background-color: var(--bg-hover); background-image: none; }
.tl-row.paused .tl-mark { opacity: 0.35; }

/* 一处排期一道青色刻度，居中在那个时刻（照 OpenLucy .mtl-mark）。跑过没跑过不分色、不分形状：
   别做「过去压暗 / 按结果上色 / 加图例」，排了哪些才是这条轴要看的，现在几点看红线（用户 10-07 否过上色那版，D175） */
.tl-mark {
  position: absolute;
  top: var(--space-1);
  bottom: var(--space-1);
  width: var(--tl-mark);
  transform: translateX(-50%);
  border-radius: var(--radius-xs);
  background: var(--accent);
  box-shadow: var(--tl-mark-glow);
}
.tl-mark.multi { width: var(--tl-mark-multi); }   /* 10 分钟内挨得分不开的几处并成一道，加宽；明细看蓝线顶上的标签 */

/* 盖在轨道那一栏上的一层：红实线 = 现在几点，蓝虚线 = 鼠标在问几点（吸住点转实线）。蓝线从下层标签下沿起画，红线从上层 NOW 下沿起、穿过下层 */
.tl-overlay {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--tl-name-w) + var(--space-6));
  right: calc(var(--tl-end-w) + var(--space-6));
  z-index: 2;   /* 压在钉住的刻度尺上面 */
  pointer-events: none;
}
.tl-now, .tl-probe { position: absolute; top: calc(2 * var(--tl-band)); bottom: 0; }
.tl-now { top: var(--tl-band); width: var(--border-w); background: var(--danger); }
.tl-probe { width: 0; border-left: var(--border-w) dashed var(--accent); }
.tl-probe.hit { border-left-style: solid; }
.tl-now-label, .tl-probe-label {
  position: absolute;
  left: 0;
  bottom: 100%;
  transform: translateX(-50%);
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--fs-note);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  white-space: nowrap;
}
.tl-now-label { background: var(--danger); color: var(--text); }
.tl-probe-label { background: var(--accent); color: var(--bg); }
/* 贴边时标签左 / 右对齐，不探出轨道那一栏 */
.tl-probe-label.edge-l { transform: none; }
.tl-probe-label.edge-r { transform: translateX(-100%); }
/* 吸住时标签里列出这一刻的每一处：只朝上长、不盖轨道；一列 6 条，满了往右开一列 */
.tl-probe-label.list { padding: var(--space-2) var(--space-4); }
.tl-probe-head { display: block; }
.tl-probe-grid { display: grid; grid-auto-flow: column; grid-template-rows: repeat(6, auto); gap: 0 var(--space-6); }
.tl-probe-item { display: flex; align-items: baseline; gap: var(--space-3); font-weight: var(--fw-medium); }
.tl-probe-item b { font-weight: var(--fw-semibold); }

/* 吸住时点一下出的清单：浮在鼠标旁边，这一刻跑的、跑过的每一处，点一条去看 */
.tl-pop {
  position: fixed;
  z-index: 30;
  width: var(--tl-pop-w);
  padding: var(--space-4);
  background: var(--bg-elev);
  border: var(--border-w) solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-pop);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  font-size: var(--fs-sm);
}
.tl-pop-time { font-family: var(--font-mono); font-size: var(--fs-note); color: var(--text-dim); padding: 0 var(--space-3); }
.tl-pop-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  width: 100%;
  padding: var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.tl-pop-item:hover { background: var(--active-bg); }
.tl-pop-text { display: flex; flex-direction: column; min-width: 0; }
.tl-pop-sub { font-size: var(--fs-note); color: var(--text-dim); }
.tl-pop-hint { padding: 0 var(--space-3); font-size: var(--fs-note); color: var(--text-dim); }

/* Running now（Timeline 页、Workflows 标签各一块）：标题 + 「几个在跑 / 几个亮着」，卡就是 Robots 页的 .robot-grid / .robot-card */
.wall-head { display: flex; align-items: baseline; gap: var(--space-4); }
.wall-cnt { font-family: var(--font-mono); font-size: var(--fs-note); color: var(--accent); }


/* ── Robots 页（D188 改）：一行四张卡，卡 = 屏幕（照 OpenLucy 画面卡 bot/bot.css、bot_screens.js 的 _bsBuild）：画面铺满整张卡
   （机器人窗口的比例 1600×860，D019），字浮在画面上，顶底两道暗影托字。亮着的卡上，框架在屏幕上贴实时小画面（D189），字由机器人浏览器外壳
   画在画面里（按卡的宽排，缩下来就是这里的大小）；这里画没亮的卡，也给亮着的卡在同样的位置放 ⛶、Stop、开关接鼠标（缩略图不吃鼠标，点下去落到这里）。
   边框是设备身份色（camoufox 蓝）：静着半透明，悬停满色，在跑加粗满色、外面一圈光晕呼吸 ── */
.robot-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-6); }
.robot-grid > .empty { grid-column: 1 / -1; }
@media (max-width: 1400px) { .robot-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 1100px) { .robot-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px)  { .robot-grid { grid-template-columns: minmax(0, 1fr); } }

/* 直角，不照 OpenLucy 的圆角 4（D188）：亮着的卡画面是框架贴的直角缩略图，有圆角就得字层在四个角补 */
.robot-card {
  position: relative;
  min-width: 0;
  background: var(--bg);
  border: var(--border-w) solid color-mix(in srgb, var(--accent) 50%, transparent);
  overflow: hidden;
  color: var(--text);
  cursor: pointer;
}
.robot-card:hover { border-color: var(--accent); box-shadow: 0 0 var(--card-hover-glow) var(--accent); }
.robot-card.running {
  border-width: calc(var(--border-w) * 2);
  border-color: var(--accent);
  animation: card-breathe var(--card-breathe) ease-in-out infinite;
}
@keyframes card-breathe {
  0%, 100% { box-shadow: 0 0 var(--card-glow-min) var(--accent); }
  50% { box-shadow: 0 0 var(--card-glow-max) var(--accent); }
}

.robot-screen {
  position: relative;
  aspect-ratio: 1600 / 860;
  container-type: inline-size;
  background: var(--bg);
}
.rc-scrim { position: absolute; inset: 0; background: var(--card-scrim); pointer-events: none; }
/* 左上名字一行、底下在跑那行；z 跟钮一档，名字那行的 ⛶、急停压在 Run Output、NOT RUNNING 上面（照 OpenLucy 层次） */
.rc-top { position: absolute; top: var(--card-pad); left: var(--card-pad); right: var(--card-pad); z-index: 4; min-width: 0; display: flex; flex-direction: column; text-shadow: var(--card-shadow); pointer-events: none; }
/* 底下一行：左边简介、代理、缓存三行字，右边 Settings、Power 两个钮一列，各成一摞、底边对齐（用户 10-07：「前面和后面自成体系」） */
.rc-bottom { position: absolute; left: var(--card-pad); right: var(--card-pad); bottom: var(--card-pad); display: flex; align-items: flex-end; gap: var(--space-4); pointer-events: none; }
.rc-foot { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--card-gap); text-shadow: var(--card-shadow); }
/* 名字、引用、急停、⛶ 同一个 flex 行（照 OpenLucy .bm-card-top）：钮多宽字就让多宽（急停的字各语言长短不一），行跟 ⛶ 一样高、竖向居中。
   钮在哪框架照网页量的认（app.js 的 sendOpen） */
.rc-head { display: flex; align-items: center; gap: var(--card-gap); min-width: 0; min-height: var(--card-btn); }
.rc-dot,
.rc-pdot { flex-shrink: 0; width: var(--card-dot); height: var(--card-dot); border-radius: 50%; background: var(--accent); }
.rc-pdot { background: var(--text-dim); }
.rc-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--card-fs-name);
  font-weight: var(--fw-bold);
  letter-spacing: var(--card-ls-tight);
}
.rc-spacer { flex: 1 1 auto; }
.rc-meta { display: inline-flex; flex-wrap: wrap; align-items: baseline; column-gap: var(--space-5); font-size: var(--card-fs); color: var(--text-dim); }
/* 「2 workflows · 3 tasks」：词用正文字体（等宽字里空格、点都占一整格，拉得很长），只有数字等宽（.rc-v） */
.rc-ref { flex-shrink: 0; white-space: nowrap; font-size: var(--card-fs); color: var(--text); }
.rc-sep { margin: 0 var(--space-2); color: var(--text-2); }
.rc-grp { display: inline-flex; align-items: baseline; gap: var(--space-2); }
.rc-k { color: var(--accent); }
.rc-v { font-family: var(--font-mono); font-weight: var(--fw-medium); color: var(--text); }
/* 在跑的工作链 · 任务：卡上最该一眼看到的字，▶ 跟着呼吸（OpenLucy .bm-card-task，同卡边框同频） */
.rc-task {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: var(--card-fs-task);
  color: var(--accent);
  animation: rc-breath var(--card-breathe) ease-in-out infinite;
}
.rc-task::before {
  content: "";
  display: inline-block;
  vertical-align: middle;
  margin-right: var(--space-2);
  border-left: var(--card-tri-w) solid currentColor;
  border-top: var(--card-tri-h) solid transparent;
  border-bottom: var(--card-tri-h) solid transparent;
}
@keyframes rc-breath {
  0%, 100% { opacity: 1; filter: brightness(1.1); }
  50% { opacity: 0.55; filter: brightness(0.7); }
}
@media (prefers-reduced-motion: reduce) {
  .robot-card.running,
  .rc-task { animation: none; }
}
.rc-note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--card-fs); line-height: var(--lh-base); color: var(--text-2); }
.rc-note.none { font-style: italic; color: var(--text-dim); }
.rc-note.warn { color: var(--warning); }   /* 点亮、熄灭没办成：引擎说的原因 */
.rc-proxy { display: flex; align-items: center; gap: var(--space-2); font-family: var(--font-mono); font-size: var(--card-fs); }
/* 正中：没在跑任务时半透明的 NOT RUNNING（按卡宽，OpenLucy .bm-card-norun）；连着、建号失败这类一句话照 OpenLucy .bm-screen-off 小字 */
.rc-big {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  pointer-events: none;
  font-family: var(--font-mono);
  font-size: var(--card-norun);
  font-weight: var(--fw-bold);
  letter-spacing: var(--card-ls-wide);
  color: color-mix(in srgb, var(--accent) 50%, transparent);
  text-shadow: var(--card-norun-shadow);
}
.rc-big.warn,
.rc-big.bad { font-family: var(--font-sans); font-size: var(--card-fs); font-weight: var(--fw-regular); letter-spacing: var(--card-ls-tight); color: var(--warning); text-shadow: none; }
.rc-big.bad { color: var(--danger); }
.rc-zoom,
.rc-stop {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  height: var(--card-btn);
  padding: 0;
  border: var(--border-w) solid var(--border);
  border-radius: var(--card-radius-sm);
  background: var(--card-btn-bg);
  color: var(--text);
  font-size: var(--card-fs-zoom);
  line-height: 1;
  text-shadow: none;
  pointer-events: auto;
  cursor: pointer;
}
.rc-zoom { width: var(--card-btn); }
/* 悬停变青（OpenLucy .bm-screen-zoom:hover）。亮着的卡上那份是字层画的，网页这份压在画面底下：悬停时网页给字层那份加 hot（app.js 的 hotZoom） */
.rc-zoom:hover,
.rc-zoom.hot { border-color: var(--accent); color: var(--accent); }
/* 急停照 OpenLucy 画面卡的 EMERGENCY STOP（btn-warning btn-sm）：琥珀描边、等宽大写，悬停填满琥珀 */
.rc-stop { padding: 0 var(--space-5); border-color: var(--warning); color: var(--warning); font-family: var(--font-mono); font-size: var(--card-fs); font-weight: var(--fw-medium); }
.rc-stop:hover { background: var(--warning); color: var(--bg); box-shadow: 0 0 var(--card-hover-glow) var(--warning); }
/* 墙上的卡不放急停：要停先点开（用户 10-07，同 D134）；Settings、Power 只在墙上，全屏时右下不放钮（用户 10-07） */
.robot-card:not(:fullscreen) .rc-stop,
.layer-card:not(.big) .rc-stop,
.robot-card:fullscreen .rc-acts,
.layer-card.big .rc-acts { display: none; }
/* 右下 Settings ⚙、Power ⏻：一样宽（按最长的字定），字在前、图标在后，两个图标上下一列。样子同 ⛶：暗底、细边，悬停边框和图标变青。
   Power 开着图标青、边框淡青；关着图标灰。开、关两句叠在同一格里量宽，拨的时候钮不变宽窄 */
.rc-acts { flex: none; display: grid; grid-template-columns: max-content; gap: var(--card-gap); pointer-events: auto; position: relative; z-index: 4; }
.rc-act {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  height: var(--card-act-h);
  padding: 0 var(--space-3) 0 var(--space-4);
  border: var(--border-w) solid var(--border);
  border-radius: var(--card-radius-sm);
  background: var(--card-btn-bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--card-fs);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  cursor: pointer;
}
.rc-lbl { display: grid; text-align: left; }
.rc-lbl > span { grid-area: 1 / 1; }
.rc-ghost { visibility: hidden; }
.rc-ic { display: flex; color: var(--text-dim); }
.rc-ic svg { width: var(--card-ic); height: var(--card-ic); fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.rc-settings .rc-ic { color: var(--text); }
.rc-power.on { border-color: color-mix(in srgb, var(--accent) 60%, transparent); }
.rc-power.on .rc-ic { color: var(--accent); }
.rc-act:hover:not(:disabled),
.rc-act.hot { border-color: var(--accent); color: var(--accent); }
.rc-act:hover:not(:disabled) .rc-ic,
.rc-act.hot .rc-ic { color: var(--accent); }
.rc-act:disabled { cursor: default; color: var(--text-dim); }
.rc-act:focus-visible { outline: calc(var(--border-w) * 2) solid var(--ring); outline-offset: var(--border-w); }

/* 状态小圆点（时间轴那页的机器人行） */
.robot-dot { flex-shrink: 0; width: var(--space-4); height: var(--space-4); border-radius: 50%; background: var(--border-strong); }
.robot-dot.ok   { background: var(--success); }
.robot-dot.run  { background: var(--accent); }
.robot-dot.warn { background: var(--warning); }
.robot-dot.bad  { background: var(--danger); }

/* 详情：标题旁一个状态徽章；标签条；一张卡 */
.robot-title { display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap; }
.robot-detail-card { padding: var(--space-7); }
[data-rpane] > .set-h:first-child { margin-top: 0; }
.tab-bar { display: flex; gap: var(--space-2); border-bottom: var(--border-w) solid var(--border); overflow-x: auto; }
.tab {
  height: var(--h-lg);
  padding: 0 var(--space-6);
  border: 0;
  border-bottom: var(--border-w) solid transparent;
  background: transparent;
  color: var(--text-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  cursor: pointer;
}
.tab:hover { color: var(--text); }
.tab.on { color: var(--text); border-bottom-color: var(--text); }

/* ── 在 OpenLucy 客户端（框架）里开时才有（D189，docs/explain/client-frame.md）：灯、点开（全屏）的机器人 ─────────── */
/* 灯（D167）：连上绿、连着黄、连不上红灯闪写 D029 那句 */
.link { display: flex; align-items: center; gap: var(--space-4); font-size: var(--fs-note); color: var(--text-2); }
/* 顶栏（D204）：左边灯，右边状态条；灯只在客户端里有，没有灯时状态条照样靠右。
   在内容区外面、不随页面滚，底色同侧栏、底下一条线，跟页头分开 */
.top-bar { flex-shrink: 0; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3) var(--space-7);
  min-height: calc(var(--h-lg) + var(--space-8)); padding: var(--space-3) var(--page-pad-x);
  background: var(--sidebar-bg); border-bottom: var(--border-w) solid var(--border); }
.top-bar:not(:has(> :not([hidden]))) { display: none; }
.link-ms { font-family: var(--font-mono); color: var(--accent); }
.link-ms::before { content: "· "; color: var(--text-dim); }
.link-dot { flex-shrink: 0; width: var(--space-4); height: var(--space-4); border-radius: var(--radius-pill); background: var(--border-strong); }
.link[data-state="connecting"] .link-dot { background: var(--warning); }
.link[data-state="up"] .link-dot { background: var(--success); }
.link[data-state="down"] { color: var(--danger); }
.link[data-state="down"] .link-dot { background: var(--danger); animation: link-blink var(--link-blink) steps(1) infinite; }
@keyframes link-blink { 50% { visibility: hidden; } }

/* 状态条（D204）：组织的时区、日期时刻。照 OpenLucy 页头状态条：等宽、秒位跳字不抖；
   钟按信息寿命分三层，时刻最亮、日期次之、时区名最暗 */
.sys-status { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-8);
  font-family: var(--font-mono); font-size: var(--fs-note); line-height: var(--lh-tight); font-variant-numeric: tabular-nums; }
.sys-clock { display: inline-flex; align-items: baseline; gap: var(--space-3); white-space: nowrap; }
.ck-zone { color: var(--text-dim); }
.ck-date { color: var(--text-2); }
.ck-time { color: var(--text); font-weight: var(--fw-medium); }
.sys-clock.local .ck-date, .sys-clock.local .ck-time { color: var(--text-dim); font-weight: var(--fw-regular); }   /* 组织还没定钟，走的是浏览器的 */
@media (prefers-reduced-motion: reduce) { .link[data-state="down"] .link-dot { animation: none; } }

/* 点开 = 卡自己全屏（照 OpenLucy vncFullscreen 和 bot/bot.css 的 .bm-bot-card:fullscreen）：只剩屏幕，框架把大画面铺进去。
   名字、引用、简介、代理、缓存、⛶、Stop、开关、NOT RUNNING 照 OpenLucy 浮在画面上：没亮的卡就是这里画的；亮着的卡大画面压在网页一切内容之上，
   同一份字由框架上面的字层画（text-layer.html），这里那份藏着、只给框架量钮的位置。
   屏幕跟机器人窗口一样比例（D019 的 1600×860），铺满宽、上下居中（太宽的屏铺满高、左右居中），铺不满的上下两条一样宽，是卡的黑底
   （用户 10-06：「上面的这个框和下面的框距离这个屏幕的上下部分应该是一样的……这样看起来比较美观」）。
   外圈 2 像素设备身份色（camoufox 蓝的半透明档；OpenLucy 是 1，用户 10-06 要「再厚一个 px」），跑任务时满色、不加粗（OpenLucy 加粗到 2）；
   呼吸的光晕往画面里收，画在字层上（网页画的盖不到画面上；用户 10-06：「这光晕应该是往内射的」）。框画在屏幕上、不画在卡上：画面铺到哪蓝框到哪，黑底在框外
   （用户 10-06：「这个蓝块儿……要跟着屏幕走，屏幕铺到哪儿就铺到哪儿，要不然的话，你会让我产生这个错误认知」；OpenLucy 框整张卡，D189）。
   框架拿屏幕框里面那块铺画面（app.js 的 sendOpen） */
.robot-card:fullscreen {
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: visible;
  box-shadow: none;
  animation: none;
  padding: 0;
  gap: 0;
  background: var(--bg);
  border: 0;
  border-radius: 0;
  cursor: default;
}
.robot-card:fullscreen .robot-screen {
  flex: none;
  align-self: center;
  width: min(100%, 100vh * 1600 / 860);
  aspect-ratio: 1600 / 860;
  padding: 0;
  border: calc(var(--border-w) * 2) solid color-mix(in srgb, var(--accent) 50%, transparent);
  border-radius: 0;
}
.robot-card.running:fullscreen .robot-screen { border-color: var(--accent); }

/* Run Output（D020）：照 OpenLucy 画面卡上的玻璃框（chain/chain.css 的 .sse-hud、chat/chat.css 的块样式），app.js 的 outBox 搭、写字。
   按客人屏幕的分辨率画在卡的屏幕上（墙上的卡、全屏的卡同一个框）；机器人画面是框架贴的缩略图，压在这份上面，
   看得见的那一截交给字层画在画面上面（text-layer.js），这份在画面底下接滚轮和 ▾。只透不糊：网页拿不到画面的像素，没有 OpenLucy 的 backdrop-filter。
   .robot-pic 是画面那块（位置、大小、--out-scale 是 JS 照框架的算法算的），框锚在画面右下角，按 1920 宽设计整体缩；
   机器人的鼠标压上来翻到左下角（data-left），折叠只留头尾两行（data-folded）。框、外圈的光、头一行用主题青，不照 OpenLucy 的绿（用户 10-07） */
.robot-screen { position: relative; }
.robot-pic { --out-scale: 1; position: absolute; z-index: 2; pointer-events: none; }   /* 压在卡上的字上面、NOT RUNNING 和钮下面（照 OpenLucy 层次） */
.out {
  position: absolute;
  right: calc(var(--out-pad) * var(--out-scale));
  bottom: calc(var(--out-clear) * var(--out-scale));
  width: var(--out-w);
  height: var(--out-h);
  transform: scale(var(--out-scale));
  transform-origin: 100% 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  pointer-events: auto;
  background: var(--out-glass);
  border: var(--border-w) solid var(--accent);
  border-radius: var(--radius);
  box-shadow: var(--out-glow);
  color: var(--text);
  font-size: var(--out-fs);
  line-height: var(--lh-base);
  text-align: left;
  cursor: default;
}
/* 全屏时右下没有钮，框落回离底 --out-pad（照 OpenLucy）；墙上的卡给 Power 让位（--out-clear） */
:is(.robot-card:fullscreen, .layer-card.big) .out { bottom: calc(var(--out-pad) * var(--out-scale)); }
.out[data-left] { right: auto; left: calc(var(--out-pad) * var(--out-scale)); transform-origin: 0 100%; }
.out[data-folded] { height: auto; }
.out[data-folded] .out-log { display: none; }
/* 头一行：圆点（在跑时呼吸）+ RUN OUTPUT + 折叠钮 */
.out-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  border-bottom: var(--border-w) solid var(--border);
  background: var(--out-glass);
  color: var(--accent);
  font: var(--fw-semibold) var(--out-fs-bar) var(--font-mono);
  letter-spacing: var(--out-track);
}
.out-dot { width: var(--space-3); height: var(--space-3); border-radius: var(--radius-pill); background: var(--text-dim); }
.out-dot[data-on] { background: var(--accent); animation: out-breath var(--out-breath) ease-in-out infinite; }
@keyframes out-breath { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { .out-dot[data-on] { animation: none; } }
.out-spacer { flex: 1; }
.out-fold {
  padding: 0 var(--space-3);
  border: var(--border-w) solid var(--border-soft);
  border-radius: var(--radius-ctl);
  background: none;
  color: var(--text-2);
  font: inherit;
  cursor: pointer;
}
.out[data-folded] .out-fold { transform: rotate(180deg); }
/* 日志：一块一块往下长，块间小距；每块右上角是它开始的时间 */
.out-log {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  overflow-y: auto;
  scrollbar-width: none;
  padding: var(--space-3) var(--space-4);
}
.out-msg, .out-marker { position: relative; padding-right: var(--out-stamp); }
.out-t { position: absolute; top: 0; right: 0; color: var(--text-dim); font-family: var(--font-mono); }
/* 回答：没框、白字、大一档；思考：虚线框、等宽灰字；工具：实线框、等宽灰字、玻璃底 */
.out-bubble { font-size: var(--out-fs-answer); white-space: pre-wrap; word-break: break-word; }
.out-para + .out-para, .out-list, .out-para + .out-list { margin-top: var(--space-6); }
.out-para[data-hang] { text-indent: var(--out-hang); }
.out-li { display: flex; gap: var(--out-li-gap); }
.out-li-m { flex: 0 0 var(--out-li-m); text-align: right; opacity: 0.85; }
.out-li-t { flex: 1; min-width: 0; }
.out-think { border: var(--border-w) dashed var(--border-strong); border-radius: var(--radius); }
.out-think-label { padding: var(--space-2) var(--space-5); border-bottom: var(--border-w) dashed var(--border); color: var(--text-dim); }
.out-think > pre {
  margin: 0;
  padding: var(--space-3) var(--space-5);
  white-space: pre-wrap;
  word-break: break-word;
  font-family: var(--font-mono);
  color: var(--text-2);
}
.out-tool {
  padding: var(--space-3) var(--space-4);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  background: var(--out-glass-faint);
  color: var(--text-2);
  font-family: var(--font-mono);
  white-space: pre-wrap;
  word-break: break-word;
}
.out-tool strong { color: var(--text); }
.out-tool-tag { margin-right: var(--space-2); color: var(--text-dim); }
/* 开头、收尾、看门狗这些动静：一行一条，图标定宽 */
.out-marker { color: var(--text-2); font-family: var(--font-mono); white-space: pre-wrap; word-break: break-word; }
.out-ico { display: inline-block; width: var(--out-ico); }
.out-marker[data-kind="chain"] { color: var(--accent); font-weight: var(--fw-semibold); }
.out-marker[data-kind="session"] { color: var(--accent); }
.out-marker[data-kind="done"] { color: var(--success); font-weight: var(--fw-semibold); }
.out-marker[data-kind="error"] { color: var(--danger); }
/* 指标条：等宽数字、标签暗数值亮、一根细条（占用到六成转黄、八成五转红） */
.out-stats {
  --out-level: var(--accent);
  --out-pct: 0%;
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-2) var(--space-4);
  border-top: var(--border-w) solid var(--border);
  background: var(--out-glass);
  font: var(--out-fs-bar) var(--font-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.out-stats[data-level="mid"] { --out-level: var(--warning); }
.out-stats[data-level="high"] { --out-level: var(--danger); }
.out-bar { flex: 0 0 var(--out-bar-w); height: var(--out-bar-h); background: var(--bg-row); }
.out-bar-fill { display: block; width: var(--out-pct); height: 100%; background: var(--out-level); }
.out-pct { color: var(--out-level); }
.out-unit { color: var(--text-dim); }
.robot-card.live:fullscreen :is(.rc-scrim, .rc-top, .rc-bottom, .rc-big, .rc-esc) { visibility: hidden; }

/* 点开时顶上正中「Press Esc to exit full screen」，几秒后淡出（app.js 的 showEsc；OpenLucy 的这句是 Chrome 自己出的，框架的 WebView2 不出） */
.rc-esc {
  position: absolute;
  top: var(--space-6);
  left: 50%;
  z-index: 4;
  transform: translateX(-50%);
  padding: var(--space-2) var(--space-4);
  border: var(--border-w) solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--mask);
  color: var(--text-2);
  font-size: var(--fs-xs);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--card-esc-fade) ease-in-out;
}
.robot-card.esc:fullscreen .rc-esc,
.layer-card.esc .rc-esc { opacity: 1; }
.rc-key {
  margin: 0 var(--space-1);
  padding: 0 var(--space-2);
  border: var(--border-w) solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text);
}

/* 字层（D189）：框架上面一块透明、点得穿的窗口载 text-layer.html，把亮着的卡上那份字（app.js 的 overlayHtml）按框架报的位置摆在画面上面。
   墙上的卡裁在卡片区露出来的那块里（.layer-view）；.layer-card 盖住那张卡的画面，Run Output 框（.robot-pic）铺满它、跟网页那份一样锚在右下角 */
.text-layer,
.text-layer body { background: none; overflow: hidden; }   /* 整页透明：只有字和暗影盖在画面上 */
.layer-view { position: fixed; overflow: hidden; }
.layer-card { position: absolute; container-type: inline-size; }
.layer-card > .robot-pic { inset: 0; }
.layer-card.big.running { animation: layer-breathe var(--card-breathe) ease-in-out infinite; }   /* 照 OpenLucy bm-live-breathe 的节奏，往画面里收，散得比它深 */
@keyframes layer-breathe {
  0%, 100% { box-shadow: inset 0 0 var(--card-glow-in-min) var(--accent); }
  50% { box-shadow: inset 0 0 var(--card-glow-in-max) var(--accent); }
}
@media (prefers-reduced-motion: reduce) {
  .layer-card.big.running { animation: none; box-shadow: inset 0 0 var(--card-glow-in-min) var(--accent); }
}

/* ── Workflows 页（照 OpenLucy 的工作链；app.js 的 wfCard / taskHtml / exitHtml）────────────────────────────── */
/* 工作链：一条链一行（照 OpenLucy chain.css 的 .tree-chain；用户 10-07 嫌一条占两行太松，客人的链多）。行距、上下留白都是 4 */
.wf-list { display: flex; flex-direction: column; gap: var(--space-2); }
.wf { background: var(--bg-card); border: var(--border-w) solid var(--border); border-radius: var(--radius); overflow: hidden; }
/* 状态条用往里的阴影画、不加粗左边框：边框会把整行往右挤，跟别的行列位对不齐（照 OpenLucy） */
.wf.issues { box-shadow: inset var(--wf-bar) 0 0 var(--warning); }
.wf.running { box-shadow: inset var(--wf-bar) 0 0 var(--accent), var(--wf-run-glow); }
.wf-head { display: flex; align-items: center; gap: var(--space-5); padding: var(--space-2) var(--space-7); cursor: pointer; user-select: none; }
.wf-head:hover { background: var(--bg-hover); }
.wf-caret { display: inline-flex; flex-shrink: 0; width: var(--wf-caret-w); color: var(--text-dim); transition: transform 0.15s; }
.wf.open .wf-caret { transform: rotate(90deg); color: var(--text); }
.wf-name { flex: 0 1 var(--wf-name-w); min-width: var(--wf-name-min); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: var(--fw-semibold); }
/* 「{标签:值}」一格一列，宽度写死、放不下省略（照 OpenLucy .cn-chip：用 min-width 的话长名字一撑，右边整排跟着漂） */
.wf-meta { display: flex; flex-shrink: 0; font-family: var(--font-mono); font-size: var(--fs-note); color: var(--text-dim); }
.wf-chip { margin-right: var(--space-5); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wf-c-bot { width: var(--wf-c-bot); }
.wf-c-task { width: var(--wf-c-task); }
.wf-c-sched { width: var(--wf-c-sched); }
.wf-c-last { width: var(--wf-c-last); }
.wf-v { color: var(--accent); }
.wf-v.none { color: var(--text-dim); }    /* 0、none、没跑过 */
.wf-v.plain { color: var(--text-2); }     /* 跑完的那一趟 */
.wf-v.warn { color: var(--warning); }     /* 排队 */
.wf-dot { display: inline-block; width: var(--space-3); height: var(--space-3); margin-right: var(--space-2); border-radius: 50%; background: currentColor; vertical-align: middle; }
.wf-issues { display: inline-flex; flex-shrink: 0; width: var(--wf-issues-w); }
.wf-acts { display: flex; flex-shrink: 0; gap: var(--space-2); margin-left: auto; }
.wf-body { display: none; padding: var(--space-5) var(--space-7) var(--space-6) calc(var(--space-8) + var(--space-6)); border-top: var(--border-w) solid var(--border); }
.wf.open .wf-body { display: block; }
.wf-empty { display: flex; align-items: center; gap: var(--space-6); padding: var(--space-7) 0 var(--space-2); font-size: var(--fs-sm); color: var(--text-dim); }
.wf-problems { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-6) 0 var(--space-2); font-size: var(--fs-note); color: var(--danger); }
.wf-orphans { padding: var(--space-7) 0 var(--space-2) var(--space-4); font-size: var(--fs-note); color: var(--warning); }

/* 任务树（照 OpenLucy chain.css 的几何）：所有线钉在父代号框正中（--wf-anchor）。代号框定宽，每层中线都在同一个 x 上；
   子任务缩进 = 出口文字的起点，子代号框左边正对「Pick」。树里一律不用 margin：margin 会在线中间留缝，间距全靠行高 */
.wf-tree {
  --wf-anchor: calc(var(--space-4) + var(--wf-tag-w) / 2);
  --wf-exit-pad: calc(var(--wf-anchor) + var(--wf-elbow) + var(--space-4));
  --wf-kid-pad: calc(var(--wf-exit-pad) - var(--space-4));
}
.wf-task { position: relative; }
.wf-row { position: relative; display: flex; align-items: center; gap: var(--space-5); min-height: var(--wf-row-h); padding: 0 var(--space-4); border-radius: var(--radius); }
.wf-row:hover { background: var(--bg-hover); }
.wf-task.has-exits > .wf-row::after {
  content: ""; position: absolute; left: var(--wf-anchor); top: calc(50% + var(--wf-tag-h) / 2); bottom: 0;
  border-left: var(--border-w) solid var(--border-strong); pointer-events: none;
}
.wf-task.running > .wf-row { background: color-mix(in srgb, var(--warning) var(--wash), transparent); }
.wf-code {
  position: relative; z-index: 1; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: var(--wf-tag-w); height: var(--wf-tag-h); border: var(--border-w) solid var(--accent); border-radius: var(--radius-sm);
  background: var(--bg-card); font-family: var(--font-mono); font-size: var(--fs-note); color: var(--accent);
}
.wf-task.running > .wf-row .wf-code { border-color: var(--warning); color: var(--warning); }
.wf-task.done > .wf-row .wf-code { border-color: var(--success); color: var(--success); }
.wf-prompt { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-note); font-weight: var(--fw-medium); }
.wf-st { font-family: var(--font-mono); font-size: var(--fs-note); white-space: nowrap; }
.wf-st.running { color: var(--warning); }
.wf-st.done { color: var(--success); }
.wf-bot { font-family: var(--font-mono); font-size: var(--fs-note); color: var(--text-dim); white-space: nowrap; }
.wf-bot.none { color: var(--danger); }
.wf-row-acts { display: flex; gap: var(--space-2); flex-shrink: 0; }

/* 出口一行：「Pick 哪个 · 什么时候走 → 去哪」。肘线从父中线拐进来；不是最后一个出口的，竖线接着往下 */
.wf-exit { position: relative; display: flex; align-items: center; gap: var(--space-4); min-height: var(--wf-exit-h); padding: 0 var(--space-4) 0 var(--wf-exit-pad); font-size: var(--fs-note); white-space: nowrap; }
.wf-exit::before {
  content: ""; position: absolute; left: var(--wf-anchor); top: 0; width: var(--wf-elbow); height: 50%;
  border-left: var(--border-w) solid var(--border-strong); border-bottom: var(--border-w) solid var(--border-strong); pointer-events: none;
}
.wf-exit:not(.last)::after { content: ""; position: absolute; left: var(--wf-anchor); top: 50%; bottom: 0; border-left: var(--border-w) solid var(--border-strong); pointer-events: none; }
.wf-pick { flex-shrink: 0; font-family: var(--font-mono); color: var(--text-dim); }
.wf-pick b { display: inline-block; min-width: var(--space-8); padding: 0 var(--space-2); border-radius: var(--radius-xs); background: var(--bg-row); color: var(--text); font-weight: var(--fw-medium); text-align: center; }
.wf-pick b.ok { color: var(--success); background: color-mix(in srgb, var(--success) var(--wash), transparent); }
.wf-pick b.bad { color: var(--danger); background: color-mix(in srgb, var(--danger) var(--wash), transparent); }
.wf-when { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--text-2); }
.wf-arrow { flex-shrink: 0; color: var(--text-dim); }
.wf-to, .wf-back, .wf-end { flex-shrink: 0; font-family: var(--font-mono); }
.wf-to { color: var(--text-2); }
.wf-back { color: var(--warning); }
.wf-end.ok { color: var(--success); }
.wf-end.bad { color: var(--danger); }
.wf-fix { display: inline-flex; gap: var(--space-3); margin-left: auto; flex-shrink: 0; }
/* 出口接的下一个任务：缩进到出口文字起点；后面还有兄弟出口的，父中线从这一整块旁边穿过去 */
.wf-kids { position: relative; padding-left: var(--wf-kid-pad); }
.wf-kids:not(.last)::before { content: ""; position: absolute; left: var(--wf-anchor); top: 0; bottom: 0; border-left: var(--border-w) solid var(--border-strong); pointer-events: none; }

/* 窄屏一行放不下：四格挪到名字底下第二行，钮留在第一行 */
@media (max-width: 1420px) {
  .wf-head { flex-wrap: wrap; row-gap: var(--space-1); }
  .wf-meta { order: 1; flex-basis: 100%; padding-left: calc(var(--wf-caret-w) + var(--space-5)); }
}

/* ── 任务编辑框（照 OpenLucy 的 session 编辑）：机器人在标题行；指令和各类绑定一类一个标签；出口一直在底下 ── */
.modal.te { max-width: var(--te-w); height: min(var(--te-h), 100%); }
.modal.ws { max-width: var(--ws-w); }
.te-head { display: flex; align-items: center; gap: var(--space-7); }
.te-head h2 { flex: 1; min-width: 0; }
.te-code { margin-left: var(--space-3); font-family: var(--font-mono); font-size: var(--fs-base); color: var(--accent); }
.te-robot { display: flex; align-items: center; gap: var(--space-4); font-size: var(--fs-note); color: var(--text-dim); }
.te-robot .select { width: var(--te-filter-w); }
.te-hint { padding: var(--space-4) var(--space-6); border-bottom: var(--border-w) solid var(--border); background: var(--bg-hover); font-size: var(--fs-note); color: var(--text-2); }
.te-tabs { padding: 0 var(--space-6); }
.te-n { margin-left: var(--space-3); font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-dim); }
.te-n.has { color: var(--accent); }
.te-body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-5); padding: var(--space-6); }
.te-pane-hd { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-5); }
.te-label { font-family: var(--font-mono); font-size: var(--fs-xs); text-transform: uppercase; color: var(--text-2); }
.te-pane-hint { flex: 1; min-width: var(--te-filter-w); font-size: var(--fs-note); color: var(--text-dim); }
.input.te-filter { width: var(--te-filter-w); height: var(--h-sm); }
.input.te-prompt { flex: 1; height: auto; min-height: var(--te-prompt-h); padding: var(--space-6); line-height: var(--lh-base); resize: vertical; }
.te-checks { display: flex; flex-direction: column; border: var(--border-w) solid var(--border); border-radius: var(--radius); }
.te-check { display: flex; align-items: center; gap: var(--space-6); min-height: var(--h-lg); padding: var(--space-3) var(--space-6); border-bottom: var(--border-w) solid var(--border); cursor: pointer; }
.te-check:last-child { border-bottom: 0; }
.te-check:hover { background: var(--bg-hover); }
.te-check-name { min-width: var(--te-name-w); font-family: var(--font-mono); font-size: var(--fs-sm); }
.te-check-meta { flex: 1; min-width: 0; font-size: var(--fs-note); color: var(--text-dim); }
.te-none { padding: var(--space-6); font-size: var(--fs-note); color: var(--text-dim); }
.te-exits { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-6); border-top: var(--border-w) solid var(--border); background: var(--sidebar-bg); }
.te-exit-list { display: flex; flex-direction: column; gap: var(--space-3); }
.te-exit { display: flex; align-items: center; gap: var(--space-5); }
.te-tag {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; min-width: var(--te-tag-w); height: var(--h-sm);
  border: var(--border-w) solid var(--border-soft); border-radius: var(--radius-sm); font-family: var(--font-mono); font-size: var(--fs-note); color: var(--text-2);
}
.te-tag.ok { color: var(--success); }
.te-tag.bad { color: var(--danger); }
.input.te-when { flex: 1; font-family: var(--font-sans); }
.te-to { flex-shrink: 0; width: var(--te-to-w); font-size: var(--fs-note); color: var(--text-dim); white-space: nowrap; }
.te-msg { padding: 0 var(--space-6); }
.te-msg .field-hint, .te-msg .issue-list { padding-bottom: var(--space-4); }

/* ── 侧栏「资源」：技能、去重表、目标池、变量（D203，照 OpenLucy skills/、dedup/、pool/、vars/ 的页面）──────── */
.side-item.later { color: var(--text-dim); }          /* 材料库：最后做，点了先说一声 */

/* 清单：一张卡里一张表，行线跟 set-row 同一种 */
.res-card { padding: 0; overflow-x: auto; }
.dt { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.dt th {
  height: var(--h-lg);
  padding: 0 var(--space-7);
  border-bottom: var(--border-w) solid var(--border);
  font-size: var(--fs-note);
  font-weight: var(--fw-regular);
  color: var(--text-dim);
  text-align: left;
  white-space: nowrap;
}
.dt td { height: var(--h-lg); padding: var(--space-4) var(--space-7); border-bottom: var(--border-w) solid var(--border); vertical-align: middle; }
.dt tbody tr:last-child td { border-bottom: 0; }
.dt tr.click { cursor: pointer; }
.dt tr.click:hover td { background: var(--bg-hover); }
.dt .c-ns   { width: var(--res-col-ns); }
.dt .c-num  { width: var(--res-col-num); text-align: right; white-space: nowrap; }
.dt .c-time { width: var(--res-col-time); }
.dt .c-act  { width: var(--res-col-act); text-align: right; white-space: nowrap; }
.dt .c-seq  { width: calc(var(--res-col-num) / 2); font-family: var(--font-mono); color: var(--text-dim); }
.dt .c-state { width: var(--res-col-time); }
.dt .c-acts { width: calc(var(--res-col-act) * 2.6); text-align: right; white-space: nowrap; }
.dt .c-acts .btn + .btn { margin-left: var(--space-3); }
.dt .mono, .dt td.c-num, .dt td.c-time, .dt td.c-ns { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.dt td.c-time, .dt td.c-ns { color: var(--text-dim); font-size: var(--fs-note); }
.dt .none { color: var(--text-dim); }
.res-sub { margin-left: var(--space-3); font-family: var(--font-sans); font-size: var(--fs-note); color: var(--warning); }

/* 表单里的一格：小标签在上；长说明挂在 ⓘ 上悬停才出来（照 OpenLucy：不常驻撑高） */
.field { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.field-label { display: flex; align-items: center; gap: var(--space-3); font-size: var(--fs-note); color: var(--text-2); }
.field-n { color: var(--text-dim); }
.tip { display: inline-flex; color: var(--text-dim); cursor: help; }
.tip:hover { color: var(--text); }
.input.area { height: auto; min-height: calc(var(--h-md) * 2.4); padding: var(--space-4) var(--space-5); line-height: var(--lh-base); resize: vertical; }
.field-pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-5); }
.check-line { display: flex; align-items: center; gap: var(--space-4); font-size: var(--fs-sm); cursor: pointer; }

/* 详情框（大一号）、新建框 */
.modal.res { max-width: var(--res-modal-w); }
.modal.res-form { max-width: var(--ws-w); }
.res-head { display: flex; align-items: center; gap: var(--space-5); }
.res-head h2 { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.res-ns { margin-left: var(--space-4); font-family: var(--font-mono); font-size: var(--fs-note); color: var(--text-dim); }
.modal-foot.split { justify-content: space-between; }

/* 定义盘：头一行常在、带摘要，点开才是两列字段 */
.res-def { border: var(--border-w) solid var(--border); border-radius: var(--radius-md); background: var(--bg); }
.res-def-head {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  width: 100%;
  height: var(--h-lg);
  padding: 0 var(--space-6);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text);
  font-size: var(--fs-sm);
  text-align: left;
  cursor: pointer;
}
.res-def-head:hover { background: var(--bg-hover); }
.res-def-t { font-weight: var(--fw-medium); }
.res-def-sum { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-dim); }
.res-def-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-7); padding: var(--space-5) var(--space-6); border-top: var(--border-w) solid var(--border); }
.res-def-col { display: flex; flex-direction: column; gap: var(--space-5); min-width: 0; }
.res-def-tail { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-5); padding: 0 var(--space-6) var(--space-5); }
.res-def-tail.spread { justify-content: space-between; }
.res-def.closed .res-def-body, .res-def.closed .res-def-tail { display: none; }

/* 记录、目标清单：头一行（名字、数、筛、搜），下面限高框里滚 */
.res-rec-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-5); }
.res-rec-t { font-size: var(--fs-base); font-weight: var(--fw-medium); }
.res-rec-n { flex: 1; min-width: 0; font-size: var(--fs-note); color: var(--text-dim); }
.res-rec-head .input { width: var(--te-filter-w); }
.res-scroll { max-height: var(--res-list-h); overflow: auto; border: var(--border-w) solid var(--border); border-radius: var(--radius-md); }
.res-scroll .dt th { position: sticky; top: 0; background: var(--bg-card); }
.res-key { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--font-mono); }
.res-add { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) auto; gap: var(--space-3); }
.res-empty { padding: var(--space-8); text-align: center; font-size: var(--fs-sm); color: var(--text-dim); }

/* 目标池：一个目标两行（标题、地址），状态用徽章 */
.pl-target { display: flex; flex-direction: column; min-width: 0; }
.pl-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
.pl-target:hover .pl-title { text-decoration: underline; }
.pl-posted { margin-left: var(--space-4); font-family: var(--font-mono); font-size: var(--fs-note); color: var(--text-dim); }
.pl-url { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--font-mono); font-size: var(--fs-note); color: var(--text-dim); }
.pl-taken { font-family: var(--font-mono); font-size: var(--fs-note); color: var(--text-dim); white-space: nowrap; }
.seg-n { margin-left: var(--space-3); font-family: var(--font-mono); color: var(--text-dim); }
.seg-btn.on .seg-n { color: var(--text-2); }

/* 技能：整篇正文框 */
.input.code.sk-body { min-height: var(--res-editor-h); white-space: pre-wrap; }

/* 任务编辑框的绑定清单里，勾着的已经删了：照 OpenLucy 照样列出来、勾打着，点掉就摘 */
.te-check.stale .te-check-meta { color: var(--warning); }

/* ── Workflows 页的 Schedule 标签（照 _OpenLucy/chain/chain.css「任务编排」那一段；app.js 的 tt 那一段画）──────────────────
   左列竖轴 0–24 点从上到下；右列四个视图 + 月历 + 那天每条跑几次；点轴新建、点一条改、按住拖改时刻、右键拉框删 */



.wf-pane { padding-top: var(--space-7); }

.tt-wrap { position: relative; display: flex; gap: var(--space-7); min-height: var(--tt-h-min); }

/* 左列 = 缩放滚动框：不放大时轴高 = 框高；滚轮放大后在框里滚。上下内衬给 00:00 / 24:00 的半个字 */
.tt-col {
  position: relative;
  flex: 0 0 var(--tt-col-w);
  min-width: min(var(--tt-col-min), 100%);
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  padding: var(--space-6) 0;
  scrollbar-width: none;
  background: var(--bg-card);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-lg);
  isolation: isolate;   /* 行的 z-index 只在框里比，压不过挂在 body 上的浮层 */
}
.tt-col::-webkit-scrollbar { display: none; }
/* 光标只在按住时变抓握（OpenLucy 定的：空白处只有「点一下新建」一个动作，常驻手掌会误导） */
.tt-col.zoomed.panning { cursor: grabbing; }
.tt-col.zoomed.panning .tt-row { pointer-events: none; }
.tt-col.grabbing, .tt-col.grabbing .tt-row, .tt-col.grabbing .tt-seg { cursor: grabbing; }
.tt-col.dragging .tt-row:not(.dragging) { pointer-events: none; }

.tt-area { position: relative; margin-left: var(--tt-gutter); }
.tt-mark { position: absolute; left: 0; z-index: 2; width: var(--tt-mark); height: var(--tt-mark); border-radius: 50%; background: var(--border-strong); transform: translate(-50%, -50%); }
.tt-mark.major { width: var(--tt-mark-major); height: var(--tt-mark-major); background: var(--accent); }
.tt-mark.minor { width: var(--tt-mark-minor); height: var(--tt-mark-minor); }
.tt-label {
  position: absolute;
  right: calc(100% + var(--space-6));
  transform: translateY(-50%);
  font-family: var(--font-mono);
  font-size: var(--fs-note);
  color: var(--text-dim);
  white-space: nowrap;
  user-select: none;
  pointer-events: none;
}
.tt-label.major { color: var(--accent); font-weight: var(--fw-semibold); }

/* NOW：红标签在整点字那一条里，红线横穿到轴右缘（跟工作台 Timeline 的红线同色） */
.tt-now { position: absolute; left: calc(var(--tt-gutter) * -1); z-index: 3; display: flex; align-items: center; transform: translateY(-50%); pointer-events: none; }
.tt-now-label {
  flex-shrink: 0;
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--danger);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--fs-note);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
}
.tt-now-line { flex: 1; height: var(--border-w); background: var(--danger); }

/* 一个时刻一行：青线 + 时刻 + 每条一段；同一时刻的并成一行横排。宽度收到内容，右边空白还给「点一下新建」 */
.tt-row {
  position: absolute;
  left: 0;
  width: max-content;
  max-width: calc(100% - var(--space-6));
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-1) var(--space-3) var(--space-1) 0;
  overflow: hidden;
  white-space: nowrap;
  transform: translateY(-50%);
  cursor: pointer;
}
.tt-row:hover { z-index: 999 !important; }   /* 压过 JS 写的 z-index（晚的叠上面），悬停那行浮到最上 */
.tt-track { flex: 0 0 var(--tt-track); width: var(--tt-track); height: var(--border-w); background: var(--accent); }   /* width 不能省：Firefox 算整行宽时不认空 span 的 flex-basis，整行少 30 像素被截 */
.tt-row:hover .tt-track, .tt-row.running .tt-track { height: calc(var(--border-w) * 2); }
.tt-row.paused .tt-track { background: var(--warning); }
.tt-time { flex-shrink: 0; font-family: var(--font-mono); font-size: var(--fs-note); color: var(--text-dim); }
.tt-seg { display: inline-flex; align-items: center; gap: var(--space-4); padding: var(--space-1) var(--space-4); border-radius: var(--radius-sm); cursor: pointer; }
.tt-seg:hover { background: var(--active-bg); }
.tt-seg + .tt-seg { border-left: var(--border-w) solid var(--border); }
.tt-seg.paused { opacity: 0.7; }
.tt-name { font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--text); }
.tt-xrep { flex-shrink: 0; font-family: var(--font-mono); font-size: var(--fs-note); font-weight: var(--fw-semibold); color: var(--accent); }
/* 当天第几次：同一条按时刻累计，连跑一条占一段（3~5） */
.tt-ord {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  min-width: calc(var(--fs-note) + var(--space-3));
  height: calc(var(--fs-note) + var(--space-3));
  padding: 0 var(--space-2);
  border: var(--border-w) solid var(--accent);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--fs-note);
  line-height: 1;
  color: var(--accent);
}
.tt-meta { flex-shrink: 0; font-size: var(--fs-note); color: var(--warning); }
.tt-missed { flex-shrink: 0; font-family: var(--font-mono); font-size: var(--fs-note); font-weight: var(--fw-semibold); color: var(--danger); }
.tt-running { min-width: 0; overflow: hidden; text-overflow: ellipsis; font-family: var(--font-mono); font-size: var(--fs-note); color: var(--accent); }
/* 拉框圈中的：描名字 */
.tt-seg.sel .tt-name { border-radius: var(--radius-xs); outline: var(--border-w) solid var(--accent); background: color-mix(in srgb, var(--accent) var(--wash), transparent); }
/* 虚线吸到已有那一刻：那条名字慢闪（只提醒，同一刻能一起跑） */
.tt-row.overlap .tt-name { animation: tt-blink var(--tt-blink) ease-in-out infinite; }
@keyframes tt-blink { 50% { opacity: 0.25; } }
.tt-row.dragging { z-index: 1000; }

/* 鼠标在轴上走：蓝虚线吸 5 分钟，标签跟着鼠标横移 */
.tt-cross { position: absolute; left: 0; z-index: 6; height: 0; border-top: var(--border-w) dashed var(--accent); pointer-events: none; }
.tt-cross-label {
  position: absolute;
  bottom: var(--space-2);
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--bg);
  font-family: var(--font-mono);
  font-size: var(--fs-note);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  white-space: nowrap;
}
.tt-marquee { position: absolute; z-index: 60; border: var(--border-w) dashed var(--accent); background: color-mix(in srgb, var(--accent) var(--wash), transparent); pointer-events: none; }

/* 右列：模式 + 月历一张卡，单日统计一张卡，并排 */
.tt-side { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-7); overflow-y: auto; }
.tt-edit-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-7); }
.tt-cal-card { max-width: 100%; }
.tt-modes { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4); margin-bottom: var(--space-5); }
.tt-month { display: inline-flex; align-items: center; gap: var(--space-2); margin-left: auto; font-family: var(--font-mono); font-size: var(--fs-sm); font-weight: var(--fw-medium); }
.tt-sub { display: grid; grid-template-columns: repeat(7, minmax(0, var(--tt-cal-cell))); gap: var(--space-3); margin-bottom: var(--space-5); }
.tt-sub .btn { width: 100%; padding: 0; justify-content: center; }
.tt-hint { grid-column: 1 / -1; font-size: var(--fs-note); color: var(--text-dim); }
.tt-hint b { color: var(--accent); font-weight: var(--fw-semibold); }

.tt-cal { display: grid; grid-template-columns: repeat(7, minmax(0, var(--tt-cal-cell))); gap: var(--space-3); }
.tt-dow { padding: var(--space-1) 0; text-align: center; font-family: var(--font-mono); font-size: var(--fs-note); color: var(--text-dim); }
.tt-day {
  position: relative;
  aspect-ratio: 1 / 1;
  max-width: 100%;
  padding: var(--space-2) var(--space-3);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--fs-note);
  text-align: left;
  vertical-align: top;
  cursor: pointer;
}
.tt-day:hover { border-color: var(--border-strong); }
.tt-day.off { visibility: hidden; }
.tt-day.past { opacity: 0.45; }
.tt-day.nodom { opacity: 0.3; cursor: not-allowed; }
.tt-day.nodom:hover { border-color: var(--border); }
.tt-day.today { border-color: var(--accent); color: var(--text); animation: tt-breathe var(--tt-breathe) ease-in-out infinite; }
.tt-day.sel { border-color: var(--accent); background: var(--active-bg); color: var(--text); }
.tt-day-dot { position: absolute; top: var(--space-3); right: var(--space-3); width: var(--space-3); height: var(--space-3); border-radius: 50%; background: var(--accent); animation: tt-dot var(--tt-breathe) ease-in-out infinite; }
.tt-day-n { position: absolute; right: var(--space-3); bottom: var(--space-2); font-weight: var(--fw-semibold); color: var(--accent); }
.tt-day-n.missed { color: var(--danger); }
@keyframes tt-dot { 50% { opacity: 0.2; } }
@keyframes tt-breathe { 50% { background: color-mix(in srgb, var(--accent) var(--wash), transparent); } }

.tt-stats { min-width: var(--tt-stats-min); max-width: var(--tt-stats-max); }
.tt-stats-h { margin-bottom: var(--space-4); font-family: var(--font-mono); font-size: var(--fs-note); color: var(--text-dim); white-space: nowrap; }
.tt-stats-row { display: flex; align-items: baseline; gap: var(--space-7); padding: var(--space-1) 0; font-family: var(--font-mono); font-size: var(--fs-sm); }
.tt-stats-row .n { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.tt-stats-row .x { color: var(--accent); font-weight: var(--fw-semibold); }
.tt-stats-row.total { margin-top: var(--space-3); padding-top: var(--space-3); border-top: var(--border-w) solid var(--border); }
.tt-stats-row.total .n { color: var(--text-dim); }
.tt-stats-empty { font-size: var(--fs-note); color: var(--text-dim); }

/* 浮层：新建、改一条、圈选后删，三种同一个壳，挂在 body 上 */
.tt-pop {
  position: fixed;
  z-index: 30;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  width: max-content;
  min-width: var(--tt-pop-w);
  max-width: calc(100vw - var(--space-7) * 2);
  padding: var(--space-6);
  background: var(--bg-elev);
  border: var(--border-w) solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-pop);
  font-size: var(--fs-sm);
}
.tt-pop-h { font-weight: var(--fw-semibold); }
.tt-pop-sub { font-size: var(--fs-note); font-weight: var(--fw-regular); color: var(--text-dim); }
.tt-pop-row { display: flex; align-items: center; gap: var(--space-4); font-size: var(--fs-note); color: var(--text-2); }
.tt-pop-k { flex: 0 0 var(--tt-pop-k); }
.tt-pop-row > .input, .tt-pop-row > .select { flex: 1; min-width: 0; height: var(--h-md); }
.tt-pop-row .tt-num { flex: 0 0 var(--tt-num-w); width: var(--tt-num-w); height: var(--h-md); text-align: right; }

@media (prefers-reduced-motion: reduce) {
  .tt-row.overlap .tt-name, .tt-day.today, .tt-day-dot { animation: none; }
}

/* 变量清单：定宽，列宽听表头，长内容在格里截断（照 OpenLucy .ph-table） */
.dt.fixed { table-layout: fixed; }
.dt .c-name { width: var(--res-col-name); }
.dt .c-type { width: var(--res-col-num); }
.dt .c-avoid { width: var(--res-col-num); text-align: right; }
.dt td.c-avoid { font-family: var(--font-mono); }
.dt .ellip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.var-cnt { margin-right: var(--space-3); font-family: var(--font-mono); font-size: var(--fs-note); color: var(--text-dim); }

/* 任务编辑框 Prompt 标签「+ Variable」点开的小清单：挂在 body 上，位置 app.js 按钮算（照 OpenLucy .var-picker） */
.var-pick {
  position: fixed;
  z-index: 55;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: var(--var-pick-min);
  max-width: var(--tl-pop-w);
  max-height: var(--var-pick-h);
  overflow-y: auto;
  padding: var(--space-3);
  background: var(--bg-elev);
  border: var(--border-w) solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-pop);
}
.var-pick-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  padding: var(--space-3) var(--space-4);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.var-pick-item:hover { background: var(--active-bg); }
.var-pick-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--font-mono); font-size: var(--fs-sm); }
.var-pick-type { flex-shrink: 0; font-size: var(--fs-note); color: var(--text-dim); }
.var-pick-empty { padding: var(--space-4); font-size: var(--fs-note); color: var(--text-dim); }
