
:root{
  /* 20261103f · 参考小白说标 v8：橙色暖色系 + 玻璃拟态 + 大圆角 */
  --ink:#202124;
  --text:#202124;
  --secondary:#85878d;
  --tertiary:#aeb0b5;
  --muted:#85878d;
  --soft:#aeb0b5;
  --page:#eef0f3;
  --surface:#ffffff;
  --surface-subtle:#f5f5f6;
  --paper:#f2f3f5;
  --line:rgba(70,74,82,.10);
  --line-strong:rgba(70,74,82,.16);
  --orange:#f47b35;
  --orange2:#ff9b5e;
  --orange-deep:#ef702d;
  --orange-hover:#ef702d;
  --blue:#f47b35;
  --blue-hover:#ef702d;
  --red:#e05a52;
  --green:#69a88d;
  --purple:#af52de;
  --white:rgba(255,255,255,.76);
  --glass:rgba(255,255,255,.62);
  --radius:24px;
  --radius-lg:32px;
  --radius-sm:13px;
  --sidebar:228px;
  --shadow:0 18px 55px rgba(44,49,59,.08),inset 0 1px 0 rgba(255,255,255,.9);
  --shadow-hover:0 12px 24px rgba(238,117,52,.26);
}
/* 玻璃拟态卡片：半透明 + 白边 + blur 24px（参考小白说标 .glass） */
.glass{
  background:var(--glass);
  border:1px solid rgba(255,255,255,.8);
  box-shadow:var(--shadow);
  backdrop-filter:blur(24px);
  -webkit-backdrop-filter:blur(24px);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;
  color:var(--text);
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","SF Pro Display","PingFang SC","HarmonyOS Sans SC","Microsoft YaHei",sans-serif;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  background:var(--page);
  /* 三层径向渐变底纹（参考小白说标 .app-bg） */
  background-image:
    radial-gradient(ellipse at 12% 8%,rgba(255,255,255,.96),transparent 35%),
    radial-gradient(ellipse at 80% 18%,rgba(222,226,235,.72),transparent 36%),
    radial-gradient(ellipse at 55% 100%,rgba(255,255,255,.8),transparent 45%),
    linear-gradient(135deg,#eff0f2,#e7e9ee 58%,#f5f5f6);
  background-attachment:fixed;
}
button,input,select,textarea{font:inherit}
button{color:inherit}
a{color:inherit;text-decoration:none}
.hidden{display:none!important}
/* `hidden` 属性必须真的隐藏。浏览器默认样式表里的 [hidden]{display:none} 优先级
   低于任何作者样式，`.button{display:inline-flex}` 一挂上去，带 hidden 的按钮
   就照样显示 —— 「清除勾选」在没勾选时也杵在工具栏上，点了没反应。 */
[hidden]{display:none!important}
.muted{color:var(--secondary)}
.small{font-size:12px}
.hairline{height:1px;background:var(--line)}
.icon{
  width:19px;height:19px;display:inline-grid;place-items:center;flex:0 0 auto;
}
.icon svg{
  width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:1.65;
  stroke-linecap:round;stroke-linejoin:round;
}
.brand{display:flex;align-items:center;gap:9px;font-size:15px;font-weight:600;letter-spacing:-.015em}
.brand-mark{
  width:29px;height:29px;border-radius:11px;display:grid;place-items:center;
  background:linear-gradient(145deg,#ffad71,#f16f2b);color:#fff;font-size:13px;font-weight:600;
  box-shadow:0 5px 14px rgba(241,111,43,.24);
}
.button{
  appearance:none;border:0;border-radius:999px;padding:10px 17px;
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  font-size:13px;font-weight:500;cursor:pointer;transition:background .16s ease,opacity .16s ease,transform .2s ease,box-shadow .2s ease;
}
/* 主按钮：橙色渐变 + 橙色光晕（参考小白说标 .primary） */
.button.primary{
  background:linear-gradient(135deg,#ff9b5d,#ef702d);
  color:#fff;font-weight:600;
  box-shadow:0 8px 20px rgba(238,117,52,.20);
}
.button.primary:hover{
  transform:translateY(-1px);
  box-shadow:0 12px 24px rgba(238,117,52,.26);
}
.button.secondary{
  background:rgba(255,255,255,.68);
  border:1px solid rgba(255,255,255,.9);
  color:#333;
}
.button.secondary:hover{background:#fff}
/* 邮箱验证码：输入框与“获取验证码”按钮同一行 */
.code-row{display:flex;gap:10px}
.code-row .input{flex:1;min-width:0}
.code-row .button{flex:0 0 auto;white-space:nowrap}
.button.text{background:transparent;color:var(--blue);padding-inline:7px}
.button.danger{background:#fff0ef;color:#d70015}
.button:disabled{opacity:.4;cursor:not-allowed}
.badge{
  display:inline-flex;align-items:center;height:23px;padding:0 9px;border-radius:999px;
  font-size:11px;font-weight:500;background:#f1f1f3;color:var(--secondary);
}
.badge.blue{background:#edf6ff;color:#0066cc}
.badge.planned{background:#f2f2f4;color:#77777d}
.card{
  background:var(--glass);border:1px solid rgba(255,255,255,.8);
  box-shadow:var(--shadow);border-radius:var(--radius);
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
}
.topbar{
  height:52px;position:sticky;top:0;z-index:30;
  background:rgba(255,255,255,.62);border-bottom:1px solid rgba(255,255,255,.8);
  box-shadow:var(--shadow);
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
  display:flex;align-items:center;justify-content:space-between;
  padding:0 max(22px,calc((100vw - 1180px)/2));
}
.topnav{display:flex;align-items:center;gap:28px;font-size:12px;color:#424245}
.topnav a:hover{color:#000}
.top-actions{display:flex;align-items:center;gap:8px}
.link-button{border:0;background:transparent;padding:8px;cursor:pointer;font-size:12px;color:#424245}
/* ===== landing 参考小白说标：hero 双栏 + 产品框轮播 + feature strip + why strip ===== */
.pill{
  display:inline-flex;align-items:center;gap:6px;border-radius:99px;
  padding:6px 10px;background:rgba(255,255,255,.7);color:#777;font-size:12px;
}
.dot{width:7px;height:7px;border-radius:50%;display:inline-block;background:#b7bbc2}
.dot.orange{background:var(--orange)}.dot.green{background:var(--green)}.dot.red{background:#dc7772}
.landing{background:transparent;min-height:100vh}
/* 两栏宽度与列间距要一起收：上一版 `1fr / 1.05fr + gap:5% + p{max-width:500}`
   在三处各留一段空白（文字右侧、列间、轮播两侧），叠起来近 230px —— 视觉上
   文案和轮播就是「分居屏幕两头」。这里把文案列按内容宽度收紧、列间距压到
   44px 上限、轮播铺满右列，空隙整体落到 100px 以内。 */
.hero{
  padding:64px 3% 52px;display:grid;
  grid-template-columns:minmax(0,620px) minmax(0,1fr);
  align-items:center;gap:clamp(18px,2.4vw,40px);min-height:480px;text-align:left;
}
.hero-copy{max-width:620px}
.hero-copy h1{
  margin:14px 0 0;font-size:clamp(40px,5vw,54px);line-height:1.2;letter-spacing:-1.5px;
  font-weight:600;
}
.hero-copy h1 span{display:block;font-size:clamp(28px,3.5vw,36px);letter-spacing:-1px;margin-top:14px;color:var(--secondary)}
.hero-copy p{font-size:clamp(15px,1.6vw,17px);line-height:1.9;color:#777;max-width:none;margin:24px 0 30px}
.hero-actions{display:flex;gap:13px;flex-wrap:wrap}
.hero-trust{display:flex;gap:22px;margin-top:28px;color:#888;font-size:12px;flex-wrap:wrap}
/* 窄屏：文案列不再固定 620px，按两栏对半；900px 以下直接上下堆叠。 */
@media(max-width:1080px){
  .hero{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
}
@media(max-width:900px){
  .hero{grid-template-columns:1fr;gap:28px;padding:44px 5% 40px;min-height:0}
  .hero-copy{max-width:none}
  .hero-visual{min-height:320px}
}
.hero-visual{position:relative;min-height:390px;display:grid;place-items:center}
.hero-stack{position:absolute;width:82%;height:76%;border-radius:32px;transform:rotate(7deg) translate(26px,12px);background:rgba(255,255,255,.30);border:1px solid rgba(255,255,255,.75);box-shadow:0 25px 60px rgba(60,65,75,.08)}
.hero-stack.two{transform:rotate(-5deg) translate(-16px,3px);background:rgba(255,255,255,.34)}
.hero-carousel{position:relative;width:100%;min-height:340px;padding:22px 24px;border-radius:30px;z-index:2;overflow:hidden}
.carousel-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.carousel-arrows{display:flex;gap:7px}
.carousel-arrows button{width:30px;height:30px;border-radius:50%;background:rgba(255,255,255,.8);color:#666;font-size:18px;border:0;cursor:pointer}
.home-slide{display:none;min-height:245px}
.home-slide.active{display:block;animation:homeSlideIn .48s ease both}
@keyframes homeSlideIn{from{opacity:.3;transform:translateY(7px)}to{opacity:1;transform:none}}
.slide-title h2{font-size:22px;margin:5px 0}
.slide-title small{font-size:10px;letter-spacing:1.4px;color:#aaa}
.mini-steps{display:flex;align-items:center;justify-content:space-between;margin:42px 0 30px;gap:8px}
.mini-step{display:grid;justify-items:center;gap:7px;text-align:center;min-width:65px}
.mini-step b{width:43px;height:43px;border-radius:14px;display:grid;place-items:center;background:#eee;color:#aaa;font-size:18px}
.mini-step.active b{background:rgba(244,123,53,.13);color:var(--orange)}
.mini-step strong{font-size:12px}
.mini-step small{font-size:10px;color:#999}
.mini-steps>i{height:1px;flex:1;background:#dedfe2;margin:0 7px;transform:translateY(-15px)}
.mini-dashboard{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:22px 0}
.mini-kpi{background:rgba(255,255,255,.7);padding:13px;border-radius:15px}
.mini-kpi small{display:block;color:#999;font-size:10px}
.mini-kpi b{display:block;font-size:25px;margin:4px 0}
.mini-kpi span{font-size:10px;color:var(--orange)}
.mini-kpi.dark{background:#555960;color:white}
.mini-kpi.dark small,.mini-kpi.dark span{color:#ddd}
.mini-chart{grid-column:1/-1;background:rgba(255,255,255,.55);padding:12px 15px;border-radius:15px}
.mini-chart svg{width:100%;height:65px}
.mini-report{display:grid;grid-template-columns:1.15fr .85fr;gap:12px;margin:20px 0}
.mini-paper,.mini-risk{background:rgba(255,255,255,.68);border-radius:15px;padding:14px;min-height:150px}
.mini-paper{font-size:10px;color:#777;line-height:1.7}
.mini-paper p{margin:9px 0}
.mini-paper mark{background:rgba(244,123,53,.22);color:#8c4d29}
.mini-risk{display:grid;align-content:start;gap:8px}
.mini-risk b{font-size:12px}
.mini-risk p{font-size:10px;line-height:1.6;color:#888;margin:0}
.slide-foot{border-top:1px solid var(--line);padding-top:12px;color:#999;font-size:11px}
.carousel-dots{display:flex;justify-content:center;gap:7px;margin-top:8px}
.carousel-dots button{width:6px;height:6px;border-radius:9px;background:#d2d3d6;padding:0;border:0}
.carousel-dots button.active{width:20px;background:var(--orange)}
/* 首页中部三段（能力 / 为什么 / 流程）。
   上一版用 border-right 竖线把容器切成「表格条带」，why-strip 还是 1.1fr+5×1fr
   的六列 —— 最后一格文案换行到 59px，其余 38px，整条高度参差。现在三段的
   基本单元统一成「图标在上、文字在下、居中对齐」，去掉所有竖分隔线，
   靠留白和同一套 34px 上下内边距形成节奏。 */
.feature-strip{
  display:grid;grid-template-columns:repeat(5,1fr);padding:34px 20px;
  border-radius:26px;margin:0 0 18px;align-items:start;
}
.feature{
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;
  text-align:center;gap:14px;padding:6px 12px;
  transition:transform .28s cubic-bezier(.2,.7,.3,1);
}
.feature:hover{transform:translateY(-3px)}
.feature-icon{width:48px;height:48px;border-radius:16px;background:rgba(244,123,53,.10);color:var(--orange);display:grid;place-items:center;font-size:21px;flex:0 0 auto}
.feature strong{display:block;font-size:14px;letter-spacing:-.1px}
.feature small{font-size:12px;color:var(--secondary);margin-top:3px;display:block}
.why-head{text-align:center;padding:34px 0 22px}
.why-head small{font-size:11px;letter-spacing:1.6px;color:#aaa}
.why-head h2{font-size:clamp(22px,2.4vw,27px);margin:11px 0 0;letter-spacing:-.6px;font-weight:600}
.why-strip{display:grid;grid-template-columns:repeat(5,1fr);align-items:start;padding:32px 18px;border-radius:26px;gap:0;margin-bottom:6px}
.why-item{display:flex;flex-direction:column;align-items:center;text-align:center;gap:12px;padding:4px 12px}
.why-icon{
  width:42px;height:42px;border-radius:14px;flex:none;display:grid;place-items:center;
  font-size:19px;color:var(--orange);background:rgba(244,123,53,.10);
}
.why-item strong{font-size:13.5px;display:block;letter-spacing:-.1px}
.why-item small{font-size:11.5px;color:var(--secondary);line-height:1.6;display:block;margin-top:4px;max-width:150px}
@media(max-width:1080px){
  .feature-strip,.why-strip{grid-template-columns:repeat(3,1fr);row-gap:22px}
}
@media(max-width:720px){
  .feature-strip,.why-strip{grid-template-columns:repeat(2,1fr);row-gap:20px;padding:26px 14px}
}
.landing-flow{padding:58px 3% 20px;text-align:center}
.landing-flow small{font-size:11px;letter-spacing:1.4px;color:#aaa}
.landing-flow h2{font-size:30px;margin:12px 0 6px}
.landing-flow .muted{font-size:13px;color:var(--secondary)}
.flow-steps{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-top:24px;padding:25px;border-radius:24px}
.flow-step{text-align:center}
.flow-step .feature-icon{margin:0 auto 12px}
.flow-step h3{font-size:14px;margin:0 0 4px}
.flow-step small{font-size:11px;color:var(--secondary)}
.landing-footer{border-top:1px solid var(--line);margin-top:55px;padding:22px 3%;display:flex;justify-content:space-between;color:#999;font-size:11px;flex-wrap:wrap;gap:10px}
.section{padding:110px 24px}
.section.gray{background:var(--page)}
.section.dark{background:#000;color:#f5f5f7}
.section-inner{max-width:1180px;margin:auto}
.section-intro{max-width:760px;margin-bottom:48px}
.section-eyebrow{font-size:13px;font-weight:600;color:var(--blue);margin-bottom:12px}
.section.dark .section-eyebrow{color:#2997ff}
.section h2{
  margin:0 0 16px;font-size:clamp(38px,5vw,58px);line-height:1.05;
  font-weight:600;letter-spacing:-.045em;
}
.section-intro p{font-size:18px;line-height:1.65;color:var(--secondary);margin:0}
.section.dark .section-intro p{color:#a1a1a6}
.capability-list{border-top:1px solid var(--line)}
.capability{
  display:grid;grid-template-columns:70px 1fr minmax(280px,430px);gap:22px;
  align-items:start;padding:29px 0;border-bottom:1px solid var(--line);
}
.capability-index{font-size:13px;color:var(--tertiary);padding-top:3px}
.capability h3{margin:0;font-size:23px;font-weight:550;letter-spacing:-.025em}
.capability p{margin:0;color:var(--secondary);font-size:14px;line-height:1.7}
.plan-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.plan-block{padding:36px;min-height:270px;border-radius:26px;background:#111;color:#f5f5f7;border:1px solid #222}
.plan-block.light{background:#fff;color:var(--text);border-color:var(--line)}
.plan-block h3{font-size:30px;font-weight:600;letter-spacing:-.035em;margin:14px 0 12px}
.plan-block p{font-size:14px;line-height:1.72;color:#a1a1a6;margin:0}
.plan-block.light p{color:var(--secondary)}
.footer{background:var(--page);padding:28px 24px;border-top:1px solid var(--line);font-size:11px;color:var(--tertiary)}
.footer-inner{max-width:1180px;margin:auto;display:flex;justify-content:space-between;gap:18px;flex-wrap:wrap}
/* 页脚法律文本链接：全局 a 是 color:inherit，不给色就和版权文字一模一样，看不出能点。 */
.footer a{color:var(--secondary)}
.footer a:hover{color:var(--text);text-decoration:underline}

/* Auth */
.auth{
  min-height:100vh;background:#fff;display:grid;grid-template-columns:minmax(380px,1fr) minmax(420px,520px);
}
.auth-copy{
  background:var(--page);padding:70px;display:flex;flex-direction:column;justify-content:center;
}
.auth-copy h1{font-size:52px;line-height:1.05;letter-spacing:-.05em;font-weight:600;margin:28px 0 17px;max-width:620px}
.auth-copy p{max-width:580px;font-size:17px;line-height:1.7;color:var(--secondary);margin:0}
.auth-form-wrap{display:grid;place-items:center;padding:45px}
.auth-form{width:min(380px,100%)}
.auth-form h2{font-size:30px;font-weight:600;letter-spacing:-.035em;margin:36px 0 7px}
.auth-tabs{height:38px;border-radius:10px;background:#f2f2f4;padding:3px;display:flex;margin:25px 0 22px}
.auth-tab{flex:1;border:0;background:transparent;border-radius:8px;cursor:pointer;color:var(--secondary);font-size:12px}
.auth-tab.active{background:#fff;color:var(--text);box-shadow:0 1px 4px rgba(0,0,0,.08)}
.field{margin-bottom:15px}
.field label{display:block;margin-bottom:7px;font-size:12px;font-weight:500;color:#424245}
.input,.select,.textarea{
  width:100%;appearance:none;border:1px solid var(--line-strong);border-radius:11px;
  background:#fff;padding:11px 12px;font-size:13px;outline:none;color:var(--text);
}
.input:focus,.select:focus,.textarea:focus{border-color:#ffb38a;box-shadow:0 0 0 3px rgba(244,123,53,.09)}
.auth-form .button.primary{width:100%;height:42px;margin-top:5px}
.form-note{text-align:center;font-size:11px;line-height:1.55;color:var(--tertiary);margin-top:14px}
/* 登录/注册页「同意《服务条款》与《隐私政策》」里的两个链接。
   11px 小字上不叠加通栏下划线，用蓝色 + 细下边框，主次更清楚。 */
.form-note a{color:var(--blue);border-bottom:1px solid rgba(244,123,53,.35);padding-bottom:1px}
.form-note a:hover{border-bottom-color:var(--blue)}

/* App shell */
.app-shell{min-height:100vh;display:grid;grid-template-columns:var(--sidebar) 1fr}
.sidebar{
  position:fixed;inset:0 auto 0 0;width:var(--sidebar);z-index:25;
  padding:14px 12px;
  display:flex;flex-direction:column;
  /* 玻璃拟态侧栏（参考小白说标 .glass） */
  background:var(--glass);
  border-right:1px solid rgba(255,255,255,.8);
  box-shadow:var(--shadow);
  backdrop-filter:blur(24px);
  -webkit-backdrop-filter:blur(24px);
  /* 导航现在是四组（总览/招标人/投标人/通用）。矮屏（<720px 高）下不加滚动
     会把「通用」整组裁掉，用户会以为那几个工具被删了。 */
  overflow-y:auto;
}
.sidebar-brand{height:48px;display:flex;align-items:center;padding:0 8px 12px;margin-bottom:7px}
.nav-section{margin:10px 0}
.nav-label{font-size:10px;font-weight:500;color:#a1a3a8;padding:0 10px 5px;letter-spacing:.8px}
.nav-item{
  width:100%;height:38px;border:0;border-radius:13px;background:transparent;
  padding:0 10px;display:flex;align-items:center;gap:10px;cursor:pointer;
  font-size:12px;color:#5c5e63;text-align:left;margin:1px 0;
  transition:background .18s;
}
.nav-item:hover{background:rgba(255,255,255,.65)}
.nav-item.active{
  background:rgba(255,255,255,.86);color:#262626;font-weight:500;
  box-shadow:0 4px 12px rgba(45,50,60,.06);
}
.nav-item .icon{width:17px;height:17px}
.nav-item .nav-badge{margin-left:auto;font-size:9px;color:#8e8e93}
.sidebar-bottom{margin-top:auto;border-top:1px solid var(--line);padding-top:10px}
.profile-nav{
  width:100%;border:0;border-radius:13px;background:rgba(255,255,255,.58);
  border:1px solid rgba(255,255,255,.8);
  padding:9px 8px;
  display:flex;align-items:center;gap:10px;text-align:left;cursor:pointer;
}
.profile-nav:hover{background:#fff}
.profile-nav.active{background:rgba(255,255,255,.86)}
.avatar{
  width:30px;height:30px;border-radius:50%;
  background:linear-gradient(145deg,#d9dce1,#9297a1);color:#fff;
  display:grid;place-items:center;font-size:11px;font-weight:700;flex:0 0 auto;
}
.profile-meta{min-width:0;flex:1}
.profile-name{font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.profile-points{font-size:10px;color:var(--tertiary);margin-top:2px}
.app-main{grid-column:2;min-width:0;padding:0 34px 55px;position:relative}
.app-top{
  height:62px;position:sticky;top:0;z-index:20;
  background:rgba(255,255,255,.62);
  border-bottom:1px solid rgba(255,255,255,.8);
  backdrop-filter:blur(24px);
  -webkit-backdrop-filter:blur(24px);
  box-shadow:var(--shadow);
  display:flex;align-items:center;justify-content:space-between;
}
.app-top-title{font-size:13px;font-weight:500}
.app-top-actions{display:flex;gap:8px;align-items:center}
.points-pill{
  height:30px;padding:0 11px;border-radius:999px;border:1px solid rgba(255,255,255,.8);
  background:rgba(255,255,255,.58);font-size:11px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9);
}
.content{max-width:1200px;margin:0 auto}
.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:22px;padding:28px 0 22px}
.page-head h1{font-size:32px;font-weight:600;letter-spacing:-.04em;margin:0 0 7px}
.page-head p{font-size:13px;color:var(--secondary);line-height:1.6;margin:0}
.welcome{
  background:var(--glass);border:1px solid rgba(255,255,255,.8);box-shadow:var(--shadow);
  border-radius:var(--radius-lg);padding:34px 36px;
  display:flex;align-items:center;justify-content:space-between;gap:28px;
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
}
.welcome h2{font-size:29px;font-weight:600;letter-spacing:-.035em;margin:0 0 9px}
.welcome p{font-size:14px;line-height:1.7;color:var(--secondary);margin:0;max-width:650px}
.stat-row{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:14px 0 28px}
.stat{
  padding:19px;background:var(--glass);border:1px solid rgba(255,255,255,.8);
  box-shadow:var(--shadow);border-radius:var(--radius);
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
}
.stat-label{font-size:11px;color:var(--secondary)}
.stat-value{font-size:27px;letter-spacing:-.035em;font-weight:600;margin:9px 0 4px}
.stat-sub{font-size:10px;color:var(--tertiary)}
.group-title{font-size:19px;font-weight:600;letter-spacing:-.025em;margin:32px 0 14px}
.tool-list{border-top:1px solid var(--line)}
.tool-row{
  border-bottom:1px solid var(--line);padding:18px 4px;display:grid;
  grid-template-columns:42px minmax(180px,280px) 1fr auto;gap:15px;align-items:center;cursor:pointer;
}
.tool-row:hover .tool-name{color:var(--blue)}
.tool-icon{
  width:36px;height:36px;border-radius:10px;border:1px solid var(--line);
  display:grid;place-items:center;background:#fff;color:#424245;
}
.tool-icon .icon{width:18px;height:18px}
.tool-name{font-size:14px;font-weight:500}
.tool-desc{font-size:12px;color:var(--secondary);line-height:1.55}
.chevron{font-size:18px;color:#b0b0b5}

/* review workflow */
.stepper{
  background:#fff;border:1px solid var(--line);border-radius:14px;padding:13px 16px;
  display:flex;align-items:center;overflow:auto;margin-bottom:14px;
}
.step{display:flex;align-items:center;gap:7px;white-space:nowrap;font-size:11px;color:#a1a1a6}
.step-dot{
  width:21px;height:21px;border-radius:50%;background:#f1f1f3;display:grid;place-items:center;
  font-size:10px;color:#77777d;
}
.step.active{color:#1d1d1f;font-weight:500}.step.active .step-dot{background:#1d1d1f;color:#fff}
.step.done{color:#6e6e73}.step.done .step-dot{background:#e8e8ed;color:#424245}
.step-line{width:31px;height:1px;background:#dedee2;margin:0 6px;flex:0 0 auto}
.review-layout{display:grid;grid-template-columns:minmax(0,1fr) 280px;gap:14px}
.review-card{padding:28px;min-height:520px}
.review-card h2{font-size:21px;font-weight:600;letter-spacing:-.025em;margin:0 0 7px}
.review-card>.muted{font-size:12px;line-height:1.6;margin-bottom:23px}
.review-side{padding:19px;height:max-content;position:sticky;top:78px}
.panel-title{font-size:13px;font-weight:600;margin:0 0 13px}
.side-summary{display:grid;gap:12px}
.side-summary span{display:block;font-size:10px;color:var(--tertiary);margin-bottom:3px}
.side-summary b{font-size:12px;font-weight:500}
.note-box{padding:12px;border-radius:10px;background:#f7f7f9;font-size:11px;line-height:1.65;color:var(--secondary);margin-top:17px}
.upload-zone{
  min-height:190px;border:1px dashed #bdbdc2;border-radius:15px;background:#fbfbfd;
  display:grid;place-items:center;text-align:center;padding:25px;cursor:pointer;
}
.upload-zone:hover{border-color:#8e8e93}
.upload-symbol{
  width:42px;height:42px;border-radius:12px;background:#f0f0f2;
  display:grid;place-items:center;margin:0 auto 13px;color:#424245;
}
.upload-zone b{font-size:13px;font-weight:500}
.upload-zone p{font-size:11px;margin:7px 0 0;color:var(--tertiary)}
.file-chip{
  margin-top:10px;border:1px solid var(--line);border-radius:12px;background:#fff;
  display:flex;align-items:center;gap:11px;padding:11px;
}
.file-chip-main{min-width:0;flex:1}
.file-name{font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.file-size{font-size:10px;color:var(--tertiary);margin-top:3px}
.mini-button{
  display:inline-block;          /* 行内元素 margin-bottom 不生效，按钮换行会贴死 */
  border:1px solid var(--line);background:#fff;border-radius:8px;padding:6px 8px;
  cursor:pointer;font-size:10px;color:#424245;
}
/* 危险动作（终止并删除）：红字 + 淡红描边，不用实心红底 —— 实心红会和主按钮
   「继续任务」抢注意力，用户点错的代价是不可恢复的数据。 */
.mini-button.danger{color:#d70015;border-color:#f0c2bf}
.mini-button.danger:hover{background:#fff0ef}
.param-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.choice-list{display:grid;gap:8px}
.choice{
  border:1px solid var(--line);border-radius:12px;padding:12px;display:flex;gap:10px;cursor:pointer;
}
.choice:hover{background:#fafafa}
.choice input{margin-top:2px}
.choice b{font-size:12px;font-weight:500}
.choice p{font-size:11px;color:var(--secondary);line-height:1.55;margin:3px 0 0}
.review-actions{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-top:28px;padding-top:18px;border-top:1px solid var(--line);
}
.rules-card{border:1px solid var(--line);border-radius:14px;overflow:hidden;margin-top:10px}
.rules-toolbar{
  min-height:48px;display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:8px 14px;border-bottom:1px solid var(--line);background:#fbfbfd;
}
.check-all{font-size:11px;display:flex;align-items:center;gap:7px}
.rule-row{
  /* 三列：勾选框 / 名称+描述 / 风险等级。审核依据等管理信息不在勾选清单展示。 */
  display:grid;grid-template-columns:28px minmax(0,1fr) 64px;
  gap:10px;align-items:center;padding:13px 14px;border-bottom:1px solid var(--line);
}
.rule-row:last-child{border-bottom:0}
/* 全选行是 label+计数+占位+按钮四个元素，占位 span 撑开，覆盖三列布局。 */
.rule-row-plain{grid-template-columns:28px minmax(0,1fr) auto}
.rule-name{font-size:12px;font-weight:500}
.rule-desc{font-size:10px;color:var(--secondary);line-height:1.55;margin-top:3px}
.rule-risk{justify-self:end}
.risk-chip{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:500;white-space:nowrap}
.risk-chip.high{background:rgba(215,0,21,.1);color:#d70015}
.risk-chip.medium{background:rgba(178,93,0,.12);color:#b25d00}
.risk-chip.low{background:rgba(0,102,204,.1);color:#0066cc}
.risk-chip.none{background:#f2f2f7;color:#8e8e93}
.risk-level{font-size:10px}
.risk-level.high{color:#d70015}.risk-level.medium{color:#b25d00}.risk-level.low{color:#0066cc}
.confirm-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.confirm-box{border:1px solid var(--line);border-radius:12px;padding:15px}
.confirm-box span{display:block;font-size:10px;color:var(--tertiary);margin-bottom:6px}
.confirm-box b{font-size:12px;font-weight:500}
.loading{text-align:center;padding:60px 20px}
.spinner{width:40px;height:40px;border:3px solid #e3e3e7;border-top-color:#424245;border-radius:50%;animation:spin .9s linear infinite;margin:0 auto 17px}
@keyframes spin{to{transform:rotate(360deg)}}
/* 停机态（积分不足已停止）：同一个圆环但静止、变灰 —— 转圈会让用户以为还在算。 */
.spinner-stopped{border-top-color:#c7c7cc;animation:none}
.loading h2{margin:0 0 8px}
.progress{height:5px;background:#e8e8ed;border-radius:99px;overflow:hidden;max-width:430px;margin:24px auto 9px}
.progress i{display:block;width:72%;height:100%;background:#424245;border-radius:99px}

/* rule editor */
.editor-layout{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:14px}
.editor-main,.editor-side{padding:20px}
.editor-side{height:max-content;position:sticky;top:77px}
.table-wrap{overflow:auto}
.table{width:100%;border-collapse:collapse;font-size:11px}
.table th{text-align:left;color:var(--tertiary);font-weight:500;padding:10px;border-bottom:1px solid var(--line);background:#fbfbfd}
.table td{padding:11px 10px;border-bottom:1px solid var(--line);vertical-align:top;line-height:1.5}
.table tr:last-child td{border-bottom:0}
.editor-header{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:13px}

/* tools */
.utility-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.utility{padding:25px}
.utility h3{font-size:19px;font-weight:600;letter-spacing:-.025em;margin:20px 0 8px}
.utility p{font-size:12px;color:var(--secondary);line-height:1.65;margin:0}
.utility-meta{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin:18px 0}
.meta{background:#f7f7f9;border-radius:10px;padding:11px}
.meta span{display:block;font-size:9px;color:var(--tertiary);margin-bottom:3px}
.meta b{font-size:11px;font-weight:500}

/* user center */
.user-layout{display:grid;grid-template-columns:300px minmax(0,1fr);gap:16px}
.profile-card{padding:28px;text-align:center}
.avatar-large{
  width:72px;height:72px;border-radius:50%;background:#1d1d1f;color:#fff;
  display:grid;place-items:center;margin:0 auto 14px;font-size:22px;font-weight:600;
}
.profile-card h2{font-size:20px;margin:0 0 5px;font-weight:600}
/* macOS 系统设置式资料行：左标签右值、行间发丝线。
   行结构由 src/user-center.js::accountDetailRow 生成（div > span + b），
   这里只改排版，不改结构。 */
.account-details{border-top:1px solid var(--line);margin-top:20px;padding-top:4px;display:grid}
.account-details > div{
  display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  padding:9px 0;border-bottom:1px solid var(--line);
}
.account-details > div:last-child{border-bottom:0}
.account-details span{display:block;font-size:12px;color:var(--secondary);flex:none}
.account-details b{font-size:12.5px;font-weight:500;text-align:right;min-width:0;overflow-wrap:anywhere}
/* 余额卡：**积分数字与两个按钮同一行**（用户反馈整页局促）。
   用 grid 而不是把三块 flex 挤在一行：标签独占一行，数字左、按钮右，
   窄屏时按钮自动换到下一行，数字不会被压扁。 */
.balance-card{
  /* 高度被刻意压低（用户反馈）：行高 124px + 紧凑内边距 + 30px 数字。
     省出来的空间给了下方的问题反馈卡（见 .user-main-column 行定义）。 */
  padding:16px 22px;background:var(--glass);
  display:grid;grid-template-columns:minmax(0,1fr) auto;
  grid-template-areas:"label label" "number actions";
  align-items:end;column-gap:18px;row-gap:4px;
}
.balance-label{grid-area:label;display:flex;align-items:center;gap:8px;font-size:12px;font-weight:500;color:var(--secondary)}
.balance-number{grid-area:number;font-size:30px;font-weight:600;letter-spacing:-.04em;line-height:1.1;margin:0}
.balance-actions{grid-area:actions;display:flex;gap:8px;flex-wrap:wrap;justify-self:end}
@media (max-width:520px){
  .balance-card{grid-template-areas:"label label" "number number" "actions actions"}
  .balance-actions{justify-self:start}
}
.records{margin-top:14px;padding:20px}
.segmented{display:inline-flex;background:#f2f2f4;border-radius:9px;padding:3px;margin-bottom:12px}
.segmented button{border:0;background:transparent;padding:7px 11px;border-radius:7px;font-size:10px;color:var(--secondary);cursor:pointer}
.segmented button.active{background:#fff;color:var(--text);box-shadow:0 1px 3px rgba(0,0,0,.08)}

/* ---------- 用户中心 · 暖色玻璃风（2026-11-03 色板对齐） ----------
   原先这套是从 macOS 系统设置直接搬的：蓝色/绿色/紫色/灰色的实心渐变瓦片，
   头像是 iOS 蓝渐变。放进全站橙暖色 + 玻璃拟态里，账户页像另一个产品的截图。
   现在瓦片统一为「浅暖底 + 彩色线性图标」（与工作台 .metric-icon、首页
   .feature-icon 同一套做法），四个变体只差色相，明度与描边强度保持一致。 */
.uc-head{display:flex;align-items:center;gap:9px}
.uc-tile{
  width:24px;height:24px;border-radius:8px;flex:none;
  display:inline-grid;place-items:center;
  background:rgba(244,123,53,.10);
  color:var(--orange);
  border:1px solid rgba(244,123,53,.14);
}
.uc-tile .icon{width:13px;height:13px}
.uc-tile-blue{background:rgba(244,123,53,.10);color:#ef702d;border-color:rgba(244,123,53,.16)}
.uc-tile-green{background:rgba(127,156,116,.14);color:#6d8b62;border-color:rgba(127,156,116,.20)}
.uc-tile-purple{background:rgba(165,140,189,.14);color:#8f76a8;border-color:rgba(165,140,189,.22)}
.uc-tile-gray{background:rgba(169,162,155,.15);color:#8b847d;border-color:rgba(169,162,155,.22)}
/* 卡片：与全站一致的玻璃层（白边 + 24px 模糊 + 同一套阴影），
   不再用 macOS 那套「1px 贴地 + 大扩散」的冷色双层阴影。 */
.user-center-view .card{
  background:var(--glass);
  border:1px solid rgba(255,255,255,.8);
  box-shadow:var(--shadow);
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
}
.user-center-view .profile-card{background:var(--glass)}
.user-center-view .avatar-large{
  background:linear-gradient(160deg,#ffb489,#ef702d);
  box-shadow:0 8px 20px rgba(239,112,45,.26);
}
/* 反馈折叠头标题带上瓦片后改为横排（原为纯文本 span）。 */
.feedback-toggle-title{display:inline-flex;align-items:center;gap:8px}
/* 流水表：macOS 列表式悬停高亮。 */
.user-main-column .records tbody tr{transition:background .12s ease}
.user-main-column .records tbody tr:hover{background:rgba(0,0,0,.028)}

/* AI chat */
.chat-layout{display:grid;grid-template-columns:240px 1fr;gap:14px;height:calc(100vh - 120px);min-height:560px}
.chat-history{padding:12px}
.chat-thread{padding:10px;border-radius:9px;font-size:11px;cursor:pointer;margin-top:4px}
.chat-thread:hover,.chat-thread.active{background:#f2f2f4}
.chat-panel{display:flex;flex-direction:column;overflow:hidden}
.chat-messages{flex:1;overflow:auto;padding:25px}
.bubble{max-width:72%;padding:11px 13px;border-radius:14px;font-size:12px;line-height:1.65;margin-bottom:11px}
.bubble.user{margin-left:auto;background:#1d1d1f;color:#fff;border-bottom-right-radius:5px}
.bubble.assistant{background:#f2f2f4;border-bottom-left-radius:5px}
.chat-compose{border-top:1px solid var(--line);padding:12px;display:flex;gap:8px}
.chat-compose .input{flex:1}

/* planned */
.empty-state{min-height:390px;display:grid;place-items:center;text-align:center;padding:35px}
.empty-state h2{font-size:26px;font-weight:600;letter-spacing:-.03em;margin:18px 0 8px}
.empty-state p{font-size:12px;color:var(--secondary);line-height:1.7;max-width:520px;margin:0}

/* Fullscreen report — based on uploaded report's two-panel workflow, restyled
   底色与 iframe 里那份 report.html 用同一组暖色渐变：iframe 加载前先显示父页背景，
   两边不一致会在加载瞬间闪一下白，看起来像"界面抖了一下"。 */
.report-app{
  height:100vh;overflow:hidden;display:flex;flex-direction:column;
  background:#eeecea;
  background-image:radial-gradient(ellipse at 10% 0%,rgba(255,255,255,.95),transparent 42%),
                   linear-gradient(135deg,#f4f2f0,#eae8e6 58%,#f5f4f2);
}
.report-toolbar{
  height:56px;flex:0 0 auto;border-bottom:1px solid rgba(255,255,255,.9);
  background:rgba(255,255,255,.72);box-shadow:0 6px 24px rgba(44,49,59,.05);
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
  display:flex;align-items:center;gap:11px;padding:0 16px;
}
.report-back{
  width:34px;height:34px;border:0;border-radius:50%;display:grid;place-items:center;cursor:pointer;
  background:rgba(255,255,255,.7);color:#424245;transition:background .16s ease,color .16s ease,transform .2s ease;
}
.report-back:hover{background:#fff;color:var(--orange-deep);transform:translateY(-1px)}
.report-title-wrap{min-width:0;flex:1}
.report-title{font-size:14px;font-weight:650;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.report-meta{font-size:11px;color:var(--secondary);margin-top:2px;line-height:1.5}
.report-toolbar-actions{display:flex;gap:7px}
/* 报告导出菜单：一个触发器 + 三项说明。absolute 定位在触发器下方右对齐，
   父级 .report-export 必须是定位上下文，否则菜单会飘到页面左上角。 */
.report-export{position:relative}
.report-export-caret{font-size:9px;opacity:.55;margin-left:2px}
/* 透明遮罩：报告正文是 iframe，点在上面的 click 不会冒泡到父文档 ——
   没有这层，点正文时菜单永远关不掉。层级低于菜单(40)、高于页面其它内容。 */
.report-export-backdrop{position:fixed;inset:0;z-index:39;background:transparent;cursor:default}
.report-export-menu{
  position:absolute;right:0;top:calc(100% + 8px);z-index:40;width:250px;padding:7px;
  background:#fff;border:1px solid var(--line);border-radius:16px;
  box-shadow:0 24px 60px rgba(44,49,59,.16),inset 0 1px 0 rgba(255,255,255,.9);
}
.report-export-item{
  display:flex;flex-direction:column;gap:1px;width:100%;padding:9px 11px;border:0;border-radius:11px;
  background:transparent;text-align:left;font:inherit;color:inherit;text-decoration:none;cursor:pointer;
  transition:background .16s ease;
}
.report-export-item:hover,.report-export-item:focus-visible{background:#fffaf5;outline:none}
.report-export-item:hover b,.report-export-item:focus-visible b{color:var(--orange-deep)}
.report-export-item b{font-size:12px;font-weight:600}
.report-export-item span{font-size:10px;color:var(--tertiary);line-height:1.5}
.report-body{display:grid;grid-template-columns:50% 50%;flex:1;min-height:0}
.report-source,.report-review{min-width:0;display:flex;flex-direction:column;min-height:0}
.report-source{border-right:1px solid var(--line);background:#f5f5f7}
.report-review{background:#fbfbfd}
.report-panel-head{
  height:43px;flex:0 0 auto;border-bottom:1px solid var(--line);background:rgba(255,255,255,.9);
  display:flex;align-items:center;justify-content:space-between;padding:0 15px;
}
.report-panel-head h2{font-size:11px;font-weight:600;margin:0}
.report-panel-head span{font-size:9px;color:var(--tertiary)}
.report-scroll{flex:1;min-height:0;overflow:auto;padding:16px}
.document-sheet{
  max-width:850px;margin:0 auto 25px;background:#fff;border:1px solid var(--line);
  border-radius:9px;box-shadow:0 6px 18px rgba(0,0,0,.04);overflow:hidden;
}
.document-name{height:38px;border-bottom:1px solid var(--line);display:flex;align-items:center;padding:0 15px;font-size:10px;color:var(--secondary)}
.document-content{padding:23px 28px 34px;font-size:12px;line-height:1.9;color:#333336}
.doc-paragraph{padding:2px 5px;border-left:2px solid transparent;border-radius:3px;margin:2px 0;transition:background .15s,box-shadow .15s}
.doc-paragraph.chapter{font-size:17px;font-weight:600;letter-spacing:-.015em;margin:24px 0 10px}
.doc-paragraph.section-title{font-size:14px;font-weight:600;margin:17px 0 6px}
.doc-paragraph.risk-high{background:rgba(255,59,48,.09);border-left-color:var(--red);cursor:pointer}
.doc-paragraph.risk-medium{background:rgba(255,159,10,.10);border-left-color:var(--orange);cursor:pointer}
.doc-paragraph.risk-low{background:rgba(244,123,53,.09);border-left-color:var(--blue);cursor:pointer}
.doc-paragraph.focus{animation:sourcePulse .75s ease 2}
@keyframes sourcePulse{50%{box-shadow:0 0 0 3px rgba(244,123,53,.16)}}
.doc-table{width:100%;border-collapse:collapse;margin:10px 0 14px;font-size:10px;line-height:1.5}
.doc-table th,.doc-table td{border:1px solid #dedee2;padding:7px;vertical-align:top}
.doc-table th{background:#f7f7f9;font-weight:600}
.doc-table .risk-high{background:rgba(255,59,48,.09);box-shadow:inset 2px 0 var(--red);cursor:pointer}
.image-placeholder{border:1px solid var(--line);border-radius:8px;background:#f7f7f9;padding:26px;text-align:center;color:var(--tertiary);font-size:10px;margin:10px 0}
.report-summary{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:9px}
.summary-chip{height:24px;padding:0 9px;border-radius:999px;border:1px solid var(--line);background:#fff;display:inline-flex;align-items:center;font-size:10px}
.report-tools{display:flex;gap:7px;margin-bottom:11px;flex-wrap:wrap}
.filter-button{
  height:28px;border:1px solid var(--line);background:#fff;border-radius:999px;padding:0 10px;
  font-size:10px;cursor:pointer;color:#424245;
}
.filter-button.active{background:#1d1d1f;border-color:#1d1d1f;color:#fff}
.report-search{
  width:100%;height:34px;border:1px solid var(--line-strong);border-radius:9px;background:#fff;
  padding:0 11px;font-size:11px;outline:none;margin-bottom:11px;
}
.report-search:focus{border-color:#ffb38a;box-shadow:0 0 0 3px rgba(244,123,53,.08)}
.key-card,.issue-card{
  background:#fff;border:1px solid var(--line);border-radius:11px;margin-bottom:10px;overflow:hidden;
}
.key-head,.issue-head{
  min-height:39px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:8px;padding:0 12px;background:#fff;
}
.key-head h3,.issue-head h3{font-size:11px;font-weight:600;margin:0;flex:1}
.key-head span,.issue-head span{font-size:9px;color:var(--tertiary)}
.key-table{width:100%;border-collapse:collapse;font-size:10px}
.key-table th,.key-table td{padding:7px 11px;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}
.key-table tr:last-child th,.key-table tr:last-child td{border-bottom:0}
.key-table th{width:34%;font-weight:500;color:var(--secondary);background:#fbfbfd}
.issue-card{border-top:2px solid var(--red)}
.issue-card.level-medium{border-top-color:var(--orange)}
.issue-card.level-low{border-top-color:var(--blue)}
.issue-card.flash{animation:issueFlash .8s ease 2}
@keyframes issueFlash{50%{box-shadow:0 0 0 3px rgba(244,123,53,.15)}}
.level-pill{
  display:inline-flex;align-items:center;height:20px;padding:0 7px;border-radius:999px;
  font-size:9px;font-weight:600;background:#fff0ef;color:#d70015;
}
.level-pill.medium{background:#fff6e8;color:#a45100}.level-pill.low{background:#edf6ff;color:#0066cc}
.rule-line{padding:7px 12px;background:#fbfbfd;border-bottom:1px solid var(--line);font-size:9px;color:var(--secondary)}
.issue-title{font-size:12px;font-weight:600;padding:11px 12px 7px}
.evidence-row{display:flex;gap:6px;flex-wrap:wrap;padding:0 12px 10px}
.evidence-button{
  border:1px solid var(--line);background:#fff;border-radius:999px;height:24px;padding:0 9px;
  font-size:9px;cursor:pointer;color:#424245;
}
.evidence-button:hover{border-color:#a8a8ad}
.issue-section{padding:10px 12px;border-top:1px solid var(--line)}
.issue-section-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:5px}
.issue-section h4{font-size:10px;font-weight:600;color:var(--secondary);margin:0}
.issue-section p{font-size:10px;line-height:1.72;margin:0;white-space:pre-wrap;color:#333336}
.issue-section p.advice{color:#176b3a}
.copy-action{border:0;background:transparent;color:var(--blue);cursor:pointer;font-size:9px;padding:0}
.report-empty{padding:35px;text-align:center;color:var(--tertiary);font-size:11px}

/* Admin */
.admin-shell{min-height:100vh;display:grid;grid-template-columns:220px 1fr;background:var(--page)}
.admin-sidebar{
  position:fixed;inset:0 auto 0 0;width:220px;background:#fff;border-right:1px solid var(--line);
  padding:14px 12px;display:flex;flex-direction:column;
}
.admin-main{grid-column:2;padding:0 30px 50px;min-width:0}
.admin-top{height:62px;display:flex;align-items:center;justify-content:space-between}
.metric-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.metric{padding:18px}.metric span{font-size:10px;color:var(--secondary)}
.metric strong{display:block;font-size:26px;font-weight:600;letter-spacing:-.035em;margin:9px 0 4px}
.metric small{font-size:9px;color:#248a3d}
.chart-card{margin-top:12px;padding:20px}
.bars{height:190px;display:flex;gap:11px;align-items:flex-end;padding:12px 4px 25px}
.bar{flex:1;min-width:9px;background:#1d1d1f;border-radius:4px 4px 1px 1px;position:relative}
.bar:after{content:attr(data-label);position:absolute;bottom:-20px;left:50%;transform:translateX(-50%);font-size:8px;color:var(--tertiary)}
.admin-two{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:12px}

/* Modal and toast */
.modal-backdrop{
  position:fixed;inset:0;z-index:90;background:rgba(0,0,0,.24);backdrop-filter:blur(8px);
  display:grid;place-items:center;padding:20px;
}
.modal{width:min(500px,100%);background:#fff;border-radius:18px;box-shadow:0 25px 70px rgba(0,0,0,.18);padding:22px}
.modal h3{font-size:18px;font-weight:600;letter-spacing:-.02em;margin:0 0 17px}
.modal-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:18px}

/* ---------- 规则编辑弹窗：八字段式 ---------- */
/* 弹窗拆成三段：固定头部（标题 + 状态）/ 滚动正文 / 固定底栏。
   以前是整块滚动 + 按钮 sticky，标题与进度条会随正文滚出视口 —— 用户在下半屏
   点保存，界面上唯一的变化只剩按钮文案，和「点了没反应」看不出区别。 */
.rule-editor-modal{
  display:flex;
  flex-direction:column;
  max-height:88vh;
  padding:0;             /* 内边距交给三段各自处理，头部才能贴住弹窗顶边 */
  overflow:hidden;
}
.rule-editor-head{
  flex:none;
  padding:20px 22px 12px;
  background:var(--surface);
  border-bottom:1px solid var(--line);
  border-radius:18px 18px 0 0;
}
/* 头部高度会随「错误条 / 进度条」出现而变，给一点过渡，避免正文突然跳一下。 */
.rule-editor-head #xbsb-rule-editor-progress,
.rule-editor-head #xbsb-rule-editor-err{margin-top:4px}
.rule-editor-body{
  flex:1 1 auto;
  min-height:0;
  overflow-y:auto;
  overscroll-behavior:contain;
  padding:14px 22px 0;
}
.rule-editor-modal > .modal-actions{
  flex:none;
  position:static;
  margin-top:0;
  padding:14px 22px 18px;
  border-top:1px solid var(--line);
  background:var(--surface);
  border-radius:0 0 18px 18px;
}
/* 字段序号：一眼看清「八字段」里的第几项，与存储列顺序一致。 */
.rule-field-no{
  display:inline-grid;place-items:center;
  width:18px;height:18px;margin-right:7px;
  border-radius:6px;
  background:#f1f1f3;color:var(--secondary);
  font-size:11px;font-weight:600;line-height:1;
  vertical-align:-3px;
}
/* 适用条件下拉：两个维度并排，窄屏自动堆叠。 */
.rule-app-grid{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
  gap:8px 14px;
}
.rule-app-grid .field{margin:0}
.rule-app-grid .field label{font-size:11px;color:var(--secondary)}
/* 固定值（如招标文件的「审核立场：招标人」）保持可见但不可改 */
.rule-app-grid select:disabled{background:#f7f7f9;color:var(--secondary);cursor:not-allowed}
.toast{
  position:fixed;right:18px;bottom:18px;z-index:120;background:#1d1d1f;color:#fff;
  padding:10px 13px;border-radius:10px;font-size:10px;box-shadow:0 10px 30px rgba(0,0,0,.18)
}

@media(max-width:1050px){
  .topnav{display:none}
  .capability{grid-template-columns:50px 1fr}.capability p{grid-column:2}
  .stat-row,.metric-grid{grid-template-columns:repeat(2,1fr)}
  .tool-row{grid-template-columns:42px 230px 1fr auto}
  .review-layout,.editor-layout,.user-layout{grid-template-columns:1fr}
  .review-side,.editor-side{position:static}
  .auth{grid-template-columns:1fr}.auth-copy{display:none}
}
@media(max-width:780px){
  :root{--sidebar:68px}
  .sidebar{padding-inline:7px}
  .sidebar-brand .brand span,.nav-label,.nav-item span:not(.icon):not(.nav-badge),.profile-meta{display:none}
  .sidebar-brand .brand{margin:auto}.nav-item{justify-content:center;padding:0}.profile-nav{justify-content:center}
  .nav-item .nav-badge{position:absolute;margin:0 0 26px 26px}
  .app-main{padding:0 15px 40px}
  .plan-grid,.utility-grid,.param-grid,.confirm-grid{grid-template-columns:1fr}
  .tool-row{grid-template-columns:42px 1fr auto}.tool-desc{grid-column:2}.tool-row .chevron{grid-column:3;grid-row:1/3}
  .stat-row,.metric-grid{grid-template-columns:1fr}
  .report-body{grid-template-columns:1fr}
  .report-source{display:none}
  .report-review{width:100%}
  .report-toolbar .button.secondary{display:none}
  .rule-row{grid-template-columns:25px 1fr 54px}.rule-row-plain{grid-template-columns:25px 1fr auto}
  .chat-layout{grid-template-columns:1fr}.chat-history{display:none}
  .admin-shell{grid-template-columns:68px 1fr}.admin-sidebar{width:68px;padding-inline:7px}
  .admin-sidebar .brand span,.admin-sidebar .nav-label,.admin-sidebar .nav-item span:not(.icon){display:none}
  .admin-sidebar .nav-item{justify-content:center;padding:0}.admin-main{padding:0 15px 40px}
  .admin-two{grid-template-columns:1fr}
}


/* =========================================================
   V3 · Fixed workspace / fixed audit frame
   - body no longer scrolls inside user workspace
   - audit pages keep stepper + main panel + summary panel fixed
   - long lists scroll inside their own frames
   ========================================================= */
html,body{height:100%}
.app-shell{
  height:100vh;
  min-height:0;
  overflow:hidden;
}
.sidebar{
  height:100vh;
  overflow:hidden;
}
.app-main{
  height:100vh;
  min-height:0;
  overflow:hidden;
  display:flex;
  flex-direction:column;
  padding:0 28px 18px;
}
.app-top{
  height:58px;
  flex:0 0 58px;
  position:relative;
  top:auto;
  background:transparent;
  backdrop-filter:none;
  justify-content:flex-start;
}
.app-top-actions,.points-pill{display:none!important}
.app-top-title{font-size:13px;color:#424245}
.content{
  width:100%;
  max-width:1200px;
  height:calc(100vh - 58px);
  min-height:0;
  margin:0 auto;
  overflow:auto;
  padding-bottom:18px;
  scrollbar-gutter:stable;
}
.content::-webkit-scrollbar,
.review-step-scroll::-webkit-scrollbar,
.rule-scroll::-webkit-scrollbar,
.records-scroll::-webkit-scrollbar,
.editor-page-view .table-wrap::-webkit-scrollbar,
.review-side::-webkit-scrollbar{
  width:7px;height:7px;
}
.content::-webkit-scrollbar-thumb,
.review-step-scroll::-webkit-scrollbar-thumb,
.rule-scroll::-webkit-scrollbar-thumb,
.records-scroll::-webkit-scrollbar-thumb,
.editor-page-view .table-wrap::-webkit-scrollbar-thumb,
.review-side::-webkit-scrollbar-thumb{
  background:#c7c7cc;border-radius:999px;
}
.content::-webkit-scrollbar-track,
.review-step-scroll::-webkit-scrollbar-track,
.rule-scroll::-webkit-scrollbar-track,
.records-scroll::-webkit-scrollbar-track,
.editor-page-view .table-wrap::-webkit-scrollbar-track,
.review-side::-webkit-scrollbar-track{
  background:transparent;
}

/* Workspace */
.workspace-view{overflow:auto}
.workspace-view .page-head{padding:18px 0 14px}
.workspace-view .stat-row{margin:0 0 24px}

/* ---------- 工作台：任务执行状态 + 批量创建（2026-10-28 改造） ---------- */
.ws-head-actions{display:flex;gap:8px;flex-wrap:wrap}
/* 统计卡：进行中 / 本月完成 / 累计问题 / 可用积分 */
.ws-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin:0 0 14px}
.ws-stat{
  padding:15px 18px;background:var(--glass);border:1px solid rgba(255,255,255,.8);
  box-shadow:var(--shadow);border-radius:var(--radius);
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
}
.ws-stat-label{font-size:12px;color:var(--secondary)}
.ws-stat-value{
  font-size:26px;font-weight:600;letter-spacing:-.03em;line-height:1.15;margin-top:6px;
  font-variant-numeric:tabular-nums;
}
.ws-stat-value.is-live{color:var(--orange)}
.ws-stat-value.is-danger{color:#d70015}
.ws-stat-sub{font-size:11px;color:var(--tertiary);margin-top:3px}
/* 批量创建面板 */
.ws-batch{
  padding:18px 20px;margin:0 0 14px;background:var(--glass);border:1px solid rgba(255,255,255,.8);
  box-shadow:var(--shadow);border-radius:var(--radius);
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
}
.ws-batch-head{display:flex;align-items:center;justify-content:space-between;gap:12px}
.ws-batch-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px 18px;
}
.ws-batch-grid .field{margin:0}
.ws-drop{display:flex;flex-direction:column;gap:6px}
.ws-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.ws-chip{
  display:inline-flex;align-items:center;gap:6px;padding:4px 9px;border-radius:999px;
  background:#f1f1f3;font-size:11px;max-width:100%;
}
.ws-chip b{color:var(--tertiary);font-weight:500}
.ws-queue{margin-top:10px;display:grid;gap:4px;max-height:190px;overflow:auto}
.ws-queue-item{
  display:flex;align-items:center;gap:10px;font-size:11.5px;padding:5px 9px;
  border-radius:8px;background:var(--surface-subtle);
}
.ws-queue-item.is-ok .ws-queue-stage{color:#248a3d}
.ws-queue-item.is-bad{background:#fff5f4}
.ws-queue-item.is-bad .ws-queue-stage{color:#d70015}
.ws-queue-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ws-queue-stage{flex:none;color:var(--secondary);white-space:nowrap}
.ws-queue-err{flex:none;color:#d70015;max-width:44%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ws-batch-actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:14px}

/* 审核设置区：同一批文件共用；分区标题把「设置」和「文件」两段分开 */
.ws-settings{
  border:1px solid var(--line);
  border-radius:12px;
  padding:14px 16px;
  background:#fbfbfd;
}
.ws-settings-title{
  font-size:12px;font-weight:600;color:var(--text);
  margin:0 0 10px;
}
.ws-settings-hint{margin-top:8px;line-height:1.6}
.ws-rules-head{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin:14px 0 8px;padding-top:12px;border-top:1px dashed var(--line);
  flex-wrap:wrap;
}
.ws-switch{display:inline-flex;align-items:center;gap:7px;font-size:12px;cursor:pointer}
.ws-switch input{width:15px;height:15px;accent-color:var(--blue)}
.ws-rules{display:grid;gap:2px;max-height:210px;overflow:auto}
.ws-rule{
  display:flex;align-items:flex-start;gap:8px;
  padding:6px 8px;border-radius:8px;cursor:pointer;
}
/* 全选行：与规则列表之间一条发丝线分隔，视觉上「表头 vs 行」。 */
.ws-rule-all{
  border-bottom:1px solid var(--line);
  padding-bottom:8px;margin-bottom:2px;border-radius:0;
}
.ws-rule:hover{background:rgba(0,0,0,.03)}
.ws-rule input{margin-top:2px;width:14px;height:14px;accent-color:var(--blue);flex:none}
.ws-rule-text{display:flex;flex-direction:column;gap:1px;min-width:0}
.ws-rule-text b{font-weight:500;font-size:12px;line-height:1.45;overflow-wrap:anywhere}
.ws-rule-text .small{line-height:1.5}
/* 任务表 */
.ws-tasks{padding:18px 20px}
.ws-tasks-head{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin-bottom:12px;flex-wrap:wrap;
}
.ws-tabs{margin:0}
.ws-table-wrap{overflow:auto;border-top:1px solid var(--line)}
.ws-table thead th{
  position:sticky;top:0;z-index:2;
  background:rgba(251,251,253,.94);
  backdrop-filter:saturate(180%) blur(10px);
  -webkit-backdrop-filter:saturate(180%) blur(10px);
}
.ws-table td{vertical-align:middle}
.ws-file{display:flex;align-items:center;gap:10px;min-width:0}
.ws-file-ic{
  width:26px;height:26px;border-radius:8px;background:#f1f1f3;flex:none;
  display:grid;place-items:center;color:var(--secondary);
}
.ws-file-ic .icon{width:14px;height:14px}
.ws-file b{font-weight:500;display:block;line-height:1.45;overflow-wrap:anywhere}
/* 状态标签：四档语义色，与审核记录页的措辞保持一致 */
.ws-tag{
  display:inline-block;padding:2px 9px;border-radius:999px;font-size:11px;
  font-weight:500;white-space:nowrap;
}
.ws-tag.is-queued{background:#f2f2f4;color:#6e6e73}
.ws-tag.is-active{background:#e8f0fe;color:#1a56c4}
.ws-tag.is-done{background:#e7f6ec;color:#0a7d2c}
.ws-tag.is-failed{background:#fdeceb;color:#c0392b}
.ws-tag.is-off{background:#f2f2f4;color:#86868b}
.ws-stage{margin-top:4px;max-width:112px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ws-progress{display:flex;align-items:center;gap:8px}
.ws-progress-bar{flex:1;height:6px;border-radius:99px;background:#f0f0f2;overflow:hidden}
.ws-progress-bar i{
  display:block;height:100%;border-radius:99px;background:#86868b;
  transition:width .3s ease;
}
.ws-progress-bar i.is-live{background:var(--blue)}
.ws-progress span{
  font-size:11px;color:var(--secondary);min-width:34px;text-align:right;
  font-variant-numeric:tabular-nums;
}
/* ⚠️ 操作列的 td 不能用 display:flex：td 被改成 flex 后脱离表格单元格布局，
   它的行分隔线就不再与其它列在一条水平线上（2026-10-29 用户截图反馈）。
   按钮排布改用行内布局 + margin，换行语义不变。 */
.ws-row-ops{white-space:normal}
.ws-row-ops .button,
.ws-row-ops .mini-button{margin:0 6px 4px 0}
.ws-row-btn{padding:6px 12px;font-size:12px}
.ws-empty{padding:40px 20px;text-align:center;color:var(--tertiary);font-size:12.5px;line-height:1.7}
/* ---------- 工作台：左主区 + 右侧任务面板（对齐参考网页 dashboard-grid-v3） ---------- */
.ws-dashboard-grid{display:grid;grid-template-columns:minmax(0,1fr) 390px;gap:13px;align-items:start}
.ws-dashboard-main{min-width:0}
.ws-task-panel{
  padding:16px 14px 12px;position:sticky;top:16px;
  display:flex;flex-direction:column;gap:10px;max-height:calc(100vh - 40px);
}
.ws-task-panel .task-head{
  display:flex;align-items:flex-start;justify-content:space-between;gap:8px;
  padding-bottom:12px;border-bottom:1px solid var(--line);
}
.ws-task-panel .task-head h2{font-size:17px;margin:0}
.ws-task-panel .task-head small{font-size:10px;color:var(--tertiary);display:block;margin-top:4px}
.ws-task-panel .ws-tabs{margin:0;flex:none}
.ws-task-panel .ws-tabs button{padding:6px 9px;font-size:10.5px}
.ws-task-panel .task-list{flex:1;min-height:0;overflow:auto;display:grid;gap:9px;align-content:start;padding-right:2px}
.ws-task-cards{display:grid;gap:9px;align-content:start}
/* 任务卡 */
.task-card{
  padding:12px;border-radius:15px;background:rgba(255,255,255,.72);
  border:1px solid rgba(255,255,255,.85);box-shadow:0 8px 24px rgba(44,49,59,.06);
  display:grid;gap:7px;transition:box-shadow .25s ease,transform .25s ease;
}
.task-card:hover{box-shadow:0 14px 34px rgba(44,49,59,.1);transform:translateY(-1px)}
.task-card.is-done{background:rgba(247,251,248,.78)}
.task-card.is-ended{background:rgba(250,248,247,.72)}
.task-title{display:flex;align-items:center;gap:9px}
.task-file-ic{
  width:30px;height:30px;border-radius:9px;background:#f1f1f3;flex:none;
  display:grid;place-items:center;color:var(--secondary);
}
.task-file-ic .icon{width:15px;height:15px}
.task-file-ic.is-ok{background:#e7f6ec;color:#0a7d2c}
.task-title strong{font-size:12.5px;font-weight:600;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
.task-title small{font-size:10px;color:var(--tertiary);display:block;margin-top:2px}
.task-file{font-size:10.5px;color:var(--secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.task-progress .ws-progress{gap:6px}
.task-progress .ws-progress-bar{height:5px}
.task-meta{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:10.5px;color:var(--secondary)}
.task-stage{font-size:10.5px;color:var(--orange);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.task-ops{display:flex;flex-wrap:wrap;gap:6px}
.ws-card-btn{padding:5px 11px;font-size:11.5px}
.risk-tags{display:flex;flex-wrap:wrap;gap:8px;font-size:10px;color:var(--secondary)}
.risk-tags span{display:inline-flex;align-items:center;gap:4px}
.risk-dot{display:inline-block;width:6px;height:6px;border-radius:50%;flex:none}
/* ---------- metric 统计卡（eyebrow + 数字滚动） ---------- */
.ws-stat.metric-v3{padding:16px 18px}
.kpi-head{display:flex;align-items:center;gap:8px}
.eyebrow{font-size:11.5px;color:var(--secondary);font-weight:500}
.metric-icon{
  width:26px;height:26px;border-radius:9px;background:#fff;flex:none;
  display:grid;place-items:center;color:var(--orange);font-size:13px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9);
}
.ws-stat.metric-v3 .ws-stat-value{font-size:32px;margin-top:8px}
.ws-stat.metric-v3 .ws-stat-sub{margin-top:4px;font-size:10.5px}
/* ---------- 工作台数据分析面板 ----------
   一张卡、三个区：上半左右两栏（任务分布 / 风险构成），下半通栏（月度趋势），
   区之间用发丝线分隔，不靠「一块块玻璃」区分层次。上一版是三张独立卡片，
   高度各自算（196/196/181），上下沿永远对不齐。 */
.ws-insight{
  padding:18px 22px 20px;margin:0 0 14px;
  background:var(--glass);border:1px solid rgba(255,255,255,.8);
  box-shadow:var(--shadow);border-radius:var(--radius);
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
}
.insight-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:4px}
.insight-head b{font-size:13.5px;letter-spacing:-.2px}
.insight-head small{display:block;font-size:11px;color:var(--tertiary);margin-top:3px}
.insight-badge{
  flex:none;font-size:10.5px;color:var(--secondary);
  padding:4px 9px;border-radius:99px;background:rgba(255,255,255,.75);
  border:1px solid rgba(255,255,255,.9);
}
.insight-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);margin-top:6px}
.insight-pane{min-width:0;padding:14px 0 2px;display:flex;flex-direction:column}
.insight-pane .donut-wrap{flex:1}
/* 竖分隔线用 padding 而不是 margin：grid 列宽仍严格 1:1，分栏不会一大一小。 */
.insight-pane + .insight-pane{border-left:1px solid var(--line);padding-left:26px}
.insight-pane:first-child{padding-right:26px}
.insight-trend{border-top:1px solid var(--line);margin-top:16px;padding-top:16px}
.pane-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:12px}
.pane-head b{font-size:12.5px;font-weight:600}
.pane-head small{font-size:10.5px;color:var(--tertiary)}
/* 环形图：conic-gradient 画扇区，中间的洞用同色实心圆盖住。
   不引入图表库 —— 这三张图的数据结构简单，加一个 200KB 的依赖不值得。 */
.donut-wrap{display:flex;align-items:center;gap:22px;min-height:126px}
.donut{width:112px;height:112px;border-radius:50%;flex:none;display:grid;place-items:center;position:relative}
.donut-hole{width:70px;height:70px;border-radius:50%;background:#fff;display:flex;flex-direction:column;align-items:center;justify-content:center;line-height:1.1;box-shadow:0 2px 10px rgba(44,49,59,.06)}
.donut-hole b{font-size:16px;font-weight:600}
.donut-hole small{font-size:10px;color:var(--tertiary);margin-top:2px}
.donut-legend{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px}
.donut-legend-row{display:flex;align-items:center;gap:8px;font-size:12px;min-width:0}
.donut-legend-row i{width:8px;height:8px;border-radius:3px;flex:none}
.donut-legend-row span{flex:1;min-width:0;color:var(--secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.donut-legend-row b{font-weight:600;flex:none;font-variant-numeric:tabular-nums}
/* 风险四柱：柱子高度按该档数量的相对值给，绝对数字写在下面 ——
   「高 3」和「低 30」画成等高柱会误导，但只给数字又看不出量级。 */
.risk-cols{display:flex;align-items:flex-end;gap:16px;height:126px}
.risk-col{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;gap:5px;height:100%}
.risk-col-track{flex:1;width:100%;display:flex;align-items:flex-end;border-radius:9px;background:rgba(44,49,59,.045);overflow:hidden}
.risk-col-track i{display:block;width:100%;border-radius:9px;transition:height .5s ease}
.risk-col b{font-size:12px;font-weight:600;font-variant-numeric:tabular-nums}
.risk-col span{font-size:10.5px;color:var(--tertiary)}
/* 月度趋势：SVG 铺满卡片宽度，preserveAspectRatio="none" 让它随列宽拉伸；
   横轴标签单独一行，避免挤在 SVG 里被拉伸变形。 */
.trend-wrap{display:flex;flex-direction:column;gap:8px}
.trend-svg{width:100%;height:104px;display:block;overflow:visible}
.trend-labels{display:flex;justify-content:space-between;font-size:10.5px;color:var(--tertiary);padding:0 1px}
.ws-chart-empty{
  padding:16px 18px;margin:0 0 14px;display:flex;flex-direction:column;gap:5px;
  background:var(--glass);border:1px solid rgba(255,255,255,.8);
  box-shadow:var(--shadow);border-radius:var(--radius);
}
.ws-chart-empty b{font-size:13px}
.ws-chart-empty span{font-size:11.5px;color:var(--tertiary)}
/* 窄屏：两栏变上下，竖分隔线换成横的（不换会变成左侧一条悬空的线）。
   断点定在 1320 而不是 1180：1280 宽时主列只剩 562px，两栏各 270px ——
   环形图 112px 之后图例只剩 84px，工具名全被省略号吃掉。 */
@media(max-width:1320px){
  .insight-split{grid-template-columns:1fr}
  .insight-pane + .insight-pane{
    border-left:0;border-top:1px solid var(--line);
    padding-left:0;padding-top:16px;margin-top:4px;
  }
  .insight-pane:first-child{padding-right:0}
}
/* 侧栏底部只保留 profile-nav 一份用户区。
   上一版在它下面又加了一张 user-mini 积分卡，等于同一个「账户信息」入口出现两次。 */
@media(max-width:1250px){
  .ws-dashboard-grid{grid-template-columns:minmax(0,1fr) 340px}
}
@media(max-width:980px){
  .ws-dashboard-grid{grid-template-columns:1fr}
  .ws-task-panel{position:static;max-height:none}
  .ws-task-list{max-height:620px}
}
@media(max-width:1080px){
  .ws-stats{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media(max-width:640px){
  .ws-stats{grid-template-columns:1fr}
  .ws-batch-grid{grid-template-columns:1fr}
}
.workspace-section-head{
  display:flex;align-items:end;justify-content:space-between;gap:16px;
  margin:0 0 12px;
}
.workspace-section-head h2{
  font-size:20px;font-weight:600;letter-spacing:-.025em;margin:0 0 5px;
}
.workspace-section-head p{font-size:11px;color:var(--secondary);margin:0}
.recommend-grid{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:12px;
}
.recommend-card{
  height:158px;
  padding:16px;
  display:flex;
  flex-direction:column;
  overflow:hidden;
  cursor:pointer;
  transition:border-color .16s ease,transform .16s ease,box-shadow .16s ease;
}
.recommend-card:hover{
  border-color:var(--line-strong);
  transform:translateY(-1px);
  box-shadow:0 7px 18px rgba(0,0,0,.04);
}
.recommend-top{display:flex;align-items:center;justify-content:space-between;gap:10px}
.usage-count{font-size:10px;color:var(--tertiary)}
.recommend-name{font-size:14px;font-weight:550;margin:13px 0 6px;letter-spacing:-.012em}
.recommend-desc{
  font-size:10.5px;line-height:1.55;color:var(--secondary);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.recommend-foot{
  margin-top:auto;padding-top:9px;display:flex;align-items:center;justify-content:space-between;
  font-size:9px;color:var(--tertiary);
}
.recommend-foot .chevron{font-size:15px}
.workspace-hint{
  margin-top:12px;font-size:10px;color:var(--tertiary);
  padding:10px 12px;border-radius:10px;background:#ededf0;
}

/* Audit workflow: exactly one viewport, no page/body scroll */
.review-page-shell{
  height:calc(100vh - 58px);
  min-height:0;
  overflow:hidden;
  padding-bottom:18px;
  display:grid;
  /* 两列：左侧书签栏（固定 58px）｜右侧步骤条 + 内容。
     上一版是「创建方式横排一行 + 步骤条 + 内容」三行，切换器把步骤条整条往下
     推了 50px，视觉重心偏离；竖排书签不占纵向空间。 */
  grid-template-columns:58px minmax(0,1fr);
  gap:14px;
}
.review-stage{display:grid;grid-template-rows:60px minmax(0,1fr);gap:14px;min-height:0;min-width:0}
/* ---------- 创建方式：左侧竖排书签 ---------- */
.mode-rail{
  display:flex;flex-direction:column;align-items:stretch;gap:8px;
  min-height:0;overflow:hidden;
}
.mode-rail-label{
  font-size:9.5px;color:var(--tertiary);letter-spacing:1.2px;text-align:center;
  padding:2px 0 4px;
}
.mode-bookmark{
  flex:none;width:100%;padding:22px 0;border:1px solid rgba(255,255,255,.85);
  border-radius:16px;background:rgba(255,255,255,.55);cursor:pointer;
  display:grid;place-items:center;
  box-shadow:0 2px 10px rgba(44,49,59,.04);
  transition:background .22s ease,box-shadow .22s ease,transform .22s ease;
}
.mode-bookmark .bm-label{
  /* 竖排：中文从上往下读是自然的，不需要 transform:rotate(90deg)
     —— 旋转会让标点在左侧、字形发糊。 */
  writing-mode:vertical-rl;text-orientation:upright;
  font-size:12.5px;letter-spacing:3px;color:var(--secondary);line-height:1.2;
}
.mode-bookmark:hover{background:#fff;transform:translateX(2px)}
.mode-bookmark.active{
  background:linear-gradient(135deg,#ff9b5d,#ef702d);border-color:transparent;
  box-shadow:0 10px 24px rgba(239,112,45,.26);
}
.mode-bookmark.active .bm-label{color:#fff;font-weight:600}
.mode-rail-hint{
  font-size:9.5px;color:var(--orange);text-align:center;line-height:1.4;
  padding:0 4px;
}
@media(max-width:980px){
  /* 窄屏书签横过来：竖排 58px 的栏在手机上吃掉太多横向空间。 */
  .review-page-shell{grid-template-columns:1fr;grid-template-rows:auto minmax(0,1fr)}
  .mode-rail{flex-direction:row;align-items:center;gap:8px;overflow:visible}
  .mode-rail-label{padding:0 4px 0 0}
  .mode-bookmark{width:auto;padding:0 16px;height:34px;border-radius:12px}
  .mode-bookmark .bm-label{writing-mode:horizontal-tb;letter-spacing:0}
  .mode-rail-hint{padding:0}
}
/* ---------- 批量创建结果 ---------- */
.batch-results{margin-top:14px;border:1px solid var(--line);border-radius:14px;overflow:hidden;background:var(--surface)}
.batch-results-head{display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid var(--line);background:var(--surface-subtle)}
.batch-results-head b{font-size:12.5px}
.batch-goto{margin-left:auto}
.batch-result-row{display:flex;align-items:center;gap:9px;padding:8px 14px;font-size:12px;border-top:1px solid var(--line)}
.batch-result-row:first-of-type{border-top:0}
.batch-result-dot{width:7px;height:7px;border-radius:50%;flex:none;background:var(--green)}
.batch-result-row.is-fail .batch-result-dot{background:#dc7772}
.batch-result-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.batch-result-note{color:var(--tertiary);font-size:11px;flex:none;max-width:46%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.batch-result-row.is-fail .batch-result-note{color:#c96b63}
.review-page-shell .stepper{
  height:60px;
  min-height:60px;
  margin:0;
  padding:0 18px;
  overflow-x:auto;
  overflow-y:hidden;
}
.review-layout{
  height:100%;
  min-height:0;
  display:grid;
  grid-template-columns:minmax(0,1fr) 280px;
  gap:14px;
}
.review-card{
  height:100%;
  min-height:0;
  padding:0;
  overflow:hidden;
}
.review-side{
  height:100%;
  min-height:0;
  padding:20px;
  position:static;
  overflow:auto;
}
.review-step-shell{
  height:100%;
  min-height:0;
  display:flex;
  flex-direction:column;
}
.review-step-scroll{
  flex:1 1 auto;
  min-height:0;
  overflow:auto;
  padding:28px 34px 20px;
}
.review-step-scroll h2{
  font-size:21px;font-weight:600;letter-spacing:-.025em;margin:0 0 7px;
}
.review-step-scroll> .muted{
  font-size:12px;line-height:1.6;margin-bottom:22px;
}
.review-actions{
  flex:0 0 74px;
  min-height:74px;
  margin:0 34px;
  padding:17px 0 18px;
  background:#fff;
  border-top:1px solid var(--line);
}
.review-page-shell .upload-zone{
  min-height:205px;
  height:clamp(205px,31vh,250px);
}
.loading-scroll{display:grid;place-items:center}
.loading-scroll .loading{padding:20px}

/* Rule selection box stays the same size, rows scroll inside */
.rules-card{
  height:360px;
  min-height:260px;
  max-height:calc(100% - 58px);
  margin-top:10px;
  display:flex;
  flex-direction:column;
  overflow:hidden;
}
.rules-toolbar{
  flex:0 0 auto;
  min-height:52px;
}
.rule-scroll{
  flex:1 1 auto;
  min-height:0;
  overflow:auto;
}
.rule-row{min-height:72px}

/* Rule editor fixed frame */
.fixed-page{
  overflow:hidden;
}
.editor-page-view{
  display:grid;
  grid-template-rows:auto minmax(0,1fr);
  padding-bottom:18px;
}
.editor-page-view .page-head{
  padding:18px 0 14px;
}
.editor-page-view .editor-layout{
  height:100%;
  min-height:0;
}
.editor-page-view .editor-main,
.editor-page-view .editor-side{
  height:100%;
  min-height:0;
}
.editor-page-view .editor-main{
  display:flex;
  flex-direction:column;
  overflow:hidden;
}
.editor-page-view .editor-main .table-wrap{
  flex:1 1 auto;
  min-height:0;
  overflow:auto;
}
.editor-page-view .editor-side{
  position:static;
  overflow:auto;
}
.editor-page-view .table thead th{
  position:sticky;top:0;z-index:2;
}

/* Utility boxes keep equal fixed size */
.tools-page-view .page-head{padding:18px 0 14px}
.tools-page-view .utility{
  height:410px;
  overflow:auto;
}

/* User center: **自然流 + 页面滚动**（2026-10-29 起）。
   曾经是「定高网格 + 各区内部滚动」的固定框架，反馈展开后行高重算在
   定高网格里不可靠 —— 记录卡直接叠到反馈卡中间（用户截图）。改为内容
   自然长高、滚动由 `.content` 的原生滚动承接（账户页模板已去掉
   fixed-page）：反馈展开多高页面就多高，记录卡永远在反馈卡**下方**，
   结构上不可能再互相遮挡。 */
.user-center-view{
  display:grid;
  grid-template-rows:auto auto;
  padding-bottom:18px;
}
.user-center-view .page-head{padding:18px 0 14px}
.user-center-view .user-layout{
  min-height:0;
}
.user-center-view .profile-card{
  min-height:0;
  display:flex;
  flex-direction:column;
}
.profile-actions{
  margin-top:auto;
  padding-top:18px;
  display:grid;
  gap:8px;
}
.logout-button{width:100%;border:1px solid rgba(215,0,21,.12)}
.user-main-column{
  min-height:0;
  display:grid;
  /* 四行：余额 / 邀请 / 问题反馈 / 流水。**行数必须等于卡片数**，少一行会把多出来的
     卡片压进最后一行。余额行 124px；其余自然高 —— 页面（.content）滚动，
     反馈展开多高都不会挤压/遮挡别的卡（2026-10-29，见 .user-center-view 注释）。 */
  grid-template-rows:124px auto auto auto;
  gap:14px;
}
.user-main-column .balance-card{
  height:100%;
  min-height:0;
}
/* 反馈卡：折叠态 min-height 105px（用户 2026-10-28 反馈太高，要求减半；
   自然流下这一行就是 auto，min-height 只影响折叠态的视觉下限）。
   padding:18px 20px 曾在包替换时丢失（折叠头文字贴边），一并恢复。 */
.user-main-column .feedback-card{min-height:105px;padding:18px 20px}
.user-main-column .invite-card{
  padding:18px 20px;
}
/* 邀请卡：左「邀请链接 + 复制」/ 右「三个统计」两段式 grid。
   原来是 flex + `margin-left:auto`，统计块被挤到右边后又换行，
   标签正好压在下面的说明条上（用户截图）。grid 明确分栏，互不侵占。 */
.invite-body{
  display:grid;
  grid-template-columns:minmax(0,1fr) auto;
  align-items:center;
  gap:14px 24px;
  margin-top:12px;
}
/* 邀请链接整串展示（?invite=码#auth）：等宽小字、可选中、超长折行。
   不再显示裸邀请码 —— 码只在链接里流转。 */
.invite-link-box{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:6px;
  min-width:0;
}
.invite-link{
  font-family:var(--mono,ui-monospace,Menlo,Consolas,monospace);
  font-size:12.5px;
  line-height:1.5;
  color:var(--secondary);
  word-break:break-all;
  user-select:all;
  max-width:100%;
}
.invite-stats{
  display:grid;
  grid-template-columns:repeat(3,minmax(72px,auto));
  gap:10px 26px;
  justify-self:end;
  text-align:right;
}
/* 窄屏时统计块换到下一行并左对齐，别再和邀请码抢同一行 */
@media (max-width:560px){
  .invite-body{grid-template-columns:minmax(0,1fr)}
  .invite-stats{grid-template-columns:repeat(3,minmax(0,1fr));justify-self:stretch;text-align:left}
}
.invite-stats b{
  display:block;
  font-size:19px;
  line-height:1.25;
}
.invite-stats span{
  display:block;
  font-size:11px;
  color:var(--secondary);
}
.user-main-column .records{
  margin:0;
  display:flex;
  flex-direction:column;
  overflow:hidden;
}
.records-head{
  flex:0 0 auto;
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding-bottom:10px;
}
.records-head .segmented{margin:0}
/* 表格区**自带高度上限**（自然流下卡片不再被 1fr 行约束）：
   记录多时表格自己滚、表头吸顶仍然生效，卡片不会把页面拉得过长；
   记录少时按内容收缩。 */
.records-scroll{
  flex:0 0 auto;
  min-height:0;
  max-height:min(460px,56vh);
  overflow:auto;
  border-top:1px solid var(--line);
}
.records-scroll .table thead th{
  position:sticky;top:0;z-index:3;
  /* macOS 毛玻璃吸顶：半透明 + blur，滚动时行内容从表头下隐约透出。 */
  background:rgba(251,251,253,.86);
  backdrop-filter:saturate(180%) blur(16px);
  -webkit-backdrop-filter:saturate(180%) blur(16px);
}

/* Chat and planned pages also stay inside viewport */
.ai-page-view{
  display:grid;
  grid-template-rows:auto minmax(0,1fr);
  padding-bottom:18px;
}
.ai-page-view .page-head{padding:18px 0 14px}
.ai-page-view .chat-layout{
  height:100%;
  min-height:0;
}
.planned-page-view{
  display:grid;
  grid-template-rows:auto minmax(0,1fr);
  padding-bottom:18px;
}
.planned-page-view .page-head{padding:18px 0 14px}
.planned-page-view .empty-state{height:100%;min-height:0}

/* Slightly denser sidebar so all navigation remains visible without scrolling */
.nav-section{margin:7px 0}
.nav-item{height:36px}
.nav-label{padding-bottom:4px}

@media(max-width:1080px){
  .recommend-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .recommend-card{height:150px}
  .review-layout{grid-template-columns:minmax(0,1fr) 250px}
}
@media(max-width:780px){
  .app-main{padding:0 14px 14px}
  .content{height:calc(100vh - 58px)}
  .recommend-grid{grid-template-columns:1fr}
  .workspace-view{overflow:auto}
  .review-page-shell{grid-template-columns:1fr;grid-template-rows:auto minmax(0,1fr);gap:10px;padding-bottom:12px}
  .review-stage{grid-template-rows:54px minmax(0,1fr);gap:10px}
  .review-page-shell .stepper{height:54px;min-height:54px}
  .review-layout{grid-template-columns:1fr}
  .review-side{display:none}
  .review-step-scroll{padding:20px}
  .review-actions{margin:0 20px}
  .user-center-view{display:block}
  .user-main-column{grid-template-rows:auto}
  .profile-card{min-height:520px}
  .editor-page-view{overflow:auto;display:block}
  .editor-page-view .editor-layout{height:auto}
  .tools-page-view .utility{height:auto;min-height:360px}
}

/* ---------- Phase 2: 文件直传与任务状态 ---------- */
.upload-input{display:none}
.upload-zone.disabled{cursor:not-allowed;opacity:.72}
.upload-zone.disabled:hover{border-color:#bdbdc2}
.upload-zone.is-dragging{border-color:#1d1d1f;background:#f2f2f5}
.upload-progress{margin-top:14px;padding:14px;border:1px solid var(--line);border-radius:12px;background:#fbfbfd}
.upload-progress-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;font-size:11px}
.upload-progress-head span:first-child{min-width:0;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.upload-progress-head span:last-child{flex:0 0 auto;color:var(--tertiary)}
.note-box.danger{background:#fff2f2;color:#a3000f}
.loading-actions{display:flex;flex-wrap:wrap;gap:9px;justify-content:center;margin-top:23px}
.rule-section-title{padding:11px 14px;font-size:10px;letter-spacing:.04em;color:var(--tertiary);background:#fbfbfd;text-transform:uppercase}
.rule-row-locked{background:#fbfbfd}
.rule-row-locked .rule-name{font-weight:400;color:#6e6e73}
.rule-row-mine{grid-template-columns:28px minmax(0,1fr) 130px}
.rule-row-plain{grid-template-columns:minmax(0,1fr) auto;background:#fff}
.confirm-box b{overflow-wrap:anywhere}
.report-banner{padding:11px 19px;font-size:11px;line-height:1.6;color:#8a5a10;background:#fdf4e3;border-bottom:1px solid rgba(237,160,63,.24)}
/* 报告正文：服务端规范产物（report.html）经 iframe 承载，见 app.js::realReportShell。
   iframe 要 flex:1 **且** min-height:0 —— flex 子项默认 min-height:auto，
   只写 flex:1 会被内容高度顶开、撑不出滚动。 */
.report-app--document .report-frame{flex:1;min-height:0;width:100%;border:0;display:block;background:#eeecea}
/* 模拟模型护栏横幅：产物里的同类提示藏在「审核范围与局限」列表，用户要滚下去才看到，
   而模拟报告与真实报告结构完全一致 —— 所以在外层再放一条常驻提醒。 */
.report-engine-banner{
  flex:0 0 auto;display:flex;gap:9px;align-items:baseline;
  padding:10px 16px;font-size:11px;line-height:1.6;
  color:#a3352e;background:#fdeeec;border-bottom:1px solid rgba(224,90,82,.24);
}
.report-engine-banner b{flex:0 0 auto;font-weight:600}

/* ---------- 我的规则（独立一页） ----------
 * 规则库是**内容长度不可预估**的（一个库几十条规则，展开后更高）。
 * 定高框架装不下它 —— 与「邀请卡」那次踩的坑同一类。所以这一页
 * 整页滚动；账户信息页维持原来的定高 + 内部滚动。 */
/* 「我的规则」页：**表头以下部分滑动查看**（用户 2026-10-28 明确要求）。
   页面表头（「我的规则」标题 + 账户信息入口）固定；表头以下是一整块滚动区，
   里面规则库列表与提取面板一起滚 —— 只保留**一个**滚动条。
   ⚠️ 曾做成「左栏列表自己滚 + 右栏面板自己滚」，两个小窗口互相抢滚动，
   用户反馈「不对」。 */
.rules-page-view{
  overflow:hidden;
  display:grid;
  grid-template-rows:auto minmax(0,1fr);
  padding-bottom:18px;
}
.rules-page-view .page-head{
  padding:18px 0 14px;
  display:flex;align-items:flex-start;justify-content:space-between;gap:12px;
}
/* 规则页 / 标讯页统一版式：**上方设置（可折叠）+ 下方成果列表**，单列堆叠。
   上一版是「左列表 + 右设置」两栏，设置常驻占掉 360–380px，列表挤在剩下的
   宽度里，一到 1280 就只剩三四列可读。 */
.user-rules-layout{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:14px;
  align-items:start;
  /* 行高按内容给，别撑满容器：`height:100%` + 默认 align-content 会把两行
     平均拉开，设置收起后标题和下面的列表之间会出现一大段空白。 */
  align-content:start;
  min-height:0;
  height:100%;
  /* 唯一的滚动容器：表头以下的一切都在这里滚。 */
  overflow-y:auto;
  overscroll-behavior:contain;
  scrollbar-gutter:stable;
  padding-right:4px;
}
/* ---------- 可折叠设置面板（规则提取 / 标讯采集设置共用） ---------- */
.foldable{position:relative}
.fold-head{
  display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
  cursor:default;
}
.fold-head-main{min-width:0}
.fold-head-main b{display:block;font-size:15.5px;letter-spacing:-.2px}
.fold-head-main small{display:block;margin-top:4px;font-size:11.5px;color:var(--tertiary);line-height:1.6}
.fold-btn{
  flex:none;padding:6px 13px;border-radius:999px;cursor:pointer;
  border:1px solid rgba(255,255,255,.9);background:rgba(255,255,255,.7);
  color:#5f5f66;font-size:12px;white-space:nowrap;
  box-shadow:0 2px 8px rgba(44,49,59,.05);
  transition:background .2s ease,color .2s ease,box-shadow .2s ease,transform .2s ease;
}
.fold-btn:hover{background:#fff;color:var(--orange-deep);box-shadow:0 4px 14px rgba(44,49,59,.09);transform:translateY(-1px)}
.fold-btn:focus-visible{outline:2px solid var(--orange2);outline-offset:2px}
/* 收起 = 只留标题行。用 :not(.fold-head) 而不是逐个列子节点，
   这样任何面板往里加一段内容都不用同步改样式。 */
.foldable.is-folded > :not(.fold-head){display:none}
.foldable.is-folded .fold-head{padding-bottom:2px}
.foldable.is-folded .fold-head-main b::after{
  content:"已收起";margin-left:9px;padding:2px 8px;border-radius:999px;
  background:rgba(244,123,53,.1);color:var(--orange-deep);font-size:10.5px;font-weight:500;
  vertical-align:middle;
}
.rule-libs-host,.rule-extract-host{min-width:0}
.rule-libs-card{
  padding:20px;background:var(--glass);border:1px solid rgba(255,255,255,.8);
  box-shadow:var(--shadow);border-radius:var(--radius);
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
}
/* 适用审核对象的多选控件（提取面板）：药丸式勾选，一眼看出选了哪几个 */
.rule-object-picker{display:flex;flex-wrap:wrap;gap:8px}
.rule-object-option{
  display:inline-flex;align-items:center;gap:7px;
  padding:7px 12px;border-radius:999px;border:1px solid var(--line);
  background:var(--surface);font-size:12.5px;cursor:pointer;
  transition:background .15s ease,border-color .15s ease;
}
.rule-object-option:hover{border-color:#c9c9cf}
.rule-object-option.is-on{background:#e8f0fe;border-color:#a9c4f5;color:#1a56c4;font-weight:500}
.rule-object-option input{width:14px;height:14px;accent-color:var(--blue);margin:0}
/* 多对象库里逐条标出「这条规则管哪个对象」 */
.rule-object-chip{
  display:inline-block;margin-left:6px;padding:1px 7px;border-radius:999px;
  background:#f1f1f3;color:#6e6e73;font-size:10.5px;vertical-align:middle;
}
.rule-libs-list{display:grid;gap:12px}
/* 表格表头吸顶：滚动到这行时它停在滚动区顶部，列名始终可读。
   规则一多（几十条）全靠这一条才看得懂哪列是什么。 */
.rule-libs-list .table-wrap{overflow:visible}
.rule-libs-list .table thead th{
  position:sticky;
  top:-1px;
  z-index:3;
  background:rgba(251,251,253,.94);
  backdrop-filter:saturate(180%) blur(12px);
  -webkit-backdrop-filter:saturate(180%) blur(12px);
  box-shadow:0 1px 0 var(--line);
}
/* 列表表格：**行高跟随内容**，描述必须完整显示（用户 2026-10-28 要求）。
   ⚠️ 不要再加 -webkit-line-clamp / max-height / 省略号：规则描述是用户判断
   「这条规则到底查什么」的唯一入口，截断等于让人点开编辑才能读全文。 */
.rule-table-compact td{
  vertical-align:top;
  height:auto;
  padding:12px 10px;
}
.rule-table-compact tr{height:auto}
.rule-cell-id{
  font-family:var(--mono,ui-monospace,Menlo,Consolas,monospace);
  font-size:11px;
  color:var(--secondary);
  white-space:nowrap;
}
.rule-cell-name{font-weight:500}
.rule-cell-name b{font-weight:500;display:block;line-height:1.5}
.rule-cell-desc{
  font-size:12px;
  line-height:1.75;
  color:var(--text);
  white-space:pre-wrap;      /* 描述里的「审核目标：/核心事实：」两行要分行显示 */
  overflow-wrap:anywhere;
}
/* 同上：td 保持 table-cell，按钮用行内布局（竖排由列宽自然换行产生） */
.rule-cell-ops{
  white-space:normal;
}
.rule-cell-ops .mini-button{margin:0 6px 6px 0}
/* 停用态：整行降透明度 + 名称旁一枚小标，避免「以为规则在跑」 */
.rule-state-chip{
  display:inline-block;
  margin-top:5px;
  padding:1px 7px;
  border-radius:999px;
  background:#f2f2f4;
  color:var(--tertiary);
  font-size:10px;
  font-weight:500;
}
.rule-row-off .rule-cell-desc{color:var(--secondary)}
/* 「生成失败」：自动重建没成功，三列还是改描述前那版。用红字 + 原因，
   别只留一个中性灰 chip —— 用户看不出这条规则其实没按他的描述生效。 */
.rule-state-chip.is-bad{background:rgba(255,59,48,.1);color:#c9271c}
.rule-regen-err{
  margin-top:6px;
  font-size:11px;
  line-height:1.5;
  font-weight:400;
  color:#c9271c;
  white-space:normal;
}
.rule-lib-card{
  border:1px solid rgba(255,255,255,.8);
  border-radius:12px;
  padding:15px;
  background:var(--glass);
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
  box-shadow:var(--shadow);
}
.rule-lib-head{
  display:flex;align-items:flex-start;justify-content:space-between;
  gap:12px;margin-bottom:7px;
}
.rule-lib-name{font-size:12px;font-weight:600;margin-bottom:4px}
.rule-lib-ops{display:flex;flex-wrap:wrap;gap:6px;flex:0 0 auto}
.rule-extract-card{
  padding:20px;background:var(--glass);border:1px solid rgba(255,255,255,.8);
  box-shadow:var(--shadow);border-radius:var(--radius);
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
}
/* 粘贴 / 上传并排，中间用一枚「或」小圆标补上原来的分隔行。 */
.extract-methods{display:grid;grid-template-columns:1fr 1fr;gap:26px;position:relative;margin-top:4px}
.extract-methods::after{
  content:"或";position:absolute;left:50%;top:58px;transform:translate(-50%,-50%);
  width:26px;height:26px;border-radius:50%;display:grid;place-items:center;
  background:#fff;border:1px solid var(--line);color:var(--tertiary);
  font-size:11px;pointer-events:none;z-index:1;
}
@media(max-width:900px){
  .extract-methods{grid-template-columns:1fr;gap:14px}
  .extract-methods::after{display:none}
}
@media(max-width:1080px){
  /* 窄屏单列：改由页面自己滚（一道滚动条），否则 1fr 行里的滚动区
     会和页面滚动作业叠加，手机上手势很难受。 */
  .rules-page-view{display:block;overflow:auto}
  .user-rules-layout{grid-template-columns:1fr;height:auto;overflow:visible;padding-right:0}
  /* 表格在窄屏允许横向滚动（列宽有下限，硬压会挤成一片字） */
  .rule-libs-list .table-wrap{overflow-x:auto}
}
/* 规则区拆成独立一页后，账户信息页恢复「定高 + 内部滚动」。
   之前改成整页滚动是为容纳规则区，现在理由已消失 —— 留着会让
   积分流水表按内容撑高、整页高度失控（见 .user-main-column 注释）。 */
@media(max-width:900px){
  .user-rules-layout{grid-template-columns:1fr}
}

/* ---------- 平台规则总开关 ---------- */
.rule-row-system{grid-template-columns:28px minmax(0,1fr)}
.rule-row-system .rule-name{font-weight:600}
.rule-row-system:not(.is-on){background:#fbfbfd}
.rule-row-system:not(.is-on) .rule-name{color:#6e6e73;font-weight:400}

/* ---------- 公告铃铛（用户端） ---------- */
.bell-button{
  position:relative;width:34px;height:34px;border-radius:10px;border:1px solid var(--line);
  background:var(--surface);display:inline-flex;align-items:center;justify-content:center;
  cursor:pointer;padding:0;flex:none;
}
.bell-button:hover{border-color:var(--line-strong)}
.bell-button .icon{width:16px;height:16px;color:var(--secondary)}
.bell-button .icon svg{width:100%;height:100%}
.bell-dot{
  position:absolute;top:-3px;right:-3px;width:9px;height:9px;border-radius:50%;
  background:var(--red);border:2px solid var(--surface);box-sizing:content-box;
}
.bell-panel{
  position:absolute;top:52px;right:16px;width:340px;max-height:420px;overflow:auto;
  background:var(--surface);border:1px solid var(--line);border-radius:14px;
  box-shadow:0 12px 40px rgba(0,0,0,.14);z-index:60;padding:6px;
}
.bell-panel-head{
  display:flex;align-items:center;justify-content:space-between;
  padding:10px 12px 8px;font-size:13px;
}
.bell-unread{font-size:11px;color:var(--red);font-weight:600}
.bell-item{
  padding:10px 12px;border-radius:10px;cursor:pointer;
}
.bell-item:hover{background:var(--surface-subtle)}
.bell-item-head{display:flex;align-items:center;gap:7px;font-size:13px;line-height:1.4}
.bell-item-head b{font-weight:600;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bell-item-dot{width:7px;height:7px;border-radius:50%;background:var(--blue);flex:none}
.bell-item-time{font-size:11px;color:var(--tertiary);flex:none}
.bell-item-body{
  font-size:12px;color:var(--secondary);line-height:1.6;margin-top:4px;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
}
.bell-item.unread .bell-item-head b{color:var(--text)}
.bell-empty{padding:22px 12px;text-align:center;font-size:12px;color:var(--tertiary)}

/* ---------- 后台：模型来源 ---------- */
.llm-effective{
  display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  background:var(--surface-subtle);border:1px solid var(--line);border-radius:12px;
  padding:12px 14px;font-size:13px;
}
.llm-active-toggle{display:flex;gap:8px}
/* ⚠️ 这里曾经也叫 `.segmented` —— 与账户页/后台的**药丸筛选条**同名，
   结果这条 grid 规则全局覆盖了药丸条，账户页的「全部/充值/消耗/赠送」
   被排成 2×2（用户截图里能看到）。两列卡片网格一律用 `.seg-grid`。 */
.seg-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px}
.seg-item{
  text-align:left;border:1px solid var(--line);border-radius:12px;background:var(--surface);
  padding:13px 15px;cursor:pointer;display:flex;flex-direction:column;gap:3px;
}
.seg-item:hover{border-color:var(--line-strong)}
.seg-item.active{border-color:#185FA5;background:#E6F1FB}
.seg-item b{font-size:14px;font-weight:500;color:var(--text)}
.seg-item span{font-size:12px;color:var(--secondary)}
.seg-item.active b{color:#0C447C}
.ep-list{display:flex;flex-direction:column;gap:12px;margin-top:10px}
.ep-row{border:1px solid var(--line);border-radius:12px;padding:12px 14px;background:var(--surface)}
.ep-row.is-primary{border-color:#0F6E56;background:#F4FBF8}
.ep-row-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.ep-row-head .button{padding:5px 12px;font-size:12px}
.ep-label{max-width:220px;flex:1;min-width:140px}
.ep-radio,.ep-enabled{display:inline-flex;align-items:center;gap:5px;font-size:12px;color:var(--secondary);white-space:nowrap}
.ep-row-body{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:10px;margin-top:10px}
.ep-row-body .field{margin:0}
.ep-row-warn{margin-top:8px;font-size:12px;color:#A32D2D}
.llm-save-bar{display:flex;align-items:flex-end;gap:10px;margin-top:18px;flex-wrap:wrap}
@media (max-width:720px){
  .segmented{grid-template-columns:1fr}
  .ep-row-body{grid-template-columns:1fr}
}

/* 营销策略：套餐行编辑器 + 活动开关（2026-10-12 后台去演示化） */
.mk-row{display:grid;grid-template-columns:1.4fr .8fr 1fr auto auto;gap:10px;align-items:center;margin-bottom:8px}
.mk-row .mk-name{min-width:120px}
.mk-amount{display:flex;align-items:center;gap:6px}
.mk-amount .input{width:100%}
.mk-amount span{font-size:12px;color:var(--secondary)}
.mk-points{font-size:12px;color:var(--secondary);white-space:nowrap}
/* 用户端充值弹窗的套餐档位 */
.pkg-chips{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:8px}
.pkg-chip{display:flex;flex-direction:column;gap:2px;align-items:flex-start;border:1px solid var(--line);border-radius:10px;background:var(--surface);padding:8px 10px;cursor:pointer;text-align:left}
.pkg-chip:hover{border-color:var(--line-strong)}
.pkg-chip b{font-size:13px;color:var(--text)}
.pkg-chip span{font-size:12px;color:var(--secondary)}
.pkg-chip small{font-size:11px;color:var(--secondary)}
@media (max-width:720px){.mk-row{grid-template-columns:1fr 1fr}}

/* ---------- 用户反馈（用户中心提交 + 我的反馈；后台处理） ---------- */
/* 折叠头：平时只占一行，把「被采纳送多少积分」摆在最显眼处（那是用户点它的理由），
   右边带「我的反馈 N 条 · M 条已回复」——收起时也得让人看见有人回了他。 */
/* 折叠头：**顶对齐**而不是居中 ——
   标题 + 说明是上下两行，垂直居中的箭头会正好落在两行文字中间，
   视觉上像是压住了那行字（用户截图）。改成顶对齐后箭头与标题同一基线。 */
.feedback-toggle{
  width:100%;display:flex;align-items:flex-start;gap:12px;background:transparent;border:0;
  padding:0;cursor:pointer;text-align:left;
}
.feedback-toggle-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}
.feedback-toggle-title{font-size:15px;font-weight:600;letter-spacing:-.01em;color:var(--text)}
.feedback-toggle-sub{font-size:12px;line-height:1.6;color:var(--secondary);overflow-wrap:anywhere}
.feedback-toggle-sub b{color:#0a7d2c;font-weight:600}
.feedback-toggle-side{display:flex;align-items:center;gap:7px;flex:none;padding-top:2px}
.feedback-count{font-size:11px;color:var(--tertiary);white-space:nowrap}
.feedback-toggle .chevron{transition:transform .18s ease}
.feedback-toggle[aria-expanded="true"] .chevron{transform:rotate(90deg)}
.feedback-textarea{min-height:88px;resize:vertical;line-height:1.7;font-family:inherit}
.feedback-form .field{margin-bottom:12px}
.feedback-actions{display:flex;align-items:center;gap:10px}
/* 反馈弹窗（2026-10-29）：卡片只是入口，表单+历史记录都在弹窗里。
   历史区自带滚动上限，反馈再多也不会把弹窗撑到超出视口。 */
.feedback-modal .panel-title{margin-bottom:2px}
.feedback-modal-history{margin-top:16px;border-top:1px solid var(--line);padding-top:12px}
.feedback-modal-history-title{font-size:13px;font-weight:600;margin-bottom:10px;color:var(--text)}
.feedback-modal .feedback-list{max-height:36vh;overflow-y:auto;overscroll-behavior:contain}
.feedback-modal-actions{display:flex;justify-content:flex-end;margin-top:14px}
.feedback-list{margin-top:16px;display:flex;flex-direction:column;gap:10px}
.feedback-list:empty{margin-top:0}
.feedback-item{
  border:1px solid var(--line);border-radius:12px;padding:11px 13px;background:var(--surface-subtle);
}
.feedback-item-head{display:flex;align-items:center;gap:8px;margin-bottom:7px}
.feedback-item-meta{font-size:11px;color:var(--tertiary);flex:1;min-width:0}
.feedback-item-reward{font-size:11px;font-weight:600;color:#0a7d2c}
.feedback-item-body{
  font-size:12.5px;line-height:1.7;color:var(--text);
  white-space:pre-wrap;overflow-wrap:anywhere;
}
.feedback-item-reply{
  margin-top:9px;padding:9px 11px;border-radius:10px;
  background:#fff;border:1px solid var(--line);
  font-size:12.5px;line-height:1.7;color:var(--secondary);
  white-space:pre-wrap;overflow-wrap:anywhere;
}
.feedback-item-reply b{color:var(--blue);font-weight:600}
/* 状态标签：三档配色与"待处理优先被看见"的顺序一致（红 > 蓝 > 绿）。 */
.feedback-chip{
  flex:none;display:inline-block;padding:2px 8px;border-radius:999px;
  font-size:10px;font-weight:600;line-height:1.6;
}
.feedback-chip.is-pending{background:#fdeceb;color:#c0392b}
.feedback-chip.is-replied{background:#e8f0fe;color:#1a56c4}
.feedback-chip.is-accepted{background:#e7f6ec;color:#0a7d2c}
.fb-cell{max-width:380px}
.fb-cell-reply{margin-top:4px;font-size:11px;color:var(--tertiary)}
.fb-actions{display:flex;align-items:center;gap:6px;white-space:nowrap}
/* 内容整格可点 → 详情弹窗（正文只显示前 60 字，长反馈必须能点开看全文+截图）。 */
.fb-cell-click{cursor:pointer;border-radius:8px;padding:4px 6px;margin:-4px -6px;transition:background .15s}
.fb-cell-click:hover{background:var(--surface-subtle)}
.fb-cell-text{display:block}
.fb-cell-imgs{display:inline-flex;align-items:center;gap:3px;margin-top:3px;font-size:11px;color:var(--blue)}
.fb-cell-imgs .icon{width:12px;height:12px}

/* ---------- 留言截图：拖拽/粘贴区、缩略图、大图 ---------- */
.feedback-drop{
  border:1px dashed var(--line-strong);border-radius:12px;padding:10px;
  background:var(--surface-subtle);
}
.feedback-drop-actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.feedback-thumbs{display:flex;flex-wrap:wrap;gap:8px}
.feedback-thumbs:empty{display:none}
.feedback-thumb-box{position:relative}
.feedback-thumb{
  width:74px;height:74px;object-fit:cover;border-radius:9px;border:1px solid var(--line);
  background:#fff;cursor:zoom-in;display:block;
}
.feedback-thumb:hover{border-color:var(--line-strong)}
.feedback-thumb-del{
  position:absolute;top:-6px;right:-6px;width:20px;height:20px;border-radius:50%;
  border:2px solid var(--surface);background:#1d1d1f;color:#fff;font-size:12px;line-height:1;
  display:grid;place-items:center;cursor:pointer;padding:0;
}
.fb-detail-thumbs{margin-top:12px}
.image-lightbox{padding:40px}
.image-lightbox img{
  max-width:100%;max-height:100%;border-radius:12px;box-shadow:0 25px 70px rgba(0,0,0,.35);
}
.image-lightbox{cursor:zoom-out}
.image-lightbox img{cursor:default}

.profile-legal{display:flex;align-items:center;justify-content:center;gap:6px;margin-top:6px;font-size:11px;color:var(--tertiary)}
.profile-legal .link-button{padding:4px 2px;font-size:11px;color:var(--tertiary)}
.profile-legal .link-button:hover{color:var(--text)}
.profile-legal span{color:var(--line-strong);user-select:none}

/* ---------------- 标讯搜集 ----------------
   与「我的规则」同一套版式：上方可折叠采集设置、下方标讯列表，
   共用 .user-rules-layout 的栅格，这里只补本页特有的列表与设置卡样式。 */
.bid-list-host,.bid-settings-host{min-width:0;display:flex;flex-direction:column;gap:12px}
.bid-toolbar{display:flex;gap:8px;align-items:center;margin-bottom:10px}
.bid-toolbar .bid-search{flex:1;min-width:0}
.bid-toolbar .bid-select{width:150px;flex:none}
/* 导出是个 <a>：浏览器默认给它下划线，这里按按钮口径抹掉。 */
.bid-toolbar .bid-export-link{text-decoration:none;flex:none;white-space:nowrap}
/* 勾了行之后按钮变成「导出选中 N 条」，给它一点强调 —— 否则用户分不清
   自己点的是「全部」还是「刚勾的那几条」。 */
.bid-toolbar .bid-export-link.is-selected{color:var(--blue);border-color:rgba(244,123,53,.45);background:rgba(244,123,53,.07)}
.bid-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;margin-bottom:12px}
.bid-stat{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:12px 14px;display:flex;flex-direction:column;gap:2px}
.bid-stat b{font-size:20px;font-weight:600;letter-spacing:-.02em}
.bid-stat span{font-size:11px;color:var(--tertiary)}
/* 标讯列表是**表格**，不是卡片流。
   用户 2026-11-02：「招标信息没有以列表的形式展示，给了个公告链接」——
   原来的卡片式单行 + 「打开原文」大按钮，看起来就是把一个公告地址贴上来。
   表格的价值在于可扫读：标题一列，来源/日期/操作各一列，能横着比。 */
.bid-count{font-size:11px;color:var(--tertiary);margin:0 0 8px}
.bid-table-wrap{background:var(--surface);border:1px solid var(--line);border-radius:14px;overflow:auto}
.bid-table{min-width:520px}
.bid-table thead th{position:sticky;top:0;z-index:1;white-space:nowrap}
.bid-table .bid-col-no{width:38px;color:var(--tertiary);font-variant-numeric:tabular-nums}
/* 勾选列：只放一个框，宽度按框算，别跟着表头文字撑开。 */
.bid-table .bid-col-check{width:32px;padding-left:4px;padding-right:0;text-align:center}
.bid-table .bid-col-check input{margin:0;cursor:pointer;vertical-align:middle}
.bid-table .bid-col-check input:disabled{cursor:not-allowed}
.bid-table tbody tr:hover .bid-col-check input{cursor:pointer}
.bid-table .bid-col-source{width:132px}
.bid-table .bid-col-date{width:96px;white-space:nowrap;color:var(--secondary)}
.bid-table .bid-col-ops{width:104px;text-align:right;white-space:nowrap}
.bid-row:hover td{background:#fbfbfd}
/* 展开详情后让整行保持底色：否则用户点开的那一行和下面的详情块在视觉上断开，
   分不清详情属于哪一条。 */
.bid-row.is-open td{background:rgba(244,123,53,.04)}
.bid-table .mini-button{margin-left:6px}
.bid-table .mini-button:first-child{margin-left:0}
.bid-table a.mini-button{text-decoration:none}
.bid-sub{font-size:11px;color:var(--tertiary);margin-top:3px}
.bid-detail-row td{padding:0 10px 12px;background:rgba(244,123,53,.04)}
.bid-detail{display:flex;flex-direction:column;gap:6px;border-left:2px solid rgba(244,123,53,.35);padding:2px 0 2px 12px}
.bid-detail-kv{display:flex;gap:10px;font-size:11px;line-height:1.6}
.bid-detail-kv span{flex:none;width:88px;color:var(--tertiary)}
.bid-detail-kv b{font-weight:400;color:var(--secondary)}
.bid-more{display:flex;justify-content:center;padding:14px 0}
.bid-title{font-size:14px;font-weight:500;color:var(--text);text-decoration:none;line-height:1.45}
.bid-title:hover{color:var(--blue)}
.bid-meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.bid-chip{display:inline-block;padding:1px 8px;border-radius:999px;background:var(--surface-subtle);border:1px solid var(--line);font-size:11px;color:var(--secondary);max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bid-settings{display:flex;flex-direction:column;gap:12px}
/* 标讯的设置容器本身没有卡片外观（里面每块是独立 .card），
   所以折叠标题要自带一张卡，否则收起后只剩两行字浮在背景上。 */
.bid-settings > .fold-head{
  padding:14px 16px;align-items:center;
  background:var(--glass);border:1px solid rgba(255,255,255,.8);
  border-radius:var(--radius);box-shadow:var(--shadow);
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
}
/* 卡片区独立成块：重绘它（改关键词/范围/开关）时不能连带底部保存栏 ——
   保存栏节点被换掉，用户正在按下的那次点击就没了。 */
.bid-settings-cards{display:flex;flex-direction:column;gap:12px}
/* 说明文字左对齐：.form-note 原本是给登录表单用的居中排版，
   放到多行说明的设置项下面会读起来一顿一顿的。 */
.bid-card .form-note{text-align:left;margin-top:8px}
.bid-card{padding:14px 16px}
.bid-card h2{font-size:14px;font-weight:500;margin:0 0 8px}
.bid-card-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
.bid-card-head h2{margin:0}
/* 卡片头右侧：统计文字 + 全选。两者贴在一起，别让「已选 N 个」被挤到下一行。 */
.bid-head-right{display:flex;align-items:center;gap:10px;flex:none}
.bid-selectall{display:inline-flex;align-items:center;gap:5px;font-size:12px;color:var(--secondary);
  cursor:pointer;user-select:none;padding:2px 6px;border-radius:7px;white-space:nowrap}
.bid-selectall:hover{background:var(--surface-subtle);color:var(--text)}
.bid-selectall input{margin:0;flex:none;cursor:pointer}
.bid-selectall input:disabled{cursor:not-allowed}
.bid-kv{display:flex;align-items:baseline;justify-content:space-between;gap:10px;padding:5px 0;border-top:1px solid var(--line);font-size:12px}
.bid-kv:first-of-type{border-top:none}
.bid-kv span{color:var(--tertiary)}
.bid-kv b{font-weight:500;text-align:right}
/* 「执行时间」行尾的补充说明：19:xx 这个写法本身就是错峰结果，理由缩成一句尾注，
   不再单独占一行 form-note —— 同一件事说两遍只会让配置卡变啰嗦。 */
.bid-kv b .bid-kv-sub{font-size:11px;font-weight:400;margin-left:6px;white-space:nowrap}
.bid-textarea{resize:vertical;min-height:64px;font-family:inherit}

/* ---- 检索条件：关键词标签 / 时间范围 / 地区 / 是否 ---- */
/* 必填星号：与表单里其它必填项保持同一套写法，不另造一套语气。 */
.bid-req{color:var(--red);margin-left:2px}
/* 标签输入：外框负责「这是一个输入框」的视觉，内部 input 透明无边框 ——
   否则标签和输入框会长成两个割裂的方块，用户不知道能不能在标签旁边接着打。 */
.bid-tagfield{display:flex;flex-wrap:wrap;align-items:center;gap:5px;padding:6px 8px;
  border:1px solid var(--line);border-radius:10px;background:var(--surface);cursor:text;
  transition:border-color .16s,box-shadow .16s}
.bid-tagfield:focus-within{border-color:var(--blue);box-shadow:0 0 0 3px rgba(244,123,53,.08)}
.bid-tag-chip{display:inline-flex;align-items:center;gap:1px;max-width:100%;padding:2px 3px 2px 8px;
  border:1px solid rgba(244,123,53,.2);border-radius:6px;background:rgba(244,123,53,.07);
  font-size:12px;line-height:1.6;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bid-tag-x{border:none;background:none;cursor:pointer;color:var(--tertiary);font-size:13px;line-height:1;
  padding:1px 4px;border-radius:4px}
.bid-tag-x:hover{background:rgba(255,59,48,.12);color:var(--red)}
.bid-tag-input{flex:1;min-width:110px;border:none;outline:none;background:transparent;
  font-size:13px;color:var(--text);font-family:inherit;padding:3px 2px}
.bid-tag-input::placeholder{color:var(--tertiary)}
/* 输入框右侧的「清空」：文字按钮而不是图标 —— 「×」在标签里和「删这一个」容易混淆。 */
.bid-inline-clear{flex:none;border:none;background:none;cursor:pointer;color:var(--tertiary);
  font-size:12px;padding:3px 6px;border-radius:6px;transition:background .16s,color .16s}
.bid-inline-clear:hover:not(:disabled){background:var(--surface-subtle);color:var(--secondary)}
.bid-inline-clear:disabled{opacity:.35;cursor:default}
/* 地区输入：清空按钮叠在框内右侧，用的是 .input 现成的边框，不重造一个输入框。 */
.bid-textfield{position:relative;display:flex;align-items:center}
.bid-textfield .input{padding-right:56px}
.bid-textfield .bid-inline-clear{position:absolute;right:4px}
.bid-range{display:flex;flex-wrap:wrap;gap:6px}
/* 时间范围下拉：一次性采集 / 自动采集各一个，样式与「执行钟点」保持一类。 */
.bid-range-row{display:flex;align-items:center;gap:8px}
.bid-range-select{width:auto;min-width:132px;flex:none}
.bid-range-opt,.bid-yesno-opt{border:1px solid var(--line);border-radius:999px;background:var(--surface);
  color:var(--text);font-size:12px;cursor:pointer;transition:border-color .16s,background .16s,color .16s}
.bid-range-opt{padding:6px 13px}
.bid-yesno{display:flex;gap:8px}
.bid-yesno-opt{min-width:58px;padding:6px 16px}
.bid-range-opt:hover,.bid-yesno-opt:hover{border-color:var(--line-strong)}
.bid-range-opt.is-on,.bid-yesno-opt.is-on{border-color:var(--blue);background:rgba(244,123,53,.08);
  color:var(--blue);font-weight:600}
/* 触屏：药丸按钮在窄屏上会挤成两行，让它们各自吃掉半行。 */
@media (max-width:640px){
  .bid-range-opt{flex:1 1 auto;text-align:center}
}
.bid-sites{display:flex;flex-direction:column;gap:2px;max-height:230px;overflow-y:auto;padding-right:2px}
/* 站点行 = 勾选框 + 名称 + 行尾删除。hover 时删除按钮才显形：常驻会让
   48 行里多出 48 个 ×，看上去比不删还乱。触屏没有 hover，另用媒体查询常显。 */
.bid-site-row{display:flex;align-items:center;gap:4px;border-radius:8px}
.bid-site-row:hover{background:var(--surface-subtle)}
.bid-site{display:flex;align-items:center;gap:8px;padding:5px 6px;border-radius:8px;cursor:pointer;font-size:12px;flex:1;min-width:0}
.bid-site input{margin:0;flex:none}
.bid-site-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bid-site-del{flex:none;width:22px;height:22px;line-height:1;border:0;border-radius:6px;background:transparent;
  color:var(--tertiary);font-size:14px;cursor:pointer;opacity:.45;transition:opacity .14s,color .14s,background .14s}
/* 常驻淡显而不是 hover 才出现：`opacity:0` 在列表里等于没有删除入口，
   用户扫一眼只会得出「这些站点删不掉」的结论 —— 而删除恰恰是他要的功能。
   淡一点即可：48 行都挂一个实心 × 会把站点名挤得很吵。 */
.bid-site-row:hover .bid-site-del,.bid-site-del:focus-visible{opacity:1}
.bid-site-del:hover{background:rgba(163,0,15,.08);color:#a3000f}
@media (hover:none){.bid-site-del{opacity:.55}}
/* 已删除站点的恢复区：一行一个「恢复」，点一下就回到上面的清单。 */
.bid-removed-list{display:flex;flex-wrap:wrap;gap:6px;margin:8px 0}
.bid-removed-item{display:inline-flex;align-items:center;gap:6px;border:1px dashed var(--line-strong);
  border-radius:8px;background:var(--surface);padding:4px 8px;font-size:12px;color:var(--secondary);cursor:pointer}
.bid-removed-item:hover{border-color:var(--blue);color:var(--blue)}
.bid-removed-item b{font-weight:500;color:var(--blue)}
.bid-restore-all{padding:5px 12px;font-size:12px}
.bid-tag{margin-left:6px;font-size:10px;color:var(--green);border:1px solid currentColor;border-radius:4px;padding:0 3px}
.bid-more-sites{margin-top:8px;border-top:1px solid var(--line);padding-top:8px}
.bid-more-sites summary{cursor:pointer;font-size:12px;color:var(--secondary);list-style:none}
.bid-more-sites summary::-webkit-details-marker{display:none}
.bid-more-sites summary::before{content:"＋ ";color:var(--tertiary)}
.bid-more-sites[open] summary::before{content:"－ "}
.bid-actions{display:flex;gap:8px;position:sticky;bottom:0;background:linear-gradient(to top,var(--page) 70%,transparent);padding:10px 0 4px}
.bid-actions .button{flex:1}
.switch{position:relative;display:inline-block;width:40px;height:24px;flex:none}
.switch input{opacity:0;width:0;height:0;position:absolute}
.switch span{position:absolute;inset:0;background:rgba(0,0,0,.16);border-radius:999px;transition:background .18s}
.switch span::after{content:"";position:absolute;width:18px;height:18px;left:3px;top:3px;background:#fff;border-radius:50%;transition:transform .18s;box-shadow:0 1px 3px rgba(0,0,0,.2)}
.switch input:checked+span{background:var(--green)}
.switch input:checked+span::after{transform:translateX(16px)}
@media(max-width:900px){
  .bids-layout{height:auto}
  .bid-stats{grid-template-columns:repeat(2,minmax(0,1fr))}
  .bid-toolbar{flex-wrap:wrap}
  .bid-toolbar .bid-select{width:calc(50% - 4px)}
}
.bid-sitelog{display:flex;flex-direction:column;gap:4px;margin-top:6px}
.bid-sitelog-row{display:flex;align-items:baseline;justify-content:space-between;gap:8px;font-size:12px}
/* 频次选择器：三个等宽按钮，副标题写明该频次覆盖的时间窗。
   用按钮而不是 select：频次是这张卡里最常改的一项，一次点击即可切换，
   而且「每天 = 一天内」这种对应关系只有并排才看得出来。 */
.bid-freq{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}
.bid-freq-opt{display:flex;flex-direction:column;align-items:center;gap:2px;padding:8px 6px;border:1px solid var(--line);border-radius:10px;background:var(--surface);color:var(--text);font-size:13px;cursor:pointer;transition:border-color .16s,background .16s}
.bid-freq-opt small{font-size:10px;color:var(--tertiary)}
.bid-freq-opt:hover{border-color:var(--line-strong)}
.bid-freq-opt.is-on{border-color:var(--blue);background:rgba(244,123,53,.06)}
.bid-freq-opt.is-on small{color:var(--blue)}
.bid-days{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:4px;margin-top:8px}
.bid-day-opt{padding:7px 2px;border:1px solid var(--line);border-radius:8px;background:var(--surface);color:var(--text);font-size:12px;cursor:pointer;transition:border-color .16s,background .16s}
.bid-day-opt:hover{border-color:var(--line-strong)}
.bid-day-opt.is-on{border-color:var(--blue);background:rgba(244,123,53,.06);color:var(--blue);font-weight:600}
.bid-day-row{display:flex;align-items:center;gap:8px;margin-top:8px}
.bid-day-row .small{margin:0}
.bid-day-select{width:92px;padding:6px 8px}
/* 执行钟点：24 项下拉，宽度按「HH:00」定，跟「每月 N 号」的下拉区分开 */
.bid-hour-select{width:104px;padding:6px 8px}
.bid-sitelog-row span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--secondary)}
.bid-sitelog-row b{font-weight:500;flex:none}
/* 自定义网址：一行一个站，名称 + 域名 + 测试/删除。
   把域名单独列出来是必要的：用户常给同一个站起不同名字（"XX交易中心"/"XX市招标"），
   只有域名能区分它们到底是不是同一个地址。 */
.bid-custom-list{display:flex;flex-direction:column;gap:2px;margin:8px 0 10px}
.bid-custom-row{display:flex;align-items:center;gap:8px;padding:6px 8px;border:1px solid var(--line);border-radius:8px;background:var(--surface)}
.bid-custom-main{display:flex;flex-direction:column;min-width:0;flex:1;gap:1px}
.bid-custom-main b{font-size:12px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bid-custom-main .small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bid-custom-ops{display:flex;gap:4px;flex:none}
.bid-custom-result{margin-top:10px}
.bid-custom-result .small{margin-top:4px;line-height:1.55}
.bid-custom-samples{margin-top:6px;display:flex;flex-direction:column;gap:3px}
.bid-custom-sample{font-size:12px;line-height:1.5;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bid-custom-sample a{color:var(--text);text-decoration:none}
.bid-custom-sample a:hover{color:var(--blue);text-decoration:underline}

/* 本轮采集状态条（左栏顶部）：排队位 / 站点进度 / 完成结果。
   为什么放在列表上面而不是设置区里：用户点完「立即采集」视线会回到左侧
   结果区看「来了什么」，状态条正好在这条视线上；放进右栏底部要滚回去才看得见。 */
.bid-live{border:1px solid var(--line);background:var(--surface);border-radius:12px;padding:10px 12px;margin-bottom:12px;box-shadow:var(--shadow)}
.bid-live.is-bad{border-color:rgba(255,59,48,.32);background:#fff8f8}
.bid-live.is-done{border-color:rgba(52,199,89,.32);background:#f7fdf9}
.bid-live-head{display:flex;align-items:center;justify-content:space-between;gap:10px}
.bid-live-head b{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bid-live-head .small{flex:none}
.bid-live-dot{width:7px;height:7px;border-radius:50%;background:var(--blue);display:inline-block;flex:none;animation:bid-live-pulse 1.2s ease-in-out infinite}
@keyframes bid-live-pulse{0%,100%{opacity:.25}50%{opacity:1}}
.bid-live-bar{margin-top:8px;height:6px;border-radius:3px;background:rgba(244,123,53,.12);overflow:hidden}
.bid-live-bar i{display:block;height:100%;background:var(--blue);border-radius:3px;transition:width .4s ease}
.bid-live .small{margin-top:6px;line-height:1.55}
.bid-live-error{color:#a3000f}
/* 采集完成后卡片上的两个动作。放在正文下面单独一行：和「新增 N 条」挤在一行
   会让用户以为那是状态的一部分，而不是能点的东西。 */
.bid-live-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.bid-live-actions .button{font-size:12px;padding:5px 12px;text-decoration:none}
.bid-live-actions a.button{display:inline-flex;align-items:center}
/* 「查看标讯」点了之后列表闪一下：否则在长页面上看不出哪里变了。 */
@keyframes bid-flash{0%{box-shadow:0 0 0 0 rgba(244,123,53,.35)}100%{box-shadow:0 0 0 12px rgba(244,123,53,0)}}
[data-xbsb-bid-list-host].is-flash .bid-table-wrap{animation:bid-flash .7s ease-out 2}

/* ---------------- 帮助与反馈（智能客服） ----------------
   布局与 editor-page-view 同构：页面自身不滚，滚动发生在消息列表内部。
   否则整页滚动时输入框会跟着跑出视口，用户每问一句都得往下找输入框。 */
.help-page-view{display:grid;grid-template-rows:auto minmax(0,1fr);overflow:hidden}
.help-page-view .page-head{padding:18px 0 14px}
.help-layout{display:grid;grid-template-columns:minmax(0,1fr) 292px;gap:14px;min-height:0}
.help-chat{display:flex;flex-direction:column;min-height:0;overflow:hidden;padding:0}
.help-chat-head{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--line)}
.help-chat-title{display:flex;flex-direction:column;gap:2px;min-width:0}
.help-chat-title b{font-size:13px;font-weight:600}
.help-chat-head .mini-button{margin-left:auto}
.help-messages{flex:1;min-height:0;overflow:auto;padding:16px;display:flex;flex-direction:column;gap:11px}
.help-msg{display:flex;flex-wrap:wrap;gap:8px;align-items:flex-start}
.help-msg.is-user{justify-content:flex-end}
.help-avatar{flex:0 0 auto;width:26px;height:26px;border-radius:8px;display:grid;place-items:center;background:linear-gradient(180deg,#c983ea,#8a4bab);color:#fff;font-size:9px}
.help-bubble{max-width:78%;padding:10px 13px;border-radius:13px;font-size:13px;line-height:1.68;white-space:pre-wrap;word-break:break-word;background:#f2f2f4;border-bottom-left-radius:5px}
.help-msg.is-user .help-bubble{background:#1d1d1f;color:#fff;border-bottom-left-radius:13px;border-bottom-right-radius:5px}
.help-bubble.is-error{background:#fdeceb;color:#b3261e}
.help-bubble.is-warn{background:#fff6e6}
.help-typing{color:var(--secondary)}
.help-note{flex:1 0 100%;margin-left:34px;display:flex;align-items:center;flex-wrap:wrap;gap:8px;font-size:11px;line-height:1.6;padding:8px 10px;border-radius:10px}
.help-note.is-warn{background:#fff8ec;color:#8a5a00}
.help-note.is-ok{background:#eaf7ee;color:#1a6b32}
/* 回答依据：需要可读但绝不能抢回答本身的注意力，所以用中性灰、字号更小。 */
.help-note.is-cite{background:rgba(0,0,0,.03);color:var(--tertiary);font-size:10.5px;padding:6px 10px}
.help-cite-text{color:var(--secondary)}
.help-followups{flex:1 0 100%;margin-left:34px;display:flex;flex-wrap:wrap;gap:6px}
.help-chip{border:1px solid var(--line-strong);background:#fff;border-radius:999px;padding:5px 10px;font-size:11px;color:#424245;cursor:pointer}
.help-chip:hover{background:#f5f5f7}
.help-compose{display:flex;gap:8px;align-items:flex-end;padding:12px 16px;border-top:1px solid var(--line)}
.help-input{flex:1;resize:none;min-height:44px;max-height:120px;line-height:1.6;font-size:13px}
.help-page-view .form-note{margin:0;padding:0 16px 12px;text-align:left}
.help-side{display:flex;flex-direction:column;gap:14px;min-height:0;overflow:auto}
.help-quick-card,.help-human-card{padding:16px}
.help-quick{display:flex;flex-direction:column;gap:6px;font-size:11px;color:var(--tertiary)}
.help-quick-item{text-align:left;border:1px solid var(--line);background:var(--surface-subtle);border-radius:11px;padding:9px 11px;cursor:pointer;display:flex;flex-direction:column;gap:2px}
.help-quick-item:hover{background:#f5f5f7}
.help-quick-item b{font-size:12px;font-weight:600;color:var(--text)}
.help-quick-item span{font-size:11px;color:var(--secondary);line-height:1.5}
.help-human-card .small{margin:0 0 10px;line-height:1.65}
.help-human-card .button{width:100%}
.help-human-card .form-note{text-align:left;margin-top:10px;padding:0}
@media(max-width:900px){
  .help-layout{grid-template-columns:1fr}
  .help-chat{height:62vh}
  .help-side{overflow:visible}
}

/* ------------------------------------------------------------------ */
/* 规则体检建议（保存后弹出，逐条采纳/忽略）                            */
/* ------------------------------------------------------------------ */

/* 不做成提示条而是独立弹窗：建议里带"替换后的完整文本"，长度可能是十几行，
   塞在编辑表单顶部会把原本要编辑的字段全顶出视口。 */
.rule-check-list{
  display:flex;
  flex-direction:column;
  gap:14px;
  max-height:56vh;
  overflow-y:auto;
  overscroll-behavior:contain;
  padding-right:4px;
}
/* 按字段分组：一个字段的几条建议是互斥的（建议文本是整段替换稿），
   分组是让「同一字段只能选一条」这件事在视觉上成立。 */
.rule-check-group{
  display:flex;
  flex-direction:column;
  gap:8px;
}
.rule-check-group-head{
  display:flex;
  align-items:baseline;
  gap:8px;
  padding:0 2px;
}
.rule-check-group-head b{
  font-size:13px;
  font-weight:600;
  color:var(--secondary);
}
.rule-check-item{
  border:1px solid var(--line);
  border-radius:10px;
  padding:12px 14px;
  background:#fff;
  transition:border-color .15s ease,background .15s ease,box-shadow .15s ease;
}
/* 已选中：边框变蓝 + 浅底。只改按钮文案不够 —— 用户扫一眼列表要能看出
   「哪几条我已经决定要了」，否则五条建议里选了两条，回头就找不到了。 */
.rule-check-item.is-chosen{
  border-color:var(--blue);
  background:#f7fbff;
  box-shadow:0 0 0 1px var(--blue) inset;
}
.rule-check-foot{
  display:flex;
  align-items:center;
  gap:10px;
  /* 列表是自己滚动的，底栏必须有明确分隔 —— 否则最后一条被 56vh 边界切一半，
     看着像被按钮盖住了，用户不会想到「还能往下滚」。 */
  margin-top:14px;
  padding-top:12px;
  border-top:1px solid var(--line);
}
.rule-check-count{
  margin-right:auto;
  font-size:12px;
  color:var(--secondary);
}
.rule-check-head{
  display:flex;
  align-items:center;
  gap:8px;
  margin-bottom:6px;
}
.rule-check-field{
  font:600 12px/1 ui-monospace,Menlo,Consolas,monospace;
  color:#414855;
  background:#f2f4f7;
  border-radius:5px;
  padding:3px 7px;
}
.rule-check-problem{
  font-size:13px;
  line-height:1.7;
  margin-bottom:4px;
}
.rule-check-diff{
  margin:8px 0 4px;
}
.rule-check-diff > summary{
  cursor:pointer;
  font-size:12px;
  color:var(--blue);
  padding:3px 0;
}
.rule-check-diff > pre{
  margin:6px 0 0;
  padding:10px 12px;
  background:#f7f8fa;
  border-radius:8px;
  font:12px/1.7 ui-monospace,Menlo,Consolas,monospace;
  white-space:pre-wrap;
  word-break:break-word;
  max-height:220px;
  overflow:auto;
}
.rule-check-actions{
  display:flex;
  gap:8px;
  margin-top:10px;
}

/* ------------------------------------------------------------------ */
/* 规则的保存 / 体检过渡态                                             */
/* ------------------------------------------------------------------ */
/* 这一步要等一次模型调用（十几秒到一分钟）。以前界面全程静止，用户只能得出
   「保存卡住了」的结论；进度条 + 秒数增长是唯一能区分「在跑」和「死了」的东西。 */
.rule-check-progress{
  border:1px solid rgba(244,123,53,.22);
  background:linear-gradient(180deg,rgba(244,123,53,.075),rgba(244,123,53,.03));
  border-radius:12px;
  padding:12px 14px;
  margin:0 0 12px;
}
.rule-check-progress-head{
  display:flex;
  align-items:center;
  gap:8px;
  font-size:13px;
  line-height:1.5;
}
.rule-spinner{
  width:14px;height:14px;flex:none;border-radius:50%;
  border:2px solid rgba(244,123,53,.25);
  border-top-color:var(--blue);
  animation:rule-spin .8s linear infinite;
}
@keyframes rule-spin{to{transform:rotate(360deg)}}
/* 动效敏感用户：不看旋转，但进度条与秒数照旧，信息不丢。 */
@media (prefers-reduced-motion:reduce){
  .rule-spinner{animation:none;border-top-color:rgba(244,123,53,.55)}
}
/* 按钮自己的忙碌态。`:disabled` 默认只把透明度压到 .4 —— 那更像「被禁用」，
   不像「正在跑」，所以这里保持不透明并挂一个转圈。 */
.button.is-busy:disabled{
  opacity:1;
  cursor:progress;
}
.button.primary.is-busy .rule-spinner{
  border-color:rgba(255,255,255,.45);
  border-top-color:#fff;
}
.rule-check-progress-bar{
  height:4px;
  border-radius:2px;
  background:rgba(244,123,53,.14);
  overflow:hidden;
  margin-top:9px;
}
.rule-check-progress-bar > i{
  display:block;
  height:100%;
  width:6%;
  background:var(--blue);
  border-radius:2px;
  transition:width .9s ease-out;
}
