/* P4-Web 前端样式 · 无 CDN / 无框架 / 移动优先
   色板：底 #FFF8F0、卡片白、主色 #FF6B35（派工单指定） */

:root{
  --bg:#FFF8F0;
  --card:#FFFFFF;
  --ink:#2B2118;
  --muted:#7A6A5E;
  --line:#F0E2D4;
  --soft:#FFF2E7;
  --soft-2:#FFE8D6;
  --primary:#FF6B35;
  --primary-dark:#E9551F;
  --primary-ink:#8A3210;
  --ok:#2F7D4F; --ok-bg:#EDF8F1; --ok-line:#CBE9D6;
  --bad:#B42318; --bad-bg:#FDECEA; --bad-line:#F5C9C4;
  --warn:#9A5B00; --warn-bg:#FFF7E6; --warn-line:#F1DDB6;
  --info:#205EA8; --info-bg:#EEF4FF; --info-line:#CFE0FA;
  --radius:16px;
  --shadow:0 10px 30px rgba(122,42,11,.08);
  --shadow-sm:0 2px 8px rgba(122,42,11,.06);
}

*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%; text-size-adjust:100%}
body{
  margin:0;
  min-width:0;
  background:var(--bg);
  color:var(--ink);
  font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Noto Sans CJK SC",sans-serif;
  font-size:15px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
img,svg,video{max-width:100%; height:auto}
a{color:var(--primary-ink)}
a:hover{color:var(--primary-dark)}
code,.mono{
  font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono",monospace;
  font-size:.9em;
  overflow-wrap:anywhere;
}
button,input,select,textarea{font:inherit; color:inherit}
:focus-visible{outline:3px solid rgba(255,107,53,.45); outline-offset:2px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip{position:absolute;left:8px;top:-48px;z-index:100;background:var(--ink);color:#fff;padding:8px 12px;border-radius:10px;text-decoration:none}
.skip:focus{top:8px}

/* 演示模式横幅：始终可见，避免假数据被当成真实跑数 */
.demo-ribbon{
  position:static; z-index:60;
  background:var(--ink); color:#FFE8D6;
  font-size:12.5px; line-height:1.45; text-align:center;
  padding:6px 12px; letter-spacing:.01em;
  overflow-wrap:anywhere;
}
.demo-ribbon b{color:#fff}

.wrap{width:min(1080px, 100% - 32px); margin-inline:auto}
@media (max-width:420px){ .wrap{width:calc(100% - 24px)} }

/* 顶栏 */
.appbar{
  position:sticky; top:0; z-index:50;
  background:rgba(255,248,240,.94);
  border-bottom:1px solid var(--line);
  backdrop-filter:saturate(1.2) blur(8px);
}
.appbar-inner{display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; padding:10px 0}
.brand{display:inline-flex; align-items:center; gap:9px; text-decoration:none; color:var(--ink); min-width:0}
.brand-mark{
  width:34px;height:34px;border-radius:11px;flex:none;
  background:linear-gradient(135deg,#FF9A6B,#FF5A1F);
  color:#fff;display:grid;place-items:center;font-weight:800;font-size:15px;
  box-shadow:0 5px 14px rgba(255,90,31,.28);
}
.brand-text{display:grid; line-height:1.15; min-width:0}
.brand-text strong{font-size:15px; letter-spacing:.01em}
.brand-text small{color:var(--muted); font-size:11px}
.nav{display:flex; align-items:center; gap:2px; flex-wrap:wrap}
.nav a,.nav button{
  appearance:none; border:0; background:transparent; cursor:pointer;
  color:var(--muted); text-decoration:none; font-size:13px; font-weight:600;
  padding:7px 10px; border-radius:999px; min-height:34px;
}
.nav a[aria-current="page"]{background:var(--soft); color:var(--primary-ink)}
.nav a:hover,.nav button:hover{background:var(--soft)}
@media (max-width:520px){
  .brand-text small{display:none}
  .nav a,.nav button{padding:6px 8px; font-size:12.5px}
  .nav [data-user]{display:none}
}

main{padding:18px 0 40px; min-width:0}
.page-head{display:flex; align-items:flex-end; justify-content:space-between; gap:12px; flex-wrap:wrap; margin:2px 0 16px}
.page-head h1{font-size:22px; line-height:1.25; margin:0; letter-spacing:-.01em}
.page-head p{margin:4px 0 0; color:var(--muted); font-size:13px}
.eyebrow{color:var(--primary-ink); font-size:12px; font-weight:700; letter-spacing:.06em; text-transform:uppercase}

.card{
  background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
  padding:18px; box-shadow:var(--shadow-sm); min-width:0;
}
@media (max-width:420px){ .card{padding:15px; border-radius:14px} }
.card + .card{margin-top:14px}
.card-head{display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; margin-bottom:12px}
.card-head h2{font-size:16px; margin:0; line-height:1.35}
.card-head .sub{color:var(--muted); font-size:12px}
.stack{display:grid; gap:14px}

/* 按钮 */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  min-height:42px; padding:9px 15px; border-radius:12px;
  border:1px solid var(--line); background:#fff; color:var(--ink);
  font-size:14px; font-weight:650; text-decoration:none; cursor:pointer;
  min-width:0; transition:background .15s ease, border-color .15s ease, transform .05s ease;
}
.btn:hover{background:#FFFCF8; border-color:#E8D4C0}
.btn:active{transform:translateY(1px)}
.btn:disabled,.btn[aria-disabled="true"]{opacity:.5; cursor:not-allowed; transform:none}
.btn-primary{background:var(--primary); border-color:var(--primary); color:#fff; box-shadow:0 7px 18px rgba(255,107,53,.24)}
.btn-primary:hover{background:var(--primary-dark); border-color:var(--primary-dark); color:#fff}
.btn-ghost{background:transparent}
.btn-block{width:100%}
.btn-sm{min-height:34px; padding:5px 11px; font-size:13px; border-radius:10px}
.btn-row{display:flex; gap:8px; flex-wrap:wrap}

/* 表单 */
.field{display:grid; gap:6px; margin-bottom:14px; min-width:0}
.field > label{font-size:13px; font-weight:650}
.field .hint{margin:0}
.input,select,textarea{
  width:100%; min-height:46px; padding:10px 12px;
  border:1px solid var(--line); border-radius:12px; background:#fff;
  color:var(--ink); min-width:0;
}
.input::placeholder{color:#B5A394}
.input:focus,select:focus,textarea:focus{border-color:var(--primary); outline:none; box-shadow:0 0 0 3px rgba(255,107,53,.16)}
.hint{font-size:12.5px; color:var(--muted); margin:8px 0 0; overflow-wrap:anywhere}
.hint code{background:var(--soft); padding:1px 5px; border-radius:5px}

/* 提示条 */
.notice{
  border:1px solid var(--line); background:#FFFCF8; color:var(--ink);
  border-radius:12px; padding:11px 13px; font-size:13px; line-height:1.55;
  overflow-wrap:anywhere;
}
.notice + .notice{margin-top:10px}
.notice-bad{border-color:var(--bad-line); background:var(--bad-bg); color:#7A1A12}
.notice-warn{border-color:var(--warn-line); background:var(--warn-bg); color:#6E4100}
.notice-ok{border-color:var(--ok-line); background:var(--ok-bg); color:#1D5C39}
.notice-info{border-color:var(--info-line); background:var(--info-bg); color:#1B4C86}
.notice strong{font-weight:700}
.notice .code-line{display:block; margin-top:4px; font-size:12px; color:inherit; opacity:.85}
.notice button{margin-top:8px}

/* 徽标 */
.badge{
  display:inline-flex; align-items:center; gap:6px;
  border:1px solid var(--line); border-radius:999px;
  padding:2px 9px; font-size:12px; font-weight:650; line-height:1.5;
  max-width:100%; overflow-wrap:anywhere;
  background:#FBF7F2; color:var(--muted);
}
.badge::before{content:""; width:6px; height:6px; border-radius:50%; background:currentColor; flex:none; opacity:.85}
.badge-ok{border-color:var(--ok-line); background:var(--ok-bg); color:var(--ok)}
.badge-bad{border-color:var(--bad-line); background:var(--bad-bg); color:var(--bad)}
.badge-warn{border-color:var(--warn-line); background:var(--warn-bg); color:var(--warn)}
.badge-info{border-color:var(--info-line); background:var(--info-bg); color:var(--info)}
.badge-muted{border-color:var(--line); background:#FBF7F2; color:var(--muted)}

/* 登录 */
.login-shell{min-height:calc(100dvh - 120px); display:grid; grid-template-columns:minmax(0,1fr); justify-items:center; align-content:center; padding:24px 0}
.login-card{width:100%; max-width:420px; min-width:0; background:var(--card); border:1px solid var(--line); border-radius:20px; padding:26px; box-shadow:var(--shadow)}
@media (max-width:420px){ .login-card{padding:20px; border-radius:16px} }
.login-brand{display:grid; gap:8px; margin-bottom:20px}
.login-brand .brand-mark{width:46px;height:46px;border-radius:14px;font-size:19px;margin-bottom:2px}
.login-brand h1{font-size:23px; margin:0; letter-spacing:-.01em}
.login-brand p{margin:0; color:var(--muted); font-size:13px; line-height:1.55}
.form-error{margin:0 0 14px}
.login-foot{margin-top:18px; padding-top:14px; border-top:1px dashed var(--line); color:var(--muted); font-size:12px}

/* 上传 */
.dropzone{
  display:block;
  border:2px dashed #E7CDB6; border-radius:16px; background:#FFFCF8;
  padding:26px 16px; text-align:center; cursor:pointer;
  transition:border-color .15s ease, background .15s ease;
}
.dropzone:hover,.dropzone.is-drag{border-color:var(--primary); background:var(--soft)}
.dropzone:focus-within{outline:3px solid rgba(255,107,53,.35); outline-offset:2px}
.dropzone input[type="file"]{position:absolute; width:1px; height:1px; opacity:0; pointer-events:none}
.dropzone .dz-icon{width:44px;height:44px;margin:0 auto 8px;border-radius:14px;background:var(--soft);display:grid;place-items:center;color:var(--primary-ink);font-size:20px;font-weight:800}
.dropzone strong{display:block; font-size:15px}
.dropzone span{display:block; color:var(--muted); font-size:12.5px; margin-top:3px}
.file-chip{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  border:1px solid var(--line); background:#FFFCF8; border-radius:12px;
  padding:9px 11px; margin-top:12px; font-size:13px; min-width:0;
}
.file-chip .name{font-weight:650; overflow-wrap:anywhere; min-width:0}
.file-chip .size{color:var(--muted); font-size:12px; font-variant-numeric:tabular-nums}
.form-grid{display:grid; gap:12px; grid-template-columns:1fr}
@media (min-width:640px){ .form-grid{grid-template-columns:1.2fr .8fr; align-items:end} }
.form-actions{display:flex; gap:8px; flex-wrap:wrap; margin-top:14px}
.two-col{display:grid; gap:14px; min-width:0}
@media (min-width:900px){ .two-col{grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr)} .two-col > .card + .card{margin-top:0} }
.mt-12{margin-top:12px}
.mt-14{margin-top:14px}
.mb-0{margin-bottom:0}
.align-center{align-self:center}

/* 任务列表 */
.job-list{display:grid; gap:10px}
.job-card{
  display:grid; gap:8px; padding:13px 14px; border:1px solid var(--line);
  border-radius:14px; background:#FFFCF8; text-decoration:none; color:inherit;
  transition:border-color .15s ease, background .15s ease;
}
.job-card:hover{border-color:#E3C6AC; background:#FFF7EE}
.job-card .row{display:flex; align-items:center; gap:8px; flex-wrap:wrap; min-width:0}
.job-card .fname{font-weight:650; font-size:14px; overflow-wrap:anywhere; min-width:0}
.job-card .meta{color:var(--muted); font-size:12px; display:flex; gap:10px; flex-wrap:wrap}
.job-card .meta code{background:var(--soft); padding:1px 5px; border-radius:5px}
.empty{
  border:1px dashed #E7CDB6; border-radius:14px; padding:26px 16px;
  text-align:center; color:var(--muted); background:#FFFCF8;
}
.empty strong{display:block; color:var(--ink); font-size:14px; margin-bottom:3px}
.empty span{font-size:12.5px}

/* 任务详情 */
.meta-chips{display:flex; gap:6px; flex-wrap:wrap; margin:2px 0 0}
.chip{font-size:12px; border:1px solid var(--line); border-radius:999px; padding:2px 9px; background:#FFFCF8; color:var(--muted); max-width:100%; overflow-wrap:anywhere}
.chip code{color:var(--ink); background:transparent; padding:0}
.progress-head{display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; margin-bottom:8px}
.progress-head strong{font-size:14px}
.progress-head span{color:var(--muted); font-size:12px}
.bar{height:10px; border-radius:999px; background:var(--soft-2); overflow:hidden}
.bar.bar-steps{display:grid; grid-template-columns:repeat(6,minmax(0,1fr)); gap:4px; height:10px; background:transparent; overflow:visible}
.bar-steps .seg{display:block; height:10px; border-radius:999px; background:var(--soft-2)}
.bar-steps .seg.is-done{background:linear-gradient(90deg,#FF9A6B,var(--primary))}
.bar-steps .seg.is-running{background:#FFB38F; animation:stepPulse 1.2s ease-in-out infinite}
.bar-steps .seg.is-failed{background:var(--bad)}
.bar-steps .seg.is-skipped{background:#EADFD5}
.bar.is-failed .seg.is-pending{background:#F6E3DE}
@keyframes stepPulse{0%,100%{opacity:.55} 50%{opacity:1}}
.steps{display:grid; gap:8px; margin:14px 0 0; padding:0; list-style:none}
.step{display:grid; grid-template-columns:34px 1fr auto; gap:10px; align-items:center; border:1px solid var(--line); border-radius:12px; padding:9px 11px; background:#fff; min-width:0}
.step .idx{width:30px;height:30px;border-radius:9px;background:var(--soft);color:var(--primary-ink);display:grid;place-items:center;font-size:12px;font-weight:750}
.step .body{min-width:0}
.step .name{font-size:13.5px; font-weight:650; display:flex; align-items:center; gap:7px; flex-wrap:wrap}
.step .desc{color:var(--muted); font-size:11.5px; overflow-wrap:anywhere}
.step .right{text-align:right; display:grid; gap:3px; justify-items:end}
.step .dur{font-size:12px; color:var(--muted); font-variant-numeric:tabular-nums}
.step.is-running{border-color:#FFD2BD; background:#FFF8F2}
.step.is-done .idx{background:var(--ok-bg); color:var(--ok)}
.step.is-failed{border-color:var(--bad-line); background:#FFF9F8}
.step.is-failed .idx{background:var(--bad-bg); color:var(--bad)}
.step.is-skipped{opacity:.7}

/* 结果页 · 七数 */
.kpi-section .card-head{align-items:flex-start}
.kpis{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:9px}
@media (min-width:720px){ .kpis{grid-template-columns:repeat(4,minmax(0,1fr))} }
@media (min-width:1000px){ .kpis{grid-template-columns:repeat(7,minmax(0,1fr))} }
@media (max-width:719px){ .kpis .kpi:last-child{grid-column:1 / -1} }
.kpi{border:1px solid var(--line); border-radius:12px; padding:10px 11px; background:linear-gradient(#fff,#FFFCF8); min-width:0}
.kpi .k-label{display:block; color:var(--muted); font-size:11.5px; line-height:1.35; min-height:3.1em; overflow-wrap:anywhere}
.kpi .k-value{display:block; font-size:clamp(19px,5.4vw,24px); font-weight:750; line-height:1.2; letter-spacing:-.01em; font-variant-numeric:tabular-nums; overflow-wrap:anywhere}
.kpi .k-note{display:block; color:var(--muted); font-size:10.5px; line-height:1.35; margin-top:3px; min-height:2.7em; overflow-wrap:anywhere}
.kpi.is-warn{border-color:var(--warn-line); background:#FFFBF2}
.kpi.is-missing{border-style:dashed}

/* 结果页 · 逐份 */
.items{display:grid; gap:10px}
.item{border:1px solid var(--line); border-radius:14px; padding:12px 13px; background:#fff; min-width:0}
.item-top{display:flex; align-items:center; gap:8px; flex-wrap:wrap; min-width:0}
.item-no{width:26px;height:26px;border-radius:8px;background:var(--soft);color:var(--primary-ink);display:grid;place-items:center;font-size:11.5px;font-weight:750;flex:none}
.item .noteid{font-size:12px; color:var(--ink); background:#FBF7F2; padding:2px 6px; border-radius:6px; max-width:100%}
.item .badge{margin-left:auto}
@media (max-width:420px){ .item .badge{margin-left:0} }
.item-meta{display:flex; gap:8px 12px; flex-wrap:wrap; color:var(--muted); font-size:12px; margin-top:7px; min-width:0}
.item-note{margin:8px 0 0; color:var(--muted); font-size:12px; line-height:1.5; overflow-wrap:anywhere}
.item-actions{display:flex; gap:7px; flex-wrap:wrap; margin-top:10px}
.thumb{display:block; width:100%; max-height:320px; object-fit:contain; background:#FBF7F2; border:1px solid var(--line); border-radius:10px; margin-top:10px}
.thumb-placeholder{display:grid; place-items:center; height:92px; border:1px dashed #E7CDB6; border-radius:10px; background:#FFFCF8; color:var(--muted); font-size:12px; margin-top:10px}

/* 页脚 / 边界 */
.foot{border-top:1px solid var(--line); padding:16px 0 26px; color:var(--muted); font-size:12px}
.foot .wrap{display:flex; gap:8px 16px; flex-wrap:wrap; justify-content:space-between}
.foot .foot-legal{margin-top:6px; font-size:12px; color:#9A8A7E}
.foot .foot-legal a{color:#9A8A7E; text-decoration:none}
.foot .foot-legal a:hover,.foot .foot-legal a:focus-visible{color:#FF6B35; text-decoration:underline}
.boundary{background:#FFFCF8; border-color:var(--line)}
.boundary ul{margin:0; padding-left:18px}
.boundary li{margin:4px 0; font-size:12.5px; color:var(--muted); overflow-wrap:anywhere}
.boundary strong{color:var(--ink)}

/* toast */
.toast{
  position:fixed; left:50%; bottom:calc(18px + env(safe-area-inset-bottom));
  transform:translateX(-50%) translateY(12px);
  background:var(--ink); color:#FFF3E8; font-size:13px; line-height:1.45;
  border-radius:999px; padding:9px 15px; box-shadow:var(--shadow);
  opacity:0; pointer-events:none; transition:opacity .18s ease, transform .18s ease;
  max-width:calc(100vw - 32px); text-align:center; z-index:90;
}
.toast.is-on{opacity:1; transform:translateX(-50%) translateY(0)}
.toast.is-bad{background:#7A1A12; color:#FFE9E6}

/* 载入占位 */
.skeleton{position:relative; overflow:hidden; background:#FBF3EA; border-radius:10px; min-height:14px; color:transparent!important}
.sk-74{height:74px}
.sk-96{height:96px}
.skeleton::after{content:""; position:absolute; inset:0; background:linear-gradient(90deg,transparent,rgba(255,255,255,.7),transparent); transform:translateX(-100%); animation:shimmer 1.3s infinite}
@keyframes shimmer{to{transform:translateX(100%)}}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important; animation-iteration-count:1!important; transition-duration:.001ms!important; scroll-behavior:auto!important}
}

/* ---------- D3：引用 / 跳过 / 受阻 与产物清单 ---------- */
.step.is-imported{border-color:var(--warn-line); background:#FFFCF4}
.step.is-imported .idx{background:var(--warn-bg); color:var(--warn)}
.step.is-blocked{border-color:var(--warn-line); background:#FFFCF4}
.step.is-blocked .idx{background:var(--warn-bg); color:var(--warn)}
.step.is-skipped .idx{background:#F2ECE4; color:var(--muted)}
.bar .seg.is-imported,.bar .seg.is-blocked{background:var(--warn)}
.bar .seg.is-skipped{background:#CBBFB2}
.bar .seg.is-imported,.bar .seg.is-blocked,.bar .seg.is-skipped{opacity:.85}
.code-hint,.reason-text{display:block; margin-top:3px; color:var(--muted); overflow-wrap:anywhere}
.code-hint{color:#6E4100}
.arts{margin-top:7px; font-size:12px}
.arts summary{cursor:pointer; color:var(--muted)}
.arts summary:hover,.arts summary:focus-visible{color:var(--ink)}
.arts ul{margin:6px 0 0; padding-left:0; list-style:none}
.arts li{display:flex; flex-direction:column; gap:2px; padding:5px 0; border-top:1px dashed var(--line)}
.art-path{font-size:11.5px; overflow-wrap:anywhere; word-break:break-all; color:var(--ink)}
.art-meta{font-size:11.5px; color:var(--muted)}
.artifact-list{margin:0; padding:0; list-style:none}
.artifact-list li{display:flex; flex-direction:column; gap:3px; padding:7px 0; border-top:1px dashed var(--line)}
.artifact-list li:first-child{border-top:0}
.json{max-height:340px; overflow:auto; background:#FBF7F2; border:1px solid var(--line); border-radius:10px; padding:10px; font-size:11.5px; line-height:1.5; white-space:pre-wrap; word-break:break-all}

/* ---------- D3：批次台 ---------- */
.source-line{display:flex; flex-wrap:wrap; gap:6px 14px; font-size:12px; color:var(--muted); margin:-4px 0 12px; overflow-wrap:anywhere}
.batch-list{display:grid; grid-template-columns:repeat(auto-fill,minmax(300px,1fr)); gap:10px}
.batch-card{border:1px solid var(--line); border-radius:12px; background:#FFFDFA; padding:10px 12px}
.batch-top{display:flex; align-items:center; justify-content:space-between; gap:8px; flex-wrap:wrap}
.batch-top .noteid{font-size:11.5px; word-break:break-all}
.batch-card .item-meta{margin-top:6px; display:flex; flex-wrap:wrap; gap:4px 10px; font-size:12px; color:var(--muted)}
.batch-card .item-meta code{font-size:11.5px}
.claim-on code{color:var(--ok); border-color:var(--ok-line); background:var(--ok-bg)}
.batch-card .item-actions{margin-top:8px}
.subhead{font-size:13px; margin:16px 0 6px}
.kv{display:grid; grid-template-columns:minmax(90px,180px) 1fr; gap:4px 12px; margin:0; font-size:12.5px}
.kv dt{color:var(--muted)}
.kv dd{margin:0; overflow-wrap:anywhere; word-break:break-all}
.reasons{margin:0; padding-left:18px; font-size:12.5px; color:var(--muted); overflow-wrap:anywhere}
.reasons li{margin:3px 0}

@media (max-width:520px){
  .batch-list{grid-template-columns:1fr}
  .kv{grid-template-columns:1fr}
  .kv dt{margin-top:5px}
  .kv dd{padding-bottom:4px; border-bottom:1px dashed var(--line)}
}
