/* ==========================================================================
   MachModel 机加工工时精算 —— SaaS 界面样式
   浅色、两栏工作台：左=零件参数 / 右=特征清单（上）+ 计算结果（下）
   ========================================================================== */
:root{
  --bg:#f4f6fa;
  --panel:#ffffff;
  --panel-2:#f7f9fc;
  --ink:#101828;
  --ink-2:#475467;
  --ink-3:#697386;
  --line:#e4e7ec;
  --line-2:#f2f4f7;
  --brand:#102840;
  --brand-d:#0a1c2e;
  --brand-s:#eaf0f8;
  --accent:#1b64d9;
  --ok:#0a7a4b;
  --ok-s:#e9f8f0;
  --warn:#a15c07;
  --warn-s:#fff5e8;
  --danger:#b42318;
  --danger-s:#fef3f2;
  --r:12px;
  --r-s:8px;
  --sh:0 1px 2px rgba(16,24,40,.04), 0 1px 3px rgba(16,24,40,.06);
  --sh-hi:0 12px 32px rgba(16,40,70,.10);
  --mono:ui-monospace,SFMono-Regular,Consolas,"Liberation Mono",Menlo,monospace;
}

*{box-sizing:border-box}
html,body{margin:0;padding:0;height:100%}
html,body{overflow:hidden}
body{
  background:var(--bg);
  color:var(--ink);
  font:14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei",
       "PingFang SC","Hiragino Sans GB",sans-serif;
  -webkit-font-smoothing:antialiased;
  display:flex;flex-direction:column;
}
.topbar,.foot{flex:0 0 auto}
h1,h2,h3{margin:0;font-weight:650}
p{margin:0}
button{font:inherit;color:inherit}

/* ==================== 启动告警条 ==================== */
.bootwarn{
  display:block;margin:0;padding:12px 20px;
  background:var(--warn-s);border-bottom:1px solid #f0dcb4;
  color:#7a4d00;font-size:13px;line-height:1.6;
}
.bootwarn[hidden]{display:none!important}
.bootwarn b{color:#5c3a00}
.bootwarn code{font:12.5px/1 var(--mono);background:#fff;border:1px solid #f0dcb4;
  padding:2px 6px;border-radius:5px;color:#7a4d00}

/* ============================== 顶栏 ============================== */
.topbar{
  position:sticky;top:0;z-index:50;
  display:flex;align-items:center;gap:16px;
  height:60px;padding:0 20px;
  background:rgba(255,255,255,.92);
  backdrop-filter:saturate(180%) blur(12px);
  border-bottom:1px solid var(--line);
}
.brand{display:flex;align-items:center;gap:11px;flex:0 0 auto}
.logo{display:block;width:30px;height:30px;flex:0 0 auto;border-radius:8px}
.brand-txt{display:flex;flex-direction:column;line-height:1.2}
.brand-txt b{font-size:15px;letter-spacing:.3px;color:var(--brand)}
.brand-txt span{font-size:11.5px;color:var(--ink-3)}
.topbar-mid{flex:1 1 auto;display:flex;justify-content:center;min-width:0}
.topbar-right{display:flex;align-items:center;gap:8px;flex:0 0 auto}
.ver{font:11.5px/1 var(--mono);color:var(--ink-3);background:var(--panel-2);
  border:1px solid var(--line);padding:5px 8px;border-radius:99px}
.ver[hidden]{display:none!important}

/* 覆盖度胶囊（默认不显示；仅在需要时由 JS 填充） */
.cov{display:none;align-items:center;gap:7px;font-size:12px;color:var(--ink-2);
  background:var(--panel-2);border:1px solid var(--line);
  padding:5px 12px;border-radius:99px;white-space:nowrap}
.cov b{color:var(--ink);font-weight:600}
.cov .bar{width:78px;height:5px;border-radius:99px;background:#e6ecf4;overflow:hidden}
.cov .bar i{display:block;height:100%;border-radius:99px;background:var(--ok)}

/* ============================== 按钮 ============================== */
.btn{
  border:1px solid transparent;background:transparent;cursor:pointer;
  border-radius:var(--r-s);padding:8px 14px;font-size:13px;font-weight:500;
  transition:background .15s,border-color .15s,box-shadow .15s,transform .06s;
  white-space:nowrap;display:inline-flex;align-items:center;gap:5px;
}
.btn:active{transform:translateY(1px)}
a.btn{text-decoration:none}
.btn-sm{padding:6px 11px;font-size:12.5px}
.btn-ghost{color:var(--ink-2);border-color:var(--line);background:var(--panel)}
.btn-ghost:hover{background:var(--panel-2);color:var(--ink);border-color:#d3dde8}
.btn-line{color:var(--accent);border-color:#c7dbfa;background:var(--brand-s)}
.btn-line:hover{background:#dbe9fd}
.btn-primary{
  background:var(--brand);color:#fff;border-color:var(--brand);font-weight:600;
  box-shadow:0 2px 8px rgba(27,100,217,.18);
}
.btn-primary:hover{background:var(--brand-d)}
.btn-primary:disabled{background:#a8bcd8;border-color:#a8bcd8;box-shadow:none;cursor:default}
.btn-primary.btn-sm{
  background:var(--accent);border-color:var(--accent);
  box-shadow:0 2px 6px rgba(27,100,217,.22);
}
.btn-primary.btn-sm:hover{background:#1550b0}
/* 深蓝主按钮（「计算工时」，跟蓝色「添加特征」区分开） */
.btn-dark{background:var(--brand);color:#fff;border-color:var(--brand);font-weight:600;
  box-shadow:0 2px 6px rgba(16,40,64,.22)}
.btn-dark:hover{background:var(--brand-d);border-color:var(--brand-d)}
/* 「清空」的二次确认态 */
.btn-ghost.armed{color:#fff;background:var(--danger);border-color:var(--danger)}
.btn-ghost.armed:hover{background:#a71d1d;border-color:#a71d1d;color:#fff}
/* 「明细展开」当天次数用完：标灰提示，但仍可点（收起永远不受限制） */
.btn-ghost.quota-out{color:var(--ink-3);border-color:var(--line-2);background:var(--panel-2)}
.btn-ghost.quota-out:hover{background:#eef2f7;color:var(--ink-3);border-color:var(--line)}
.btn-icon{
  width:28px;height:28px;padding:0;display:inline-flex;align-items:center;
  justify-content:center;border-radius:7px;color:var(--ink-3);
  border:1px solid transparent;background:transparent;cursor:pointer;font-size:12px;
}
.btn-icon:hover{background:var(--panel-2);color:var(--ink);border-color:var(--line)}

/* ============================== 布局 ============================== */
.wrap{
  display:grid;
  /* 零件参数区为两列输入，左栏 268px；
     两列后纵向字段数减半，「基础工艺/配置行/毛坯直径」等不会被截断。 */
  grid-template-columns:268px minmax(0,1fr);
  gap:16px;padding:16px 20px 60px;
  max-width:1600px;margin:0 auto;width:100%;
  flex:1 1 auto;min-height:0;overflow:hidden;
  align-items:stretch;
}
.col{display:flex;flex-direction:column;gap:14px;min-width:0;min-height:0;overflow:hidden}
.col-left{overflow-y:auto;overscroll-behavior:contain;padding-right:2px}
/* 主区：特征清单（上）与计算结果（下）各占一半高度，位置固定不动，
   两者内容各自在自己的区域里滚动 */
.col-main{
  overflow:hidden;gap:14px;
  display:flex;flex-direction:column;
}

.card{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--sh);overflow:hidden;display:flex;flex-direction:column;
}
.card[hidden]{display:none!important}
/* 主区由「特征收叠 / 结果收叠」两个按钮控制高度。
   默认：特征区展开（固定 210px），结果区展开（占剩余）。
   任一区收叠时，另一区自动占满剩余空间；两区都收叠时只剩标题栏。 */
.col-main>.card{min-height:0}
.col-main>.card-feat{flex:0 0 210px;overflow:hidden}
.col-main>.card-result{flex:1 1 0;overflow:hidden}
.col-main.feat-collapsed .card-feat{flex:0 0 auto}
.col-main.result-collapsed .card-result{flex:0 0 auto}
.col-main.feat-collapsed .card-result{flex:1 1 0}
.col-main.result-collapsed .card-feat{flex:1 1 0}
.col-main.feat-collapsed.result-collapsed .card-feat,
.col-main.feat-collapsed.result-collapsed .card-result{flex:0 0 auto}
.card-feat.collapsed #featBody,
.card-result.collapsed .result-scroll{display:none}

/* 卡片头：白底 + 底边框 + 品牌图标（替代原来的深蓝标题条）
   标题与按钮一律靠左排（不两端对齐） */
.card-head{
  display:flex;align-items:center;justify-content:flex-start;gap:12px;
  padding:12px 16px;border-bottom:1px solid var(--line);
  background:var(--panel);flex:0 0 auto;
}
.card-head h2{
  display:flex;align-items:center;gap:7px;
  font-size:14px;font-weight:650;letter-spacing:.2px;color:var(--brand);
}
.card-head h2 svg{color:var(--accent);opacity:.9;flex:0 0 auto}
.card-head .cnt{
  font:11.5px/1 var(--mono);color:var(--ink-3);background:var(--panel-2);
  border:1px solid var(--line);padding:3px 8px;border-radius:99px;font-weight:500;
}
.head-actions{display:flex;align-items:center;gap:7px;flex:0 0 auto}

.card-input{display:flex;flex-direction:column;min-height:0;flex:0 0 auto}
#partBody{flex:1 1 auto;min-height:0;overflow:visible;padding:2px 0 4px}

/* 零件参数区为两列布局 ——
   单列时纵向字段太多（零件名称/材料/机床型号/机床类型/批量/起始状态/工况/
   转速限制/毛坯直径/余量/零件总长）。两列后高度减半。
   「计算方式」已于 2026-10-15 整项删除，.sub-grid[data-grp=mode] 暂无使用者，
   规则先留着（将来若恢复某个整行字段，直接套这个类即可）。 */
#partForm{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:9px 10px;align-items:start;
}
#partForm .sub-grid[data-grp="mode"]{grid-column:1 / -1}
#partForm .fld{min-width:0}
#partForm .fld input,#partForm .fld select{width:100%;min-width:0}
#partForm .fld .lbl-row{gap:4px;flex-wrap:wrap}
#partForm .fld .lbl-row label{white-space:nowrap}

#featBody{display:flex;flex-direction:column;min-height:0;flex:1 1 auto;overflow:hidden}

.muted{color:var(--ink-3)}

/* 顶部一整行＝蓝色总工时大卡(左)＋5个细分磁贴(右并排)，
   下方依次是完成提示 / 分隔线 / 逐特征明细列表。
   蓝色大卡与磁贴左右并排成一整行，最省纵向空间；
   顶部一行常驻置顶(sticky)，明细滚动时概览条不脱离视线。 */
.result-scroll{
  flex:1 1 auto;min-height:0;
  overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;
  padding:12px 14px 14px;
}
.result-top{
  position:sticky;top:0;z-index:2;
  display:flex;flex-direction:row;gap:12px;align-items:stretch;
  background:#fff;
  margin:0 0 4px;
}
.result-main-box{flex:0 1 auto;min-width:240px;display:flex;flex-direction:column}
#pendingWarn{margin:0 0 6px;min-width:0}
.result-divider{height:1px;background:var(--line-2);margin:0 0 6px;min-width:0}
#featResults{min-width:0}

/* 结果区占位 */
.card-placeholder{border-style:dashed;background:transparent;box-shadow:none;align-items:center;justify-content:center}
.ph-inner{padding:48px 24px;text-align:center}
.ph-icon{font-size:34px;opacity:.4;margin-bottom:10px}
.ph-t{font-size:14px;font-weight:650;margin-bottom:5px;color:var(--ink-2)}
.ph-inner .muted{font-size:12.5px}

/* 窄屏：单栏堆叠 + 恢复整页滚动（矮视口下锁死高度反而看不全内容）
   顺序按填写流程：零件参数 → 特征清单 → 计算结果 */
@media (max-width:1240px){
  html,body{height:auto;overflow:auto}
  body{display:block}
  .wrap{grid-template-columns:1fr;overflow:visible;flex:none;
    padding:14px 14px 80px;display:flex;flex-direction:column;gap:14px}
  .col{overflow:visible}
  .col-left,.col-main{overflow:visible}
  .col-main>.card{flex:0 0 auto}
  .card-input,.card-feat,.col-main>.card{display:block}
  .card-feat{overflow:visible}
  #partBody,#featBody{overflow:visible}
  #featBody{display:block}
  #featBody>.empty{display:flex}
  .table-scroll{max-height:none}
  .card-result{overflow:visible}
  .result-scroll{overflow:visible;min-height:0}
}
/* 窄屏：顶部一行改上下排（蓝卡在上、磁贴在下方换行），避免挤 */
@media (max-width:1000px){
  .result-top{position:static;flex-direction:column;gap:10px}
  .result-main-box{min-width:0}
  .tiles{grid-template-columns:repeat(auto-fit,minmax(78px,1fr))}
}

/* ============================== 表单 ============================== */
.grid{
  display:grid;gap:10px 11px;padding:13px 14px 15px;
  grid-template-columns:repeat(auto-fill,minmax(132px,1fr));
}
.sub-grid{
  grid-column:1 / -1;display:grid;gap:10px 11px;
  grid-template-columns:repeat(auto-fill,minmax(132px,1fr));
}
.fld{display:flex;flex-direction:column;gap:4px;min-width:0}
.fld label{font-size:11.5px;color:var(--ink-2);font-weight:500}
.fld .hint{font-size:10.5px;color:var(--ink-3)}
/* 🔴 2026-10-18 用户报「会员中心升级套餐里文字竖排，一行一个字」。
   根因就是这条 `input{width:100%}`：它给**所有** input 设了满宽，
   包括 radio/checkbox。本该 13px 的圆点被撑成 448px（整行宽度），
   把旁边的文字挤到只剩一条缝 → 中文只能一行一个字。
   正确做法是排除掉那几个「非文本输入」类型，它们有自己的默认尺寸。 */
input:not([type=checkbox]):not([type=radio]):not([type=range]),
select{
  width:100%;padding:6px 8px;font:inherit;font-size:12.5px;
  color:var(--ink);background:var(--panel);
  border:1px solid var(--line);border-radius:var(--r-s);
  outline:none;transition:border-color .14s,box-shadow .14s;
}
/* 这几个要显式还原：全局规则里的 padding/border/background 会画出一个
   巨大的方框来包住小圆点，即使 width 修好了也不对。 */
input[type=checkbox],input[type=radio]{
  width:auto;height:auto;padding:0;border:0;border-radius:0;
  background:none;box-shadow:none;accent-color:var(--accent);
  flex:0 0 auto;margin:0;cursor:pointer;appearance:auto;
}
input[type=file]{width:auto;padding:0;border:0;background:none;
  font:inherit;font-size:12px}
input[type=range]{width:100%;padding:0;border:0;background:none;
  accent-color:var(--accent)}
input[type=submit],input[type=button],input[type=reset]{
  width:auto;padding:6px 12px;font:inherit;cursor:pointer;
  background:var(--brand,#0a7);color:#fff;border:0;border-radius:var(--r-s)}
input[type=hidden]{display:none}
input:hover,select:hover{border-color:#cfdae6}
input:focus,select:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(27,100,217,.13)}
/* 所有输入/下拉的数值一律靠左显示 —— 同样要排除非文本输入 */
input:not([type=checkbox]):not([type=radio]),select{text-align:left}
input[type=number]{font-family:var(--mono);text-align:left}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;appearance:none;margin:0}
input[type=number]{-moz-appearance:textfield;appearance:textfield}
select{cursor:pointer;appearance:none;
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5L6 8l3.5-3.5' fill='none' stroke='%235b6b80' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 7px center;background-size:11px;
  padding-right:23px;}
input:disabled,select:disabled{background:var(--panel-2);color:var(--ink-3);cursor:not-allowed}
.interlock-locked{border:1px dashed var(--ink-3)!important;opacity:.7}
.inp-row{display:flex;align-items:center;gap:6px;min-width:0}
.inp-row>input,.inp-row>select{flex:1 1 auto;min-width:0}
.lbl-row{display:flex;align-items:center;gap:6px;min-width:0}
.lbl-row>label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:0 0 auto}
.lbl-row>.hint{white-space:nowrap;flex:0 0 auto}
.lbl-row>.cond-inline{flex:0 0 auto}

/* ============================== 特征表 ============================== */
/* ---- 机床信息查询（零件参数卡内，跟随所选 机床型号；v0.5.1 同步）---- */
.machine-info{margin-top:14px;padding:12px 14px;border:1px solid var(--line);border-radius:var(--r-s);
  background:var(--panel-2)}
.machine-info h3{font-size:13px;font-weight:650;color:var(--brand);margin:0 0 8px;
  display:flex;align-items:center;gap:6px}
.machine-info table{border-collapse:collapse;width:100%}
.machine-info td{padding:3px 6px;font-size:12px;line-height:1.5;vertical-align:top}
.machine-info td.k{color:var(--ink-3);white-space:nowrap;width:1%}
.machine-info td.v{color:var(--ink);font-weight:500}
.machine-info .mi-empty{color:var(--ink-3);font-size:12px}

.table-scroll{
  overflow:auto;padding:0;
  flex:1 1 auto;min-height:0;max-height:none;
  overscroll-behavior:contain;
}
.feat-table{border-collapse:separate;border-spacing:0;width:100%}
.feat-table th{
  position:sticky;top:0;z-index:2;
  font-size:11px;font-weight:600;color:var(--ink-2);text-align:left;
  padding:8px 5px;background:var(--panel-2);
  border-bottom:1px solid var(--line);white-space:nowrap;
}
.feat-table th.g-start{text-align:left;padding-left:14px}
/* 与 td.c-name 同宽，避免表头把「名称」列撑宽 */
.feat-table th.h-name{width:58px;min-width:58px;padding-left:10px}
.feat-table td{padding:4px 4px;border-bottom:1px solid var(--line-2);vertical-align:middle}
.feat-table tr:last-child td{border-bottom:0}
.feat-table tr:hover td{background:#fbfdff}
.feat-table td input,.feat-table td select{padding:4px 6px;font-size:12px}
/* 特征名列缩窄（名称一般是「特征1/端面A」这类短文本） */
.feat-table td.c-name{min-width:58px;padding-left:10px}
.feat-table td.c-name input{text-align:left;font-family:inherit;width:100%;padding-left:4px}
.feat-table td.num input{width:48px}
/* 列最小宽（2026-10-24）：窗口窄/缩放时列被压扁，固定宽的下拉会溢出
   压到隔壁格（「外圆周」文字与余量值框重叠就是这个）。
   给每列 min-width，压不下时由 .table-scroll 横向滚动兜底。 */
.feat-table td.c-type{min-width:102px}
.feat-table td.c-type select{width:92px}   /* 82px 装不下「光孔/内圆」 */
.feat-table td.c-st{min-width:106px}
.feat-table td.c-cond{min-width:106px}
.feat-table td.num{min-width:58px}
.feat-table td.c-th{min-width:106px}
.feat-table td.sl{min-width:68px}
.feat-table td.c-cf select{width:56px}
.feat-table td.sl input{width:56px}
.feat-table td.na{background:repeating-linear-gradient(135deg,#fafbfd 0 6px,#f4f6fa 6px 12px);opacity:.55}
.empty{padding:40px 24px;text-align:center;color:var(--ink-3);font-size:13px;
  display:flex;flex-direction:column;align-items:center;gap:6px}
.empty[hidden]{display:none!important}
.empty-icon{font-size:30px;opacity:.4}
.empty p{font-size:14px;font-weight:600;color:var(--ink-2)}
.empty .muted{font-size:12.5px}

/* ================= 弹窗 ================= */
.modal{position:fixed;inset:0;z-index:300;display:flex;align-items:center;justify-content:center}
.modal[hidden]{display:none!important}
.modal-bg{position:absolute;inset:0;background:rgba(20,30,50,.42);backdrop-filter:blur(2px)}
.modal-card{position:relative;background:#fff;border-radius:14px;
  box-shadow:0 24px 64px rgba(20,40,70,.26);min-width:380px;max-width:560px;
  width:90%;max-height:82vh;overflow:auto}
.modal-card .card-hd{padding:18px 22px 12px;border-bottom:1px solid var(--line-2);margin:0}
.modal-card .card-hd h3{margin:0;font-size:17px;color:var(--ink)}
.modal-body{padding:18px 22px 22px}
.card-hd.row{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
.card-ft{display:flex;align-items:center;justify-content:flex-start;gap:12px;
  padding:12px 18px;border-top:1px solid var(--line);background:var(--panel-2)}
.card-ft .row{display:flex;align-items:center;gap:8px}
.tabs{display:flex;gap:2px;padding:10px 22px 0;border-bottom:1px solid var(--line-2);flex:0 0 auto}
.tab-btn{padding:9px 18px;background:transparent;border:none;border-bottom:2px solid transparent;
  cursor:pointer;font-size:13px;font-weight:500;color:var(--ink-3);transition:all .15s}
.tab-btn:hover{color:var(--ink);background:var(--panel-2)}
.tab-btn.active{color:var(--accent);border-bottom-color:var(--accent);font-weight:600}
.tab-pane{padding-top:14px}
.tab-pane[hidden]{display:none!important}
#settingsModal .modal-body{flex:1;min-height:0;overflow:auto}

.feat-table td.idx{width:30px;text-align:center;color:var(--ink-3);
  font:11.5px/1 var(--mono);padding-left:10px}
/* 删除列钉在右侧：圆周槽等宽行把表格撑出横向滚动时，删除键始终可见（2026-11-02） */
.feat-table td.c-del{width:34px;text-align:center;position:sticky;right:0;z-index:1;
  background:#fff;box-shadow:-8px 0 8px -8px rgba(17,20,23,.22)}
.feat-table tr:hover td.c-del{background:#fbfdff}
.feat-table thead th:last-child{position:sticky;right:0;z-index:3;
  box-shadow:-8px 0 8px -8px rgba(17,20,23,.22)}
.feat-table tr.feat-detail.hidden{display:none}
.feat-detail-cell{background:var(--panel-2);border-top:1px dashed var(--line)}
.feat-detail-grid{display:flex;flex-wrap:wrap;gap:10px 30px;padding:10px 14px;align-items:center}
.feat-detail-title{font-size:12px;font-weight:600;color:var(--accent);margin:0 10px 0 0;flex:0 0 auto}
/* 标签在左、输入框在右（同一行）；item 间距放大，标签绝不贴到前一个框上 */
.feat-detail-item{display:flex;flex-direction:row;align-items:center;gap:8px;min-width:0}
.feat-detail-item label{font-size:11px;color:var(--ink-3);white-space:nowrap;flex:0 0 auto;margin-right:4px}
/* 🔴 全局「input:not(…){width:100%}」（本文件 ~278 行）特异性 (0,3,1)，
   比 .feat-detail-item input (0,1,1) 高 —— 定宽被顶掉，框被撑满整个槽位
   后溢出，正好压住下一项的标签（2026-10-29 用户实测「字被框挡住」）。
   这里必须 !important 才赢得回来；数值框收窄到 88px、下拉 140px。 */
.feat-detail-item input[type=number]{width:88px !important;flex:0 0 auto}
.feat-detail-item input[type=text]{width:110px !important;flex:0 0 auto}
.feat-detail-item select{width:140px !important;flex:0 0 auto}

/* ============================== 吸底状态栏 ============================== */
.statusbar{
  position:fixed;left:0;right:0;bottom:0;z-index:60;
  display:flex;align-items:center;gap:9px;
  height:36px;padding:0 20px;
  background:rgba(255,255,255,.94);
  backdrop-filter:saturate(180%) blur(12px);
  border-top:1px solid var(--line);
  font-size:12.5px;color:var(--ink-2);
}
.dot{width:8px;height:8px;border-radius:99px;background:var(--ink-3);flex:0 0 auto}
.dot.ok{background:var(--ok)}
.dot.err{background:var(--danger)}
.dot.warn{background:var(--warn)}
.dot.busy{background:var(--warn);animation:pulse 1s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}

/* ============================== 结果 ============================== */
/* 主结果卡：总工时大数字，一眼看到结论 */
.result-main{
  margin:0;padding:12px 14px;border-radius:var(--r-s);
  flex:1 1 auto;display:flex;flex-direction:column;justify-content:center;
  background:linear-gradient(135deg,#102840 0%,#1d3d5c 100%);
  color:#fff;box-shadow:0 4px 14px rgba(16,40,64,.18);
}
.result-main .rm-k{font-size:11.5px;color:#b9cbe0;letter-spacing:.3px}
/* 总工时区占一整行的左半，数字 36px，
   秒数与括号分钟数同行不换行(nowrap)，卡片宽度由内容撑开 */
.result-main .rm-v{font:700 36px/1.1 var(--mono);margin-top:4px;letter-spacing:-1px;white-space:nowrap}
.result-main .rm-v span{font:600 30px/1 inherit;margin-left:3px;color:#ffffff}
.result-main .rm-v .rm-min{margin-left:10px;font:500 14px/1 inherit;color:#b9cbe0}
.result-main .rm-sub{font-size:12px;color:#a8bdd6;margin-top:6px}

.tiles{
  display:grid;gap:6px;padding:0;align-content:stretch;
  flex:1 1 0;min-width:0;
  grid-template-columns:repeat(5,minmax(0,1fr));
}
.tile{display:flex;flex-direction:column;justify-content:center}
.tile{
  background:var(--panel-2);border:1px solid var(--line);
  border-radius:var(--r-s);padding:5px 7px;
}
/* 磁贴整体缩小一号（标题/数值/单位都收一点），把横向空间让给明细 */
.tile .k{font-size:10px;color:var(--ink-3);line-height:1.2}
.tile .v{font:600 13.5px/1.2 var(--mono);margin-top:1px;letter-spacing:-.3px}
.tile .u{font-size:10px;color:var(--ink-3);font-family:inherit;font-weight:400;margin-left:1px}
.tile.hi{background:var(--brand-s);border-color:#c7dbfa}
.tile.hi .v{color:var(--brand-d)}

.banner{
  margin:0;padding:5px 10px;border-radius:var(--r-s);
  font-size:12.5px;display:flex;gap:9px;align-items:flex-start;
}
.banner.warn{background:var(--warn-s);border:1px solid #f0dcb4;color:#7d5000}
.banner.ok{background:var(--ok-s);border:1px solid #c4e8d8;color:#0a6849}
.banner b{font-weight:650}

/* 特征结果卡 */
.fr{margin:7px 0 0;border:1px solid var(--line);border-radius:var(--r-s);overflow:hidden}
.fr:last-of-type{margin-bottom:14px}
.fr-hd{
  display:flex;align-items:center;justify-content:flex-start;gap:10px;
  padding:10px 13px;background:var(--panel-2);border-bottom:1px solid var(--line);
}
.fr-hd .t{display:flex;align-items:center;gap:9px;min-width:0;flex:0 0 auto}
.fr-hd .t b{font-size:13.5px}
.tag{font:11px/1 var(--mono);color:var(--ink-2);background:#fff;
  border:1px solid var(--line);padding:4px 7px;border-radius:99px}
/* 特征尺寸摘要（2026-11-04）：标题行里「大直径/深度」等，灰底小字紧跟类型标签 */
.fr-dims{font:11.5px/1.2 var(--mono);color:var(--ink-2);background:var(--panel-2);
  border:1px dashed var(--line);padding:4px 8px;border-radius:6px;white-space:nowrap}
.fr-hd .sum{font:600 14px/1 var(--mono);color:var(--brand-d);white-space:nowrap}
.fr-hd .sum small{font:11px/1 inherit;color:var(--ink-3);margin-left:3px}

.fr-summary{
  display:flex;align-items:center;gap:16px;
  padding:7px 13px;background:#fff;border-bottom:1px solid var(--line);
  font-size:11.5px;color:var(--ink-2);
}
.fr-summary span{font:600 12px/1 var(--mono);color:var(--ink)}

/* 工序行（.pr）—— 选择器行此前丢失，整块规则失效导致行与行挤在一起；
   2026-10-14 恢复选择器并把行内边距由 8px 提到 11px，行距更舒展。 */
.pr{
  display:grid;grid-template-columns:52px 1fr 80px 78px 22px;
  align-items:center;gap:8px;padding:11px 12px;
  border-bottom:1px solid var(--line-2);font-size:13px;
}
.pr:last-child{border-bottom:0}
.pr:hover{background:#fbfdff}
.pr.clickable{cursor:pointer}
.pr .code{font:11.5px/1 var(--mono);color:var(--accent);background:var(--brand-s);
  border-radius:5px;padding:4px 6px;text-align:left}
.pr .nm{color:var(--ink);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 工序行内的数据一律靠左显示 */
.pr .sec{font:600 13px/1 var(--mono);text-align:left;color:var(--ink)}
.pr .sec.none{color:var(--ink-3);font-weight:400;font-family:inherit;font-size:12px}
.pr .st{font-size:11.5px;text-align:left;border-radius:99px;padding:3px 8px}
.pr .st.ok{background:var(--ok-s);color:var(--ok)}
.pr .st.pending{background:var(--warn-s);color:var(--warn)}
.pr .caret{color:var(--ink-3);text-align:center;font-size:11px;transition:transform .15s}
.pr.open .caret{transform:rotate(90deg)}
.detail{
  grid-column:1/-1;margin:2px 0 8px;padding:11px 12px;
  background:var(--panel-2);border:1px dashed var(--line);border-radius:var(--r-s);
}
.det-grid{display:grid;gap:7px 18px;grid-template-columns:repeat(auto-fill,minmax(215px,1fr))}
/* 键与值都靠左（值紧跟键） */
.det-grid .kv{display:flex;justify-content:flex-start;align-items:baseline;gap:10px;
  border-bottom:1px dotted var(--line);padding-bottom:3px}
.det-grid .kv .k{font-size:12px;color:var(--ink-2);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.det-grid .kv .v{font:12px/1.5 var(--mono);color:var(--ink);text-align:left;word-break:break-all}
.det-sub{margin-top:10px}
.det-sub>.h{font-size:11.5px;color:var(--accent);font-weight:600;margin-bottom:5px;
  padding-bottom:3px;border-bottom:1px solid var(--line)}
.warns{margin-top:9px;display:flex;flex-direction:column;gap:5px}
.warns .w{font-size:12px;color:#7d5000;background:var(--warn-s);
  border:1px solid #f0dcb4;border-radius:6px;padding:6px 9px}

.foot{
  display:flex;justify-content:space-between;gap:16px;
  padding:0 20px 40px;font-size:11.5px;color:var(--ink-3);
}
.foot span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* 滚动条 */
::-webkit-scrollbar{height:10px;width:10px}
::-webkit-scrollbar-thumb{background:#cfd9e5;border-radius:99px;border:2px solid var(--bg)}
::-webkit-scrollbar-thumb:hover{background:#b6c4d4}
::-webkit-scrollbar-track{background:transparent}

@media (max-width:900px){
  .topbar-mid{display:none}
  .wrap{padding:14px 12px 30px}
}

/* ============================== 宽弹窗（配置） ============================== */
.modal-wide{position:fixed;inset:0;z-index:300;display:flex;align-items:center;justify-content:center}
.modal-wide[hidden]{display:none!important}
.modal-wide .modal-card{width:min(1480px,96vw);max-width:none;
  height:min(820px,92vh);max-height:92vh;overflow:hidden;display:flex;flex-direction:column}
.modal-3col .modal-body{flex:1;display:grid;grid-template-columns:210px 1fr 330px;
  gap:12px;padding:12px 14px;min-height:0;overflow:hidden}
.modal-3col .card-ft{padding:10px 14px;border-top:1px solid var(--line);background:var(--panel-2);flex:0 0 auto}
.modal-3col .card-hd{padding:14px 18px 10px;flex:0 0 auto}
.btn-mini{font-size:12.5px;padding:4px 9px;border-radius:7px;white-space:nowrap;
  border:1px solid var(--line);background:#fff;cursor:pointer;color:var(--ink-2)}
.btn-mini:hover{background:var(--panel-2);border-color:#c8d4e2}
.params-col{display:flex;flex-direction:column;min-height:0}
.params-col-sets,.params-col-table,.params-col-doc{background:var(--panel-2);
  border:1px solid var(--line);border-radius:8px;padding:10px}
.params-col-doc{overflow:auto}
.col-title{font-weight:600;font-size:13px;color:var(--ink-2);margin-bottom:8px}
.params-sets{list-style:none;margin:0;padding:0;font-size:13px;flex:1;overflow:auto}
.params-sets li{padding:6px 8px;border-radius:6px;cursor:pointer;display:flex;
  justify-content:space-between;align-items:center;gap:6px}
.params-sets li:hover{background:var(--panel-2)}
.params-sets li.active{background:var(--brand);color:#fff}
.params-table-scroll{flex:1;overflow:auto;min-height:0;border:1px solid var(--line);
  border-radius:6px;background:#fff}
.params-table{width:100%;border-collapse:collapse;font-size:12.5px}
.params-table th,.params-table td{padding:5px 8px;border-bottom:1px solid var(--line);
  text-align:left;vertical-align:top}
.params-table th{background:var(--panel-2);position:sticky;top:0;z-index:2;
  font-weight:600;color:var(--ink-2)}
.params-table td.path{font-family:var(--mono);color:var(--ink-2);white-space:nowrap}
.params-table td.val{font-family:var(--mono)}
.params-doc code{background:var(--panel-2);padding:1px 5px;border-radius:3px;font-size:12px}

/* ============ 输入参数（弹窗内） ============ */
.modal-card.modal-param{width:min(720px,94vw);max-width:720px;
  display:flex;flex-direction:column;max-height:88vh;overflow:hidden}
.modal-param .modal-body{flex:1;min-height:0;overflow:auto;padding:16px 22px}
.modal-param .card-ft{padding:10px 18px;border-top:1px solid var(--line);
  background:var(--panel-2);display:flex;align-items:center;justify-content:space-between;gap:12px}
/* ============ 通用「输入名称」弹窗 ============ */
.modal-card.modal-name{width:min(460px,92vw);max-width:460px;
  display:flex;flex-direction:column;overflow:hidden}
.modal-name .modal-body{padding:16px 22px 8px}
.modal-name .fld{display:flex;flex-direction:column;gap:6px}
.modal-name .fld span{font-size:12.5px;color:var(--ink-2)}
.modal-name .card-ft{padding:10px 18px;border-top:1px solid var(--line);
  background:var(--panel-2);display:flex;align-items:center;justify-content:space-between;gap:12px}
.ip-grid{display:grid;gap:12px 16px;grid-template-columns:repeat(auto-fill,minmax(215px,1fr))}
.fld.ip-empty input{background:var(--panel-2);border-style:dashed}
.fld.ip-set input,.fld.ip-set select{background:#fff;border-color:#bcd6f7}

.btn-feed{padding:3px 7px;font-size:11.5px;border-radius:6px;white-space:nowrap;
  border:1px solid var(--line);background:#fff;cursor:pointer;color:var(--ink-2)}
.btn-feed:hover{background:var(--brand-s);border-color:#c7dbfa;color:var(--accent)}
.btn-feed.on{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:600}

input.bound-bad,select.bound-bad{border-color:#e05252 !important;background:#fff6f6 !important;
  box-shadow:0 0 0 2px rgba(224,82,82,.12)}
input.bound-bad:focus{border-color:#c93030 !important}
.feetd{width:100px}

/* 配置集 */
#configTabs{margin:0 0 12px;padding:0;border-bottom:1px solid var(--line)}
.cfg-hit{display:inline-block;font:12px/1 var(--mono);padding:3px 8px;border-radius:99px;
  background:var(--ok-s);color:var(--ok);margin-left:8px}
.cfg-hit.miss{background:var(--warn-s);color:var(--warn)}
.cfg-src{font:11.5px/1 var(--mono);padding:2px 7px;border-radius:99px;white-space:nowrap}
.cfg-src.ok{background:var(--brand-s);color:var(--accent)}
.cfg-src.back{background:var(--warn-s);color:var(--warn)}
.cfg-note{background:var(--panel-2);border:1px solid var(--line);border-radius:8px;
  padding:10px 12px;margin:0 0 12px;font-size:12.5px;color:var(--ink-2);line-height:1.6}

/* 工序参数小胶囊 */
.pr-params{
  grid-column:1/-1;
  display:flex;flex-wrap:wrap;gap:6px;
  padding:8px 12px 10px 13px;margin:0;
  border-bottom:1px solid var(--line-2);background:var(--panel-2);
}
.pchip{
  display:inline-flex;align-items:baseline;gap:5px;
  font-size:11.5px;line-height:1.5;
  background:#fff;border:1px solid var(--line);border-radius:99px;
  padding:2px 9px;white-space:nowrap;
}
.pchip .pk{color:var(--ink-3)}
.pchip .pv{font-family:var(--mono);color:var(--ink);font-weight:600}
.pchip.warn{border-color:#f0dcb4;background:var(--warn-s);color:var(--warn)}

/* ---------- 配置编辑表 ---------- */
.cfg-bar{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;flex-wrap:wrap}
.fld.inline{flex-direction:row;align-items:center;gap:8px}
.fld.inline>span{font-size:12px;color:var(--ink-2);white-space:nowrap}
.fld.inline select{width:auto;min-width:170px}
.cfg-scroll{max-height:52vh;overflow:auto;border:1px solid var(--line);border-radius:var(--r-s)}
.cfg-edit{border-collapse:collapse;width:100%;font-size:12px}
.cfg-edit th{
  position:sticky;top:0;z-index:2;background:var(--brand);color:#fff;
  font-weight:600;font-size:11.5px;text-align:left;white-space:nowrap;
  padding:6px 8px;border-right:1px solid rgba(255,255,255,.14);
}
.cfg-edit td{padding:2px;border:1px solid var(--line-2);background:#fff}
.cfg-edit td.idx{text-align:center;color:var(--ink-3);font-family:var(--mono);
  background:var(--panel-2);width:34px}
.cfg-edit input.cell,.cfg-edit select.cell{
  width:100%;min-width:66px;padding:3px 5px;font-size:11.5px;
  border:1px solid transparent;border-radius:4px;background:transparent;
}
.cfg-edit input.cell:hover,.cfg-edit select.cell:hover{border-color:var(--line);background:var(--panel-2)}
.cfg-edit input.cell:focus,.cfg-edit select.cell:focus{border-color:var(--accent);background:#fff;outline:none}
.cfg-edit select.cell{cursor:pointer;height:24px}
.btn-mini.danger{color:var(--danger);border-color:#f5c9c5}
.btn-mini.danger:hover{background:var(--danger-s)}

/* ========================================================== 工况配图 */
.cond-inline{display:flex;align-items:center;gap:0;margin-top:0;flex:0 0 auto}
.cond-inline .btn-mini{font-size:14px;line-height:1;padding:4px 7px}
.cond-modal-card{max-width:860px;width:94%}
.cond-modal-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));
  gap:14px;padding:4px 0}
.cond-modal-cell{border:1px solid var(--line);border-radius:10px;background:#fff;
  padding:10px;cursor:pointer;transition:.12s;display:flex;flex-direction:column;gap:8px}
.cond-modal-cell:hover{border-color:#c7dbfa;background:var(--brand-s)}
.cond-modal-cell.on{border-color:var(--accent);background:var(--brand-s);
  box-shadow:0 0 0 2px rgba(27,100,217,.14)}
.cond-modal-img{width:100%;height:auto;max-height:240px;object-fit:contain;
  border-radius:6px;background:#fbfdff}
.cond-modal-cap{font-size:12.5px;color:var(--ink-2);text-align:center;font-weight:500}
.cond-modal-cell.on .cond-modal-cap{color:var(--accent);font-weight:600}

/* ================= 使用说明（帮助弹窗，2026-10-14 新增） ================= */
.modal-card.modal-help{width:min(780px,94vw);max-width:780px;max-height:86vh;
  display:flex;flex-direction:column;overflow:hidden}
.modal-card.modal-help .card-hd{flex:0 0 auto}
.modal-card.modal-help .card-ft{flex:0 0 auto;justify-content:space-between}
.help-body{flex:1;min-height:0;overflow:auto;padding:6px 22px 18px}
.help-sec{padding:14px 0;border-top:1px dashed var(--line)}
.help-sec:first-child{border-top:none;padding-top:8px}
.help-sec h4{margin:0 0 8px;font-size:14px;font-weight:600;color:var(--ink);
  letter-spacing:-.1px}
.help-list{margin:0;padding-left:20px}
.help-list li{font-size:13px;line-height:1.8;color:var(--ink-2)}
.help-list li + li{margin-top:4px}
.help-list li b{color:var(--ink);font-weight:600}
.help-list ul{margin:5px 0 2px;padding-left:18px}
.help-list ul li{font-size:12.5px;line-height:1.75}
.help-sec .muted{font-size:12.5px}
@media (max-width:720px){
  .help-body{padding:6px 14px 14px}
  .help-list li{font-size:12.5px}
}

/* ---------- 特征参数图示（2026-10-30） ---------- */
/* 类型格：下拉 + 相机按钮 */
.feat-table td.c-type{min-width:128px;white-space:nowrap}
.btn-featimg{width:22px;height:22px;margin-left:3px;vertical-align:middle;
  font-size:11px;border:1px solid var(--line);border-radius:5px}
/* 中心特征列表头可点（有图） */
.feat-table thead th.th-imglink{cursor:pointer;text-decoration:underline dotted;
  text-underline-offset:3px}
/* 灯箱 */
.img-lightbox{position:fixed;inset:0;z-index:9999;background:rgba(17,24,39,.78);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  cursor:zoom-out;padding:24px}
.img-lightbox img{max-width:92vw;max-height:80vh;background:#fff;border-radius:8px;
  box-shadow:0 12px 48px rgba(0,0,0,.45)}
.img-lightbox-cap{margin-top:10px;color:#fff;font-size:13px}
/* 帮助弹窗图组 */
.help-figs{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px}
.help-figs figure{margin:0;border:1px solid var(--line);border-radius:8px;
  padding:8px;background:var(--panel)}
.help-figs img{width:100%;height:auto;display:block;border-radius:4px;cursor:zoom-out}
.help-figs figcaption{margin-top:6px;font-size:12px;color:var(--ink-2);text-align:center}

/* ---------- 小屏/矮视口优化（2026-10-30 用户反馈） ----------
   ① 左栏：卡片保持自然高度，超出由 .col-left 出滚动条。
      旧写法 flex:0 1 auto 会把卡片压到可视高度、内容被 .card 的
      overflow:hidden 剪掉 —— 左栏永远不溢出，滚动条根本不出现，
      「机床规格」等底部字段看不到也滚不动。 */
.col-left>.card-input{flex:0 0 auto}
/* ② 还没计算时：等待占位压小，特征清单占满剩余高度，方便先看/先填特征。
      算完占位隐藏后自动恢复：特征区 210px、结果区占剩余。 */
.col-main:has(#resultPlaceholder:not([hidden]))>.card-feat{flex:1 1 auto}
.col-main:has(#resultPlaceholder:not([hidden]))>.card-placeholder{flex:0 0 auto}
.col-main:has(#resultPlaceholder:not([hidden])) .ph-inner{padding:14px 24px 12px}
.col-main:has(#resultPlaceholder:not([hidden])) .ph-icon{font-size:24px;margin-bottom:4px}

/* ===== 3D 识别特征入口（2026-11-03） =====
   气泡不用浏览器原生 title：那个要悬停 1 秒才出、样式改不了、手机上根本不出现。 */
.tip-wrap{position:relative;display:inline-flex;flex:0 0 auto}
.tip-bub{
  position:absolute;left:50%;top:calc(100% + 9px);transform:translateX(-50%) translateY(-3px);
  width:250px;padding:9px 11px;border-radius:8px;
  background:var(--brand);color:#fff;font-size:12px;line-height:1.62;font-weight:400;
  letter-spacing:0;text-align:left;white-space:normal;
  box-shadow:0 8px 22px rgba(16,40,64,.22);
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .15s ease,transform .15s ease,visibility .15s;
  z-index:60;
}
.tip-bub::before{
  content:"";position:absolute;left:50%;top:-5px;width:9px;height:9px;
  transform:translateX(-50%) rotate(45deg);background:var(--brand);
}
.tip-bub b{color:#ffd591;font-weight:600}
.tip-wrap:hover .tip-bub,.tip-wrap:focus-within .tip-bub{
  opacity:1;visibility:visible;transform:translateX(-50%) translateY(0);
}
.tip-inline{
  display:none;padding:2px 16px 10px;font-size:11px;line-height:1.5;color:var(--ink-3);
}
.tip-inline b{color:var(--ink-2);font-weight:600}
/* 触屏 / 窄屏出不了 hover：气泡换成一行常显 */
@media (hover:none){
  .tip-bub{display:none}
  .tip-inline{display:block}
}
@media (max-width:720px){
  .tip-bub{display:none}
  .tip-inline{display:block}
}
