/* ============================================================
   全包管家 · 设计系统
   走「专业工作台」路线：信息密度够、对比清楚、不花哨。

   配色：整屏统一走橙色色相（2026-10 定的）。
   为什么橙：全包管家是「出稿前后的尺子」，和全案掌柜的蓝紫
   放一起时，一眼能分出「这个在算东西、那个在管经营」。
   做法不是「把蓝色换成橙色」就完事：
     · 中性色全部带到暖调（米白、暖褐、焦糖），冷灰一律不用；
     · 侧栏用深咖啡褐，不用原来的深靛蓝；
     · 橙只做「强调」，大面积仍是低饱和暖白，否则满屏橙会看花眼；
     · 好／提醒／错三色保留绿、琥珀、红，在一屏橙里仍然分得清。
   橙色文字压到 #c2410c 保证白底可读，按钮渐变再深一档。
   ============================================================ */

:root{
  /* ── 品牌色：一条橙色色阶（浅 → 深） ── */
  --brand-soft:#f59e0b;      /* 琥珀亮橙：高光、渐变的浅端 */
  --brand:#f97316;           /* 标准橙：强调、图标 */
  --brand-deep:#ea580c;      /* 深橙：按钮渐变 */
  --brand-dark:#b8420b;      /* 焦糖橙：渐变暗端、描边 */

  /* 主色：橙做主，琥珀做辅 */
  --tea:#c2410c;             /* 浅色底上的文字/描边，压暗一档才够对比 */
  --tea-2:#f97316;           /* 亮版：按钮、强调 */
  --gold:#a16207;            /* 辅助：琥珀 */
  --gold-soft:#fbbf24;

  /* 侧栏：深咖啡褐 */
  --ink:#241309;
  --ink-2:#301a0b;

  /* 中性：全部带暖调，不用冷灰 */
  --bg:#fbf7f1;
  --panel:#fffdfa;
  --panel-2:#fff8ef;
  --line:#efe1d0;
  --line-2:#ddc7ae;
  --txt:#241a12;
  --txt-2:#6e5540;
  --txt-3:#9c8470;

  /* 语义色：在橙底上仍要一眼分清「好 / 提醒 / 错」 */
  --ok:#157347;   --ok-bg:#e9f6ee;   --ok-line:#c3e7d1;
  --warn:#a16207; --warn-bg:#fdf4d9; --warn-line:#efdca8;
  --bad:#c0392b;  --bad-bg:#fdecea;  --bad-line:#f6cac5;
  --info:#b8480a; --info-bg:#fff0e2; --info-line:#ffd3ad;

  --r:10px;
  --r-sm:7px;
  --r-lg:16px;
  --sh:0 1px 2px rgba(74,45,20,.06), 0 4px 14px rgba(74,45,20,.07);
  --sh-lg:0 8px 30px rgba(74,45,20,.17);
  --side-w:236px;
  --mono:"SF Mono",ui-monospace,Menlo,Consolas,monospace;

  /* 品牌渐变：按钮、logo 底、强调条都用它 */
  --grad:linear-gradient(135deg,var(--brand-deep),var(--brand-dark));
  --grad-full:linear-gradient(120deg,var(--brand-soft),var(--brand) 35%,var(--brand-deep) 70%,var(--brand-dark));
}

*{box-sizing:border-box}
html,body{height:100%}

/* 关键：下面这些浮层（.boot/.busy/.modal/.toast/.shell）都写了 display:flex，
   而作者样式的优先级高于浏览器给 [hidden] 的 display:none，
   结果就是「hidden 了却还显示」——启动屏会一直盖在最上面。
   这里统一兜住，让 hidden 说了算。 */
[hidden]{display:none !important}

body{
  margin:0;background:var(--bg);color:var(--txt);
  font:14px/1.6 -apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  -webkit-font-smoothing:antialiased;
}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer}
a{color:var(--tea);text-decoration:none}
a:hover{text-decoration:underline}
::selection{background:rgba(249,115,22,.26);color:var(--txt)}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-thumb{background:#e2cdb7;border-radius:6px;border:2px solid var(--bg)}
::-webkit-scrollbar-thumb:hover{background:#c9a987}
::-webkit-scrollbar-track{background:transparent}

/* ---------------------------------------------------------- 启动屏 */
/* 启动屏直接用 App 图标那张（自带圆角白底和投影），
   所以这里不再套第二层白底 —— 两层白叠在一起会露出一圈灰边。 */
.boot{position:fixed;inset:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:18px;background:var(--bg);z-index:999}
.boot-mark{width:104px;height:104px;display:grid;place-items:center;
  animation:pulse 1.6s ease-in-out infinite}
.boot-mark img{width:100%;height:100%;object-fit:contain;display:block}
@keyframes pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.07)}}
.boot-txt{color:var(--txt-2);font-size:13px;letter-spacing:.06em}

/* ---------------------------------------------------------- 布局 */
/* 高度用 100vh 打底，再补 100dvh：手机上地址栏伸缩时 vh 会算错，
   结果底部一截被浏览器工具栏糊住。旧浏览器不认 dvh，会忽略这行。 */
.shell{display:flex;height:100vh;height:100dvh;overflow:hidden}

.side{width:var(--side-w);flex:0 0 var(--side-w);background:var(--ink);color:#ecd9c4;
  display:flex;flex-direction:column;overflow:hidden}
/* 品牌区：logo 缩小、贴在最前面，标题与副标题跟在右边，三者同一行。
   2026-10-19 改：原来 logo 独占 76px 一行、文字在下一行，占了侧栏顶部
   一大块，导航第一屏被挤下去两行。现在改横向一行，省出约 60px 高度。 */
.brand{display:flex;flex-direction:row;align-items:center;gap:9px;
  padding:12px 12px 10px}
/* logo 在深色侧栏上：新 logo 是白底方图，本身就是一块「白卡片」，
   所以承载面改成纯白 + 圆角，不再用半透明渐变（会把白底染成灰蓝）。
   一行布局里它是配角，尺寸从 76px 收到 40px（原来占满一行时的近一半），
   圆角跟着同比例收小，否则小图上会显得太圆。 */
.brand-mark{width:40px;height:40px;flex:0 0 40px;aspect-ratio:1;
  border-radius:10px;background:#fff;
  display:grid;place-items:center;padding:0;
  box-shadow:0 2px 6px rgba(0,0,0,.24), 0 0 0 1px rgba(255,255,255,.08);
  overflow:hidden}
.brand-mark img{width:100%;height:100%;object-fit:contain;display:block}
/* 标题 + 副标题排在一行：标题稍大、副标题紧跟其后，中间用小圆点分隔。
   窄侧栏（236px）减去 logo 与间距后只剩约 170px，副标题放不下就
   省略号收尾 —— 主标题绝不压缩、不换行。 */
.brand-txt{display:flex;align-items:baseline;gap:5px;min-width:0;flex:1 1 auto;
  padding:0;overflow:hidden}
.brand-txt b{font-size:13px;letter-spacing:.02em;flex:0 0 auto;white-space:nowrap}
.brand-txt span{font-size:10px;color:#b19274;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;flex:0 1 auto;min-width:0}
.brand-txt span::before{content:"·";margin-right:4px;opacity:.5}

.nav{flex:1;overflow-y:auto;padding:6px 10px 14px}
.nav::-webkit-scrollbar-thumb{background:#3a2210;border-color:var(--ink)}
.nav-group{margin-bottom:14px}
.nav-group>h4{margin:0 0 5px;padding:0 8px;font-size:10.5px;font-weight:600;
  letter-spacing:.13em;color:#a37f5d;text-transform:uppercase}
.nav-item{display:flex;align-items:center;gap:9px;width:100%;padding:8px 9px;margin-bottom:2px;
  background:none;border:0;border-radius:var(--r-sm);color:#e5d1ba;text-align:left;
  font-size:13.2px;transition:background .12s,color .12s;position:relative}
.nav-item:hover{background:#3a2210;color:#fff}
.nav-item.on{background:linear-gradient(90deg,rgba(249,115,22,.22),rgba(194,65,12,.16));color:#fff}
.nav-item.on::before{content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);
  width:3px;height:17px;border-radius:0 3px 3px 0;background:var(--grad-full)}
.nav-item .ic{width:17px;flex:0 0 17px;text-align:center;font-size:13.5px;opacity:.9}
.nav-item .nm{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nav-item .tag{font-size:9.5px;padding:1px 5px;border-radius:20px;background:#4a2b12;color:#e0c9b2}
.nav-item .tag.mine{background:var(--grad);color:#fff;font-weight:600}

.side-foot{padding:10px 12px 14px;border-top:1px solid #3a2210}
.pill{display:flex;align-items:center;gap:7px;padding:6px 9px;border-radius:20px;
  background:#2c1708;font-size:11.5px;color:#c2a482;cursor:pointer;margin-bottom:8px}
.pill:hover{background:#45280f}
.pill .dot{width:7px;height:7px;border-radius:50%;background:#a37f5d;flex:0 0 7px}
.pill.on .dot{background:#22c58b;box-shadow:0 0 7px #22c58b}
.pill.on{color:#d6e8d3}
.side-links{display:flex;gap:6px}
.linkbtn{flex:1;padding:6px;background:#2c1708;border:0;border-radius:var(--r-sm);
  color:#c2a482;font-size:11.5px}
.linkbtn:hover{background:#45280f;color:#fff}

.main{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0}
.top{display:flex;align-items:center;gap:14px;padding:15px 26px;background:var(--panel);
  border-bottom:1px solid var(--line);flex:0 0 auto}
.menubtn{display:none;background:none;border:0;font-size:19px;color:var(--txt-2)}
.top-title{flex:1;min-width:0}
.top-title h1{margin:0;font-size:19px;font-weight:650;letter-spacing:.01em}
.top-title p{margin:1px 0 0;font-size:12.5px;color:var(--txt-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.top-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap;justify-content:flex-end}

.view{flex:1;overflow-y:auto;padding:22px 26px 60px}
.view.wide{padding:0}

/* ---------------------------------------------------------- 基础组件 */
.btn{display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border-radius:var(--r-sm);
  border:1px solid var(--line-2);background:var(--panel);color:var(--txt);font-size:13px;
  font-weight:500;transition:all .13s;white-space:nowrap}
.btn:hover{border-color:var(--tea-2);color:var(--tea);background:#fffdf9;
  box-shadow:0 0 0 3px rgba(249,115,22,.12)}
.btn:active{transform:translateY(1px)}
.btn.primary{background:var(--grad);border-color:transparent;
  color:#fff;box-shadow:0 2px 8px rgba(249,115,22,.28)}
.btn.primary:hover{filter:brightness(1.08);color:#fff}
.btn.ghost{background:transparent;border-color:transparent;color:var(--txt-2)}
.btn.ghost:hover{background:#fdf1e4;color:var(--txt)}
.btn.danger{color:var(--bad);border-color:#f3c4bc}
.btn.danger:hover{background:var(--bad-bg);border-color:var(--bad)}
.btn.sm{padding:5px 10px;font-size:12px}
.btn.lg{padding:11px 20px;font-size:14px}
.btn[disabled]{opacity:.5;pointer-events:none}

.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:16px;box-shadow:var(--sh)}
.card+.card{margin-top:14px}
.card-h{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.card-h h3{margin:0;font-size:14.5px;font-weight:620;flex:1}
.card-h .sub{font-size:12px;color:var(--txt-3);font-weight:400}

.grid{display:grid;gap:14px}
.g2{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.g3{grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
.g4{grid-template-columns:repeat(auto-fit,minmax(175px,1fr))}

label.field{display:block;margin-bottom:11px}
label.field>span{display:block;font-size:12px;color:var(--txt-2);margin-bottom:4px;font-weight:500}
label.field>span em{font-style:normal;color:var(--txt-3);font-weight:400}
input[type=text],input[type=number],input[type=password],select,textarea{
  width:100%;padding:8px 10px;border:1px solid var(--line-2);border-radius:var(--r-sm);
  background:var(--panel-2);transition:border-color .13s,box-shadow .13s}
input:focus,select:focus,textarea:focus{outline:0;border-color:var(--tea-2);
  box-shadow:0 0 0 3px rgba(194,65,12,.16);background:#fff}
textarea{resize:vertical;min-height:76px;line-height:1.6}
select{appearance:none;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 12 12'><path d='M2 4l4 4 4-4' stroke='%236b6259' stroke-width='1.6' fill='none' stroke-linecap='round'/></svg>");
  background-repeat:no-repeat;background-position:right 9px center;padding-right:28px}
input[type=range]{width:100%;accent-color:var(--tea-2)}
input[type=checkbox]{accent-color:var(--tea-2);width:15px;height:15px}
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.row.between{justify-content:space-between}
.flex1{flex:1;min-width:0}
.mt{margin-top:12px}.mt2{margin-top:22px}.mb{margin-bottom:12px}
.muted{color:var(--txt-3)}
.small{font-size:12px}
.mono{font-family:var(--mono);font-size:12.3px}

/* 指标卡 */
.kpi{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:14px 15px;box-shadow:var(--sh);position:relative;overflow:hidden}
.kpi::after{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--line-2)}
.kpi.k-tea::after{background:var(--grad)}
.kpi.k-gold::after{background:linear-gradient(180deg,var(--brand-deep),var(--brand-dark))}
.kpi.k-ok::after{background:var(--ok)}
.kpi.k-warn::after{background:var(--warn)}
.kpi.k-bad::after{background:var(--bad)}
.kpi .lbl{font-size:11.5px;color:var(--txt-3);letter-spacing:.03em}
.kpi .val{font-size:26px;font-weight:680;line-height:1.25;letter-spacing:-.01em;
  font-variant-numeric:tabular-nums}
.kpi .hint{font-size:11.5px;color:var(--txt-3);margin-top:2px}

/* 标签 */
.chip{display:inline-flex;align-items:center;gap:4px;padding:2px 9px;border-radius:20px;
  background:#f2e3d4;color:var(--txt-2);font-size:11.5px;border:1px solid transparent}
.chip.ok{background:var(--ok-bg);color:var(--ok)}
.chip.warn{background:var(--warn-bg);color:var(--warn)}
.chip.bad{background:var(--bad-bg);color:var(--bad)}
.chip.info{background:var(--info-bg);color:var(--info)}
.chip.tea{background:#ffe9d5;color:var(--tea)}

/* 表格 */
table.tb{width:100%;border-collapse:collapse;font-size:13px}
table.tb th{text-align:left;padding:8px 10px;border-bottom:1.5px solid var(--line-2);
  font-size:11.5px;font-weight:600;color:var(--txt-2);letter-spacing:.04em;white-space:nowrap;
  position:sticky;top:0;background:var(--panel);z-index:1}
table.tb td{padding:8px 10px;border-bottom:1px solid var(--line);vertical-align:top}
table.tb tr:hover td{background:var(--panel-2)}
table.tb td.num{text-align:right;font-variant-numeric:tabular-nums;font-family:var(--mono);font-size:12.3px}
table.tb .strong{font-weight:600}
.tbwrap{overflow:auto;max-height:none;border:1px solid var(--line);border-radius:var(--r);
  background:var(--panel)}

/* 空状态 */
.empty{text-align:center;padding:44px 20px;color:var(--txt-3)}
.empty .ic{font-size:34px;opacity:.35;display:block;margin-bottom:10px}
.empty b{display:block;color:var(--txt-2);margin-bottom:4px;font-size:14px}
.empty p{margin:0;font-size:12.5px}

/* 提示条 */
.hintbar{display:flex;gap:9px;padding:10px 13px;border-radius:var(--r-sm);font-size:12.8px;
  line-height:1.55;margin-bottom:13px;align-items:flex-start}
.hintbar .ic{flex:0 0 auto}
.hintbar.info{background:var(--info-bg);color:var(--info);border:1px solid var(--info-line)}
.hintbar.warn{background:var(--warn-bg);color:var(--warn);border:1px solid var(--warn-line)}
.hintbar.bad{background:var(--bad-bg);color:var(--bad);border:1px solid var(--bad-line)}
.hintbar.ok{background:var(--ok-bg);color:var(--ok);border:1px solid var(--ok-line)}

/* 结果块 */
.result{background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:13px;font-size:13px}
.result pre{margin:0;white-space:pre-wrap;word-break:break-word;font-family:var(--mono);font-size:12.2px}
.big-num{font-size:32px;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums;
  line-height:1.2}
.copybox{position:relative}
.copybox .btn{position:absolute;right:7px;top:7px}

/* 进度/评分条 */
.bar{height:6px;border-radius:20px;background:#f4e3d2;overflow:hidden}
.bar>i{display:block;height:100%;border-radius:20px;background:var(--tea-2);transition:width .3s}
.bar.ok>i{background:var(--ok)} .bar.warn>i{background:var(--warn)} .bar.bad>i{background:var(--bad)}

/* ---------------------------------------------------------- 功能卡（项目库 / 功能管理） */
.fcard{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:14px;box-shadow:var(--sh);transition:transform .13s,box-shadow .13s,border-color .13s;
  display:flex;flex-direction:column;gap:9px}
.fcard:hover{transform:translateY(-2px);box-shadow:var(--sh-lg);border-color:var(--line-2)}
.fcard .fh{display:flex;gap:10px;align-items:flex-start}
.fcard .fic{width:34px;height:34px;flex:0 0 34px;border-radius:9px;display:grid;place-items:center;
  background:#ffe9d5;color:var(--tea);font-size:16px}
.fcard .fic.brand svg{display:block}
/* 品牌图标换成她自己的彩色方形图：自带底色，容器不再铺浅色。
   圆角交给图片自己 —— 再套一层 9px 方框会变成「圆角套圆角」。 */
.fic.brand{background:transparent;border-radius:0}
.pf-icon{display:block;border-radius:22%;object-fit:contain}
/* 下面四条浅色底只给单色 SVG 兜底用；有 PNG 的平台会盖回透明 */
.fic.brand[data-pf="xiaohongshu"]{background:#FFE8EC;color:#FF2442}
.fic.brand[data-pf="douyin"]{background:#E8EAf2;color:#161823}
.fic.brand[data-pf="bilibili"]{background:#E0F5FC;color:#00A1D6}
.fic.brand[data-pf="wechat_channels"]{background:#E6F9EE;color:#07C160}
.fic.brand:has(.pf-icon){background:transparent}
/* 标题行里的小图标（平台规则弹窗的 h3）：跟文字对齐，别把行高撑开 */
h3 .pf-icon{display:inline-block;vertical-align:-4px}
.fcard .ft{flex:1;min-width:0}
.fcard .ft b{display:block;font-size:14px;font-weight:620;margin-bottom:1px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fcard .ft span{font-size:11.5px;color:var(--txt-3);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.fcard .fd{font-size:12.3px;color:var(--txt-2);line-height:1.55;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.fcard .fm{display:flex;gap:6px;flex-wrap:wrap;font-size:11px;color:var(--txt-3);
  margin-top:auto;padding-top:4px;border-top:1px dashed var(--line)}
.fcard .fa{display:flex;gap:6px;flex-wrap:wrap}

/* 产物列表 */
.plist{display:flex;flex-direction:column;gap:1px;margin-top:6px;max-height:210px;overflow:auto}
.pitem{display:flex;gap:9px;align-items:center;padding:5px 7px;border-radius:6px;
  font-size:12.3px;cursor:pointer;transition:background .11s}
.pitem:hover{background:#fdf1e4}
.pitem .pk{font-size:10px;padding:1px 6px;border-radius:4px;background:#f4e3d2;
  color:var(--txt-2);flex:0 0 auto;min-width:40px;text-align:center}
.pitem .pn{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pitem .ps{color:var(--txt-3);font-size:11px;flex:0 0 auto;font-family:var(--mono)}

/* ---------------------------------------------------------- 画布工作台
   版面参照稿定 AI 的编辑器骨架，但按「一个人做包装稿」重排：
     顶栏：文件与模式、画布名、保存状态、导出
     左侧：工具条（选择/图形/文字/图片/手绘/修补）
     中间：无限画布（SVG），底部常驻 AI 输入条
     右侧：图层 + 属性 + 素材/生成记录三个页签
   左下角状态：元素数、尺寸、缩放；右下角缩放控件。
   为什么 AI 输入条常驻底部而不是弹窗：出图是高频动作，
   弹窗会把「边看画布边改提示词」这个动作打断。
   ============================================================ */
.canvas-wrap{display:flex;height:100%;overflow:hidden;background:#f3e8db;position:relative}
.cv-tools{width:52px;flex:0 0 52px;background:var(--panel);border-right:1px solid var(--line);
  display:flex;flex-direction:column;align-items:center;gap:3px;padding:9px 0;overflow-y:auto}
.cv-tool{width:38px;height:38px;border:1px solid transparent;border-radius:9px;background:none;
  font-size:16px;color:var(--txt-2);display:grid;place-items:center;transition:all .12s;position:relative}
.cv-tool:hover{background:#fdf1e4;color:var(--txt)}
.cv-tool.on{background:var(--grad);color:#fff;border-color:transparent;box-shadow:0 2px 7px rgba(249,115,22,.30)}
.cv-tool.wide{width:38px;font-size:11px;font-weight:600;letter-spacing:-.02em}
.cv-sep{width:24px;height:1px;background:var(--line);margin:4px 0}

.cv-stage{flex:1;position:relative;overflow:hidden;cursor:default;min-width:0}
.cv-stage.panning{cursor:grabbing}
.cv-stage.drawing{cursor:crosshair}
#cvSvg{position:absolute;inset:0;width:100%;height:100%;display:block}
.cv-side{width:286px;flex:0 0 286px;background:var(--panel);border-left:1px solid var(--line);
  display:flex;flex-direction:column;min-height:0}
.cv-side-tabs{display:flex;gap:1px;border-bottom:1px solid var(--line-2);padding:0 6px;flex:0 0 auto}
.cv-side-tab{flex:1;background:none;border:0;border-bottom:2px solid transparent;padding:9px 4px;
  font-size:12.3px;color:var(--txt-2);font-weight:520;transition:all .12s}
.cv-side-tab:hover{color:var(--txt);background:#fdf2e6}
.cv-side-tab.on{color:var(--tea);border-bottom-color:var(--tea-2)}
.cv-side-body{flex:1;overflow-y:auto;padding:12px;min-height:0}

/* 画布顶部浮条：名字 + 保存状态 + 尺寸档 */
.cv-topbar{position:absolute;left:12px;top:12px;z-index:5;display:flex;gap:7px;align-items:center;
  background:rgba(255,255,255,.96);backdrop-filter:blur(10px);padding:6px 9px;border-radius:9px;
  border:1px solid var(--line);box-shadow:var(--sh);font-size:12px;max-width:calc(100% - 320px)}
.cv-topbar b{font-weight:620;font-size:12.5px;max-width:280px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;cursor:text}
.cv-topbar .dot-state{width:6px;height:6px;border-radius:50%;background:var(--ok);flex:0 0 6px}
.cv-topbar .dot-state.dirty{background:var(--warn)}
.cv-sizechips{display:flex;gap:3px;margin-left:2px}
.cv-sizechip{border:1px solid var(--line-2);background:#fff;border-radius:6px;padding:2px 7px;
  font-size:11px;color:var(--txt-2);cursor:pointer;white-space:nowrap}
.cv-sizechip:hover{border-color:var(--tea-2);color:var(--tea)}
.cv-sizechip.on{border-color:var(--tea-2);background:#fff0df;color:var(--tea);font-weight:600}

/* 选中元素后浮出的工具条：稿定那种「选中就能做最常用的那几件事」 */
.cv-seltool{position:absolute;z-index:7;display:flex;gap:2px;align-items:center;
  background:rgba(255,255,255,.98);backdrop-filter:blur(10px);padding:3px;border-radius:9px;
  border:1px solid var(--line-2);box-shadow:0 6px 20px rgba(74,45,20,.18);transform:translateX(-50%)}
.cv-seltool-btn{border:0;background:none;border-radius:6px;padding:4px 7px;font-size:11.3px;
  color:var(--txt-2);white-space:nowrap;line-height:1.5}
.cv-seltool-btn:hover{background:#fff3e6;color:var(--tea)}
.cv-seltool-btn.danger:hover{background:var(--bad-bg);color:var(--bad)}

/* 底部 AI 输入条：常驻，不弹窗 */
.cv-prompt{position:absolute;left:50%;transform:translateX(-50%);bottom:16px;z-index:6;
  width:min(760px,calc(100% - 100px));background:rgba(255,255,255,.98);
  border:1px solid var(--line-2);border-radius:13px;box-shadow:0 8px 28px rgba(74,45,20,.17);
  padding:9px 10px 9px 12px;display:flex;flex-direction:column;gap:7px}
.cv-prompt-row{display:flex;gap:7px;align-items:center}
.cv-prompt-opts{display:flex;gap:6px;align-items:center;flex-wrap:wrap;font-size:11.5px;color:var(--txt-2)}
.cv-prompt-opts select{width:auto;min-width:0;padding:3px 6px;font-size:11.5px;border-radius:6px}
.cv-prompt textarea{flex:1;min-height:38px;max-height:120px;border:1px solid var(--line);border-radius:9px;
  padding:7px 9px;font-size:12.5px;line-height:1.5;resize:none;background:#fffdf9}
.cv-prompt textarea:focus{outline:0;border-color:var(--tea-2);background:#fff;
  box-shadow:0 0 0 3px rgba(249,115,22,.12)}
.cv-prompt-hint{font-size:10.8px;color:var(--txt-3);display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.cv-prompt-hint .k{font-family:var(--mono);font-size:10px;border:1px solid var(--line-2);
  border-radius:4px;padding:0 4px;color:var(--txt-2);background:#fff}
.cv-prompt .btn.primary{padding:7px 15px;font-size:12.5px}

/* 左下状态条 + 右下缩放 */
.cv-status{position:absolute;left:12px;bottom:16px;z-index:5;display:flex;gap:8px;align-items:center;
  background:rgba(255,255,255,.94);backdrop-filter:blur(8px);padding:4px 9px;border-radius:7px;
  border:1px solid var(--line);font-size:11px;color:var(--txt-2);box-shadow:var(--sh);pointer-events:none}
.cv-zoombar{position:absolute;right:12px;bottom:16px;z-index:5;display:flex;gap:3px;
  background:rgba(255,255,255,.96);backdrop-filter:blur(10px);padding:4px;border-radius:9px;
  border:1px solid var(--line);box-shadow:var(--sh)}
.cv-zoombar button{width:28px;height:28px;border:0;background:none;border-radius:6px;font-size:13px;
  color:var(--txt-2);display:grid;place-items:center}
.cv-zoombar button:hover{background:#fdf1e4;color:var(--tea)}
.cv-zoombar button.wide{width:auto;padding:0 8px;font-size:11px;font-family:var(--mono)}

/* 空画布：不写说明书，给三张能一键照做的起点卡片 */
.cv-empty{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none;z-index:3}
.cv-empty-in{pointer-events:auto;text-align:center;max-width:560px;padding:0 20px}
.cv-empty-in h3{margin:0 0 6px;font-size:17px;font-weight:650}
.cv-empty-in p{margin:0 0 16px;font-size:12.5px;color:var(--txt-3);line-height:1.7}
.cv-starts{display:grid;grid-template-columns:repeat(3,1fr);gap:9px}
.cv-start{background:#fff;border:1px solid var(--line);border-radius:11px;padding:12px 11px;
  text-align:left;cursor:pointer;transition:all .13s;box-shadow:var(--sh)}
.cv-start:hover{border-color:var(--tea-2);transform:translateY(-1px);box-shadow:0 6px 18px rgba(249,115,22,.18)}
.cv-start .si{font-size:19px;color:var(--tea-2);line-height:1}
.cv-start b{display:block;font-size:12.5px;margin:6px 0 3px}
.cv-start span{font-size:11px;color:var(--txt-3);line-height:1.5;display:block}

/* 素材 / 生成记录 */
.ast-grid{display:grid;grid-template-columns:1fr 1fr;gap:7px}
.ast-item{position:relative;border:1px solid var(--line);border-radius:8px;overflow:hidden;
  background:repeating-conic-gradient(#f6ece1 0% 25%,#fff 0% 50%) 50%/13px 13px;cursor:pointer;
  transition:border-color .12s,box-shadow .12s}
.ast-item:hover{border-color:var(--tea-2);box-shadow:0 0 0 3px rgba(249,115,22,.12)}
.ast-item img{width:100%;height:78px;object-fit:cover;display:block}
.ast-item .an{font-size:10px;color:var(--txt-3);padding:3px 5px;background:#fff;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ast-item .badge{position:absolute;left:4px;top:4px;font-size:9px;padding:1px 5px;border-radius:20px;
  background:rgba(74,45,20,.70);color:#fff}
.ast-item .badge.local{background:rgba(150,96,10,.86)}
.ast-item .acts{position:absolute;right:3px;top:3px;display:none;gap:3px}
.ast-item:hover .acts{display:flex}
.ast-item .acts button{width:20px;height:20px;border:0;border-radius:5px;background:rgba(255,255,255,.94);
  color:var(--txt-2);font-size:11px;display:grid;place-items:center;box-shadow:0 1px 3px rgba(0,0,0,.16)}
.ast-item .acts button:hover{color:var(--tea)}

/* 右侧属性里的紧凑行 */
.cv-row{display:flex;gap:6px;align-items:center;margin-bottom:7px}
.cv-row>label{width:50px;flex:0 0 50px;font-size:11.5px;color:var(--txt-2)}
.cv-row>input,.cv-row>select,.cv-row>.flex1{flex:1;min-width:0}
.cv-row input[type=number],.cv-row input[type=text],.cv-row select{padding:4px 6px;font-size:12px;
  border-radius:6px;min-width:0}
.cv-align-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:4px;margin-bottom:8px}
.cv-align-grid button{padding:6px 0;font-size:12px;border:1px solid var(--line-2);border-radius:6px;
  background:#fff;color:var(--txt-2)}
.cv-align-grid button:hover{border-color:var(--tea-2);color:var(--tea);background:#fff3e6}

/* 图层行（原样式保留，补一下拖拽与可见性） */
.layer{display:flex;gap:6px;align-items:center;padding:5px 6px;border-radius:6px;font-size:12.3px;
  cursor:pointer;transition:background .11s}
.layer:hover{background:#fdf1e4}
.layer.on{background:#ffe9d5;color:var(--tea);font-weight:550}
.layer .li{width:15px;text-align:center;font-size:12px;opacity:.7;flex:0 0 15px}
.layer .ln{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.layer .xbtn{border:0;background:none;color:var(--txt-3);border-radius:4px;line-height:1}
.layer .xbtn:hover{background:#f4e3d2;color:var(--txt)}
.swatch{width:26px;height:26px;border-radius:6px;border:1px solid var(--line-2);padding:0;
  cursor:pointer;overflow:hidden}
.swatch input{width:200%;height:200%;margin:-25%;border:0;padding:0;cursor:pointer;background:none}

/* 颜色选择器：不依赖浏览器原生的 type=color 外观
   （各引擎渲染差异大，有的直接留白），
   自己画一个色块 + 一个隐形的原生取色器叠在上面。 */
.colorctl{position:relative;width:100%;height:30px;border:1px solid var(--line-2);
  border-radius:6px;background:var(--panel-2);overflow:hidden;cursor:pointer}
.colorctl:hover{border-color:var(--tea-2)}
.colorctl .fill{position:absolute;inset:2px;border-radius:4px;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.10)}
.colorctl .hex{position:absolute;right:7px;top:50%;transform:translateY(-50%);
  font-family:var(--mono);font-size:11px;color:var(--txt-2);
  background:rgba(255,255,255,.82);padding:0 4px;border-radius:3px}
.colorctl input[type=color]{position:absolute;inset:0;width:100%;height:100%;
  opacity:0;border:0;padding:0;cursor:pointer;appearance:none;-webkit-appearance:none}
.colorctl input[type=color]::-webkit-color-swatch-wrapper{padding:0}
.colorctl input[type=color]::-webkit-color-swatch{border:0}
.props-row{display:flex;gap:7px;align-items:center;margin-bottom:8px}
.props-row>label{width:56px;flex:0 0 56px;font-size:12px;color:var(--txt-2)}
.props-row>input,.props-row>select{flex:1}

/* ---------------------------------------------------------- 客户维护（CRM）
   版式参考简道云：指标 → 视图页签 → 筛选条 → 内容区。
   看板要能横向滚（七个阶段在 13 寸屏放不下），
   漏斗要能一眼看出「哪一格掉得最狠」，
   抽屉要能盖住内容但不遮住侧栏 —— 关掉就回到原来的筛选状态。
   ============================================================ */

/* 视图页签：不做成胶囊按钮，做成「文件页签」——
   更像表格工具，也更明确「这是同一份数据的四种看法」 */
.viewtabs{display:flex;gap:2px;border-bottom:1px solid var(--line-2);margin:2px 0 12px}
.viewtab{background:none;border:0;border-bottom:2px solid transparent;padding:9px 15px;
  font-size:13.5px;color:var(--txt-2);font-weight:520;border-radius:6px 6px 0 0;
  transition:color .12s,background .12s,border-color .12s}
.viewtab:hover{background:#fdf1e4;color:var(--txt)}
.viewtab.on{color:var(--tea);border-bottom-color:var(--tea-2);background:linear-gradient(180deg,transparent,#fff1e2)}
.viewtab.on::after{content:""}

/* 筛选条 */
.crm-filter{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:10px 12px;box-shadow:var(--sh);margin-bottom:13px}
.crm-filter-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.crm-filter-row>select{margin:0}
.crm-q{flex:1 1 220px;min-width:180px}
.crm-sel{flex:0 0 132px;width:132px}
.crm-filter-row .btn{margin:0}

.crm-pane{min-height:120px}
.crm-listbar{display:flex;gap:9px;align-items:center;margin-bottom:9px;flex-wrap:wrap}
.crm-listbar>select{width:auto;min-width:150px}

/* ---- 漏斗 */
.funnel{display:flex;flex-direction:column;gap:6px}
.funnel-row{display:grid;grid-template-columns:250px 1fr 74px 250px;gap:14px;align-items:center;
  padding:11px 14px;background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  cursor:pointer;transition:border-color .13s,box-shadow .13s,transform .13s}
.funnel-row:hover{border-color:var(--tea-2);box-shadow:0 0 0 3px rgba(249,115,22,.08)}
.funnel-row.on{border-color:var(--tea-2);background:#fff2e4;
  box-shadow:0 0 0 3px rgba(249,115,22,.15)}
.funnel-row.zero{opacity:.62}
.fl-name{display:flex;gap:7px;align-items:center;min-width:0;flex-wrap:wrap}
.fl-name b{font-size:14px;font-weight:600}
.fl-name span{font-size:11.5px;color:var(--txt-3);flex:1 1 100%;padding-left:16px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fl-bar{height:9px;border-radius:20px;background:#f2e3d4;overflow:hidden}
.fl-bar>i{display:block;height:100%;border-radius:20px;transition:width .35s ease}
.fl-num{text-align:right;white-space:nowrap}
.fl-num .big{font-size:19px;font-weight:680;font-variant-numeric:tabular-nums}
.fl-meta{display:flex;gap:5px;align-items:center;flex-wrap:wrap;justify-content:flex-end}
.ok-txt{color:var(--ok)} .warn-txt{color:var(--warn)} .bad-txt{color:var(--bad)} .tea-txt{color:var(--tea)}
.st-dot{width:9px;height:9px;border-radius:50%;flex:0 0 9px;display:inline-block}
.crm-note .note-item b{font-size:12.5px;display:block;margin-bottom:2px}
.crm-note .note-item p{margin:0;line-height:1.55}

/* ---- 看板
   列宽取舍：**宁可横向滚，也不把标题截成「演示003 …」**。
   卡片上最要紧的就是「谁、什么时候该跟」，压到 158px 就只剩省略号。
   所以给 196px 下限、按剩余空间平分；放不下就横向滚（滚一条比读一串省略号强）。
   窄屏另有规则：整块改成竖排，见 820px 那一节。 */
.kanban{display:flex;gap:10px;overflow-x:auto;padding:2px 2px 14px;align-items:flex-start}
.kcol{flex:1 1 196px;min-width:196px;background:#f7efe5;border:1px solid var(--line);
  border-radius:var(--r);padding:9px;min-height:130px;transition:background .13s,border-color .13s}
.kcol.over{background:#ffe4cc;border-color:var(--tea-2);box-shadow:inset 0 0 0 2px rgba(249,115,22,.24)}
.kcol-h{display:flex;gap:7px;align-items:center;padding:2px 3px 0}
.kcol-h b{font-size:13px;font-weight:620;flex:1}
.kcount{font-size:11.5px;font-weight:600;color:var(--txt-2);background:#fff;
  border:1px solid var(--line-2);border-radius:20px;padding:0 7px;min-width:22px;text-align:center}
.kcol-hint{font-size:11px;color:var(--txt-3);padding:3px 3px 7px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kcards{display:flex;flex-direction:column;gap:7px}
.kempty{border:1px dashed var(--line-2);border-radius:var(--r-sm);padding:14px 8px;text-align:center}
.kempty>span{display:block;font-size:11.5px;color:var(--txt-3)}
.kempty p{margin:3px 0 0;font-size:10.8px;line-height:1.45}
/* 列底部的「还有 N 张 · 展开」：做成虚线小条，不抢卡片注意力，
   但整条可点 —— 一列几百张时它是唯一的出口 */
.kmore{width:100%;background:none;border:1px dashed var(--line-2);border-radius:var(--r-sm);
  padding:6px 8px;font-size:11.5px;color:var(--txt-2);cursor:pointer;transition:all .12s}
.kmore:hover{border-color:var(--tea-2);color:var(--tea);background:#fff2e4}
.kcard{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:9px 10px;box-shadow:0 1px 2px rgba(74,45,20,.06);cursor:pointer;
  display:flex;flex-direction:column;gap:5px;
  transition:box-shadow .13s,transform .13s,border-color .13s}
.kcard:hover{transform:translateY(-1px);box-shadow:var(--sh);border-color:var(--line-2)}
.kcard.dragging{opacity:.45;transform:rotate(1.4deg)}
.kc-top{display:flex;gap:6px;align-items:flex-start}
.kc-top b{flex:1;font-size:13px;font-weight:600;line-height:1.35;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kc-sub{font-size:11.2px;color:var(--txt-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kc-follow{font-size:11.3px;line-height:1.4}
.kc-follow.bad b{color:var(--bad)}
.kc-follow.warn b{color:var(--warn)}
.kc-foot{display:flex;gap:5px;align-items:center;flex-wrap:wrap;margin-top:1px}
.kc-tags{display:flex;gap:4px;flex-wrap:wrap}
.kc-tags>span{font-size:10.4px;color:var(--txt-2);background:#fdf1e4;border-radius:4px;padding:1px 5px;
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hdot{display:inline-flex;gap:4px;align-items:center;font-size:11px;font-weight:600;
  font-variant-numeric:tabular-nums}
.hdot>i{width:6px;height:6px;border-radius:50%;display:block;background:var(--txt-3)}
.hdot.ok{color:var(--ok)} .hdot.ok>i{background:var(--ok)}
.hdot.warn{color:var(--warn)} .hdot.warn>i{background:var(--warn)}
.hdot.bad{color:var(--bad)} .hdot.bad>i{background:var(--bad)}

/* ---- 列表 */
.crm-table tbody tr.clickable{cursor:pointer}

/* ---- 今日 */
.agenda-row{display:flex;gap:10px;align-items:center;padding:9px 0;
  border-bottom:1px solid var(--line);flex-wrap:wrap}
.agenda-row:last-child{border-bottom:0}
.ar-main{flex:1 1 300px;min-width:0;cursor:pointer}
.ar-title{display:flex;gap:7px;align-items:center;flex-wrap:wrap}
.ar-title b{font-size:13.2px}
.ar-act{display:flex;gap:6px;flex-wrap:wrap}

/* ---- 客户抽屉 */
.crm-mask{position:fixed;inset:0;background:rgba(74,45,20,.32);backdrop-filter:blur(2px);
  z-index:880;animation:fade .16s ease}
.crm-mask.out{opacity:0;transition:opacity .18s}
.crm-drawer{position:fixed;top:0;right:0;bottom:0;width:min(620px,94vw);background:var(--bg);
  box-shadow:-14px 0 44px rgba(74,45,20,.22);z-index:890;display:flex;flex-direction:column;
  transform:translateX(22px);opacity:0;transition:transform .19s cubic-bezier(.2,.9,.3,1),opacity .19s}
.crm-drawer.in{transform:none;opacity:1}
.dw-body{display:flex;flex-direction:column;height:100%;overflow:hidden}
.dw-head{display:flex;gap:10px;align-items:flex-start;padding:16px 18px 11px;
  background:var(--panel);border-bottom:1px solid var(--line)}
.dw-title{display:flex;gap:10px;align-items:flex-start;flex:1;min-width:0}
.dw-av{width:40px;height:40px;flex:0 0 40px;border-radius:11px;display:grid;place-items:center;
  background:var(--grad);color:#fff;font-size:17px;font-weight:600}
.dw-title h2{margin:0;font-size:17px;font-weight:650;line-height:1.3}
.dw-chips{display:flex;gap:5px;flex-wrap:wrap;margin-top:6px}
.dw-head>.xbtn{margin-top:2px}
.dw-actions{display:flex;gap:6px;align-items:center;flex-wrap:wrap;
  padding:10px 18px;background:var(--panel);border-bottom:1px solid var(--line)}
.dw-stage{display:flex;gap:6px;align-items:center}
.dw-stage>span{white-space:nowrap}
.dw-stage>select{width:auto;min-width:104px}
.dw-tabs{display:flex;gap:2px;padding:8px 14px 0;background:var(--panel);
  border-bottom:1px solid var(--line);overflow-x:auto}
.dw-tab-btn{background:none;border:0;border-bottom:2px solid transparent;padding:7px 12px;
  font-size:12.8px;color:var(--txt-2);font-weight:520;white-space:nowrap}
.dw-tab-btn:hover{color:var(--txt)}
.dw-tab-btn.on{color:var(--tea);border-bottom-color:var(--tea-2)}
.dw-tab{flex:1;overflow-y:auto;padding:15px 18px 40px}
.dw-tab>.hintbar:first-child{margin-top:0}

/* 时间线：真实沟通和系统动作要分得开 —— 系统记的「建档」是背景声 */
.tl{position:relative;padding-left:19px}
.tl::before{content:"";position:absolute;left:4.5px;top:5px;bottom:5px;width:1.5px;background:var(--line-2)}
.tl-item{position:relative;padding-bottom:15px}
.tl-dot{position:absolute;left:-19px;top:5px;width:10px;height:10px;border-radius:50%;
  border:2px solid var(--bg);box-shadow:0 0 0 1px var(--line-2)}
.tl-h{display:flex;gap:7px;align-items:center;flex-wrap:wrap}
.tl-h b{font-size:13px}
.tl-h .muted{font-size:11px}
.tl-body{font-size:12.6px;line-height:1.55}
.tl-item.sys .tl-h b{font-weight:500;color:var(--txt-2);font-size:12.2px}
.tl-item.sys .tl-body{color:var(--txt-3)}
.rem-row{display:flex;gap:10px;align-items:center;padding:9px 0;border-bottom:1px solid var(--line)}
.rem-row:last-child{border-bottom:0}
.rem-row.done{opacity:.55}
.rem-row b{font-size:12.8px;font-weight:550}

/* ---------------------------------------------------------- 弹窗 / 提示 */
.modal{position:fixed;inset:0;background:rgba(28,26,23,.42);backdrop-filter:blur(3px);
  display:flex;align-items:center;justify-content:center;z-index:900;padding:22px;
  animation:fade .16s ease}
@keyframes fade{from{opacity:0}to{opacity:1}}
.modal-box{background:var(--panel);border-radius:var(--r-lg);box-shadow:var(--sh-lg);
  width:100%;max-width:600px;max-height:86vh;max-height:86dvh;display:flex;flex-direction:column;
  animation:rise .19s cubic-bezier(.2,.9,.3,1)}
.modal-box.wide{max-width:900px}
@keyframes rise{from{transform:translateY(14px) scale(.98);opacity:0}to{transform:none;opacity:1}}
.modal-head{display:flex;align-items:center;gap:10px;padding:15px 19px;border-bottom:1px solid var(--line)}
.modal-head b{flex:1;font-size:15.5px}
.xbtn{background:none;border:0;font-size:15px;color:var(--txt-3);padding:4px 7px;border-radius:6px}
.xbtn:hover{background:#fdf1e4;color:var(--txt)}
.modal-body{padding:19px;overflow-y:auto;flex:1}
.modal-foot{display:flex;gap:9px;justify-content:flex-end;padding:13px 19px;
  border-top:1px solid var(--line);background:var(--panel-2);border-radius:0 0 var(--r-lg) var(--r-lg)}

.busy{position:fixed;inset:0;background:rgba(251,247,241,.90);backdrop-filter:blur(4px);
  display:flex;align-items:center;justify-content:center;z-index:950}
.busy-box{display:flex;flex-direction:column;align-items:center;gap:12px;text-align:center}
.busy-box b{font-size:15px}
.busy-box span{font-size:12.5px;color:var(--txt-3)}
.spin{width:34px;height:34px;border:3px solid var(--line-2);border-top-color:var(--tea-2);
  border-radius:50%;animation:sp .8s linear infinite}
@keyframes sp{to{transform:rotate(360deg)}}

.toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%);z-index:990;
  padding:11px 19px;border-radius:var(--r);background:var(--ink);color:#fdf1e4;font-size:13.2px;
  box-shadow:var(--sh-lg);max-width:76vw;display:flex;gap:9px;align-items:center;
  animation:up .2s ease}
@keyframes up{from{transform:translate(-50%,14px);opacity:0}to{transform:translate(-50%,0);opacity:1}}
.toast.ok{background:#157347}
.toast.bad{background:#b83232}
.toast.warn{background:#96600a}

/* 读不到工作区时的顶部提示条：能点，点开告诉用户去哪开权限 */
.ws-warn{position:fixed;top:0;left:0;right:0;z-index:995;
  display:flex;gap:10px;align-items:center;justify-content:center;flex-wrap:wrap;
  padding:9px 16px;background:#96600a;color:#fdf7ea;font-size:12.8px;
  cursor:pointer;box-shadow:var(--sh)}
.ws-warn b{font-weight:600}
.ws-warn span{text-decoration:underline;opacity:.92}

/* ---------------------------------------------------------- 响应式 */
@media(max-width:1000px){
  /* 中等屏：右栏收窄到 248，属性行还放得下「宽/高」两个输入框 */
  .cv-side{width:248px;flex:0 0 248px}
  .cv-prompt{width:calc(100% - 84px)}
  /* 漏斗的「转化/逾期/健康」那一栏在中等屏会挤爆，挪到下一行 */
  .funnel-row{grid-template-columns:200px 1fr 66px;row-gap:7px}
  .fl-meta{grid-column:1/-1;justify-content:flex-start;padding-left:16px}
}
/* 窄屏（手机 / 竖屏平板）。
   这一段只在 ≤820px 生效，桌面端一个像素都不受影响。
   目标是「能查能录」：看得清、点得中、表格不竖排。 */
@media(max-width:820px){
  :root{--side-w:262px}
  .side{position:fixed;left:0;top:0;bottom:0;z-index:800;transform:translateX(-100%);
    transition:transform .22s ease;box-shadow:var(--sh-lg);
    padding-bottom:env(safe-area-inset-bottom)}
  body.navopen .side{transform:none}
  body.navopen::after{content:"";position:fixed;inset:0;background:rgba(28,26,23,.4);z-index:790}
  .menubtn{display:grid;place-items:center;width:40px;height:40px;flex:0 0 40px;
    border-radius:9px;font-size:18px}
  .menubtn:active{background:#fdf1e4}
  .view{padding:16px 15px calc(60px + env(safe-area-inset-bottom))}
  /* 窄屏：右栏改成底部抽屉（点「属性」才出来），画布占满；
     AI 输入条贴着安全区，不压住状态条。 */
  .cv-side{position:absolute;right:0;top:0;bottom:0;z-index:30;width:280px;flex-basis:auto;
    box-shadow:-8px 0 26px rgba(74,45,20,.18);transform:translateX(102%);transition:transform .2s}
  body.cvside .cv-side{transform:none}
  .cv-zoombar{right:12px;bottom:calc(84px + env(safe-area-inset-bottom))}
  .cv-zoombar button{width:38px;height:38px;font-size:16px}
  .cv-tool{width:42px;height:42px}
  .cv-prompt{width:calc(100% - 74px);bottom:calc(12px + env(safe-area-inset-bottom))}
  .cv-status{display:none}
  .cv-topbar{max-width:calc(100% - 24px)}
  .toast{bottom:calc(26px + env(safe-area-inset-bottom))}

  /* ---- 顶栏：第一行「菜单 + 标题」，第二行整行放操作按钮。
         按钮原来挤在标题右边会被截掉半个 —— 看得见点不着比看不见更糟。 */
  .top{padding:10px 12px 0;gap:8px;flex-wrap:wrap;row-gap:0;align-items:flex-start}
  /* flex-basis 必须是 0：auto 会按标题内容撑宽，把菜单挤到上一行去 */
  .top-title{flex:1 1 0;min-width:0;padding-top:2px}
  .top-title h1{font-size:16.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .top-title p{font-size:11.5px}
  .top-actions{flex:1 1 100%;justify-content:flex-start;flex-wrap:nowrap;
    overflow-x:auto;overflow-y:hidden;padding:6px 0 10px;
    -webkit-overflow-scrolling:touch;scrollbar-width:none}
  .top-actions::-webkit-scrollbar{display:none}
  .top-actions>.btn{flex:0 0 auto;min-height:36px}
  /* 没按钮的页面别留一条空行（空容器也有 padding，会白占 16px 高度） */
  .top-actions:empty{display:none}

  /* ---- 点得中：触控目标不小于 36–40px（手指点不中等于没这功能） */
  .btn{min-height:38px;padding:9px 13px}
  .btn.sm{min-height:34px;padding:7px 11px}
  .linkbtn{padding:10px 6px;font-size:12px}
  .xbtn{width:38px;height:38px;font-size:17px;display:grid;place-items:center}
  .nav-item{padding:11px 10px}
  input[type=checkbox]{width:20px;height:20px}

  /* ---- iOS 聚焦不放大：输入框字号必须 ≥16px（低于 16px 会自动推近页面） */
  input[type=text],input[type=number],input[type=password],select,textarea{font-size:16px}
  label.field>span{font-size:12.5px}

  /* ---- 表格改卡片：表头隐藏，每行一张卡，每格「标签 + 值」。
         标签由 app.js 的 labelTableCells() 写进 data-label。 */
  .tbwrap{border:0;background:transparent;overflow:visible}
  table.tb{display:block;font-size:13.5px}
  table.tb thead{display:none}
  table.tb tbody{display:block}
  table.tb tr{display:block;background:var(--panel);border:1px solid var(--line);
    border-radius:var(--r);padding:10px 12px;margin-bottom:10px;box-shadow:var(--sh)}
  table.tb tr:hover td{background:transparent}
  table.tb td{display:flex;align-items:center;justify-content:space-between;gap:12px;
    padding:5px 0;border:0;text-align:right;word-break:break-word;min-height:26px}
  table.tb td[data-label]:not([data-label=""])::before{
    content:attr(data-label);color:var(--txt-3);font-size:12px;font-weight:500;
    flex:0 0 auto;text-align:left;align-self:center}
  table.tb td:empty{display:none}
  /* 数字格照样「标签在左、数字在右」—— 别为了右对齐把标签也推到右边，
     否则一行读起来像「权限数 23」粘在一起 */
  table.tb td.num{font-variant-numeric:tabular-nums}
  /* 没有表头的列（操作按钮那种）：靠右，别孤零零吊在左边 */
  table.tb td:not([data-label]){justify-content:flex-end}
  /* 没有 thead 的键值表（客户档案、合规清单这类）：
     标签在上、值在下，比两栏对齐更好读 */
  table.tb.tbl-kv tr{display:block}
  table.tb.tbl-kv td{display:block;text-align:left;padding:2px 0;min-height:0}
  table.tb.tbl-kv td:first-child{color:var(--txt-3);font-size:12px;padding-top:6px}
  /* 卡里放表单控件时别拉满，右边留个手指的落点 */
  table.tb td>input:not([type=checkbox]),table.tb td>select,table.tb td>textarea{
    flex:0 1 auto;max-width:64%;min-width:0}
  /* 卡里最后那个操作按钮独占一行，好点 */
  table.tb td>.btn:only-child{margin-left:auto}

  /* ---- 客户维护：窄屏从「横向看板」改成「一列一列往下堆」。
         看板横向滚在手机上没法拖（拖动会变成滚动），
         所以窄屏干脆按阶段竖排，拖拽保留但用「阶段下拉」更稳。 */
  .viewtab{padding:9px 12px;font-size:13px;flex:1 1 auto;text-align:center;min-height:36px}
  .crm-filter{padding:9px}
  .crm-q{flex:1 1 100%}
  .crm-sel{flex:1 1 calc(50% - 4px);width:auto;min-width:0}
  .crm-filter-row .btn{flex:1 1 auto;min-height:34px}
  /* 漏斗在窄屏改为「名称 / 数字 / 条 / 备注」四行。
     顺序靠 order 明确指定 —— 只写 grid-column 会让不带 order 的
     .fl-bar 跑到最后（它就是被这个坑排到了数字下面）。 */
  .funnel-row{grid-template-columns:1fr 62px;row-gap:6px}
  .fl-name{grid-column:1;order:1}
  .fl-num{grid-column:2;order:1;align-self:start}
  .fl-bar{grid-column:1/-1;order:2}
  .fl-meta{grid-column:1/-1;order:3;justify-content:flex-start;padding-left:0}
  .kanban{flex-direction:column;overflow-x:visible;gap:9px}
  .kcol{flex:1 1 auto;width:100%;min-width:0}
  .kcards{flex-direction:row;flex-wrap:wrap}
  .kcard{flex:1 1 100%}
  /* 抽屉铺满：手机上一半宽度的抽屉等于没法用 */
  .crm-drawer{width:100vw;box-shadow:none}
  .dw-head{padding:14px 14px 10px}
  .dw-actions{padding:9px 14px}
  .dw-actions>.btn{flex:1 1 auto;justify-content:center}
  .dw-tab{padding:14px 14px 90px}
}

/* ---------------------------------------------------------- 登录页 */
.loginpage{
  position:fixed;inset:0;z-index:800;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(160deg,#1a0d04,#2a1608 45%,#3a2210);
  padding:22px;overflow-y:auto;
}
.loginpage::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(520px 320px at 18% 12%,rgba(249,115,22,.22),transparent 65%),
    radial-gradient(520px 340px at 84% 82%,rgba(194,65,12,.20),transparent 65%);
}
.loginbox{
  position:relative;width:100%;max-width:392px;
  background:var(--panel);border-radius:var(--r-lg);
  padding:26px;box-shadow:0 24px 70px rgba(30,12,4,.45);
  animation:rise .26s cubic-bezier(.2,.9,.3,1);
}
.loginbrand{display:flex;flex-direction:column;align-items:center;gap:9px;margin-bottom:16px}
/* 白底方图：给它一个圆角 + 极轻的边，白底白卡时才分得出边界 */
.loginbrand img{width:96px;height:96px;object-fit:contain;display:block;
  border-radius:20px;background:#fff;
  box-shadow:0 4px 16px rgba(74,45,20,.11), inset 0 0 0 1px rgba(74,45,20,.07)}
.loginbrand b{font-size:15.5px;letter-spacing:.02em}
.loginbrand span{font-size:11.5px;color:var(--txt-3)}
.loginbox .btn.lg{width:100%}
/* 侧栏底部加一条账号信息 */
.whoami{
  display:flex;align-items:center;gap:7px;padding:6px 9px;border-radius:var(--r-sm);
  background:#2b1a0d;background:rgba(255,255,255,.05);margin-bottom:8px;
  font-size:11.5px;color:#e0c9b2;cursor:pointer;
}
.whoami:hover{background:rgba(255,255,255,.09)}
.whoami .av{
  width:20px;height:20px;flex:0 0 20px;border-radius:50%;
  background:var(--grad);color:#fff;font-size:10.5px;font-weight:700;
  display:grid;place-items:center;
}
.whoami .nm{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.whoami .rl{font-size:10px;opacity:.62}

/* ============================================================
   节点编排 · 画布的第二模式
   ------------------------------------------------------------
   左：节点库 / 中：节点图 / 右：节点参数。
   跟画布共用同一套边距与圆角，切模式时不该像换了软件。

   为什么单独放文件末尾：这块是后加的，文件上半部分常被改动，
   写在中间容易被下一次整体重写冲掉（踩过一次：样式整段消失，
   三栏铺成了上下堆叠）。
   ============================================================ */
.flow-wrap{display:flex;height:100%;overflow:hidden;background:#f3e8db}
.flow-lib{width:186px;flex:0 0 186px;background:var(--panel);border-right:1px solid var(--line);
  overflow-y:auto;padding:11px 9px 22px}
.flow-lib-h{display:flex;align-items:center;gap:6px;padding:3px 4px 7px}
.flow-lib-h b{font-size:12px;font-weight:620;color:var(--txt-2);letter-spacing:.03em}
.flow-lib-g{font-size:10.5px;color:var(--txt-3);padding:7px 5px 3px;letter-spacing:.06em}
.flow-lib-item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 8px;border:0;
  background:none;border-radius:7px;text-align:left;transition:background .11s;cursor:pointer}
.flow-lib-item:hover{background:#fdf1e4}
.flow-lib-item .fi{width:19px;text-align:center;font-size:13px;color:var(--tea);flex:0 0 19px}
.flow-lib-item .fn{font-size:12.5px;color:var(--txt)}
.flow-tpl{display:flex;flex-direction:column;gap:2px;width:100%;padding:8px 9px;
  border:1px solid var(--line);border-radius:8px;background:none;text-align:left;
  margin-bottom:6px;transition:all .12s;cursor:pointer}
.flow-tpl:hover{border-color:var(--tea-2);background:#fff3e6}
.flow-tpl b{font-size:12px;font-weight:560;line-height:1.35}
.flow-stage{flex:1;position:relative;overflow:hidden;min-width:0;cursor:default}
#flowSvg{position:absolute;inset:0;width:100%;height:100%;display:block}
.fnode{cursor:grab}
.fnode:active{cursor:grabbing}
.fnode text{user-select:none;pointer-events:none}
.fnode circle{cursor:crosshair}
.flow-side{width:254px;flex:0 0 254px;background:var(--panel);border-left:1px solid var(--line);
  overflow-y:auto;padding:11px}
.flow-side .card{box-shadow:none;padding:12px}
.flow-thumb{display:flex;flex-direction:column;gap:6px;padding:8px 0;
  border-bottom:1px solid var(--line)}
.flow-thumb:last-child{border-bottom:0}
.flow-thumb img{width:100%;max-height:150px;object-fit:contain;border-radius:7px;
  background:repeating-conic-gradient(#f5ebe0 0% 25%, #fff 0% 50%) 50%/14px 14px;
  border:1px solid var(--line)}

/* 窄屏：编排三栏竖排，节点图给固定高度 */
@media(max-width:820px){
  .flow-wrap{flex-direction:column;overflow-y:auto}
  .flow-lib{width:100%;flex:0 0 auto;border-right:0;border-bottom:1px solid var(--line);
    max-height:190px;padding:9px}
  .flow-lib-g{display:inline-block;padding:4px 6px}
  .flow-lib-item{display:inline-flex;width:auto;margin:2px 3px 2px 0;padding:6px 9px;
    border:1px solid var(--line);border-radius:20px;background:#fff}
  .flow-tpl{margin-bottom:5px}
  .flow-stage{flex:0 0 auto;height:300px;order:2}
  .flow-side{width:100%;flex:0 0 auto;border-left:0;border-top:1px solid var(--line);order:3}
}

/* ============================================================
   包装成本引擎（工作台式版面）
   ============================================================
   三栏：盒型库 / 图纸 / 参数与报价。
   为什么不做成一列长表单：
     接单时的真实顺序是「先定结构 → 再看长什么样 → 最后谈价」，
     一列长表单把这三件事压成一条竖线，改一个尺寸要滚回去找。
   三栏之后，左边选、中间看、右边改，互不打断。
   窄屏（≤1100px）退化成单列：盒型库折叠成一条横滑，图纸在上、参数在下。
   ============================================================ */
.pk-wrap{display:flex;height:100%;overflow:hidden;background:var(--bg)}
.pk-wrap .g2,.pk-wrap .pk-g2{display:grid;gap:10px;grid-template-columns:1fr 1fr}

/* ---- 左：盒型库 */
.pk-lib{width:272px;flex:0 0 272px;background:var(--panel);border-right:1px solid var(--line);
  display:flex;flex-direction:column;min-height:0}
.pk-lib-h{display:flex;align-items:center;gap:8px;padding:13px 14px 8px}
.pk-lib-h b{font-size:13.5px;flex:1}
.pk-count{font-size:11px;color:var(--txt-3)}
.pk-search{width:calc(100% - 28px);margin:0 14px 8px;padding:7px 10px;font-size:12.5px;
  border:1px solid var(--line-2);border-radius:8px;background:var(--panel-2)}
.pk-search:focus{outline:0;border-color:var(--tea-2);background:#fff;
  box-shadow:0 0 0 3px rgba(249,115,22,.12)}
.pk-lib-body{flex:1;overflow-y:auto;padding:0 10px 16px}
.pk-cat{margin:12px 4px 6px;display:flex;flex-direction:column;gap:1px}
.pk-cat b{font-size:11px;font-weight:650;color:var(--txt-2);letter-spacing:.06em}
.pk-cat span{font-size:10.5px;color:var(--txt-3)}
.pk-boxcard{display:block;width:100%;text-align:left;background:var(--panel);
  border:1px solid var(--line);border-radius:var(--r);padding:10px 11px;margin-bottom:7px;
  transition:all .13s;cursor:pointer}
.pk-boxcard:hover{border-color:var(--tea-2);box-shadow:0 3px 12px rgba(249,115,22,.15)}
.pk-boxcard.on{border-color:var(--tea-2);background:#fff2e4;
  box-shadow:0 0 0 2px rgba(249,115,22,.18)}
.pk-boxcard-h{display:flex;align-items:center;gap:6px;margin-bottom:3px}
.pk-boxcard-h b{font-size:12.8px;flex:1;line-height:1.35}
.pk-code{font-family:var(--mono);font-size:9.5px;color:var(--txt-3);
  border:1px solid var(--line-2);border-radius:4px;padding:0 4px;flex:0 0 auto}
.pk-boxcard p{margin:0 0 6px;font-size:11.4px;line-height:1.5;color:var(--txt-2)}
.pk-feats{display:flex;flex-wrap:wrap;gap:4px}
.pk-feats .chip{font-size:10px;padding:1px 6px}

/* ---- 中：图纸 */
.pk-stage{flex:1;display:flex;flex-direction:column;min-width:0;min-height:0}
.pk-toolbar{display:flex;align-items:center;gap:6px;padding:9px 14px;background:var(--panel);
  border-bottom:1px solid var(--line);flex:0 0 auto;flex-wrap:nowrap;overflow-x:auto;
  scrollbar-width:none}
.pk-toolbar::-webkit-scrollbar{display:none}
.pk-toolbar .btn{flex:0 0 auto}
.pk-tab{white-space:nowrap}
.pk-tabs{display:flex;gap:2px;background:#f5e9dc;border-radius:8px;padding:2px}
.pk-tab{border:0;background:none;padding:6px 13px;border-radius:6px;font-size:12.5px;
  color:var(--txt-2);font-weight:520;transition:all .12s}
.pk-tab:hover{color:var(--txt)}
.pk-tab.on{background:#fff;color:var(--tea);font-weight:650;
  box-shadow:0 1px 3px rgba(74,45,20,.11)}
.pk-flex{flex:1 1 0;min-width:0}
@media(max-width:1280px){.pk-price{min-width:0;right:10px;top:10px}
  .pk-price>span{padding:5px 9px;font-size:12px}}
.pk-canvas{flex:1;position:relative;overflow:hidden;background:
  linear-gradient(0deg,rgba(74,45,20,.07) 1px,transparent 1px) 0 0/22px 22px,
  linear-gradient(90deg,rgba(74,45,20,.07) 1px,transparent 1px) 0 0/22px 22px,
  #fdf8f1;
  cursor:grab}
.pk-canvas.grabbing{cursor:grabbing}
.pk-svgbox{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  padding:24px}
.pk-zoomable{transform-origin:center center;transition:transform .1s ease-out;
  max-width:100%;max-height:100%;display:flex;align-items:center;justify-content:center}
.pk-zoomable svg{max-width:100%;max-height:calc(100vh - 260px);height:auto;display:block;
  background:#fffdf8;border:1px solid var(--line);border-radius:10px;
  box-shadow:0 4px 20px rgba(74,45,20,.10)}
/* 浮在图纸右上角的价格牌：改尺寸时价格跟着眼前动 */
.pk-price{position:absolute;right:14px;top:14px;z-index:4;display:flex;flex-direction:column;
  gap:0;background:rgba(255,255,255,.97);backdrop-filter:blur(10px);
  border:1px solid var(--line);border-radius:10px;box-shadow:var(--sh);overflow:hidden;
  min-width:150px}
.pk-price>span{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  padding:6px 11px;font-size:13px;font-family:var(--mono);font-weight:650;color:var(--txt)}
.pk-price>span+span{border-top:1px solid var(--line)}
.pk-price i{font-style:normal;font-size:10px;color:var(--txt-3);font-weight:400;
  font-family:-apple-system,"PingFang SC",sans-serif}
.pk-price>span:first-child{background:linear-gradient(90deg,rgba(249,115,22,.12),rgba(234,88,12,.10))}
.pk-basis{flex:0 0 auto;padding:0 14px;background:var(--panel)}
.pk-basis[hidden]{display:none}
.pk-basis .hintbar{margin:8px 0 0;font-size:11.4px;padding:7px 10px}
.pk-status{flex:0 0 auto;padding:7px 14px;background:var(--panel);border-top:1px solid var(--line);
  font-size:11.5px;color:var(--txt-2);font-family:var(--mono);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ---- 右：参数与报价 */
.pk-side{width:392px;flex:0 0 392px;background:var(--panel);border-left:1px solid var(--line);
  display:flex;flex-direction:column;min-height:0}
.pk-side-body{flex:1;overflow-y:auto;padding:14px 15px 60px}
.pk-sec{margin-bottom:16px}
.pk-sec-h{display:flex;align-items:baseline;gap:8px;margin-bottom:9px;
  padding-bottom:6px;border-bottom:1px solid var(--line)}
.pk-sec-h b{font-size:12.8px;font-weight:650}
.pk-sec-h span{font-size:10.8px;color:var(--txt-3)}
.pk-side label.field{margin-bottom:9px}
.pk-side label.field>span{font-size:11.4px}
.pk-side input,.pk-side select{padding:7px 9px;font-size:12.6px}
.pk-actions{display:flex;gap:8px;margin:4px 0 16px}
.pk-actions .btn{flex:1;justify-content:center}
.pk-kpis{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin-bottom:14px}
.pk-kpis .kpi{padding:10px 11px}
.pk-kpis .kpi .val{font-size:19px}
.pk-kpis .kpi .lbl{font-size:10.6px}
.pk-kpis .kpi .hint{font-size:10.2px}
.pk-result .hintbar{margin:9px 0;font-size:11.6px;padding:8px 10px}
.pk-tier tr.on td{background:#fff0df}
.pk-note{margin-top:10px;padding:9px 11px;border-radius:var(--r-sm);
  background:var(--panel-2);border:1px dashed var(--line-2);
  font-size:11.4px;line-height:1.6;color:var(--txt-2)}
.pk-note strong{color:var(--txt)}
.pk-det{margin:12px 0;border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.pk-det>summary{padding:9px 12px;font-size:12.4px;font-weight:600;cursor:pointer;
  background:var(--panel-2);list-style:none;display:flex;align-items:center;gap:6px}
.pk-det>summary::before{content:"▸";font-size:10px;color:var(--txt-3);transition:transform .12s}
.pk-det[open]>summary::before{transform:rotate(90deg)}
.pk-det>summary:hover{background:#fdf2e6}
.pk-det .tbwrap{border:0;border-radius:0;max-height:320px;overflow:auto}
.pk-det table.tb td,.pk-det table.tb th{padding:6px 9px;font-size:11.8px}

/* ---- 窄屏：三栏变一列，但顺序仍是「结构 → 图 → 价」 */
@media(max-width:1180px){
  .pk-wrap{flex-direction:column;overflow-y:auto}
  .pk-lib{width:100%;flex:0 0 auto;border-right:0;border-bottom:1px solid var(--line);
    max-height:none}
  .pk-lib-body{display:flex;gap:8px;overflow-x:auto;overflow-y:hidden;padding:0 12px 10px}
  .pk-lib-body .pk-cat{display:none}
  .pk-boxcard{flex:0 0 240px;margin-bottom:0}
  .pk-stage{min-height:52vh;flex:1 1 auto}
  .pk-zoomable svg{max-height:46vh}
  .pk-side{width:100%;flex:0 0 auto;border-left:0;border-top:1px solid var(--line)}
  .pk-side-body{overflow:visible;padding-bottom:30px}
}

/* 编排面板里的参数行：label 让宽一点，长说明不要挤扁输入框 */
.flow-side .props-row{align-items:flex-start}
.flow-side .props-row>label{width:46px;flex:0 0 46px;padding-top:5px;line-height:1.3}
.flow-side .props-row>.flex1{min-width:0}
.flow-side .props-row textarea,.flow-side .props-row input,.flow-side .props-row select{width:100%}

/* 节点图上的浮层工具条：跟画布的缩放条同一套观感 */
/* 编排模式顶栏：跟画布一样做成一条浮起的白条。
   原来只给按钮加了白底、容器本身透明，于是「▶ 跑一遍」右边空出一片 ——
   原因是这一条用了 right:12px 撑满宽度，flex 又把按钮推到最右，
   中间那段其实什么都没有。改成「一条实心白条 + 主按钮收在右侧」，
   按钮本身换成品牌渐变，一眼知道那是主操作。 */
.flow-toolbar{position:absolute;left:12px;top:12px;right:12px;z-index:5;display:flex;
  gap:6px;align-items:center;flex-wrap:wrap;pointer-events:none}
.flow-toolbar>*{pointer-events:auto}
.flow-toolbar .btn{background:var(--panel);box-shadow:var(--sh);border-color:var(--line)}
.flow-toolbar #flowRunBtn{background:var(--grad);border-color:transparent;color:#fff;
  font-weight:600;box-shadow:0 2px 9px rgba(249,115,22,.30)}
.flow-toolbar #flowRunBtn:hover{filter:brightness(1.07);color:#fff}

/* ---------------------------------------------------------- 自带中文字体
   画布与导出的默认字体是 TTH Noto Sans SC（Noto Sans SC 子集，OFL 1.1）。
   为什么必须自带而不是用系统字体：
     · 苹方/宋体/黑体是 macOS/Windows 的**显示授权**，印在包装上属于商业使用，
       需要另外取得字库方授权 —— 「字体素材台账」里它们全被标成不可商用。
     · 同一个稿子在别的电脑上打开，系统字体缺失会静默回退成别的字形，
       排版就变了；自带字体保证「你看到的 = 印出来的」。
   体积：每个字重约 800KB（只收 GB2312 + ASCII + 中文标点），
   三个字重共约 2.4MB，本机加载无感。
   授权：见 fonts/OFL.txt —— 可商用、可交印、可随稿交付。 */
@font-face{font-family:"TTH Noto Sans SC";font-style:normal;font-weight:400;
  font-display:swap;src:url("/static/fonts/TTHNotoSansSC-400.woff2") format("woff2")}
@font-face{font-family:"TTH Noto Sans SC";font-style:normal;font-weight:700;
  font-display:swap;src:url("/static/fonts/TTHNotoSansSC-700.woff2") format("woff2")}
@font-face{font-family:"TTH Noto Sans SC";font-style:normal;font-weight:900;
  font-display:swap;src:url("/static/fonts/TTHNotoSansSC-900.woff2") format("woff2")}

/* ---------------------------------------------------------- 出稿预检
   导出弹窗里的那道闸。三段信息按「够不够印」的重要性排：
     结论（hintbar）→ 扫了什么（可折叠，不黑箱）→ 逐条问题（表格）
   字体单独一排 chip，因为它不在文案里，混进问题表会让人以为是一类东西。 */
.gate-box{display:flex;flex-direction:column;gap:2px}
.gate-box .hintbar{margin-bottom:6px}
.gate-detail{margin:2px 0 8px}
.gate-detail summary{cursor:pointer;font-size:11.8px;color:var(--txt-3);
  padding:3px 0;user-select:none;list-style:none}
.gate-detail summary::-webkit-details-marker{display:none}
.gate-detail summary::before{content:'▸ ';color:var(--txt-3)}
.gate-detail[open] summary::before{content:'▾ '}
.gate-detail summary:hover{color:var(--tea)}
.gate-detail .result{max-height:170px;overflow:auto;margin-top:4px}
.gate-box table.tb td:last-child{max-width:260px;line-height:1.55}
/* 预检闸门：页脚按钮在 block 时是禁用态，要看得出来「不是坏了，是不让导」 */
.modal-foot .btn[disabled]{opacity:.45;cursor:not-allowed;filter:grayscale(.5)}
.modal-foot .btn[disabled]:hover{filter:grayscale(.5)}

/* ---------------------------------------------------------- 台账里的稿子
   一张稿在台账里只需要三样信息：长什么样、叫什么、有没有「带风险导出」的记录。
   所以做成缩略图格子，不做成表格 —— 她是靠看图认稿的，不是靠读文件名。 */
.oc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:9px}
.oc-item{background:none;border:1px solid var(--line);border-radius:9px;padding:0;overflow:hidden;
  text-align:left;cursor:pointer;transition:border-color .12s,box-shadow .12s,transform .12s}
.oc-item:hover{border-color:var(--tea-2);box-shadow:0 4px 14px rgba(249,115,22,.18);transform:translateY(-1px)}
.oc-thumb{height:78px;background:repeating-conic-gradient(#f6ece1 0% 25%,#fff 0% 50%) 50%/12px 12px;
  display:grid;place-items:center;overflow:hidden}
.oc-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.oc-noimg{font-size:22px;color:var(--line-2)}
.oc-name{font-size:11.8px;font-weight:550;padding:5px 7px 2px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.oc-meta{display:flex;gap:7px;align-items:center;padding:0 7px 6px;font-size:10.5px;color:var(--txt-3)}
.oc-warn{color:var(--warn);font-weight:600}

/* 自己的模板：跟预置模板要能一眼分开。
   她存的那套是每天在跑的，预置的只是参考 —— 混在一起就又要靠读名字分辨。 */
.flow-tpl-row{display:flex;gap:4px;align-items:stretch}
.flow-tpl-row .flow-tpl{flex:1;margin-bottom:6px}
.flow-tpl.mine{border-color:#f6c9a5;background:#fff3e6}
.flow-tpl.mine:hover{background:#fff0df}
.flow-tpl.mine b{color:var(--tea)}
.flow-tpl-del{flex:0 0 26px;margin-bottom:6px;border:1px solid var(--line);border-radius:8px;
  background:none;color:var(--txt-3);font-size:11px;cursor:pointer;transition:all .12s}
.flow-tpl-del:hover{border-color:var(--bad);color:var(--bad);background:var(--bad-bg)}
