

/*
   视觉系统「墨蓝与金」：风格对标同系产品 demoglm；令牌取自参照站实测值。
   三条硬规则：正文对比度 ≥ 4.5:1（contrast.py + uitest.py 双重校验）；
   金色只用于强调与细线；查看器内部必须白底黑字。
   警告：注释里不要出现星号紧跟斜杠的组合，会提前闭合注释；本文件曾因此
   把整个 :root 变量块吃掉，导致全站颜色退化成透明。
*/
:root{
  
  --ink-900:#0e1a2e;
  --ink-800:#14233c;
  --ink-700:#1c3050;
  --ink-600:#27436b;
  --ink-500:#33567f;
  --ink-400:#5a7ba6;
  --ink-300:#8fa8c6;
  --ink-100:#e3ebf4;
  --ink-50:#f2f6fa;

  
  
  --gold-600:#a97f16;
/*
   gold-600 做大字够用，但落在 gold-50 浅金底上只有 3.42:1，
   另设更深一档 gold-700 专作文字色。
*/
  --gold-700:#7d5c0c;
  --gold-500:#c9a227;
  --gold-400:#d9b54a;
  --gold-300:#e7cc7e;
  --gold-100:#f7efd8;
  --gold-50:#fbf7ea;

  
  --c-bg:#f6f7f9;           
  --c-surface:#ffffff;      
  --c-surface-2:#f7f9fb;    
  --c-surface-3:#eef2f7;    
  --c-line:#d7dee7;         
  --c-line-soft:#e5eaf0;    
  --c-line-gold:rgba(201,162,39,.42);

  --c-text:#1e2a3a;         
  --c-text-2:#3c4c61;       
  
/*
   说明文字也必须清楚：参照站的 ink-400(#5a7ba6) 在浅底上只有 4.13:1，
   不够做正文说明，所以压深 --c-dim 和 --c-faint。
*/
  --c-dim:#456b94;
  --c-faint:#4f6d92;

  --c-primary:var(--ink-700);
  --c-primary-lift:var(--ink-600);
  --c-accent:var(--gold-500);
  --c-jade:#1f7a52;
  --c-danger:#b4443c;
  --c-violet:#6b4fa8;
  --c-azure:#2a5c9a;

  
  --r-sm:4px; --r-md:6px; --r-lg:8px; --r-xl:16px;
  /* 卡片内边距统一走这个令牌。同一个元素常同时挂 .card 与 .template-card，
     两边各写一套 padding 会互相打架，实测出现 20/22、16/18、11/14 三种值，
     视觉节奏很乱。密度不同的场景用 --pad-card-tight。 */
  --pad-card:18px 20px;
  --pad-card-tight:13px 15px;
  --sh-1:0 1px 2px rgba(16,30,54,.05);
  --sh-2:0 2px 8px rgba(16,30,54,.07);
  --sh-3:0 2px 14px rgba(16,30,54,.14);
  --ring:0 0 0 3px rgba(39,67,107,.13);

  --font-sans:"PingFang SC","Microsoft YaHei",寰蒋闆呴粦,"Segoe UI",system-ui,sans-serif;
  --font-serif:"Noto Serif SC","Source Han Serif SC","STZhongsong","SimSun",serif;
  --font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Courier New",monospace;

  font-family:var(--font-sans);
  color:var(--c-text);
  background:var(--c-bg);
}

*{box-sizing:border-box}
html,body{margin:0;background:var(--c-bg)}
body{-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}

/* 极淡噪点（0.04）：参照站同样手法，让纸底不死平。 */
body::before{
  content:"";position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.04;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
}
#app{position:relative;z-index:1}
button,input,select,textarea{font:inherit;color:inherit}
::selection{background:var(--gold-100)}
:focus-visible{outline:2px solid var(--ink-600);outline-offset:2px;border-radius:3px}
a{color:var(--ink-600);text-decoration-thickness:1px;text-underline-offset:3px}
a:hover{color:var(--gold-600)}

/* 深底上默认滚动条很扎眼，要低调。 */
*::-webkit-scrollbar{width:11px;height:11px}
*::-webkit-scrollbar-track{background:var(--c-surface-2)}
*::-webkit-scrollbar-thumb{background:#c3cedb;border-radius:99px;border:3px solid var(--c-surface-2)}
*::-webkit-scrollbar-thumb:hover{background:#a9b8c9}


/* 财务数字必须等宽对齐，错位一列就没法读。 */
.num,.mono,.job-pct,.enrich-pct,.analysis-percent,.report-score,
.tree-meta,.kv-v,.tbl td{font-variant-numeric:tabular-nums}
.mono{font-family:var(--font-mono);font-size:12.5px}


.app-shell{display:grid;grid-template-columns:232px 1fr;min-height:100vh}


/* 反相深墨蓝底是界面锚点。
   sticky + 满高 + 自身滚动条：侧栏不随正文滚动，
   导航与底部的项目选择器始终留在视野内。
   这条也是 .project-picker 吸底能生效的前提——
   没有它，侧栏会跟着长页面一起滚走。 */
.sidebar{
  position:sticky;top:0;align-self:start;
  height:100vh;overflow-y:auto;overscroll-behavior:contain;
  padding:24px 13px 0;display:flex;flex-direction:column;
  background:var(--ink-900);color:var(--ink-100);
}
/* 深底上默认滚动条太扎眼，收窄并压低对比。 */
.sidebar::-webkit-scrollbar{width:6px}
.sidebar::-webkit-scrollbar-track{background:transparent}
.sidebar::-webkit-scrollbar-thumb{background:rgba(255,255,255,.16);border:0;border-radius:99px}
.sidebar::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.28)}
/* 导航区吃掉中间的剩余空间，把选择器压到底部 */
.side-nav{flex:1 0 auto}
.sidebar::after{
  content:"";position:absolute;top:0;right:0;width:1px;height:100%;
  background:linear-gradient(180deg,transparent,var(--c-line-gold) 16%,var(--c-line-gold) 74%,transparent);
}
/* 品牌区：金色图标方块 + 主名 + 字距副标题，三段横向排列。
   参照 demoglm.suojianxi.cn 的侧栏抬头，底部用细分隔线收口。 */
.brand{
  display:flex;align-items:center;gap:10px;
  margin:0 4px 18px;padding:0 4px 16px;
  border-bottom:1px solid var(--ink-700);
}
.brand-mark{
  width:36px;height:36px;flex-shrink:0;border-radius:9px;
  background:linear-gradient(135deg,var(--gold-400,#c9a227),var(--gold-600,#a97f16));
  /* 图标本体用 mask 从渐变底上"抠"出来：省一个 SVG 文件，
     颜色自动跟随渐变，不需要额外维护描边色。 */
  position:relative;
}
.brand-mark::after{
  content:"";position:absolute;inset:8px;
  background:#201803;
  -webkit-mask:var(--brand-icon) center/contain no-repeat;
          mask:var(--brand-icon) center/contain no-repeat;
}
:root{
  /* 参照站用的是 Lucide 的 Landmark 图标（古典建筑：底座 + 四立柱 + 三角屋顶），
     这里按它的原始几何逐笔还原，保持两站视觉一致。 */
  --brand-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='3' y1='22' x2='21' y2='22'/%3E%3Cline x1='6' y1='18' x2='6' y2='11'/%3E%3Cline x1='10' y1='18' x2='10' y2='11'/%3E%3Cline x1='14' y1='18' x2='14' y2='11'/%3E%3Cline x1='18' y1='18' x2='18' y2='11'/%3E%3Cpolygon points='12 2 20 7 4 7' fill='%23000' stroke='none'/%3E%3C/svg%3E");
}
.brand-text{min-width:0;line-height:1.25}
.brand-name{
  font-family:var(--font-serif);font-size:15px;font-weight:700;
  letter-spacing:.04em;color:#fff;white-space:nowrap;
}
.brand-sub{
  font-size:10px;letter-spacing:.2em;color:var(--ink-300);margin-top:3px;
}
.side-nav h3{
  font-size:10.5px;font-weight:600;letter-spacing:.15em;color:var(--ink-300);
  margin:19px 10px 7px;text-transform:uppercase;
}
.nav-link{
  position:relative;display:block;padding:9px 12px;margin:1px 0;
  color:#c6d4e5;text-decoration:none;border-radius:var(--r-sm);
  font-size:14px;transition:color .14s,background .14s;
}
.nav-link:hover{background:rgba(255,255,255,.07);color:#fff}
.nav-link.active{background:var(--ink-700);color:#fff;font-weight:500}
.nav-link.active::before{
  content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);
  width:2px;height:16px;background:var(--gold-500);border-radius:0 2px 2px 0;
}
/* 当前项目选择器吸底常驻左下角。
   margin-top:auto 把它推到侧栏底部；position:sticky + bottom:0 让它在
   侧栏内容超长、侧栏自身滚动时也不会被滚出视野。
   必须给不透明底色：它悬浮在导航之上，透明会和下面的链接叠在一起。
   左右负 margin 配等量 padding，让底色铺满侧栏内边距，边缘不露出内容。 */
.project-picker{
  position:sticky;bottom:0;z-index:5;margin-top:auto;
  margin-left:-13px;margin-right:-13px;
  padding:14px 13px calc(16px + env(safe-area-inset-bottom,0px));
  background:var(--ink-900);border-top:1px solid rgba(255,255,255,.12);
}
/* 上缘一段渐变：滚动到底部时内容淡入到选择器下面，
   而不是被一条硬边突然切断。 */
.project-picker::before{
  content:"";position:absolute;left:0;right:0;top:-20px;height:20px;pointer-events:none;
  background:linear-gradient(to bottom,transparent,var(--ink-900));
}
.picker-label{display:block;font-size:10.5px;letter-spacing:.13em;color:var(--ink-300);margin-bottom:6px;text-transform:uppercase}

/* 侧栏里的下拉走深底浅字，跟着侧栏走而不是跟着页面走。 */
.sidebar .select{background:var(--ink-800);color:#e8eef6;border-color:var(--ink-600)}
.sidebar .select:hover{border-color:var(--ink-500)}

.main{min-width:0;display:flex;flex-direction:column}
.topbar{
  height:58px;padding:0 28px;display:flex;align-items:center;justify-content:space-between;
  background:rgba(255,255,255,.86);border-bottom:1px solid var(--c-line);
  backdrop-filter:blur(8px);position:sticky;top:0;z-index:30;
}
.top-actions{display:flex;align-items:center;gap:10px}
.page-content{width:100%;max-width:1420px;padding:28px 28px 56px;margin:0 auto;
  animation:rise .3s cubic-bezier(.2,.7,.3,1) both}
@keyframes rise{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}


.page-head,.page-title,.page-title-row{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}
.page-title,.page-head{margin:0 0 24px;padding-bottom:14px;border-bottom:1px solid var(--c-line);position:relative}
/* 金线做刊头，给品牌和页面标题一个刊物式的起笔。 */
.page-title::after,.page-head::after{content:"";position:absolute;left:0;bottom:-1px;width:54px;height:2px;background:var(--gold-500)}
.page-title h1,.page-head h1{
  margin:0;font-family:var(--font-serif);font-size:26px;font-weight:600;
  letter-spacing:.01em;line-height:1.3;color:var(--ink-900);
}
.page-title h2,.page-head h2{margin:0;font-family:var(--font-serif);font-size:18px;font-weight:600;color:var(--ink-800)}
h2{font-family:var(--font-serif);font-weight:600;color:var(--ink-800)}
h3{font-size:15px;font-weight:600;color:var(--ink-800)}
.muted{color:var(--c-dim);font-size:13px;line-height:1.65}
.row-line{display:flex;align-items:center;gap:10px;flex-wrap:wrap}


.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  border:1px solid var(--c-line);border-radius:var(--r-md);
  padding:8px 15px;background:#fff;color:var(--ink-700);
  font-size:13.5px;cursor:pointer;white-space:nowrap;box-shadow:var(--sh-1);
  transition:background .14s,border-color .14s,box-shadow .14s;
}
.btn:hover{background:var(--c-surface-3);border-color:var(--ink-300)}
.btn:active{box-shadow:none}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn-primary{background:var(--ink-700);border-color:var(--ink-700);color:#fff;font-weight:500}
.btn-primary:hover{background:var(--ink-600);border-color:var(--ink-600)}
.btn-danger{background:var(--c-danger);border-color:var(--c-danger);color:#fff}
.btn-danger:hover{background:#9d3a33;border-color:#9d3a33}
.btn-ghost{background:transparent;box-shadow:none;border-color:var(--c-line)}
.btn-ghost:hover{background:var(--c-surface-3)}
.btn-sm{padding:5px 10px;font-size:12.5px}

.input,.select,.textarea{
  background:#fff;color:var(--c-text);
  border:1px solid var(--c-line);border-radius:var(--r-md);
  padding:9px 11px;width:100%;transition:border-color .14s,box-shadow .14s;
}
.input:hover,.select:hover,.textarea:hover{border-color:var(--ink-300)}
.input:focus,.select:focus,.textarea:focus{
  outline:none;border-color:var(--ink-600);box-shadow:var(--ring);
}
.input::placeholder,.textarea::placeholder{color:var(--ink-300)}
.input-sm{padding:6px 9px;font-size:13px}
.textarea{line-height:1.7;resize:vertical}
.select{appearance:none;padding-right:30px;
  background-image:linear-gradient(45deg,transparent 50%,var(--c-dim) 50%),linear-gradient(135deg,var(--c-dim) 50%,transparent 50%);
  background-position:calc(100% - 15px) 52%,calc(100% - 10px) 52%;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat}

.field{display:flex;flex-direction:column;gap:6px}
.field-label{font-size:12px;color:var(--c-dim)}
.field-grid,.form-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:15px}
/* min-height 24px：WCAG 2.5.5 对点击目标的建议下限。
   复选框本体 16px，靠 label 行把命中区撑到 24px。 */
.check{display:flex;align-items:center;gap:8px;min-height:24px;font-size:13.5px;cursor:pointer}
/* 点击目标：复选框本体放大到 16px，真正的命中区靠包裹它的 label 行撑到 32px。
   实测 15px 的方框对鼠标和触屏都偏小。 */
/* 自绘复选框，不用系统默认外观。
   原因：系统默认的未勾选状态只有一圈很淡的灰边，落在白色列表底上几乎看不见。
   当一屏里所有框都未勾选时（比如项目里的文件都已转换过），
   没有任何填色引导视线，用户会认为"这里没有复选框、不能选文件"。
   这里给足边框对比与悬停反馈，空框也一眼可见。 */
input[type=checkbox],input[type=radio]{
  appearance:none;-webkit-appearance:none;
  width:17px;height:17px;flex:none;cursor:pointer;margin:0;
  background:#fff;border:1.5px solid var(--ink-400);border-radius:3px;
  display:inline-grid;place-content:center;
  transition:background .12s,border-color .12s;
}
input[type=radio]{border-radius:50%}
input[type=checkbox]:hover,input[type=radio]:hover{border-color:var(--ink-600);background:var(--ink-50)}
input[type=checkbox]::before{
  content:"";width:10px;height:10px;transform:scale(0);transition:transform .12s;
  background:#fff;
  clip-path:polygon(14% 44%,0 60%,39% 100%,100% 22%,85% 7%,37% 70%);
}
input[type=radio]::before{
  content:"";width:7px;height:7px;border-radius:50%;background:#fff;
  transform:scale(0);transition:transform .12s;
}
input[type=checkbox]:checked,input[type=radio]:checked{
  background:var(--ink-600);border-color:var(--ink-600);
}
input[type=checkbox]:checked::before,input[type=radio]:checked::before{transform:scale(1)}
input[type=checkbox]:disabled,input[type=radio]:disabled{
  background:var(--c-surface-3);border-color:var(--c-line);cursor:not-allowed;
}
input[type=checkbox]:focus-visible,input[type=radio]:focus-visible{
  outline:2px solid var(--ink-600);outline-offset:2px;
}


.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}
.card{
  position:relative;background:var(--c-surface);
  border:1px solid var(--c-line);border-radius:var(--r-lg);
  padding:var(--pad-card);box-shadow:var(--sh-1);
  transition:border-color .16s,box-shadow .16s;
}
.card:hover{border-color:var(--ink-300);box-shadow:var(--sh-2)}
.card h3{margin:0 0 2px;font-family:var(--font-serif);font-size:16.5px;color:var(--ink-900)}
/* 兜底：卡片里的文字一律允许在任意字符处断行。
   中文长句没有空格可断，不加这条就会横向撑破卡片
   （经营范围、超长文件名、无分隔的 URL 都会踩到）。 */
.card,.project-card,.template-card,.provider-row,.convert-job,.report-run{
  overflow-wrap:anywhere;min-width:0;
}
.card h3,.project-card h3,.template-card h3{overflow-wrap:anywhere}
.card-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:12px}
/* margin-top:auto 把按钮组压到卡片底部。
   卡片是 flex 列且被网格拉成等高，内容少的卡片若只给固定 margin，
   按钮就停在卡片中间——同一行里几张卡的按钮高低不齐（实测差 66px）。
   auto 吃掉剩余空间，所有卡片的按钮落在同一条基线上。 */
.card-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  margin-top:auto;padding-top:14px;border-top:1px solid var(--c-line-soft)}
/* 前提：卡片本身是 flex 列，margin-top:auto 才有剩余空间可吃。
   只作用于真的含按钮组的卡片——给所有 .card 加 flex 会改变
   内部元素的外边距折叠行为，影响到不需要贴底的卡片。 */
.card:has(> .card-actions),.template-card:has(> .card-actions){
  display:flex;flex-direction:column;
}

.kv-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:10px 18px}
.kv{display:flex;flex-direction:column;gap:3px;min-width:0}
.kv-k{font-size:11px;color:var(--c-faint);letter-spacing:.04em}
.kv-v{font-size:13.5px;color:var(--c-text-2);overflow-wrap:anywhere}

.empty{
  padding:52px 26px;text-align:center;color:var(--c-dim);
  border:1px dashed var(--c-line);border-radius:var(--r-lg);background:var(--c-surface);
}
.empty h3{font-family:var(--font-serif);font-size:17px;color:var(--ink-800);margin:0 0 8px}


/* 标签用于短标记。nowrap 保证「3A 级」这类短词不被折断，
   但 max-width + 长词换行是兜底：万一塞进长文本（经营范围曾被塞进来，
   直接撑破了项目卡片），它应该换行而不是溢出容器。 */
.tag{
  display:inline-flex;align-items:center;gap:4px;
  font-size:11.5px;font-weight:500;padding:2.5px 8px;border-radius:3px;
  white-space:nowrap;border:1px solid transparent;
  max-width:100%;overflow-wrap:anywhere;
}
/* 超过一行的标签放弃 nowrap，否则 max-width 也救不了 */
.tag:has(+ .tag),.project-meta .tag{white-space:normal;text-align:left}
.tag-ok{color:#14603f;background:#e6f4ec;border-color:#bfe0cd}
.tag-warn{color:var(--gold-700);background:var(--gold-50);border-color:var(--gold-300)}
.tag-err{color:#8f322b;background:#fbeae8;border-color:#f0c9c4}
.tag-llm{color:#513a80;background:#f0ebfa;border-color:#d9cef0}

/* 两种执行者必须一眼分开：蓝＝固定代码（确定性），紫＝大模型（概率性）。 */
.tag-code{color:#1e456f;background:#e8f0f9;border-color:#c6d8ec}

.dot-wrap{display:inline-flex;align-items:center;gap:7px;font-size:13px}
.dot{width:7px;height:7px;border-radius:50%;background:var(--ink-300);flex:none}
.dot-ok{background:var(--c-jade);box-shadow:0 0 0 3px rgba(31,122,82,.14)}
.dot-warn{background:var(--gold-500);box-shadow:0 0 0 3px rgba(201,162,39,.16)}
.dot-err{background:var(--c-danger);box-shadow:0 0 0 3px rgba(180,68,60,.14)}
.health-chip{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;color:var(--c-text-2);
  padding:5px 11px;border:1px solid var(--c-line);border-radius:99px;background:#fff}


/*
   class 由 JS 按 variant 拼成 badge-xlsx、badge-docx 等，底色必须逐个给全；
   漏一个就是白字白底，看不见。
*/
.badge{display:inline-flex;align-items:center;border:0;border-radius:3px;
  padding:0 9px;min-height:24px;font-size:11px;font-weight:600;
  color:#fff;cursor:pointer;transition:filter .14s}
.badge:hover{filter:brightness(1.1)}
.badge-xlsx,.badge-data{background:#17724a}
.badge-docx,.badge-formatted{background:#26558c}
.badge-pdf{background:#9c3a2a}
.badge-md{background:#5a4a8c}


.tbl{width:100%;border-collapse:collapse;font-size:13.5px;background:#fff}
.tbl th{
  padding:9px 12px;text-align:left;font-size:11px;font-weight:600;letter-spacing:.08em;
  color:var(--c-dim);text-transform:uppercase;
  border-bottom:1px solid var(--c-line);background:var(--c-surface-2);
}
.tbl td{padding:10px 12px;border-bottom:1px solid var(--c-line-soft);color:var(--c-text-2)}
.tbl tbody tr:hover td{background:var(--ink-50)}
.tbl-steps td{font-size:12.5px;vertical-align:top}


.bar{position:relative;height:6px;background:var(--ink-100);border-radius:99px;overflow:hidden}
.bar-fill{height:100%;width:0;border-radius:99px;
  background:linear-gradient(90deg,var(--ink-600),var(--gold-500));
  transition:width .3s cubic-bezier(.3,.8,.3,1)}
.spinner{display:inline-flex;align-items:center;gap:9px;color:var(--c-dim);font-size:13px}
.spinner-ring{width:15px;height:15px;border:1.5px solid var(--ink-100);border-top-color:var(--gold-500);
  border-radius:50%;animation:spin .75s linear infinite;flex:none}
@keyframes spin{to{transform:rotate(360deg)}}


.collapse{border:1px solid var(--c-line);border-radius:var(--r-md);margin:12px 0;overflow:hidden;background:#fff}
.collapse-head{
  width:100%;text-align:left;background:transparent;color:var(--c-text);
  border:0;padding:12px 14px;cursor:pointer;font-size:13.5px;
  display:flex;align-items:center;justify-content:space-between;gap:10px;transition:background .14s;
}
.collapse-head:hover{background:var(--c-surface-2)}
.collapse-body{display:none;padding:14px;border-top:1px solid var(--c-line-soft);background:var(--c-surface-2)}
.collapse.open .collapse-body{display:block}
.collapse.open .collapse-head{background:var(--c-surface-2);border-bottom:0}

.tabbar,.seg,.tabs{display:flex;gap:2px;border-bottom:1px solid var(--c-line);margin-bottom:18px;flex-wrap:wrap}
.seg{border:1px solid var(--c-line);border-radius:var(--r-md);padding:2px;gap:2px;display:inline-flex;margin-bottom:0;background:#fff}
.tab-item,.seg-item{
  padding:9px 15px;background:transparent;color:var(--c-dim);border:0;cursor:pointer;
  font-size:13.5px;position:relative;transition:color .14s;
}
.tab-item:hover,.seg-item:hover{color:var(--ink-800)}
.tab-item.active{color:var(--ink-900);font-weight:500}
.tab-item.active::after{content:"";position:absolute;left:10px;right:10px;bottom:-1px;height:2px;background:var(--gold-500)}
.seg-item.active{background:var(--ink-700);color:#fff;border-radius:var(--r-sm)}
.tab-body{padding-top:4px}


.modal-shade{
  position:fixed;inset:0;z-index:100;display:flex;align-items:center;justify-content:center;
  padding:24px;background:rgba(14,26,46,.42);backdrop-filter:blur(3px);animation:fade .16s both;
}
@keyframes fade{from{opacity:0}to{opacity:1}}
/* 弹窗自身不滚动（overflow:hidden + flex 列），滚动交给 .modal-body。
   否则标题栏和关闭按钮会随长内容一起滚走，看报告时找不到关闭入口。 */
.modal{
  display:flex;flex-direction:column;
  width:min(620px,100%);max-height:88vh;overflow:hidden;background:#fff;
  border:1px solid var(--c-line);border-top:3px solid var(--gold-500);
  border-radius:var(--r-lg);box-shadow:0 18px 48px rgba(14,26,46,.24);
  animation:pop .2s cubic-bezier(.2,.8,.3,1) both;
}
@keyframes pop{from{opacity:0;transform:translateY(10px) scale(.99)}to{opacity:1;transform:none}}
.modal-wide .modal{width:min(1180px,100%)}
.modal-head{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:16px 20px;border-bottom:1px solid var(--c-line);flex:none;background:#fff}
.modal-head h2{margin:0;font-size:17px;font-family:var(--font-serif)}
/* 标题栏右侧的按钮组（下载、关闭等），水平排列 */
.modal-head-actions{display:flex;align-items:center;gap:8px}
.modal-body{padding:20px;overflow:auto;flex:1;min-height:0}
.modal-actions{display:flex;justify-content:flex-end;gap:9px;margin-top:20px;
  padding-top:15px;border-top:1px solid var(--c-line-soft);flex-wrap:wrap}

.toast-stack{position:fixed;right:20px;bottom:20px;z-index:200;display:flex;flex-direction:column;gap:9px}
.toast{
  padding:11px 15px;border-radius:var(--r-md);font-size:13.5px;max-width:400px;
  background:#fff;border:1px solid var(--c-line);border-left:3px solid var(--ink-400);
  box-shadow:var(--sh-3);animation:slide .22s cubic-bezier(.2,.8,.3,1) both;color:var(--c-text);
}
@keyframes slide{from{opacity:0;transform:translateX(16px)}to{opacity:1;transform:none}}
.toast-ok{border-left-color:var(--c-jade)}
.toast-err{border-left-color:var(--c-danger)}
.toast-warn{border-left-color:var(--gold-500)}

.must-change-bar{
  display:flex;align-items:center;gap:12px;padding:10px 28px;font-size:13px;
  color:var(--gold-700);background:var(--gold-50);border-bottom:1px solid var(--gold-300);
}
.notice-warn,.warn-box{
  padding:12px 14px;border-radius:var(--r-md);font-size:13px;line-height:1.7;
  color:#7a5c10;background:var(--gold-50);
  border:1px solid var(--gold-300);border-left:3px solid var(--gold-500);
}
.method-note{font-size:12px;color:var(--c-faint);line-height:1.7;margin-top:8px}


.login-page{
  min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px;
  background:linear-gradient(160deg,var(--ink-900) 0%,var(--ink-700) 58%,var(--ink-800) 100%);
}
.login-card{
  width:min(400px,92vw);padding:36px 32px;text-align:center;background:#fff;
  border-radius:var(--r-xl);box-shadow:0 24px 60px rgba(8,16,30,.42);
  border-top:3px solid var(--gold-500);
}
.login-card h1{font-family:var(--font-serif);font-size:24px;margin:0 0 6px;letter-spacing:.03em;color:var(--ink-900)}
.login-card .muted{margin:0 0 24px}
.login-card .field{text-align:left;margin-bottom:16px}
.login-card .btn{width:100%;justify-content:center;padding:11px}


.project-card{
  position:relative;background:#fff;border:1px solid var(--c-line);
  border-radius:var(--r-lg);padding:var(--pad-card);box-shadow:var(--sh-1);
  display:flex;flex-direction:column;gap:12px;
  transition:border-color .16s,box-shadow .16s;
}
.project-card:hover{border-color:var(--ink-300);box-shadow:var(--sh-2)}
.project-card::before{
  content:"";position:absolute;left:0;top:0;width:24px;height:3px;
  background:var(--gold-500);border-radius:var(--r-lg) 0 0 0;
}
.project-card h3{margin:0;font-family:var(--font-serif);font-size:17px;color:var(--ink-900);line-height:1.35}
.project-card .stats{display:flex;gap:14px;flex-wrap:wrap;font-size:12.5px;color:var(--c-text-2)}
.project-card .stats b{color:var(--gold-600);font-weight:600}
/* 用 flex 而不是等分网格：这里只有 1-2 个短标签，
   等分网格会把它们拉成两个半宽的空盒子。 */
.project-meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:12.5px}
/* 经营范围这类长文本：限高并在末行收省略号，卡片高度才不会被一段话带跑。
   完整内容在「编辑」里可见，卡片上只需给出概貌。 */
.project-business{
  margin:0;font-size:12.5px;line-height:1.7;overflow-wrap:anywhere;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden;
}

.enrich-head{display:flex;align-items:center;gap:14px;margin-bottom:14px}
/* 关键数字统一用 gold-700。gold-600 在白卡上仅 3.66:1，
   而 .job-pct 是 21px，够不上 WCAG 大字豁免的 24px 门槛，
   必须按正文标准做到 4.5:1（gold-700 为 6.16:1）。 */
.enrich-pct{font-family:var(--font-serif);font-size:30px;color:var(--gold-700);min-width:72px;line-height:1}
.enrich-log{
  max-height:190px;overflow:auto;font-family:var(--font-mono);font-size:12px;line-height:1.75;
  color:var(--c-text-2);background:var(--c-surface-2);
  border:1px solid var(--c-line-soft);border-radius:var(--r-md);padding:11px 13px;
}
.enrich-step{padding:2px 0}


.upload-panel{margin-bottom:22px}
.dropzone{
  border:1.5px dashed var(--c-line);border-radius:var(--r-lg);padding:30px 24px;
  text-align:center;color:var(--c-dim);background:#fff;
  transition:border-color .16s,background .16s,color .16s;
}
.dropzone:hover{border-color:var(--ink-300)}
.dropzone.over{border-color:var(--gold-500);background:var(--gold-50);color:var(--ink-800)}
.dropzone p{margin:.25em 0;font-size:13.5px}
.upload-actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:14px}
.file-input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.upload-actions .bar{flex:1;min-width:130px}
.pending-tree{margin-top:16px}
.pending-head{display:flex;justify-content:space-between;align-items:center;padding:9px 0;border-bottom:1px solid var(--c-line)}
.pending-list{max-height:260px;overflow:auto;margin-top:4px}
.pending-row{display:grid;grid-template-columns:1fr auto auto;gap:10px;align-items:center;
  padding:6px 2px;border-bottom:1px solid var(--c-line-soft);font-size:13px}
.pending-path{font-family:var(--font-mono);font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.tree{font-size:13.5px}
.tree-box{border:1px solid var(--c-line);border-radius:var(--r-lg);overflow:hidden;background:#fff}
.tree-row{
  display:grid;grid-template-columns:auto 1fr auto auto auto;gap:10px;align-items:center;
  padding:8px 11px;border-bottom:1px solid var(--c-line-soft);transition:background .12s;
}
.tree-row:hover{background:var(--ink-50)}
.tree-dir{cursor:pointer;font-weight:500}
.tree-caret{width:13px;color:var(--c-faint);text-align:center;transition:transform .16s}
.tree-node.open>.tree-row .tree-caret{transform:rotate(90deg)}
.tree-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tree-meta{font-size:11.5px;white-space:nowrap;color:var(--c-faint)}
.tree-actions{display:flex;gap:5px;opacity:.4;transition:opacity .14s}
.tree-row:hover .tree-actions,.tree-actions:focus-within{opacity:1}
.tree-node:not(.open)>.tree-children{display:none}
.tree-children{padding-left:16px;border-left:1px solid var(--c-line-soft);margin-left:11px}
.tree-icon{
  width:19px;height:19px;line-height:19px;text-align:center;border-radius:3px;
  font-size:10px;font-weight:700;color:#fff;background:var(--ink-500);flex:none;
}
.ft-sheet{background:#17724a}.ft-doc{background:#26558c}.ft-pdf{background:#9c3a2a}.ft-img{background:#5a4a8c}
.tree-badges{display:flex;gap:4px}
.tree-file{display:flex;align-items:center;gap:9px;padding:7px 8px;min-height:32px;
  border-radius:var(--r-sm);cursor:pointer;font-size:13px}
.tree-file:hover{background:var(--ink-50)}
/* 已勾选的行给一点底色与左侧标记：一屏几十行时，
   光靠 17px 的方框很难快速看出"我到底选了哪几个"。 */
.tree-file:has(input:checked){background:var(--gold-50);box-shadow:inset 2px 0 0 var(--gold-500)}
.tree-file:has(input:checked):hover{background:var(--gold-100)}



.convert-job{
  background:#fff;border:1px solid var(--c-line);border-radius:var(--r-lg);
  padding:var(--pad-card);margin-bottom:13px;box-shadow:var(--sh-1);
}
.job-now{display:flex;align-items:center;gap:12px;margin-bottom:10px;flex-wrap:wrap}
.job-pct{font-family:var(--font-serif);font-size:21px;color:var(--gold-700);min-width:56px}
.job-msg{font-size:13px;color:var(--c-text-2);flex:1;min-width:0}
.job-part{font-size:11.5px;color:var(--c-faint)}
.job-detail{margin-top:13px;padding-top:13px;border-top:1px solid var(--c-line-soft)}
.xcheck-item{padding:8px 0;border-bottom:1px solid var(--c-line-soft);font-size:13px}
.stage-mark{display:inline-flex;align-items:center;gap:5px;font-size:12px;color:var(--c-dim)}


.analysis-files{
  max-height:300px;overflow:auto;border:1px solid var(--c-line);
  border-radius:var(--r-lg);padding:11px;background:#fff;
}

/* 模型选择区：参考 demoglm 改成固定 2 列（宽屏 3 列）的带框卡片。
   auto-fill 在 1254px 下能铺 4 列，22 个模型看起来很密，
   而且参考站的确切布局就是 2/3 列。 */
.analysis-targets{
  display:grid;grid-template-columns:repeat(2,1fr);gap:8px;
}
@media (min-width:1280px){
  .analysis-targets{grid-template-columns:repeat(3,1fr)}
}
/* 每张模型卡是带框的可点区域：边框 + 圆角 + 内边距，选中时描金边配金底。
   参考站的确切写法: border px-3 py-2 rounded-md。 */
.model-choice{
  display:flex;align-items:center;gap:8px;padding:8px 12px;min-height:40px;
  cursor:pointer;border:1px solid var(--c-line-soft);border-radius:var(--r-md);
  transition:border-color .15s,background .15s;
  background:#fff;min-width:0;
}
.model-choice:hover{background:var(--ink-50);border-color:var(--c-line)}
.model-choice:has(input:checked){
  background:var(--gold-50);border-color:var(--gold-400);
  box-shadow:none;  /* 覆盖掉全局 has(input:checked) 给的左侧标记 */
}
/* 厂商名小号浅色作前缀；模型名是主信息，字重 500 够抓眼；
   视觉模型的小标注用 gold-700（6.16:1）而不是 gold-600（3.66:1），
   11px 正文按 WCAG AA 要求至少 4.5:1；都收 nowrap + ellipsis 防挤破。 */
.model-vendor{font-size:12.5px;color:var(--c-dim);flex:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.model-name{font-size:13px;font-weight:500;color:var(--ink-900);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.model-vision{font-size:11px;font-weight:600;color:var(--gold-700);flex:none;white-space:nowrap}
/* 全选/清空和已选计数放模型网格下方，小字浅色，按钮与文字在一行。 */
.model-tools{display:flex;align-items:center;gap:10px;margin-top:10px;font-size:12.5px;color:var(--c-dim)}
.model-count{flex:1}

.pick-group{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:12px 0 5px;
  padding-top:9px;border-top:1px solid var(--c-line-soft);font-size:12.5px;color:var(--c-text-2)}
.pick-group:first-child{margin-top:0;padding-top:0;border-top:0}
.pick-group strong{font-weight:600;color:var(--ink-800)}
.pick-hint{font-size:11.5px;color:var(--c-faint)}
.pick-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pick-note{font-size:11px;flex:none}
.pick-acts{display:flex;gap:6px;margin-top:11px;padding-top:9px;border-top:1px solid var(--c-line-soft)}

.analysis-progress{
  background:#fff;border:1px solid var(--c-line);border-left:3px solid var(--gold-500);
  border-radius:var(--r-lg);padding:var(--pad-card);margin-bottom:18px;box-shadow:var(--sh-1);
}
.analysis-current{display:flex;align-items:center;gap:14px;margin-bottom:13px;flex-wrap:wrap}
.analysis-percent{font-family:var(--font-serif);font-size:32px;color:var(--gold-700);line-height:1;min-width:80px}
.analysis-stages{display:flex;gap:6px;flex-wrap:wrap;margin:13px 0}
.analysis-stage{
  font-size:11.5px;padding:3px 9px;border-radius:3px;
  color:var(--c-dim);background:var(--c-surface-2);border:1px solid var(--c-line-soft);
}
.analysis-stage.active{color:var(--gold-700);background:var(--gold-50);border-color:var(--gold-300)}
.analysis-stage.done{color:#14603f;background:#e6f4ec;border-color:#bfe0cd}
.analysis-models{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:10px;margin-top:14px}
.model-row{background:var(--c-surface-2);border:1px solid var(--c-line-soft);
  border-radius:var(--r-md);padding:var(--pad-card-tight);font-size:12.5px}
.model-row-head{display:flex;align-items:center;justify-content:space-between;gap:9px;margin-bottom:8px}
.model-rows{display:flex;flex-direction:column;gap:8px}

/* 深底浅字：它是机器输出，与业务内容在视觉上分开。 */
.analysis-log{
  max-height:240px;overflow:auto;font-family:var(--font-mono);font-size:11.5px;line-height:1.8;
  color:#c6d4e5;background:var(--ink-900);border-radius:var(--r-md);
  padding:12px 14px;margin-top:14px;
}


.report-run{
  background:#fff;border:1px solid var(--c-line);border-radius:var(--r-lg);
  margin-bottom:15px;overflow:hidden;box-shadow:var(--sh-1);
}
.report-run-body{padding:var(--pad-card)}
.report-score{font-family:var(--font-serif);font-size:27px;color:var(--gold-700);
  line-height:1;display:inline-flex;align-items:baseline;gap:3px}
.report-score small{font-size:12px;color:var(--c-faint);font-family:var(--font-sans)}
.history-child{padding-left:19px;border-left:3px solid var(--gold-300);background:var(--gold-50)}
.history-acts{display:flex;gap:7px;flex-wrap:wrap}
.history-note{font-size:12px;color:var(--c-faint);margin-top:5px}
.revise-box{margin-top:14px;padding-top:14px;border-top:1px dashed var(--c-line)}
.archive-link{font-size:12.5px}


.template-group{margin-bottom:26px}
.template-group>h2{
  font-family:var(--font-serif);font-size:17px;margin:0 0 12px;padding-bottom:8px;
  border-bottom:1px solid var(--c-line);position:relative;
}
.template-group>h2::after{content:"";position:absolute;left:0;bottom:-1px;width:32px;height:2px;background:var(--gold-500)}
/* 用 auto-fill 而不是 auto-fit：auto-fit 会把空轨道折叠掉，
   于是只有一个模板的分组里，那张卡片会被拉满整行宽（实测 1152px），
   又宽又空。auto-fill 保留空轨道，单卡只占一列宽。 */
.template-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:14px}
.template-card{
  border:1px solid var(--c-line);border-radius:var(--r-lg);padding:var(--pad-card);background:#fff;
  display:flex;flex-direction:column;gap:9px;box-shadow:var(--sh-1);
  transition:border-color .16s,box-shadow .16s;
}
.template-card:hover{border-color:var(--ink-300);box-shadow:var(--sh-2)}
.template-card h3{margin:0;font-family:var(--font-serif);font-size:16px;color:var(--ink-900)}
.template-suggested{border-color:var(--gold-400);box-shadow:0 0 0 1px var(--gold-300),var(--sh-2)}
.template-form{margin-top:13px;padding-top:13px;border-top:1px solid var(--c-line-soft);display:flex;flex-direction:column;gap:11px}
.template-preview{font-size:13px;color:var(--c-text-2);line-height:1.7}
.prompt-content{
  font-family:var(--font-mono);font-size:11.5px;line-height:1.75;white-space:pre-wrap;
  color:var(--c-text-2);background:var(--c-surface-2);border:1px solid var(--c-line-soft);
  border-radius:var(--r-md);padding:11px 13px;max-height:130px;overflow:hidden;
}
.outline-editor{font-family:var(--font-mono);font-size:12px;line-height:1.75}
.outline-preview{
  border:1px solid var(--c-line);border-radius:var(--r-md);padding:14px 16px;
  background:var(--c-surface-2);max-height:320px;overflow:auto;font-size:13px;line-height:1.75;
}
.outline-preview h1{font-family:var(--font-serif);font-size:17px;color:var(--gold-600);margin:.4em 0}
.outline-preview h2{font-family:var(--font-serif);font-size:15px;color:var(--ink-700);margin:.5em 0 .3em}
.outline-preview h3{font-size:13.5px;margin:.5em 0 .3em;color:var(--ink-800)}
.suggestion-card{
  border-left:3px solid var(--gold-500);background:var(--gold-50);color:#7a5c10;
  padding:var(--pad-card-tight);border-radius:0 var(--r-md) var(--r-md) 0;font-size:13px;line-height:1.7;
}


.provider-list{display:flex;flex-direction:column;gap:11px}
.provider-row{background:#fff;border:1px solid var(--c-line);border-radius:var(--r-lg);
  overflow:hidden;box-shadow:var(--sh-1)}
.provider-summary{display:flex;align-items:center;gap:13px;padding:14px 17px;flex-wrap:wrap}
.provider-ident{display:flex;flex-direction:column;gap:3px;flex:1;min-width:180px}
.provider-ident strong{font-size:14.5px;font-weight:600;color:var(--ink-900)}
.provider-actions{display:flex;gap:7px;flex-wrap:wrap}
.provider-edit{padding:0 17px 17px}
.provider-edit-host{border-top:1px solid var(--c-line-soft);margin-top:2px;padding-top:15px}
.model-table{width:100%;border-collapse:collapse;font-size:13px;margin-top:11px}
.model-table th{font-size:11px;letter-spacing:.07em;color:var(--c-dim);text-transform:uppercase;
  padding:8px 10px;text-align:left;border-bottom:1px solid var(--c-line);background:var(--c-surface-2)}
.model-table td{padding:9px 10px;border-bottom:1px solid var(--c-line-soft);color:var(--c-text-2)}
.model-table-head{display:flex;align-items:center;justify-content:space-between;gap:11px;margin-top:18px}
.model-test-result{font-size:12.5px;margin-top:9px;line-height:1.7}


.markdown{font-size:14px;line-height:1.85;color:var(--c-text-2)}
.markdown h1,.markdown h2,.markdown h3{font-family:var(--font-serif);color:var(--ink-900)}
.markdown h1{font-size:22px;margin:1.1em 0 .5em}
.markdown h2{font-size:18px;margin:1.3em 0 .5em;padding-bottom:6px;border-bottom:1px solid var(--c-line)}
.markdown h3{font-size:15.5px;margin:1.2em 0 .4em}
.markdown code{font-family:var(--font-mono);font-size:12.5px;background:var(--ink-50);
  padding:1px 5px;border-radius:3px;color:#8a5f0a}
.markdown blockquote{margin:1em 0;padding:2px 0 2px 15px;border-left:3px solid var(--gold-400);color:var(--c-dim)}
.markdown table{border-collapse:collapse;width:100%;font-size:13px;margin:1em 0}
.markdown th,.markdown td{border:1px solid var(--c-line);padding:8px 11px;text-align:left}
.markdown th{background:var(--c-surface-2);color:var(--ink-800);font-weight:600}
.markdown img{max-width:100%;border-radius:var(--r-md);border:1px solid var(--c-line)}


/* 工具条吸顶：文件名、视图切换、下载入口在长文档里必须始终可见。
   它在 .modal-body 内部，所以 sticky 参照的是 .modal-body 的滚动。
   负 margin + 等量 padding 让它吸顶时铺满整个宽度，不露出下层内容。 */
.viewer-tools{
  position:sticky;top:0;z-index:6;display:flex;align-items:center;gap:11px;flex-wrap:wrap;
  margin:-20px -20px 0;padding:13px 20px;background:#fff;
  border-bottom:1px solid var(--c-line);
}
/*
   表格查看器的第二排工具条（放大/缩小/100%/查找）。
   ⚠ 它落在 .viewer-stage 内部，而后者背景是 var(--ink-800) 深藏蓝。
   之前这里没有背景色也没有文字色，于是 .btn-ghost 的 background:transparent
   + 继承来的深色文字，变成"深蓝字压在深蓝底上"，几乎看不见。
   现在显式给白底 + 深色文字，并 sticky 吸顶（父容器由 JS 设成 flex 列，
   表格滚动被限制在 .xl-stage 内，这条吸顶是双保险）。
*/
.viewer-subtools{
  position:sticky;top:0;z-index:5;flex:none;
  display:flex;align-items:center;gap:9px;flex-wrap:wrap;font-size:12.5px;
  padding:8px 10px;margin-bottom:8px;
  background:#fff;color:var(--ink-900);
  border:1px solid var(--c-line);border-radius:var(--r-md);
}
/* 按钮在白底上要有明确的深色文字与可见描边，不能依赖继承 */
.viewer-subtools .btn{background:#fff;color:var(--ink-900);border-color:var(--c-line)}
.viewer-subtools .btn:hover{background:var(--c-surface-3);color:var(--ink-900)}
/* 提示文字用中等灰，在白底上够清楚（--c-faint 是给深底配的，太浅） */
.viewer-subtools .xl-hint{color:var(--c-dim)}
.viewer-name{font-size:14px;font-weight:500;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;color:var(--ink-900);flex:1;min-width:0}
.viewer-body{display:flex;flex-direction:column;min-height:0}
/* 工具条之后的内容要把负 margin 补回来，否则会顶到弹窗边缘 */
.viewer-tools+*{margin-top:16px}

.viewer-stage{flex:1;min-height:0;overflow:auto;background:var(--ink-800);
  border:1px solid var(--ink-700);border-radius:var(--r-md)}
/*
   查看器内部（纸张、表格、PDF）一律白底黑字：报表底色、边框、红色负数在
   深底上会失真，「像纸」是唯一验收标准。浅色主题下白纸不再自然突出，
   改用深色台面 + 描边 + 投影衬托。
*/
.viewer-text{flex:1;overflow:auto;background:#fff;color:#111;padding:22px;margin:0;
  font-family:var(--font-mono);font-size:12.5px;line-height:1.8;white-space:pre-wrap}
.viewer-image-wrap{display:flex;align-items:center;justify-content:center;padding:20px;background:var(--ink-800)}
.viewer-image{max-width:100%;box-shadow:0 6px 24px rgba(0,0,0,.4);background:#fff}

.paper{
  width:794px;max-width:100%;min-height:400px;padding:58px 70px;
  background:#fff;color:#111;margin:24px auto;
  border:1px solid var(--c-line);box-shadow:0 6px 28px rgba(16,30,54,.16);
  font-family:var(--font-serif);font-size:15px;line-height:1.9;
}
.paper h1,.paper h2,.paper h3{font-family:var(--font-serif);color:#111}
.paper h1{font-size:24px;text-align:center;margin:0 0 1.2em}
.paper h2{font-size:19px;margin:1.5em 0 .6em;padding-bottom:5px;border-bottom:1px solid #ddd}
.paper h3{font-size:16px;margin:1.2em 0 .4em}
.paper table{border-collapse:collapse;width:100%;font-size:13px;margin:1em 0;font-family:var(--font-sans)}
.paper table td,.paper table th,.doc-tbl td,.doc-tbl th{border:1px solid #9aa4a0;padding:6px 9px;vertical-align:top}

/* 表头显式写深色文字，不要依赖父级继承，报告表格会被复用到别处。 */
.paper table th,.doc-tbl th{background:#eef1ef;color:#111;font-weight:600}
.doc-tbl td{color:#111}
.doc-tbl{border-collapse:collapse}
.paper img{max-width:100%}
.paper code{font-family:var(--font-mono);font-size:12.5px;background:#f0f2f0;color:#111;padding:1px 4px}
.paper pre{background:#f4f5f4;color:#111;padding:12px;overflow:auto;font-size:12px}
.paper blockquote{margin:1em 0;padding-left:14px;border-left:3px solid var(--gold-500);color:#444}


.xl-wrap{display:flex;flex-direction:column;min-height:0;overflow:hidden}
.xl-pane{display:flex;flex-direction:column;min-height:0;flex:1}
.xl-stage{flex:1;min-height:0;overflow:auto;background:#fff;border:1px solid #c3ccc7;border-radius:var(--r-md)}
.xl-sheet{border-collapse:separate;border-spacing:0;background:#fff;color:#111;font-size:12.5px;font-family:var(--font-sans)}
.xl-sheet td,.xl-sheet th{border-right:1px solid #d8ded9;border-bottom:1px solid #d8ded9;
  padding:4px 8px;white-space:pre;color:#111}
.xl-sheet th{background:#eff2f0;color:#333;font-weight:600;position:sticky;top:0;z-index:4;
  font-size:11.5px;text-align:center}
.xl-sheet .xl-rowhead{background:#eff2f0;color:#333;position:sticky;left:0;z-index:3;
  text-align:center;font-size:11px;font-weight:600}
.xl-sheet .frz-row{position:sticky;z-index:3;background:#fff}
.xl-sheet .frz-col{position:sticky;z-index:2;background:#fff}
.xl-sheet tbody tr:hover td{background:#f5f9f6}
.xl-sheet td.xl-num{text-align:right;font-variant-numeric:tabular-nums}
.xl-sheet td.xl-neg{color:#c00}
.xl-sheet td.xl-hit{background:#fff6d5!important;color:#111}
.xl-sheet td.xl-hit-cur{background:#ffd966!important;color:#111;outline:2px solid var(--gold-500)}
.xl-tabbar{display:flex;gap:2px;overflow-x:auto;padding:6px 0 0;border-top:1px solid var(--c-line)}
.xl-tab{padding:6px 13px;font-size:12.5px;border:1px solid var(--c-line);border-bottom:0;
  border-radius:var(--r-md) var(--r-md) 0 0;background:var(--c-surface-2);color:var(--c-dim);
  cursor:pointer;white-space:nowrap}
.xl-tab.active{background:#fff;color:var(--ink-900);font-weight:600}
.xl-finder{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.xl-hint{font-size:12px;color:var(--c-faint)}

.pdf-pages{padding:20px;text-align:center;background:var(--ink-800)}
.pdf-page{position:relative;display:inline-block;margin:0 auto 18px;
  box-shadow:0 6px 26px rgba(0,0,0,.42);background:#fff}
.pdf-pageno{font-size:11.5px;color:var(--ink-300);margin-bottom:6px}
.pdf-jump{display:flex;align-items:center;gap:7px;font-size:12.5px}


@media(max-width:1160px){
  .app-shell{grid-template-columns:62px 1fr}
  .sidebar{padding:20px 7px}
  .brand{font-size:0;margin-bottom:18px;text-align:center}
  .brand::first-letter{font-size:20px}
  .brand::after{margin:10px auto 0}
  .side-nav h3,.project-picker{display:none}
  .nav-link{font-size:0;text-align:center;padding:11px 0}
  .nav-link::first-letter{font-size:17px}
  .nav-link.active::before{display:none}
}
@media(max-width:760px){
  .app-shell{display:block}
  .sidebar{display:none}
  .topbar{padding:0 16px;height:54px}
  .page-content{padding:20px 16px 44px}
  .page-title h1,.page-head h1{font-size:21px}
  .form-grid,.field-grid{grid-template-columns:1fr}
  .modal{max-height:94vh}
  .analysis-targets{grid-template-columns:1fr}
  .must-change-bar{padding:10px 16px}
  .paper{padding:32px 22px}
}
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important}
}
@media print{
  .sidebar,.topbar,.viewer-tools,.card-actions,.toast-stack{display:none!important}
  body,.page-content{background:#fff;color:#000}
  .paper{box-shadow:none;border:0;margin:0;width:auto}
}

/* 报告页里运行中记录的进度详情 */
.run-detail{
  border:1px solid var(--line,#e6ecf3);border-radius:10px;
  padding:12px 14px;margin-bottom:14px;background:var(--ink-50,#f2f6fa);
}
.run-detail-stage{font-size:13px;margin-bottom:10px}
.run-detail-label{
  font-size:11px;letter-spacing:.08em;color:var(--ink-400,#5a7ba6);
  margin:10px 0 6px;
}
.run-detail-models{display:grid;gap:5px}
/* 三列定宽：模型名 / 状态 / 进度条，让多行之间竖直对齐好扫读。 */
.run-model-row{
  display:grid;grid-template-columns:1fr 56px 84px;gap:10px;align-items:center;
  font-size:12px;
}
.run-model-name{
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-variant-numeric:tabular-nums;
}
.run-model-state{font-size:11px;color:var(--ink-400,#5a7ba6)}
.run-model-row.is-running .run-model-state{color:var(--gold-600,#a97f16);font-weight:600}
.run-model-row.is-success .run-model-state{color:#1a7f52}
.run-model-row.is-failed  .run-model-state{color:#b3261e}
.run-model-row .bar{height:5px;border-radius:99px;background:rgba(0,0,0,.08);overflow:hidden}
.run-model-row .bar-fill{display:block;height:100%;background:var(--gold-500,#c9a227)}
.run-detail-steps{max-height:190px;overflow-y:auto}

/* 进度详情里的百分比：右对齐、等宽数字，刷新时不会因位数变化而抖动。 */
.run-detail-stage{display:flex;align-items:baseline;gap:8px}
.run-detail-pct{
  font-variant-numeric:tabular-nums;font-weight:600;
  color:var(--gold-600,#a97f16);font-size:12px;
}
