/* ==========================================================================
   工艺深化与报价系统 — Taste Visual System

   Design tokens
   - 字体: IBM Plex Sans + IBM Plex Mono (CDN, self-host 可选)
   - 主题: 单 Light (企业 B2B SaaS, 信任第一)
   - 调色板: Slate Stone (深石板蓝) + 琥珀金 (工艺材料的温暖专业)
   - VARIANCE: 4 (非对称仅用于表格和报价编辑区)
   - MOTION: 3 (无复杂动效, 只 hover/transition 200ms)
   - DENSITY: 5 (企业级数据密度)

   BANNED Tells: no em-dash, no AI-purple, no fake screenshots, no 3-equal cards,
                 no Inter default, no premium-consumer warm beige family.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap');

:root {
  /* Stone / Slate 中性色系 */
  --bg:            #f8fafc;        /* slate-50 */
  --surface:       #ffffff;
  --surface-soft:  #f1f5f9;        /* slate-100 */
  --border:        #e2e8f0;        /* slate-200 */
  --border-strong: #cbd5e1;        /* slate-300 */

  --text:          #0f172a;        /* slate-900 */
  --text-soft:     #475569;        /* slate-600 */
  --text-mute:     #94a3b8;        /* slate-400 */

  /* 主色: 深石板蓝 */
  --primary:       #1e293b;        /* slate-800 - 品牌主色 */
  --primary-hover: #0f172a;        /* slate-900 */
  --primary-on:    #ffffff;

  /* 强调色: 琥珀金 (工艺温暖专业感) */
  --accent:        #b45309;        /* amber-700 */
  --accent-soft:   #fef3c7;        /* amber-100 */
  --accent-hover:  #92400e;        /* amber-800 */

  /* 状态色 */
  --success:       #047857;        /* emerald-700 */
  --success-bg:    #d1fae5;        /* emerald-100 */
  --warn:          #b45309;
  --warn-bg:       #fef3c7;
  --danger:        #b91c1c;        /* red-700 */
  --danger-bg:     #fee2e2;        /* red-100 */
  --info:          #1d4ed8;        /* blue-700 */
  --info-bg:       #dbeafe;        /* blue-100 */

  --radius:        6px;   /* sm — 输入框 / 按钮 / 内联徽章 */
  --radius-md:     10px;  /* md — 卡片 / 工具栏 / 表格容器 */
  --radius-lg:     14px;  /* lg — 弹窗 / 浮层 */

  --skeleton:      #e9eef5;
  --skeleton-hi:   #f5f8fc;

  --shadow-sm:     0 1px 2px rgba(15, 23, 42, 0.04);
  --shadow:        0 1px 3px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04);
  --shadow-lg:     0 4px 12px rgba(15, 23, 42, 0.08);

  --font-sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;
  --font-mono: 'IBM Plex Mono', 'JetBrains Mono', Menlo, monospace;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { overflow-y: scroll; scrollbar-gutter: stable; }
html, body { font-family: var(--font-sans); color: var(--text); background: var(--bg); -webkit-font-smoothing: antialiased; }
body { font-size: 14px; line-height: 1.5; font-feature-settings: "cv02", "cv03", "cv04"; }

/* ============ Typography ============ */
h1 { font-size: 24px; font-weight: 600; letter-spacing: -0.02em; }
h2 { font-size: 18px; font-weight: 600; letter-spacing: -0.01em; }
h3 { font-size: 15px; font-weight: 600; }
h4 { font-size: 13px; font-weight: 600; color: var(--text-soft); text-transform: uppercase; letter-spacing: 0.06em; }
p, span, label { color: var(--text); }
small, .muted { color: var(--text-mute); font-size: 12px; }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* ============ Top Bar ============ */
.topbar {
  height: 56px;
  background: var(--primary);
  color: white;
  display: flex;
  align-items: center;
  padding: 0 32px;
  position: sticky;
  top: 0;
  z-index: 100;
}
.topbar .brand {
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.02em;
  display: flex;
  align-items: center;
  gap: 10px;
  margin-right: 36px;
}
.topbar .brand-mark {
  width: 22px; height: 22px;
  background: var(--accent);
  border-radius: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700;
}
.topbar nav {
  display: flex;
  gap: 4px;
  flex: 1;
}
.topbar nav a {
  color: rgba(255,255,255,0.7);
  text-decoration: none;
  padding: 6px 12px;
  border-radius: var(--radius);
  font-size: 13px;
  transition: all 0.15s;
}
.topbar nav a:hover { color: white; background: rgba(255,255,255,0.06); }
.topbar nav a.active { color: white; background: rgba(255,255,255,0.10); }
.topbar .user-area {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 13px;
  color: rgba(255,255,255,0.85);
}
.topbar .role-tag {
  background: var(--accent);
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 500;
  color: white;
}
.topbar .logout-btn {
  background: none;
  border: 1px solid rgba(255,255,255,0.2);
  color: white;
  padding: 5px 12px;
  border-radius: var(--radius);
  font-size: 12px;
  cursor: pointer;
}
.topbar .logout-btn:hover { background: rgba(255,255,255,0.08); }

/* ============ Layout ============ */
main { max-width: 1400px; margin: 0 auto; padding: 32px; }
.page-header {
  display: flex; justify-content: space-between; align-items: flex-end;
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}
.page-header .title { display: flex; flex-direction: column; gap: 4px; }
.page-header h1 { font-size: 22px; }
.page-header .subtitle { color: var(--text-soft); font-size: 13px; }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 24px;
  box-shadow: var(--shadow-sm);
}
.card + .card { margin-top: 16px; }

/* ============ Buttons ============ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 500;
  font-family: var(--font-sans);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  transition: all 0.15s;
  text-decoration: none;
  white-space: nowrap;
}
.btn:hover { background: var(--surface-soft); border-color: var(--text-soft); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn span,
.auth-tabs button span { color: inherit; }

.btn-primary {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--primary-on);
}
.btn-primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); }

.btn-accent {
  background: var(--accent);
  border-color: var(--accent);
  color: white;
}
.btn-accent:hover { background: var(--accent-hover); border-color: var(--accent-hover); }

.btn-danger-ghost {
  border-color: var(--danger);
  color: var(--danger);
  background: white;
}
.btn-danger-ghost:hover { background: var(--danger-bg); }

.btn-sm { padding: 4px 10px; font-size: 12px; }
.btn-soft {
  background: var(--surface-soft);
  border-color: var(--border-strong);
  color: var(--primary);
  font-weight: 500;
}
.btn-soft:hover { background: var(--primary); border-color: var(--primary); color: var(--primary-on); }

/* ============ Forms ============ */
label { display: block; font-size: 12px; font-weight: 500; color: var(--text-soft); margin-bottom: 6px; letter-spacing: 0.02em; }
.field { margin-bottom: 14px; }
input[type=text], input[type=password], input[type=number], input[type=tel], input[type=email], select, textarea {
  width: 100%;
  padding: 9px 12px;
  font-size: 13px;
  font-family: var(--font-sans);
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  transition: border-color 0.15s, box-shadow 0.15s;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(30, 41, 59, 0.08);
}
textarea { resize: vertical; min-height: 60px; font-family: var(--font-sans); }
input::placeholder, textarea::placeholder { color: var(--text-mute); }

/* ============ Login ============ */
.skip-link {
  position: fixed;
  left: 16px;
  top: -48px;
  z-index: 200;
  padding: 9px 14px;
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  box-shadow: var(--shadow-lg);
  transition: top 0.2s ease;
}
.skip-link:focus { top: 16px; }

.auth-bg {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  position: relative;
  isolation: isolate;
  overflow-x: hidden;
  padding: 32px 20px;
  background-color: #111827;
  background-image:
    radial-gradient(circle at 18% 12%, rgba(180, 83, 9, 0.18), transparent 28rem),
    radial-gradient(circle at 86% 84%, rgba(51, 65, 85, 0.72), transparent 30rem);
}
.auth-bg::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.18;
  background-image:
    linear-gradient(rgba(255,255,255,0.08) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.08) 1px, transparent 1px);
  background-size: 48px 48px;
  mask-image: linear-gradient(to bottom, rgba(0,0,0,0.72), transparent 88%);
}

.auth-shell {
  width: min(980px, calc(100vw - 40px));
  min-height: 650px;
  display: grid;
  grid-template-columns: minmax(330px, 0.88fr) minmax(460px, 1.12fr);
  background: var(--surface);
  border: 1px solid rgba(255,255,255,0.14);
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 30px 90px rgba(2, 6, 23, 0.46), 0 4px 18px rgba(15, 23, 42, 0.24);
}

.auth-showcase {
  min-width: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 42px 38px 34px;
  overflow: hidden;
  color: #f8fafc;
  background:
    radial-gradient(circle at 108% 4%, rgba(180,83,9,0.30), transparent 18rem),
    #1e293b;
}
.auth-showcase::before {
  content: "CQ";
  position: absolute;
  right: -28px;
  bottom: -72px;
  color: rgba(255,255,255,0.035);
  font-family: var(--font-mono);
  font-size: 190px;
  font-weight: 700;
  letter-spacing: -0.12em;
  line-height: 1;
  pointer-events: none;
}
.auth-showcase::after {
  content: "";
  position: absolute;
  right: 24px;
  top: 0;
  width: 1px;
  height: 128px;
  background: linear-gradient(to bottom, var(--accent), transparent);
  opacity: 0.72;
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
}
.brand-inverse { position: relative; z-index: 1; }
.brand-mark-icon {
  width: 38px;
  height: 38px;
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  border-radius: 9px 9px 9px 3px;
  color: white;
  background: var(--accent);
  box-shadow: 0 8px 22px rgba(146, 64, 14, 0.28);
}
.brand-mark-icon svg {
  width: 21px;
  height: 21px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.brand-copy { display: grid; gap: 1px; }
.brand-copy strong { color: #f8fafc; font-size: 14px; font-weight: 600; letter-spacing: 0.01em; }
.brand-copy small { color: rgba(226,232,240,0.58); font-size: 11px; }

/* 公司 Logo 替换原 CQ/SVG 品牌标 (2026-08-12) */
.brand-logo {
  height: 28px;
  width: auto;
  display: block;
  flex: 0 0 auto;
  padding: 3px 8px;
  background: rgba(255, 255, 255, 0.96);
  border-radius: 4px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}
.topbar .brand-logo {
  height: 26px;
  padding: 2px 6px;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
}
.brand-logo-lg {
  height: 44px;
  padding: 4px 10px;
  border-radius: 6px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
}

.showcase-copy {
  position: relative;
  z-index: 1;
  margin-top: 76px;
}
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-bottom: 16px;
  color: #fbbf24;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
}
.showcase-copy h1 {
  max-width: 390px;
  color: #f8fafc;
  font-size: clamp(31px, 3.2vw, 41px);
  font-weight: 600;
  line-height: 1.14;
  letter-spacing: -0.045em;
  text-wrap: balance;
}
.showcase-copy h1 em {
  color: #fbbf24;
  font-style: normal;
}
.showcase-copy p {
  max-width: 33rem;
  margin-top: 18px;
  color: rgba(226,232,240,0.68);
  font-size: 13px;
  line-height: 1.75;
  text-wrap: pretty;
}

.workflow-list {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 1px;
  margin-top: 34px;
  border-block: 1px solid rgba(255,255,255,0.08);
}
.workflow-item {
  min-height: 68px;
  display: grid;
  grid-template-columns: 24px 34px 1fr;
  align-items: center;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.workflow-item:last-child { border-bottom: 0; }
.workflow-index {
  color: rgba(226,232,240,0.35);
  font-family: var(--font-mono);
  font-size: 10px;
}
.workflow-icon {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(251,191,36,0.20);
  border-radius: 8px 8px 8px 3px;
  color: #fbbf24;
  background: rgba(180,83,9,0.10);
}
.workflow-icon svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.workflow-item > span:last-child { display: grid; gap: 2px; }
.workflow-item strong { color: #f8fafc; font-size: 12px; font-weight: 500; }
.workflow-item small { color: rgba(226,232,240,0.48); font-size: 10px; }

.showcase-foot {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: auto;
  padding-top: 24px;
}
.showcase-foot span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: rgba(226,232,240,0.52);
  font-size: 10px;
}

.auth-panel {
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 48px 54px 32px;
  background: var(--surface);
}
.auth-heading { margin-bottom: 24px; }
.auth-kicker {
  display: inline-block;
  margin-bottom: 7px;
  color: var(--accent);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
}
.auth-heading h2 {
  color: var(--text);
  font-size: 27px;
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.2;
}
.auth-heading p {
  margin-top: 7px;
  color: var(--text-soft);
  font-size: 13px;
}

.auth-tabs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 5px;
  margin-bottom: 24px;
  padding: 5px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-soft);
}
.auth-tabs button {
  min-width: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 9px 8px;
  border: 0;
  border-radius: 6px;
  color: var(--text-soft);
  background: transparent;
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}
.auth-tabs button:hover { color: var(--text); background: rgba(255,255,255,0.56); }
.auth-tabs button:active { transform: scale(0.98); }
.auth-tabs button:focus-visible {
  outline: 2px solid rgba(180,83,9,0.48);
  outline-offset: 2px;
}
.auth-tabs button.active {
  color: var(--text);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(15,23,42,0.07), 0 4px 12px rgba(15,23,42,0.04);
}
.auth-tabs button.active .tab-icon { color: var(--accent); }

.ui-icon,
.tab-icon,
.tip-icon,
.field-icon,
.btn-icon {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ui-icon { width: 14px; height: 14px; }
.tab-icon { width: 17px; height: 17px; flex: 0 0 auto; }
.tip-icon { width: 17px; height: 17px; flex: 0 0 auto; }
.field-icon { width: 18px; height: 18px; }
.btn-icon { width: 17px; height: 17px; flex: 0 0 auto; }

.auth-pane { display: none; }
.auth-pane.active {
  display: block;
  animation: auth-pane-in 0.24s ease both;
}
@keyframes auth-pane-in {
  from { opacity: 0; transform: translateY(5px); }
  to { opacity: 1; transform: translateY(0); }
}

.auth-tip {
  min-height: 38px;
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 18px;
  padding: 9px 11px;
  border: 1px solid #fde68a;
  border-radius: 7px;
  color: var(--accent-hover);
  background: var(--accent-soft);
  font-size: 11px;
  line-height: 1.45;
}
.auth-tip span { color: inherit; }
.auth-tip-neutral {
  color: var(--text-soft);
  border-color: var(--border);
  background: var(--surface-soft);
}

.auth-panel .field { margin-bottom: 16px; }
.auth-panel .field label {
  margin-bottom: 7px;
  color: var(--text-soft);
  font-size: 11px;
  font-weight: 600;
}
.input-shell {
  position: relative;
  min-width: 0;
  flex: 1;
}
.input-shell .field-icon {
  position: absolute;
  left: 13px;
  top: 50%;
  z-index: 1;
  color: var(--text-mute);
  transform: translateY(-50%);
  pointer-events: none;
  transition: color 0.18s ease;
}
.input-shell input[type=text],
.input-shell input[type=password],
.input-shell input[type=tel] {
  height: 46px;
  padding: 10px 13px 10px 42px;
  border-color: var(--border-strong);
  border-radius: 8px;
  background: #fbfdff;
  font-size: 13px;
  transition: border-color 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
}
.input-shell:hover input { border-color: #aebaca; }
.input-shell:focus-within .field-icon { color: var(--accent); }
.input-shell:focus-within input {
  border-color: var(--accent);
  background: var(--surface);
  box-shadow: 0 0 0 3px rgba(180,83,9,0.10);
}

.code-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 9px;
}
.code-btn {
  min-width: 128px;
  height: 46px;
  border-radius: 8px;
  color: var(--primary);
  background: var(--surface);
}
.code-btn:hover {
  color: var(--accent-hover);
  border-color: var(--accent);
  background: #fffbeb;
}
.code-btn.is-loading .btn-icon { animation: send-pulse 1s ease infinite; }
@keyframes send-pulse {
  50% { opacity: 0.45; transform: translateX(2px); }
}

.auth-submit {
  width: 100%;
  height: 48px;
  justify-content: space-between;
  margin-top: 5px;
  padding: 0 16px 0 18px;
  border-radius: 8px;
  box-shadow: 0 8px 18px rgba(30,41,59,0.16);
  transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
}
.auth-submit .btn-icon {
  width: 28px;
  height: 28px;
  padding: 6px;
  border-radius: 6px;
  color: #fbbf24;
  background: rgba(255,255,255,0.08);
}
.auth-submit:hover {
  transform: translateY(-1px);
  box-shadow: 0 12px 24px rgba(30,41,59,0.22);
}
.auth-submit:active { transform: translateY(1px); box-shadow: 0 4px 12px rgba(30,41,59,0.15); }
.auth-submit:focus-visible,
.code-btn:focus-visible {
  outline: 3px solid rgba(180,83,9,0.20);
  outline-offset: 2px;
}

.auth-msg {
  min-height: 20px;
  margin-top: 8px;
  color: var(--text-soft);
  font-size: 12px;
  text-align: center;
}
.auth-msg.error { color: var(--danger); }
.auth-msg.success { color: var(--success); }

.auth-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: auto;
  padding-top: 22px;
  border-top: 1px solid var(--border);
  color: var(--text-mute);
  font-size: 10px;
}
.auth-meta .system-state {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text-mute);
}
.auth-meta .system-state i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 3px var(--success-bg);
}
.auth-meta a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--accent);
  font-weight: 500;
  text-decoration: none;
}
.auth-meta a:hover { color: var(--accent-hover); text-decoration: underline; text-underline-offset: 3px; }

/* ============ Upload (Dropzone) ============ */
.dropzone {
  border: 2px dashed var(--border-strong);
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: 48px 24px;
  text-align: center;
  cursor: pointer;
  transition: all 0.15s;
}
.dropzone:hover { border-color: var(--primary); background: var(--surface-soft); }
.dropzone.dragging { border-color: var(--accent); background: var(--accent-soft); border-style: solid; }
.dropzone.dragging .dropzone-icon { color: var(--accent); }
.dropzone.has-file {
  border-style: solid;
  border-color: var(--success);
  background: var(--success-bg);
}
.dropzone input[type=file] { display: none; }
.dropzone .icon { font-size: 32px; margin-bottom: 12px; color: var(--text-soft); }
.dropzone .hint { font-size: 12px; color: var(--text-mute); margin-top: 8px; }
.dropzone .preview {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--success);
  margin-top: 8px;
}

/* ============ Tables (报价编辑核心) ============ */
.tbl-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
table.tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
table.tbl th {
  position: sticky; top: 0; z-index: 2;
  text-align: left;
  padding: 12px 14px;
  background: var(--surface-soft);
  border-bottom: 1px solid var(--border-strong);
  color: var(--text-soft);
  font-weight: 600;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  white-space: nowrap;
}
table.tbl td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  color: var(--text);
}
table.tbl tr:last-child td { border-bottom: none; }
table.tbl tbody tr { transition: background 0.12s ease; }
table.tbl tbody tr:hover { background: #f6f9fc; }
table.tbl tbody tr:hover td:first-child { box-shadow: inset 2px 0 0 var(--accent); }
table.tbl .col-num { color: var(--text-mute); font-size: 11px; width: 40px; }
table.tbl .col-amount { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
table.tbl .col-name input { font-weight: 500; }
table.tbl .col-spec textarea,
table.tbl .col-spec input { font-size: 12px; }
table.tbl input, table.tbl textarea, table.tbl select {
  border-color: transparent;
  background: transparent;
  padding: 6px 8px;
  font-size: 13px;
}
table.tbl input:hover, table.tbl textarea:hover { background: var(--surface-soft); }
table.tbl input:focus, table.tbl textarea:focus { background: white; border-color: var(--primary); }
table.tbl td.cell-empty {
  text-align: center;
  color: var(--text-mute);
  padding: 32px 12px;
}
table.tbl .badge {
  display: inline-flex; align-items: center;
  padding: 3px 9px;
  border-radius: var(--radius);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.03em;
  line-height: 1.4;
}
table.tbl .badge.ai { background: var(--info-bg); color: var(--info); }
table.tbl .badge.edited { background: var(--accent-soft); color: var(--accent-hover); }
table.tbl .row-del {
  background: none;
  border: none;
  color: var(--text-mute);
  cursor: pointer;
  font-size: 14px;
}
table.tbl .row-del:hover { color: var(--danger); }
table.tbl tfoot td {
  font-weight: 600;
  background: var(--surface-soft);
  border-top: 2px solid var(--text);
  padding: 12px;
}

/* ============ Quote Summary Card ============ */
.summary {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 24px;
}
.summary .label { font-size: 11px; color: var(--text-mute); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 8px; }
.summary .total {
  font-size: 36px;
  font-weight: 700;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.summary .total .currency { font-size: 18px; color: var(--text-soft); margin-right: 4px; }
.summary .meta { font-size: 12px; color: var(--text-soft); margin-top: 8px; line-height: 1.7; }
.summary .meta b { color: var(--text); }

/* ============ Status Badge ============ */
.status {
  display: inline-flex; align-items: center;
  padding: 3px 10px;
  border-radius: var(--radius);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
  line-height: 1.4;
}
.status.pending     { background: var(--surface-soft); color: var(--text-soft); }
.status.recognizing { background: var(--info-bg); color: var(--info); }
.status.recognized  { background: var(--accent-soft); color: var(--accent-hover); }
.status.editing     { background: var(--warn-bg); color: var(--warn); }
.status.confirmed   { background: var(--success-bg); color: var(--success); }
.status.archived    { background: var(--surface-soft); color: var(--text-mute); }
.status.failed      { background: var(--danger-bg); color: var(--danger); }
.status.active      { background: var(--success-bg); color: var(--success); }
.status.disabled    { background: var(--danger-bg); color: var(--danger); }
.status.deleted     { background: var(--surface-soft); color: var(--text-mute); }
.status.queued      { background: var(--surface-soft); color: var(--text-soft); }
.status.running     { background: var(--info-bg); color: var(--info); }
.status.success     { background: var(--success-bg); color: var(--success); }

/* ============ Quote List (Cards) ============ */
.quote-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 14px;
}
.quote-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px;
  cursor: pointer;
  transition: all 0.15s;
  text-decoration: none;
  color: inherit;
  display: block;
}
.quote-card:hover {
  border-color: var(--primary);
  box-shadow: var(--shadow);
  transform: translateY(-1px);
}
.quote-card .head {
  display: flex; justify-content: space-between; align-items: flex-start;
  margin-bottom: 10px;
}
.quote-card .title {
  font-size: 14px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 200px;
}
.quote-card .quote-no {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-mute);
  margin-top: 2px;
}
.quote-card .amount {
  font-size: 20px;
  font-weight: 700;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  margin-top: 8px;
}
.quote-card .amount.empty { color: var(--text-mute); font-size: 14px; font-weight: 400; }
.quote-card .meta { display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: var(--text-mute); }

/* ============ Empty state ============ */
.empty {
  text-align: center;
  padding: 64px 24px;
  color: var(--text-mute);
}
.empty .icon { font-size: 32px; opacity: 0.4; margin-bottom: 12px; }
.empty h3 { color: var(--text); margin-bottom: 6px; font-weight: 500; }

/* ============ Progress (识别中页面) ============ */
.progress {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 32px;
  text-align: center;
}
.progress .bar {
  height: 8px;
  background: var(--surface-soft);
  border-radius: 4px;
  overflow: hidden;
  margin: 24px 0 12px;
}
.progress .bar > div {
  height: 100%;
  background: var(--accent);
  border-radius: 4px;
  transition: width 0.4s;
}
.progress .step { font-size: 12px; color: var(--text-soft); }

/* ============ Loading spinner ============ */
.spinner {
  display: inline-block;
  width: 14px; height: 14px;
  border: 2px solid var(--border-strong);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  vertical-align: middle;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ============ Toolbar (admin lists) ============ */
.toolbar {
  display: flex;
  gap: 12px;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 12px 16px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.toolbar select, .toolbar input {
  width: auto;
  padding: 7px 10px;
  font-size: 13px;
}
.toolbar .stat { color: var(--text-soft); font-size: 12px; margin-left: auto; }

/* ============ Tabs (admin logs) ============ */
.tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 16px;
}
.tabs button {
  background: none;
  border: none;
  padding: 10px 16px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-soft);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  font-family: var(--font-sans);
}
.tabs button:hover { color: var(--text); }
.tabs button.active {
  color: var(--primary);
  border-bottom-color: var(--primary);
}

/* ============ Utility ============ */
.row { display: flex; gap: 12px; align-items: center; }
.row.right { justify-content: flex-end; }
.row.between { justify-content: space-between; }
.gap-sm { gap: 8px; }
.mt-md { margin-top: 16px; }
.mt-lg { margin-top: 24px; }
.text-right { text-align: right; }
.text-soft { color: var(--text-soft); }
.text-mute { color: var(--text-mute); }
.text-mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
hr { border: none; border-top: 1px solid var(--border); margin: 20px 0; }
code { font-family: var(--font-mono); background: var(--surface-soft); padding: 1px 5px; border-radius: 3px; font-size: 12px; }

/* ============ Responsive ============ */
@media (max-width: 900px) {
  main { padding: 16px; }
  .topbar { padding: 0 16px; }
  .topbar .brand { margin-right: 16px; }
  .quote-grid { grid-template-columns: 1fr; }
  .toolbar { flex-direction: column; align-items: stretch; }
}

/* ============ File list / upload list ============ */
.file-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 8px;
}
.file-row .icon {
  width: 36px; height: 36px;
  background: var(--accent-soft);
  color: var(--accent-hover);
  border-radius: var(--radius);
  display: flex; align-items: center; justify-content: center;
  font-weight: 600;
  font-size: 12px;
}
.file-row .meta { flex: 1; min-width: 0; }
.file-row .meta .name { font-weight: 500; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-row .meta .info { font-size: 11px; color: var(--text-mute); font-family: var(--font-mono); }

/* ============ QR 扫码 ============ */
.qr-block {
  display: grid;
  justify-items: center;
  gap: 14px;
  padding: 10px 0 8px;
  text-align: center;
}
.qr-frame {
  position: relative;
  width: 300px;
  height: 300px;
  display: grid;
  place-items: center;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
  box-shadow: 0 12px 32px rgba(15,23,42,0.08);
}
.wechat-qr-container {
  width: 100%;
  height: 100%;
  overflow: hidden;
  display: grid;
  place-items: center;
}
.wechat-qr-container iframe {
  width: 300px !important;
  height: 300px !important;
  min-width: 300px !important;
  min-height: 300px !important;
  border: 0 !important;
  display: block;
}
.qr-frame::before {
  content: "微信扫码";
  position: absolute;
  left: 50%;
  bottom: -9px;
  z-index: 2;
  padding: 1px 9px;
  color: var(--text-mute);
  background: var(--surface);
  font-size: 9px;
  letter-spacing: 0.08em;
  transform: translateX(-50%);
}
.qr-frame img {
  width: 300px;
  height: 300px;
  display: block;
  object-fit: contain;
  border: 0;
  border-radius: 7px;
}
.qr-corner {
  position: absolute;
  width: 22px;
  height: 22px;
  border-color: var(--accent);
  border-style: solid;
  pointer-events: none;
}
.qr-corner.corner-a { left: -1px; top: -1px; border-width: 2px 0 0 2px; border-radius: 14px 0 0 0; }
.qr-corner.corner-b { right: -1px; top: -1px; border-width: 2px 2px 0 0; border-radius: 0 14px 0 0; }
.qr-corner.corner-c { left: -1px; bottom: -1px; border-width: 0 0 2px 2px; border-radius: 0 0 0 14px; }
.qr-corner.corner-d { right: -1px; bottom: -1px; border-width: 0 2px 2px 0; border-radius: 0 0 14px 0; }
.qr-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 30px;
  margin-top: 0;
  padding: 6px 13px;
  border: 1px solid var(--border);
  border-radius: 7px;
  color: var(--text-soft);
  background: var(--surface-soft);
  font-size: 11px;
}
.qr-status .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--text-mute);
  animation: pulse 1.5s infinite;
}
.qr-status.scanned { border-color: #fde68a; background: var(--warn-bg); color: var(--warn); }
.qr-status.scanned .dot { background: var(--warn); }
.qr-status.confirmed { border-color: #a7f3d0; background: var(--success-bg); color: var(--success); }
.qr-status.confirmed .dot { background: var(--success); animation: none; }
@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.4; transform: scale(0.85); }
}

@media (max-width: 860px) {
  .auth-shell {
    width: min(650px, calc(100vw - 32px));
    grid-template-columns: 1fr;
  }
  .auth-showcase { padding: 28px 32px 30px; }
  .showcase-copy { margin-top: 38px; }
  .showcase-copy h1 { font-size: 31px; }
  .showcase-copy p { max-width: 34rem; }
  .workflow-list { grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 26px; border: 0; }
  .workflow-item {
    min-height: 0;
    grid-template-columns: 26px 1fr;
    gap: 8px;
    padding: 10px;
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 8px;
  }
  .workflow-item:last-child { border-bottom: 1px solid rgba(255,255,255,0.08); }
  .workflow-index { display: none; }
  .workflow-icon { width: 26px; height: 26px; }
  .workflow-icon svg { width: 15px; height: 15px; }
  .workflow-item small { display: none; }
  .showcase-foot { margin-top: 20px; padding-top: 0; }
  .auth-panel { min-height: 540px; padding: 38px 46px 28px; }
}

@media (max-width: 560px) {
  .auth-bg { padding: 14px; place-items: start center; }
  .auth-shell { width: 100%; min-height: calc(100dvh - 28px); border-radius: 14px; }
  .auth-showcase { padding: 23px 22px 24px; }
  .auth-showcase::after { display: none; }
  .showcase-copy { margin-top: 30px; }
  .showcase-copy h1 { font-size: 27px; }
  .showcase-copy p { font-size: 12px; margin-top: 12px; }
  .workflow-list,
  .showcase-foot { display: none; }
  .auth-panel { min-height: 0; padding: 30px 22px 24px; }
  .auth-heading h2 { font-size: 24px; }
  .auth-tabs button { flex-direction: column; gap: 3px; padding: 8px 4px; font-size: 10px; }
  .tab-icon { width: 16px; height: 16px; }
  .code-row { grid-template-columns: 1fr; }
  .code-btn { width: 100%; }
  .auth-meta { margin-top: 26px; }
}

@media (prefers-reduced-motion: reduce) {
  .auth-pane.active,
  .qr-status .dot,
  .code-btn.is-loading .btn-icon { animation: none; }
  .auth-tabs button,
  .auth-submit,
  .input-shell input { transition: none; }
}

/* ==========================================================================
   Dashboard redesign v2 — 登录后工作台
   ========================================================================== */
html { scroll-behavior: smooth; }
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

body.app-shell {
  min-height: 100dvh;
  background:
    radial-gradient(circle at 88% 4%, rgba(180,83,9,0.055), transparent 27rem),
    linear-gradient(#f8fafc, #f8fafc);
}
body.app-shell::before {
  content: "";
  position: fixed;
  inset: 68px 0 auto;
  height: 220px;
  pointer-events: none;
  opacity: 0.48;
  background-image:
    linear-gradient(rgba(148,163,184,0.06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(148,163,184,0.06) 1px, transparent 1px);
  background-size: 36px 36px;
  mask-image: linear-gradient(to bottom, #000, transparent);
}

.ui-svg,
.nav-svg,
.brand-svg,
.user-svg,
[data-ui-icon] > svg {
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ui-svg { width: 17px; height: 17px; }

body.app-shell .topbar {
  height: 68px;
  gap: 0;
  padding-inline: max(24px, calc((100vw - 1440px) / 2 + 32px));
  border-bottom: 1px solid rgba(255,255,255,0.08);
  background: rgba(24,33,50,0.98);
  box-shadow: 0 8px 24px rgba(15,23,42,0.12);
  backdrop-filter: blur(14px);
}
body.app-shell .topbar .brand {
  gap: 11px;
  min-width: 184px;
  margin-right: 30px;
}
body.app-shell .topbar .brand-mark {
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  border-radius: 8px 8px 8px 3px;
  color: white;
  background: var(--accent);
  box-shadow: 0 7px 18px rgba(146,64,14,0.3);
}
body.app-shell .topbar .brand-mark .brand-svg { width: 19px; height: 19px; }
body.app-shell .topbar .brand-copy { display: grid; gap: 0; }
body.app-shell .topbar .brand-copy strong { color: #f8fafc; font-size: 13px; font-weight: 600; }
body.app-shell .topbar .brand-copy small { color: rgba(226,232,240,0.48); font-size: 9px; }
body.app-shell .topbar nav { align-self: stretch; align-items: center; gap: 3px; }
body.app-shell .topbar nav a {
  position: relative;
  height: 38px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 0 12px;
  border-radius: 7px;
  color: rgba(226,232,240,0.65);
  font-size: 12px;
  transition: color 0.18s ease, background 0.18s ease, transform 0.18s ease;
}
body.app-shell .topbar nav a span { color: inherit; }
body.app-shell .topbar nav a .nav-svg { width: 16px; height: 16px; }
body.app-shell .topbar nav a:hover { color: white; background: rgba(255,255,255,0.07); }
body.app-shell .topbar nav a:active { transform: scale(0.98); }
body.app-shell .topbar nav a.active {
  color: white;
  background: rgba(255,255,255,0.1);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.04);
}
body.app-shell .topbar nav a.active::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: -15px;
  height: 2px;
  background: #f59e0b;
  border-radius: 2px 2px 0 0;
}
body.app-shell .topbar .user-area { gap: 11px; margin-left: 20px; }
.user-badge { display: inline-flex; align-items: center; gap: 8px; }
.user-avatar {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255,255,255,0.11);
  border-radius: 8px;
  color: #fbbf24;
  background: rgba(255,255,255,0.06);
}
.user-avatar .user-svg { width: 16px; height: 16px; }
.user-copy { display: grid; gap: 0; }
.user-copy b { color: #f8fafc; font-size: 11px; font-weight: 500; }
.user-copy small { color: rgba(226,232,240,0.48); font-size: 9px; }
body.app-shell .topbar .role-tag {
  padding: 2px 7px;
  border-radius: 4px;
  color: #fef3c7;
  background: rgba(180,83,9,0.38);
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: 0.04em;
}
body.app-shell .topbar .logout-btn {
  height: 32px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  border-color: rgba(255,255,255,0.13);
  border-radius: 7px;
  color: rgba(255,255,255,0.72);
  transition: color 0.18s ease, background 0.18s ease, border-color 0.18s ease;
}
body.app-shell .topbar .logout-btn span { color: inherit; }
body.app-shell .topbar .logout-btn .nav-svg { width: 14px; height: 14px; }
body.app-shell .topbar .logout-btn:hover { color: white; border-color: rgba(255,255,255,0.24); background: rgba(255,255,255,0.08); }
body.app-shell .topbar a:focus-visible,
body.app-shell .topbar button:focus-visible { outline: 2px solid #fbbf24; outline-offset: 2px; }

body.app-shell main {
  position: relative;
  z-index: 1;
  max-width: 1500px;
  padding: 38px 32px 72px;
}
body.app-shell .page-header {
  min-height: 108px;
  align-items: center;
  margin-bottom: 26px;
  padding: 4px 0 24px;
  border-bottom-color: rgba(203,213,225,0.75);
}
body.app-shell .page-header .title { gap: 0; }
.page-kicker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 9px;
  color: var(--accent);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.07em;
}
.kicker-icon {
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  border-radius: 6px 6px 6px 2px;
  color: var(--accent);
  background: var(--accent-soft);
}
.kicker-icon .ui-svg { width: 13px; height: 13px; }
body.app-shell .page-header h1 {
  color: var(--text);
  font-size: clamp(26px, 2.4vw, 32px);
  font-weight: 600;
  letter-spacing: -0.045em;
  line-height: 1.15;
}
body.app-shell .page-header .subtitle {
  max-width: 48rem;
  margin-top: 8px;
  color: var(--text-soft);
  font-size: 13px;
  line-height: 1.65;
}
.page-context { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.page-context > span,
.autosave-note {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-soft);
  background: rgba(255,255,255,0.72);
  font-size: 10px;
  box-shadow: var(--shadow-sm);
}
.page-context i,
.autosave-note i { width: 14px; height: 14px; color: var(--accent); }
.page-context .ui-svg,
.autosave-note .ui-svg { width: 14px; height: 14px; }

body.app-shell .btn {
  min-height: 38px;
  gap: 7px;
  padding: 8px 14px;
  border-radius: 7px;
  font-size: 12px;
  transition: transform 0.18s ease, background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}
body.app-shell .btn > [data-ui-icon],
body.app-shell .btn > svg { width: 16px; height: 16px; color: inherit; }
body.app-shell .btn:hover { transform: translateY(-1px); }
body.app-shell .btn:active { transform: translateY(1px); }
body.app-shell .btn-primary { box-shadow: 0 7px 16px rgba(30,41,59,0.14); }
body.app-shell .btn-primary:hover { box-shadow: 0 10px 22px rgba(30,41,59,0.2); }
body.app-shell .btn:focus-visible { outline: 3px solid rgba(180,83,9,0.18); outline-offset: 2px; }
.page-primary-action { min-width: 122px; }

.surface-card {
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: rgba(255,255,255,0.94);
  box-shadow: 0 1px 2px rgba(15,23,42,0.03), 0 9px 28px rgba(15,23,42,0.035);
}
.panel-heading {
  display: flex;
  align-items: center;
  gap: 13px;
  margin-bottom: 20px;
}
.panel-heading.compact { gap: 10px; margin-bottom: 16px; }
.heading-icon {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  border-radius: 10px 10px 10px 4px;
  color: var(--primary);
  background: var(--surface-soft);
  border: 1px solid var(--border);
}
.heading-icon.amber { color: var(--accent); border-color: #fde68a; background: #fffbeb; }
.heading-icon .ui-svg { width: 20px; height: 20px; }
.panel-heading.compact .heading-icon { width: 36px; height: 36px; border-radius: 8px 8px 8px 3px; }
.panel-heading.compact .heading-icon .ui-svg { width: 17px; height: 17px; }
.panel-step {
  display: block;
  margin-bottom: 2px;
  color: var(--text-mute);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.08em;
}
.panel-heading h2 { color: var(--text); font-size: 16px; font-weight: 600; }
.panel-heading p { margin-top: 3px; color: var(--text-soft); font-size: 11px; }

/* Upload */
.upload-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(300px, 0.65fr);
  gap: 20px;
  align-items: stretch;
}
.upload-primary { padding: 26px 28px 24px; }
body.app-shell .dropzone {
  min-height: 286px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 32px 24px;
  border: 1.5px dashed #b9c5d4;
  border-radius: 12px;
  color: var(--text);
  background:
    radial-gradient(circle at 50% 5%, rgba(180,83,9,0.055), transparent 16rem),
    #f8fafc;
  transition: border-color 0.2s ease, background 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
body.app-shell .dropzone:hover {
  border-color: var(--accent);
  background: #fffbeb;
  box-shadow: inset 0 0 0 3px rgba(180,83,9,0.04);
  transform: translateY(-1px);
}
.dropzone-icon {
  width: 58px;
  height: 58px;
  display: grid;
  place-items: center;
  margin-bottom: 16px;
  border: 1px solid #fde68a;
  border-radius: 15px 15px 15px 6px;
  color: var(--accent);
  background: var(--accent-soft);
  box-shadow: 0 10px 24px rgba(180,83,9,0.1);
}
.dropzone-icon .ui-svg { width: 26px; height: 26px; }
.dropzone strong { color: var(--text); font-size: 15px; font-weight: 600; }
.dropzone-copy { margin-top: 7px; color: var(--text-soft); font-size: 11px; }
.file-type-row { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 18px; flex-wrap: wrap; }
.file-type-row b {
  padding: 3px 7px;
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-soft);
  background: white;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 500;
}
.file-type-row em { margin-left: 5px; color: var(--text-mute); font-size: 9px; font-style: normal; }
body.app-shell .dropzone .preview {
  display: block;
  min-height: 0;
  margin-top: 16px;
  color: inherit;
}
body.app-shell .dropzone.has-file { border-style: solid; border-color: var(--success); background: #ecfdf5; }

/* 已选文件预览卡片 */
.preview-card {
  display: flex;
  align-items: center;
  gap: 12px;
  text-align: left;
  max-width: 440px;
  margin: 0 auto;
  padding: 10px 12px;
  background: #fff;
  border: 1px solid #a7f3d0;
  border-radius: 10px;
  box-shadow: 0 8px 20px rgba(16, 185, 129, 0.14);
  animation: previewPop 0.22s ease;
}
@keyframes previewPop {
  from { opacity: 0; transform: translateY(6px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.preview-thumb {
  width: 54px;
  height: 54px;
  flex: 0 0 54px;
  border-radius: 8px;
  object-fit: cover;
  overflow: hidden;
  border: 1px solid #fde68a;
  background: var(--accent-soft);
}
.preview-thumb.file-thumb { display: grid; place-items: center; }
.preview-thumb.file-thumb span {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--accent);
}
.preview-meta { flex: 1 1 auto; min-width: 0; }
.preview-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.preview-sub {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 5px;
  font-size: 11px;
  color: var(--text-soft);
}
.preview-sub .chip {
  font-family: var(--font-mono);
  font-size: 9px;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  color: var(--text-soft);
}
.preview-remove {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #fff;
  color: var(--text-soft);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.preview-remove:hover { color: var(--danger); border-color: var(--danger); background: var(--danger-bg); }
.preview-remove .ui-svg { width: 14px; height: 14px; }
body.app-shell .dropzone.has-file .dropzone-icon { color: var(--success); border-color: #a7f3d0; background: var(--success-bg); }
.optional { color: var(--text-mute); font-size: 10px; font-weight: 400; }
.app-input-wrap { position: relative; min-width: 0; }
.app-input-wrap > [data-ui-icon] {
  position: absolute;
  left: 12px;
  top: 50%;
  z-index: 1;
  color: var(--text-mute);
  transform: translateY(-50%);
  pointer-events: none;
}
.app-input-wrap > [data-ui-icon] .ui-svg { width: 16px; height: 16px; }
.app-input-wrap input { min-height: 42px; padding-left: 39px; border-radius: 7px; background: #fbfdff; }
.app-input-wrap:focus-within > [data-ui-icon] { color: var(--accent); }
.panel-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}
.action-hint { display: inline-flex; align-items: center; gap: 6px; color: var(--text-mute); font-size: 10px; }
.action-hint i { color: var(--success); }
.action-hint .ui-svg { width: 14px; height: 14px; }
.workflow-panel { padding: 26px 24px 22px; background: rgba(241,245,249,0.72); }
.workflow-steps { list-style: none; position: relative; display: grid; gap: 0; }
.workflow-steps::before { content: ""; position: absolute; left: 17px; top: 31px; bottom: 31px; width: 1px; background: var(--border); }
.workflow-steps li { position: relative; z-index: 1; display: grid; grid-template-columns: 36px 1fr; gap: 11px; align-items: center; min-height: 58px; }
.workflow-steps li > span {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: 9px 9px 9px 3px;
  color: var(--text-soft);
  background: white;
}
.workflow-steps li:nth-child(2) > span { color: var(--accent); border-color: #fde68a; background: #fffbeb; }
.workflow-steps .ui-svg { width: 17px; height: 17px; }
.workflow-steps li div { display: grid; gap: 2px; }
.workflow-steps b { color: var(--text); font-size: 11px; font-weight: 600; }
.workflow-steps small { color: var(--text-mute); font-size: 9px; }
.field-guide { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border); }
.guide-label { color: var(--text-mute); font-size: 9px; font-weight: 600; letter-spacing: 0.06em; }
.guide-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.guide-tags span { padding: 3px 7px; border-radius: 4px; color: var(--text-soft); background: white; font-size: 9px; box-shadow: inset 0 0 0 1px var(--border); }
.workflow-note { display: flex; align-items: center; gap: 10px; margin-top: 18px; padding: 11px; border-radius: 7px; color: var(--accent); background: var(--accent-soft); }
.workflow-note > .ui-svg { width: 17px; height: 17px; }
.workflow-note p { display: grid; gap: 1px; }
.workflow-note b { color: var(--accent-hover); font-size: 10px; }
.workflow-note small { color: #a16207; font-size: 9px; }

/* Metrics and content sections */
.metric-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-bottom: 26px; }
.metric-card {
  position: relative;
  min-height: 116px;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(15,23,42,0.03);
  overflow: hidden;
  transition: transform 0.16s ease, box-shadow 0.16s ease, border-color 0.16s ease;
}
.metric-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); border-color: var(--border-strong); }
.metric-icon {
  width: 42px; height: 42px;
  display: grid; place-items: center;
  flex: 0 0 auto;
  border-radius: var(--radius);
  color: var(--primary);
  background: var(--surface-soft);
  box-shadow: inset 0 0 0 1px rgba(15,23,42,0.04);
}
.metric-icon.success { color: var(--success); background: var(--success-bg); }
.metric-icon.warning { color: var(--accent); background: var(--accent-soft); }
.metric-icon.danger { color: var(--danger); background: var(--danger-bg); }
.metric-icon .ui-svg { width: 20px; height: 20px; }
.metric-card > div { min-width: 0; display: grid; grid-template-columns: 1fr auto; column-gap: 10px; align-items: end; }
.metric-card small { grid-column: 1 / -1; color: var(--text-soft); font-size: 11px; font-weight: 500; letter-spacing: 0.02em; }
.metric-card strong { color: var(--text); font-family: var(--font-mono); font-size: 26px; font-weight: 600; letter-spacing: -0.04em; line-height: 1.2; }
.metric-card em { color: var(--text-mute); font-size: 11px; font-style: normal; white-space: nowrap; }
.metric-card.featured {
  border-color: transparent;
  background: linear-gradient(135deg, #1e293b 0%, #243449 100%);
  box-shadow: 0 12px 28px rgba(30,41,59,0.20);
}
.metric-card.featured::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 80% at 90% 0%, rgba(251,191,36,0.14), transparent 60%);
  pointer-events: none;
}
.metric-card.featured .metric-icon { color: #fbbf24; background: rgba(255,255,255,0.10); box-shadow: none; }
.metric-card.featured small,
.metric-card.featured em { color: rgba(226,232,240,0.60); }
.metric-card.featured strong { color: #f8fafc; }
.content-section { margin-top: 4px; }
.section-bar { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-bottom: 14px; }
.section-bar h2 { color: var(--text); font-size: 16px; font-weight: 600; }
.section-bar p { margin-top: 3px; color: var(--text-mute); font-size: 12px; }
.section-meta { display: inline-flex; align-items: center; gap: 6px; color: var(--text-mute); font-size: 11px; }
.section-meta .ui-svg { width: 13px; height: 13px; color: var(--accent); }

/* Quote list */
body.app-shell .quote-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 15px; }
body.app-shell .quote-card {
  position: relative;
  min-height: 194px;
  padding: 20px 20px 17px;
  border-radius: 11px;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(15,23,42,0.03), 0 10px 24px rgba(15,23,42,0.025);
}
body.app-shell .quote-card::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 3px; background: var(--border-strong); }
body.app-shell .quote-card.status-confirmed::before { background: var(--success); }
body.app-shell .quote-card.status-editing::before,
body.app-shell .quote-card.status-recognized::before { background: var(--accent); }
body.app-shell .quote-card.status-failed::before { background: var(--danger); }
body.app-shell .quote-card:hover { border-color: #b8c4d3; box-shadow: 0 15px 34px rgba(15,23,42,0.09); transform: translateY(-2px); }
.quote-card .head { align-items: center; margin-bottom: 22px; }
.quote-ident { display: flex; align-items: center; gap: 11px; min-width: 0; }
.quote-card-icon {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  border-radius: 9px 9px 9px 3px;
  color: var(--accent);
  background: var(--accent-soft);
}
.quote-card-icon .ui-svg { width: 18px; height: 18px; }
body.app-shell .quote-card .title { max-width: none; font-size: 14px; }
body.app-shell .quote-card .quote-no { margin-top: 3px; font-size: 9px; }
.amount-label { color: var(--text-mute); font-size: 9px; }
body.app-shell .quote-card .amount { margin-top: 3px; font-size: 24px; letter-spacing: -0.035em; }
body.app-shell .quote-card .amount.empty {
  min-height: 0;
  margin-top: 7px;
  padding: 0;
  border: 0;
  border-radius: 0;
  color: var(--text-soft);
  background: transparent;
  font-size: 15px;
  font-weight: 500;
  text-align: left;
}
body.app-shell .quote-card .meta { align-items: center; margin-top: 20px; padding-top: 13px; border-top: 1px solid var(--border); }
body.app-shell .quote-card .meta span { display: inline-flex; align-items: center; gap: 5px; color: var(--text-mute); }
body.app-shell .quote-card .meta .ui-svg { width: 13px; height: 13px; }
.card-arrow { margin-left: auto; color: var(--accent) !important; transition: transform 0.18s ease; }
.quote-card:hover .card-arrow { transform: translateX(3px); }
body.app-shell .empty { padding: 72px 24px; border: 1px dashed var(--border-strong); border-radius: 11px; background: rgba(255,255,255,0.62); }
.empty-icon-box { width: 48px; height: 48px; display: grid; place-items: center; margin: 0 auto 13px; border-radius: 12px; color: var(--accent); background: var(--accent-soft); }
.empty-icon-box .ui-svg { width: 23px; height: 23px; }

/* Quote editor */
.back-link { display: inline-flex; align-items: center; gap: 7px; margin-bottom: 14px; color: var(--text-soft); font-size: 10px; text-decoration: none; }
.back-link > span { color: inherit; }
.back-link .ui-svg { width: 14px; height: 14px; }
.back-link:hover { color: var(--accent); }
.quote-page-header { margin-bottom: 18px !important; }
.header-action-group { display: flex; align-items: center; justify-content: flex-end; gap: 7px; flex-wrap: wrap; }
.quote-workspace { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 18px; align-items: start; }
.line-items-panel { overflow: hidden; }
.editor-bar { align-items: center; margin: 0; padding: 17px 18px; border-bottom: 1px solid var(--border); background: rgba(248,250,252,0.72); }
.editor-legend { display: flex; gap: 12px; color: var(--text-mute); font-size: 9px; }
.editor-legend span { display: inline-flex; align-items: center; gap: 5px; color: inherit; }
.legend-dot { width: 7px; height: 7px; border-radius: 2px; }
.legend-dot.ai { background: var(--info); }
.legend-dot.edited { background: var(--accent); }
body.app-shell .editor-table-wrap { border: 0; border-radius: 0; overflow-x: auto; }
body.app-shell .editor-table { min-width: 980px; }
body.app-shell table.tbl th { padding: 11px 10px; color: var(--text-soft); background: #f8fafc; font-size: 9px; }
body.app-shell table.tbl td { padding: 8px 10px; }
body.app-shell table.tbl tbody tr { transition: background 0.15s ease; }
body.app-shell table.tbl tbody tr:hover { background: #fafcff; }
body.app-shell table.tbl input,
body.app-shell table.tbl textarea,
body.app-shell table.tbl select { min-height: 34px; border-radius: 5px; }
body.app-shell table.tbl input:hover { background: #f1f5f9; }
body.app-shell table.tbl input:focus { background: white; border-color: var(--accent); box-shadow: 0 0 0 2px rgba(180,83,9,0.08); }
.editor-table .col-price { width: 92px; }
.editor-table .col-unit { width: 64px; }
.editor-table .col-qty { width: 72px; }
.editor-table .col-total { width: 98px; }
.editor-table .col-remark { width: 110px; }
.editor-table .col-source { width: 108px; }
.editor-table .col-actions { width: 42px; }
body.app-shell table.tbl .row-del {
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 6px;
  font-size: 0;
  transition: color 0.15s ease, background 0.15s ease;
}
body.app-shell table.tbl .row-del:hover { color: var(--danger); background: var(--danger-bg); }
.row-action-svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
body.app-shell table.tbl tfoot td { background: #f8fafc; border-top: 1px solid var(--primary); }

/* ===== 报价明细编辑器 · taste 精细化 ===== */
body.app-shell .editor-table-wrap {
  border: 0;
  border-radius: var(--radius-md);
  overflow: auto;
  max-height: calc(100vh - 250px);
  background: var(--surface);
}
body.app-shell .editor-table {
  min-width: 1000px;
  border-collapse: separate;
  border-spacing: 0;
}
body.app-shell .editor-table thead th {
  position: sticky; top: 0; z-index: 4;
  background: #f8fafc;
  color: var(--text-soft);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--border-strong);
  padding: 12px 10px;
  white-space: nowrap;
}
body.app-shell .editor-table thead th.col-price,
body.app-shell .editor-table thead th.col-qty,
body.app-shell .editor-table thead th.col-total { text-align: right; }

body.app-shell .editor-table tbody td {
  padding: 7px 8px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

/* 行号 */
body.app-shell .editor-table .col-num {
  width: 46px;
  text-align: center;
  color: var(--text-mute);
  font-family: var(--font-mono);
  font-size: 11px;
}

/* 单元格字段：清晰的表单栅格感 */
body.app-shell .editor-table input,
body.app-shell .editor-table textarea {
  width: 100%;
  min-height: 34px;
  border: 1px solid var(--border);
  background: #f8fafc;
  border-radius: var(--radius);
  padding: 7px 9px;
  font-size: 13px;
  color: var(--text);
  transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
}
body.app-shell .editor-table input:hover,
body.app-shell .editor-table textarea:hover {
  background: var(--surface);
  border-color: var(--text-mute);
}
body.app-shell .editor-table input:focus,
body.app-shell .editor-table textarea:focus {
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(180,83,9,0.12);
  outline: none;
}
body.app-shell .editor-table .col-name input { font-weight: 500; }
body.app-shell .editor-table .col-spec input,
body.app-shell .editor-table .col-spec textarea { font-size: 12px; }

/* 数字列右对齐 + 隐藏步进箭头 */
body.app-shell .editor-table td.col-price input,
body.app-shell .editor-table td.col-qty input {
  text-align: right;
  font-family: var(--font-mono);
}
body.app-shell .editor-table input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}
body.app-shell .editor-table input[type="number"]::-webkit-inner-spin-button,
body.app-shell .editor-table input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* 金额列 */
body.app-shell .editor-table .col-amount {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: 13px;
  color: var(--text);
  white-space: nowrap;
}

/* 来源徽章 + 置信度 */
body.app-shell .editor-table .source-cell {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}
body.app-shell .editor-table .confidence {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-mute);
  background: var(--surface-soft);
  border-radius: 4px;
  padding: 2px 5px;
  letter-spacing: 0.02em;
}

/* 行操作 */
body.app-shell .editor-table .row-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
}
body.app-shell .editor-table .row-ref {
  font-size: 11px;
  color: var(--accent-hover);
  background: var(--accent-soft);
  border: 1px solid #fde68a;
  border-radius: var(--radius);
  padding: 5px 8px;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s ease, transform .1s ease;
}
body.app-shell .editor-table .row-ref:hover { background: #fde68a; }
body.app-shell .editor-table .row-ref:active { transform: scale(.97); }
body.app-shell .editor-table .row-del {
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border-radius: 6px;
  color: var(--text-mute);
  background: transparent;
  border: none;
  cursor: pointer;
  font-size: 0;
  transition: color .15s ease, background .15s ease, transform .1s ease;
}
body.app-shell .editor-table .row-del:hover { color: var(--danger); background: var(--danger-bg); }
body.app-shell .editor-table .row-del:active { transform: scale(.92); }

/* 合计行：强调 Grand Total */
body.app-shell .editor-table tfoot td {
  background: linear-gradient(180deg, #fffdf7, #fef9f0);
  border-top: 2px solid var(--accent);
  font-weight: 700;
  padding: 14px 10px;
  color: var(--text);
}
body.app-shell .editor-table tfoot .col-amount {
  color: var(--accent-hover);
  font-size: 15px;
}

/* 行 hover 强化 */
body.app-shell .editor-table tbody tr { transition: background .15s ease; }
body.app-shell .editor-table tbody tr:hover { background: #fafcff; }
body.app-shell .editor-table tbody tr:hover td:first-child { box-shadow: inset 2px 0 0 var(--accent); }

/* 空状态 */
body.app-shell .editor-table td.cell-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 44px 12px;
  text-align: center;
  color: var(--text-mute);
  background: var(--surface-soft);
}
body.app-shell .editor-table .empty-inline-icon {
  display: inline-grid;
  place-items: center;
  width: 30px; height: 30px;
  border-radius: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-mute);
}
body.app-shell .editor-table .empty-inline-icon .ui-svg { width: 15px; height: 15px; }

.quote-sidebar { display: grid; gap: 13px; position: sticky; top: 86px; }
.summary-emphasis {
  padding: 22px;
  border: 0;
  border-radius: 12px;
  color: #f8fafc;
  background:
    radial-gradient(circle at 100% 0, rgba(180,83,9,0.34), transparent 13rem),
    #1e293b;
  box-shadow: 0 16px 34px rgba(30,41,59,0.16);
}
.summary-top { display: flex; align-items: center; gap: 9px; }
.summary-symbol { width: 31px; height: 31px; display: grid; place-items: center; border-radius: 8px; color: #fbbf24; background: rgba(255,255,255,0.08); }
.summary-symbol .ui-svg { width: 16px; height: 16px; }
.summary-emphasis .label { margin: 0; color: rgba(226,232,240,0.58); }
.summary-emphasis .total { margin-top: 17px; color: #f8fafc; font-size: 34px; }
.summary-emphasis .total span { color: inherit; }
.summary-emphasis .total .currency { color: #fbbf24; }
.summary-emphasis .meta { color: rgba(226,232,240,0.58); }
.summary-foot { display: flex; align-items: center; gap: 6px; margin-top: 18px; padding-top: 13px; border-top: 1px solid rgba(255,255,255,0.09); color: rgba(226,232,240,0.46); font-size: 9px; }
.summary-foot .ui-svg { width: 13px; height: 13px; color: #fbbf24; }
.detail-card,
.source-card { padding: 18px; }
body.app-shell .detail-list > div { padding: 9px 0; min-height: 38px; border-bottom: 1px solid var(--border); }
body.app-shell .detail-list dt { font-size: 10px; letter-spacing: 0.03em; }
body.app-shell .detail-list dd { font-family: var(--font-mono); font-size: 11px; color: var(--text); }
body.app-shell .source-card .file-row { margin: 0; padding: 12px; border-radius: var(--radius); transition: border-color .15s ease, box-shadow .15s ease; }
body.app-shell .source-card .file-row:hover { border-color: #fde68a; box-shadow: 0 0 0 3px rgba(180,83,9,0.06); }
.detail-list { display: grid; gap: 0; }
.detail-list > div { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 34px; border-bottom: 1px solid var(--border); }
.detail-list > div:last-child { border-bottom: 0; }
.detail-list dt { color: var(--text-mute); font-size: 9px; }
.detail-list dd { max-width: 62%; color: var(--text); font-size: 10px; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.source-card .file-row { margin: 0; padding: 11px; }
.file-arrow { color: var(--text-mute); }
.file-arrow .ui-svg { width: 14px; height: 14px; }

/* Admin tools and tables */
/* 列表面板：筛选栏 + 表格 融合为同一张卡片，消除"两个浮块硬拼"的割裂感 */
.list-panel {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.list-panel > .elevated-toolbar {
  margin-bottom: 0;
  border: none;
  border-radius: 0;
  box-shadow: none;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 12px 14px;
  align-items: flex-start;
}
/* 筛选栏控件垂直对齐：搜索框/按钮无 label，补出 label 高度后与带 label 的下拉顶部齐平，底边也等高 */
.list-panel .toolbar-search,
.list-panel .elevated-toolbar > .btn { margin-top: 21px; }
.list-panel .toolbar-search input,
.list-panel .filter-control select { width: 100%; height: 40px; min-height: 40px; border-radius: 8px; }
.list-panel .elevated-toolbar > .btn { height: 40px; box-sizing: border-box; }
.list-panel > .tbl-wrap {
  border: none;
  border-radius: 0;
  box-shadow: none;
}
.elevated-toolbar {
  min-height: 64px;
  gap: 10px;
  margin-bottom: 13px;
  padding: 11px 12px;
  border-radius: var(--radius-md);
  box-shadow: 0 1px 2px rgba(15,23,42,0.03);
}
.toolbar-search { flex: 1; min-width: 220px; }
.filter-control { min-width: 145px; margin: 0; }
.filter-control > span { display: block; margin-bottom: 5px; color: var(--text-soft); font-size: 11px; font-weight: 500; }
.filter-control select { width: 100%; min-height: 38px; padding: 7px 30px 7px 11px; border-radius: var(--radius); background: var(--surface-soft); font-size: 12px; color: var(--text); }
.toolbar-caption { display: inline-flex; align-items: center; gap: 6px; color: var(--text-soft); font-size: 10px; font-weight: 600; }
.toolbar-caption .ui-svg { width: 14px; height: 14px; color: var(--accent); }
.toolbar-readonly { display: inline-flex; align-items: center; gap: 5px; margin-left: auto; color: var(--text-mute); font-size: 9px; }
.toolbar-readonly .ui-svg { width: 13px; height: 13px; color: var(--success); }
.admin-table-wrap { border-radius: var(--radius-md); overflow-x: auto; box-shadow: 0 8px 26px rgba(15,23,42,0.03); }
.admin-table { min-width: 1040px; }
.admin-table .id-col { width: 46px; }
.admin-table .num-col { width: 70px; text-align: right; }
.admin-table .action-col { width: 132px; }
.user-cell { display: flex; align-items: center; gap: 9px; }
.user-initial {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  border-radius: var(--radius);
  color: var(--accent-hover);
  background: var(--accent-soft);
  font-size: 11px;
  font-weight: 600;
}
.user-cell-copy { display: grid; gap: 1px; }
.user-cell-copy b { color: var(--text); font-size: 11px; font-weight: 500; }
.user-cell-copy small { color: var(--text-mute); font-family: var(--font-mono); font-size: 8px; }
.role-badge { display: inline-flex; align-items: center; gap: 5px; padding: 3px 7px; border-radius: var(--radius); color: var(--info); background: var(--info-bg); font-size: 8px; font-weight: 600; }
.role-badge.admin,
.role-badge.super_admin { color: var(--accent-hover); background: var(--accent-soft); }
.role-badge.operator { color: #6d28d9; background: #ede9fe; }
.action-cell { display: flex; align-items: center; gap: 5px; }
.action-cell .btn { min-height: 29px; padding: 4px 8px; font-size: 9px; }
.action-cell .btn .ui-svg { width: 12px; height: 12px; }
body.app-shell .status { border-radius: var(--radius); padding: 3px 7px; font-size: 8px; }

/* Logs */
.icon-tabs {
  gap: 7px;
  margin-bottom: 0;
  padding: 0 0 12px;
  border-bottom: 1px solid var(--border);
}
.icon-tabs button {
  min-height: 38px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  padding: 8px 12px;
  border: 1px solid transparent;
  border-radius: 7px;
  font-size: 10px;
}
.icon-tabs button span { color: inherit; }
.icon-tabs button > [data-ui-icon] { width: 16px; height: 16px; }
.icon-tabs button .ui-svg { width: 16px; height: 16px; }
.icon-tabs button:hover { background: var(--surface-soft); }
.icon-tabs button.active { border-color: var(--border); border-bottom-color: var(--border); color: var(--text); background: white; box-shadow: var(--shadow-sm); }
.log-toolbar { margin-top: 12px; }
.log-table-wrap { margin-top: 0; }
.log-table-wrap .tbl { min-width: 980px; }
.diff-block { max-width: 300px; display: grid; gap: 5px; font-family: var(--font-mono); font-size: 8px; word-break: break-word; }
.diff-before,
.diff-after { padding: 6px 7px; border-radius: 4px; }
.diff-before { color: var(--text-soft); background: var(--surface-soft); }
.diff-after { color: var(--accent-hover); background: var(--accent-soft); }
.diff-arrow { color: var(--text-mute); text-align: center; line-height: 1; }

@media (max-width: 1100px) {
  body.app-shell .topbar .brand { min-width: auto; margin-right: 14px; }
  body.app-shell .topbar .brand-copy small,
  .user-copy,
  body.app-shell .topbar .role-tag { display: none; }
  .upload-layout { grid-template-columns: 1fr; }
  .workflow-panel { display: grid; grid-template-columns: 1fr 1.5fr; gap: 20px; }
  .workflow-panel .panel-heading { grid-column: 1 / -1; }
  .workflow-panel .field-guide,
  .workflow-panel .workflow-note { align-self: end; }
  .quote-workspace { grid-template-columns: 1fr; }
  .quote-sidebar { position: static; grid-template-columns: repeat(3, minmax(0,1fr)); }
}

@media (max-width: 820px) {
  body.app-shell .topbar { height: auto; min-height: 68px; flex-wrap: wrap; padding: 10px 18px 0; }
  body.app-shell .topbar .brand { margin-right: auto; }
  body.app-shell .topbar .user-area { margin-left: 12px; }
  body.app-shell .topbar nav { order: 3; width: 100%; height: 48px; overflow-x: auto; }
  body.app-shell .topbar nav a { flex: 1; min-width: max-content; }
  body.app-shell .topbar nav a.active::after { bottom: -6px; }
  body.app-shell main { padding: 28px 18px 56px; }
  body.app-shell .page-header { align-items: flex-start; flex-direction: column; gap: 18px; }
  .metric-grid { grid-template-columns: repeat(2, minmax(0,1fr)); }
  body.app-shell .quote-grid { grid-template-columns: 1fr; }
  .workflow-panel { display: block; }
  .quote-sidebar { grid-template-columns: 1fr; }
  .header-action-group { justify-content: flex-start; }
  .autosave-note { width: 100%; }
}

@media (max-width: 560px) {
  body.app-shell .topbar .brand-copy,
  body.app-shell .topbar .logout-btn span { display: none; }
  body.app-shell .topbar nav a { flex-direction: column; justify-content: center; gap: 2px; height: 42px; padding: 4px 9px; font-size: 9px; }
  body.app-shell .topbar nav a .nav-svg { width: 14px; height: 14px; }
  body.app-shell .page-header h1 { font-size: 25px; }
  .page-context { width: 100%; }
  .metric-grid { grid-template-columns: 1fr; }
  .metric-card { min-height: 92px; }
  .upload-primary,
  .workflow-panel { padding: 20px 16px; }
  body.app-shell .dropzone { min-height: 250px; padding: 26px 16px; }
  .file-type-row em { width: 100%; margin: 4px 0 0; }
  .panel-actions { align-items: stretch; flex-direction: column; }
  .panel-actions .row { width: 100%; }
  .panel-actions .btn { flex: 1; }
  .section-bar { align-items: flex-start; flex-direction: column; gap: 8px; }
  .quote-page-header .header-action-group { width: 100%; }
  .quote-page-header .header-action-group .btn { flex: 1; }
  .quote-page-header .header-action-group .btn-danger-ghost { flex: 0 0 auto; }
  .elevated-toolbar { align-items: stretch; flex-direction: column; }
  .toolbar-search,
  .filter-control { width: 100%; }
  .toolbar-readonly { margin-left: 0; }
  .icon-tabs { display: grid; grid-template-columns: repeat(3, 1fr); }
  .icon-tabs button { justify-content: center; padding-inline: 6px; }
}

@media (prefers-reduced-motion: reduce) {
  body.app-shell *,
  body.app-shell *::before,
  body.app-shell *::after { scroll-behavior: auto !important; transition: none !important; animation: none !important; }
}

.source-cell { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
body.app-shell table.tbl .badge { border-radius: var(--radius); padding: 3px 6px; font-size: 8px; }
.confidence { color: var(--text-mute); font-family: var(--font-mono); font-size: 8px; }
.empty-inline-icon { display: inline-flex; margin-right: 6px; color: var(--accent); vertical-align: -3px; }
.empty-inline-icon .ui-svg { width: 15px; height: 15px; }
.text-compact { color: var(--text-soft); font-size: 9px; }
.role-badge.phone { color: var(--info); background: var(--info-bg); }
.role-badge.wechat { color: var(--success); background: var(--success-bg); }
.log-metrics #logMetricD,
.log-metrics #logMetricC { font-size: 18px; }



/* 骨架屏（替代圆形 spinner） */
.skeleton {
  position: relative;
  display: block;
  background: var(--skeleton);
  border-radius: var(--radius);
  overflow: hidden;
}
.skeleton::after {
  content: "";
  position: absolute; inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--skeleton-hi), transparent);
  animation: skeleton-shine 1.2s ease-in-out infinite;
}
@keyframes skeleton-shine { 100% { transform: translateX(100%); } }
.skeleton-line { height: 12px; border-radius: 6px; }
.skeleton-line.lg { height: 16px; }
.skeleton-block { height: 28px; border-radius: var(--radius); }
.skeleton-row td { padding: 12px 14px; }
.skeleton-row .skeleton { width: 100%; }

/* 编辑弹窗 */
.modal-mask {
  position: fixed; inset: 0;
  background: rgba(15,23,42,0.5);
  backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center;
  padding: 20px; z-index: 50;
  animation: modal-fade 0.18s ease both;
}
.modal-mask[hidden] { display: none; }
.modal-card {
  width: min(720px, 94vw);
  max-height: 92vh; overflow: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 60px rgba(15,23,42,0.28);
  animation: modal-rise 0.22s cubic-bezier(0.16,1,0.3,1) both;
}
@keyframes modal-rise { from { opacity: 0; transform: translateY(12px) scale(0.985); } to { opacity: 1; transform: none; } }
.modal-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 18px 22px; border-bottom: 1px solid var(--border);
}
.modal-head h3 { font-size: 16px; font-weight: 600; margin: 0; letter-spacing: -0.01em; }
.icon-btn {
  background: transparent; border: 0; padding: 6px;
  border-radius: var(--radius); cursor: pointer; color: var(--text-soft);
  display: grid; place-items: center;
  transition: background 0.15s ease, color 0.15s ease;
}
.icon-btn:hover { background: var(--surface-soft); color: var(--text); }
.icon-btn .ui-svg { width: 18px; height: 18px; }
.modal-body { padding: 20px 22px; }
.modal-body .grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 14px 18px; margin-bottom: 12px; }
.modal-body .field label { display: block; font-size: 12px; color: var(--text-soft); margin-bottom: 6px; letter-spacing: 0.02em; }
.modal-body input, .modal-body select, .modal-body textarea {
  width: 100%; padding: 9px 12px;
  border: 1px solid var(--border-strong); border-radius: var(--radius);
  background: var(--surface); color: var(--text); font-size: 13px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.modal-body input:focus, .modal-body select:focus, .modal-body textarea:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(30,41,59,0.08);
}
.modal-body textarea { resize: vertical; min-height: 64px; }
.modal-foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding-top: 16px; border-top: 1px solid var(--border); margin-top: 6px;
}
@keyframes modal-fade { from { opacity: 0; } to { opacity: 1; } }

/* Toast */
.toast {
  position: fixed; right: 24px; bottom: 24px;
  padding: 11px 18px;
  background: var(--text); color: var(--surface);
  border-radius: var(--radius-md); box-shadow: 0 12px 30px rgba(15,23,42,0.24);
  z-index: 60; font-size: 13px;
  animation: toast-in 0.2s ease both;
}
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.toast.success { background: var(--success); color: #fff; }
.toast.error { background: var(--danger); color: #fff; }


/* 2026-08-19: 多图/文件夹上传 + 用户详情 */
.process-requirement-input {
  width: 100%;
  min-height: 92px;
  resize: vertical;
  padding: 12px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  line-height: 1.6;
}
.process-requirement-input:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(30,41,59,0.08);
}
.preview-list { display: grid; gap: 8px; width: 100%; }
.multi-preview-card { width: 100%; }
.multi-file-summary { margin-top: 8px; font-size: 12px; color: var(--text-soft); text-align: left; }

.user-detail-modal { width: min(980px, 96vw); }
.detail-summary-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}
.detail-summary-grid > div {
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-soft);
}
.detail-summary-grid small { display: block; color: var(--text-mute); font-size: 11px; margin-bottom: 5px; }
.detail-summary-grid strong { font-size: 20px; font-family: var(--font-mono); }
.user-detail-table-wrap { max-height: 52vh; overflow: auto; }
.user-detail-table { min-width: 760px; }
.detail-link { color: var(--primary); font-weight: 600; text-decoration: none; }
.detail-link:hover { text-decoration: underline; }
.access-restriction { margin: 0 0 16px; }
@media (max-width: 720px) {
  .detail-summary-grid { grid-template-columns: 1fr; }
}
 .admin-table .action-col { width: 260px; min-width: 260px; }
.action-cell { display: flex; align-items: center; flex-wrap: nowrap; gap: 6px; white-space: nowrap; }
.action-cell .btn-detail {
  border-color: #94a3b8;
  background: #f8fafc;
  color: #0f172a;
  font-weight: 600;
}
.action-cell .btn-detail:hover { background: #e2e8f0; border-color: #64748b; }
.file-relative-path { max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }



/* 2026-08-19: keep cross-page chrome geometry stable during navigation/hydration. */
body.app-shell .topbar nav a { min-width: 86px; justify-content: center; }
body.app-shell .topbar .user-area { min-width: 230px; justify-content: flex-end; }
body.app-shell #userBadge { min-width: 132px; display: inline-flex; justify-content: flex-end; }
.auth-msg { white-space: pre-line; }
.detail-file-link {
  display: inline-grid;
  grid-template-columns: 18px minmax(0, 1fr);
  column-gap: 7px;
  align-items: center;
  max-width: 330px;
  color: var(--primary);
  font-weight: 600;
  text-decoration: none;
}
.detail-file-link svg { width: 16px; height: 16px; grid-row: 1 / span 2; color: var(--accent); }
.detail-file-link span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.detail-file-link em { grid-column: 2; color: var(--accent); font-size: 10px; font-style: normal; font-weight: 500; }
.detail-file-link:hover span { text-decoration: underline; }
.detail-file-link.is-disabled { color: var(--text-soft); cursor: default; }
.detail-file-link.is-disabled em { color: var(--text-mute); }

/* ============ 微信开放平台授权登录 ============ */
.wechat-auth-btn { margin-top: 2px; }
.wechat-or {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 14px 0 2px;
  color: var(--text-mute);
  font-size: 11px;
}
.wechat-or::before,
.wechat-or::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}
.wechat-or span { white-space: nowrap; }

.field-help {
  margin-top: 6px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted, #64748b);
}

/* 微信开放平台官方内嵌扫码组件：保持原二维码框尺寸，仅裁切显示扫码区 */
.wechat-qr-container {
  width: 248px;
  height: 248px;
  overflow: hidden;
  position: relative;
  border-radius: 7px;
  background: #fff;
}
.wechat-qr-container iframe {
  width: 300px !important;
  height: 400px !important;
  border: 0 !important;
  transform: scale(0.8267);
  transform-origin: 0 0;
}
.wechat-qr-loading {
  position: absolute; inset: 0; display: grid; place-items: center;
  color: var(--text-mute); font-size: 12px; line-height: 1.5; padding: 16px;
}

/* ===== 微信二维码最终尺寸覆盖 v20260819wx10 =====
   固定外框/容器 300x300，移除旧版 248px + scale 覆盖。 */
.qr-frame{width:300px!important;height:300px!important;padding:0!important;}
.wechat-qr-container{width:300px!important;height:300px!important;max-width:300px!important;max-height:300px!important;overflow:hidden!important;position:relative!important;display:block!important;border-radius:12px!important;background:#fff!important;}
.wechat-qr-container iframe{width:300px!important;height:300px!important;min-width:300px!important;min-height:300px!important;max-width:none!important;max-height:none!important;transform:none!important;transform-origin:0 0!important;margin:0!important;padding:0!important;border:0!important;display:block!important;}
\n\n/* ===== 微信二维码稳定显示 v20260819wx11 =====
   直接内嵌 qrconnect 页面：外框 300x300，裁掉微信页面标题/说明区，只显示官方二维码主体。 */
.qr-frame{width:300px!important;height:300px!important;padding:0!important;overflow:hidden!important;background:#fff!important;}
.wechat-qr-container{width:300px!important;height:300px!important;max-width:300px!important;max-height:300px!important;overflow:hidden!important;position:relative!important;display:block!important;border-radius:12px!important;background:#fff!important;}
.wechat-qr-container iframe.wechat-official-frame{position:absolute!important;left:0!important;top:-48px!important;width:300px!important;height:400px!important;min-width:300px!important;min-height:400px!important;max-width:none!important;max-height:none!important;transform:none!important;margin:0!important;padding:0!important;border:0!important;display:block!important;background:#fff!important;}
.wechat-qr-loading{position:absolute!important;inset:0!important;display:grid!important;place-items:center!important;}

/* 微信后端中继扫码：静态二维码放大并裁掉底部半截“微信扫码”文字。 */
.qr-frame{width:320px!important;height:320px!important;padding:0!important;overflow:hidden!important;background:#fff!important;box-sizing:border-box!important;}
.wechat-qr-container{width:100%!important;height:100%!important;max-width:none!important;max-height:none!important;overflow:hidden!important;position:relative!important;display:flex!important;align-items:center!important;justify-content:center!important;border-radius:14px!important;background:#fff!important;padding:0!important;box-sizing:border-box!important;}
.wechat-relay-qr-image{display:block!important;width:108%!important;height:108%!important;max-width:none!important;max-height:none!important;object-fit:cover!important;object-position:center 42%!important;margin:0!important;padding:0!important;border:0!important;background:#fff!important;image-rendering:auto;transform:translateY(-4px)!important;}


/* ===== 微信二维码显示优化 v20260820wxrelay2 ===== */
.qr-frame{width:340px!important;height:340px!important;padding:0!important;overflow:hidden!important;background:#fff!important;box-sizing:border-box!important;}
.wechat-qr-container{width:100%!important;height:100%!important;max-width:none!important;max-height:none!important;overflow:hidden!important;position:relative!important;display:flex!important;align-items:center!important;justify-content:center!important;border-radius:14px!important;background:#fff!important;padding:0!important;box-sizing:border-box!important;}
.wechat-relay-qr-image{display:block!important;width:116%!important;height:116%!important;max-width:none!important;max-height:none!important;object-fit:cover!important;object-position:center 36%!important;margin:0!important;padding:0!important;border:0!important;background:#fff!important;image-rendering:auto;transform:translateY(-12px)!important;}
.qr-status{margin-top:14px!important;}


/* ===== 报价合计：智能重新核算按钮 v20260820recalc1 ===== */
.quote-total-control{display:flex!important;align-items:center!important;justify-content:flex-end!important;gap:12px!important;white-space:nowrap;}
.btn-recalculate{min-height:32px!important;padding:6px 12px!important;border-color:#d8dee8!important;background:#fff!important;color:#334155!important;font-size:12px!important;font-weight:600!important;box-shadow:none!important;}
.btn-recalculate:hover:not(:disabled){border-color:#b45309!important;color:#b45309!important;background:#fffaf4!important;}
.btn-recalculate:disabled{opacity:.58!important;cursor:not-allowed!important;}
.btn-recalculate .ui-icon,.btn-recalculate svg{width:14px!important;height:14px!important;}


/* ===== 微信扫码界面样式回调到经典版 v20260820wxui1 ===== */
.qr-block{gap:18px!important;padding:8px 0 8px!important;}
.qr-frame{
  width:278px!important;
  height:278px!important;
  padding:18px!important;
  overflow:visible!important;
  display:flex!important;
  align-items:center!important;
  justify-content:center!important;
  border:1px solid #d8e0ea!important;
  border-radius:18px!important;
  background:#fff!important;
  box-shadow:none!important;
  box-sizing:border-box!important;
}
.wechat-qr-container{
  width:242px!important;
  height:242px!important;
  min-width:242px!important;
  min-height:242px!important;
  max-width:242px!important;
  max-height:242px!important;
  overflow:hidden!important;
  position:relative!important;
  display:flex!important;
  align-items:center!important;
  justify-content:center!important;
  border-radius:8px!important;
  background:#fff!important;
  padding:0!important;
  box-sizing:border-box!important;
}
.wechat-relay-qr-image,
.wechat-qr-container img{
  width:242px!important;
  height:242px!important;
  min-width:242px!important;
  min-height:242px!important;
  max-width:242px!important;
  max-height:242px!important;
  object-fit:contain!important;
  object-position:center center!important;
  transform:none!important;
  margin:0!important;
  padding:0!important;
  border:0!important;
  border-radius:0!important;
  display:block!important;
  background:#fff!important;
}
.wechat-qr-container iframe,
.wechat-qr-container iframe.wechat-official-frame{
  width:242px!important;
  height:320px!important;
  min-width:242px!important;
  min-height:320px!important;
  max-width:242px!important;
  max-height:320px!important;
  position:absolute!important;
  left:0!important;
  top:-38px!important;
  margin:0!important;
  padding:0!important;
  border:0!important;
  display:block!important;
  background:#fff!important;
  transform:none!important;
}
.qr-frame::before{
  content:"微信扫码"!important;
  position:absolute!important;
  left:50%!important;
  bottom:-11px!important;
  z-index:3!important;
  transform:translateX(-50%)!important;
  padding:0 8px!important;
  font-size:12px!important;
  line-height:1.2!important;
  letter-spacing:0!important;
  color:#94a3b8!important;
  background:#fff!important;
  white-space:nowrap!important;
}
.qr-corner{width:24px!important;height:24px!important;border-color:#e07b2d!important;border-width:2px!important;}
.qr-corner.corner-a{left:-1px!important;top:-1px!important;border-width:2px 0 0 2px!important;border-radius:18px 0 0 0!important;}
.qr-corner.corner-b{right:-1px!important;top:-1px!important;border-width:2px 2px 0 0!important;border-radius:0 18px 0 0!important;}
.qr-corner.corner-c{left:-1px!important;bottom:-1px!important;border-width:0 0 2px 2px!important;border-radius:0 0 0 18px!important;}
.qr-corner.corner-d{right:-1px!important;bottom:-1px!important;border-width:0 2px 2px 0!important;border-radius:0 0 18px 0!important;}
.qr-status{
  min-height:38px!important;
  margin-top:8px!important;
  padding:9px 14px!important;
  border-radius:10px!important;
  border:1px solid #d9e0ea!important;
  background:#f4f7fb!important;
  color:#64748b!important;
  font-size:13px!important;
  line-height:1.3!important;
  box-sizing:border-box!important;
}
.qr-status .dot{width:8px!important;height:8px!important;background:#94a3b8!important;animation:pulse 1.5s infinite!important;}
.qr-status.scanned{
  border-color:#f3c36a!important;
  background:#fff3d9!important;
  color:#d97706!important;
}
.qr-status.scanned .dot{background:#f59e0b!important;}
.qr-status.confirmed{
  border-color:#86efac!important;
  background:#ecfdf3!important;
  color:#15803d!important;
}
.qr-status.confirmed .dot{background:#16a34a!important;animation:none!important;}


/* ===== 20260820: 上传页识别提示隐藏 + 微信首次登录手机号补充 ===== */
#uploadMsg{display:none!important;visibility:hidden!important;height:0!important;min-height:0!important;margin:0!important;padding:0!important;border:0!important;overflow:hidden!important;}
.phone-bind-mask{position:fixed;inset:0;z-index:9999;background:rgba(15,23,42,.48);display:flex;align-items:center;justify-content:center;padding:24px;backdrop-filter:blur(3px);}
.phone-bind-mask[hidden]{display:none!important;}
.phone-bind-card{width:min(420px,calc(100vw - 32px));background:#fff;border:1px solid #e2e8f0;border-radius:18px;padding:28px;box-shadow:0 22px 60px rgba(15,23,42,.22);}
.phone-bind-card h3{margin:6px 0 8px;font-size:24px;color:#0f172a;}
.phone-bind-card p{margin:0 0 20px;color:#64748b;font-size:13px;line-height:1.7;}
.phone-bind-card .auth-submit{margin-top:8px;width:100%;}


/* 禁用账号微信登录状态 */
.qr-status.restricted{border-color:#fecaca!important;background:#fef2f2!important;color:#b91c1c!important;}
.qr-status.restricted .dot{background:#dc2626!important;animation:none!important;}


/* ===== 用户管理：用户报价只读弹窗 v20260820userscope1 ===== */
.detail-link-button{
  appearance:none;
  -webkit-appearance:none;
  border:0;
  background:transparent;
  padding:0;
  margin:0;
  cursor:pointer;
  font:inherit;
  text-align:left;
}
.user-quote-detail-modal{width:min(1080px,96vw);}
.user-quote-summary{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:20px;
  padding:14px 16px;
  margin-bottom:16px;
  border:1px solid var(--border);
  border-radius:var(--radius-md);
  background:var(--surface-soft);
}
.user-quote-summary span{font-size:12px;color:var(--text-soft);}
.user-quote-summary strong{font-size:24px;font-family:var(--font-mono);color:var(--primary);}
.user-quote-detail-table-wrap{max-height:56vh;overflow:auto;}
.user-quote-detail-table{min-width:900px;}


/* ===== 管理员查看用户报价：列对齐修复 v20260820quotealign1 ===== */
.user-quote-detail-table{
  width:100%;
  min-width:900px;
  table-layout:fixed;
}
.user-quote-detail-table .quote-col-index{width:5%;}
.user-quote-detail-table .quote-col-name{width:13%;}
.user-quote-detail-table .quote-col-spec{width:45%;}
.user-quote-detail-table .quote-col-price{width:14%;}
.user-quote-detail-table .quote-col-unit{width:12%;}
.user-quote-detail-table .quote-col-total{width:11%;}
.user-quote-detail-table th:nth-child(4),
.user-quote-detail-table td:nth-child(4),
.user-quote-detail-table th:nth-child(6),
.user-quote-detail-table td:nth-child(6){
  text-align:right!important;
  white-space:nowrap;
}
.user-quote-detail-table th:nth-child(4),
.user-quote-detail-table td:nth-child(4){
  padding-right:22px!important;
}
.user-quote-detail-table th:nth-child(5),
.user-quote-detail-table td:nth-child(5){
  padding-left:18px!important;
  white-space:nowrap;
}


.upload-action-right { justify-content: flex-end; width: 100%; }


/* 用户定制优化 */
.preview-list {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}
.multi-preview-card {
  min-width: 0;
}
.multi-preview-card .preview-name {
  max-width: 100%;
}
.process-requirement-input {
  min-height: 56px;
  height: 56px;
}
.upload-action-right {
  transform: translateY(-10px);
}
body.app-shell .detail-card .detail-list > div {
  padding: 5px 0;
  min-height: 28px;
}
body.app-shell .source-card {
  margin-top: -10px;
}

/* ===== Batch quote / adaptive editor V5 (2026-08-21) ===== */
/* 明细表：名称和规格材料按可用空间自适应，避免长名称把整张表撑宽。 */
body.app-shell .editor-table {
  width: 100%;
  min-width: 780px;
  table-layout: fixed;
}
body.app-shell .editor-table th.col-name,
body.app-shell .editor-table td.col-name { width: 25%; }
body.app-shell .editor-table th.col-spec,
body.app-shell .editor-table td.col-spec { width: 31%; }
body.app-shell .editor-table td.col-name,
body.app-shell .editor-table td.col-spec { min-width: 0; }
body.app-shell .editor-table td.col-name input,
body.app-shell .editor-table td.col-spec input,
body.app-shell .editor-table td.col-spec textarea {
  min-width: 0;
  max-width: 100%;
}

/* 我的报价：长文件名默认单行省略，确实溢出时才显示“查看全部/收起”。 */
.quote-ident-copy { flex: 1; min-width: 0; }
.quote-title-wrap { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }
body.app-shell .quote-card .quote-card-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  word-break: break-all;
}
body.app-shell .quote-card .quote-card-title.expanded {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
}
.quote-title-toggle {
  flex: 0 0 auto;
  margin-top: 1px;
  color: var(--accent);
  font-size: 10px;
  line-height: 20px;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
}
.quote-title-toggle[hidden] { display: none !important; }
.quote-title-toggle:hover { text-decoration: underline; }
.quote-title-toggle:focus-visible { outline: 2px solid rgba(180,83,9,.22); outline-offset: 2px; border-radius: 3px; }

/* 输入来源：批量报价在同一张卡片中逐个显示所有文件。 */
#sourceFiles { display: grid; gap: 8px; }
body.app-shell .source-card .batch-source-row + .batch-source-row { margin-top: 0; }
body.app-shell .source-card .batch-source-row .meta .name {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* ===== Batch V6 detail/source refinements (2026-08-21) ===== */
/* 名称列按内容自适应但设置上限，避免“文件名-部件名”把整个报价表撑宽；规格材料自动吃掉剩余空间。 */
body.app-shell .editor-table {
  width: 100%;
  min-width: 760px;
  table-layout: fixed;
  --cq-name-col: 14ch;
}
body.app-shell .editor-table th.col-name,
body.app-shell .editor-table td.col-name {
  width: var(--cq-name-col);
  max-width: 19ch;
}
body.app-shell .editor-table th.col-spec,
body.app-shell .editor-table td.col-spec {
  width: auto;
}
body.app-shell .editor-table td.col-name input,
body.app-shell .editor-table td.col-spec input,
body.app-shell .editor-table td.col-spec textarea {
  width: 100%;
  min-width: 0;
  max-width: 100%;
}

/* 输入来源整行可点击；箭头不再是无动作装饰。 */
body.app-shell .source-card a.source-file-link {
  display: flex;
  align-items: center;
  gap: 10px;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}
body.app-shell .source-card a.source-file-link .meta {
  flex: 1;
  min-width: 0;
}
body.app-shell .source-card a.source-file-link .file-arrow {
  flex: 0 0 auto;
  transition: transform .15s ease, color .15s ease;
}
body.app-shell .source-card a.source-file-link:hover .file-arrow {
  transform: translateX(2px);
  color: var(--accent);
}

/* ===== Batch V7 source modal / exact-title export refinements (2026-08-21) ===== */
body.app-shell .source-card button.source-file-link {
  width: 100%;
  border: 0;
  background: transparent;
  font: inherit;
  text-align: left;
  padding: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  color: inherit;
  cursor: pointer;
}
body.app-shell .source-card button.source-file-link .meta {
  flex: 1;
  min-width: 0;
}
body.app-shell .source-card button.source-file-link .file-arrow {
  flex: 0 0 auto;
  transition: transform .15s ease, color .15s ease;
}
body.app-shell .source-card button.source-file-link:hover .file-arrow,
body.app-shell .source-card button.source-file-link:focus-visible .file-arrow {
  transform: translateX(2px);
  color: var(--accent);
}
body.app-shell .source-card button.source-file-link:focus-visible {
  outline: 2px solid rgba(180,83,9,.25);
  outline-offset: 2px;
  border-radius: 8px;
}
body.source-preview-open { overflow: hidden; }
.source-preview-modal {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 32px;
}
.source-preview-modal.open { display: flex; }
.source-preview-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15,23,42,.56);
  backdrop-filter: blur(2px);
}
.source-preview-dialog {
  position: relative;
  z-index: 1;
  width: min(1180px, 94vw);
  height: min(820px, 88vh);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 14px;
  background: #fff;
  box-shadow: 0 26px 70px rgba(15,23,42,.28);
}
.source-preview-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 16px 20px;
  border-bottom: 1px solid #e2e8f0;
  background: #fff;
}
.source-preview-kicker {
  color: #b45309;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
}
.source-preview-header h2 {
  margin: 3px 0 0;
  max-width: 900px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #0f172a;
  font-size: 18px;
}
.source-preview-close {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border: 1px solid #cbd5e1;
  border-radius: 9px;
  background: #fff;
  color: #475569;
  font-size: 26px;
  line-height: 30px;
  cursor: pointer;
}
.source-preview-close:hover { background: #f8fafc; color: #0f172a; }
.source-preview-body {
  flex: 1;
  min-height: 0;
  background: #f1f5f9;
}
.source-preview-frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: #fff;
}
.source-preview-image-wrap {
  width: 100%;
  height: 100%;
  overflow: auto;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 18px;
}
.source-preview-image {
  display: block;
  max-width: 100%;
  height: auto;
  object-fit: contain;
  border-radius: 6px;
  box-shadow: 0 4px 18px rgba(15,23,42,.12);
}
.source-preview-empty {
  height: 100%;
  display: grid;
  place-items: center;
  color: #64748b;
  font-size: 14px;
}
@media (max-width: 760px) {
  .source-preview-modal { padding: 12px; }
  .source-preview-dialog { width: 100%; height: 92vh; border-radius: 10px; }
  .source-preview-header { padding: 13px 14px; }
}

/* ===== Batch V8 exact source / full modal / measured name width (2026-08-21) ===== */
/* 名称列由 quote-edit.js 根据“当前最长名称”的实际像素宽度实时计算；不再使用固定 ch 宽度或 19ch 上限。 */
body.app-shell .editor-table {
  --cq-name-col: 180px;
}
body.app-shell .editor-table th.col-name,
body.app-shell .editor-table td.col-name {
  width: var(--cq-name-col) !important;
  max-width: none !important;
  min-width: 0;
}
body.app-shell .editor-table th.col-spec,
body.app-shell .editor-table td.col-spec {
  width: auto !important;
  min-width: 260px;
}

/* 多文件全部保留在“输入来源”卡片中；文件较多时只在卡片内部滚动。 */
body.app-shell .source-card #sourceFiles {
  display: grid;
  gap: 8px;
  max-height: 390px;
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 2px;
}

/* 原始文件弹窗：图片/PDF 都尽量占满弹窗内容区。 */
.source-preview-modal {
  padding: 22px;
}
.source-preview-dialog {
  width: min(1480px, 96vw);
  height: min(920px, 94vh);
}
.source-preview-body {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  background: #eef2f7;
}
.source-preview-frame {
  width: 100%;
  height: 100%;
  min-height: 0;
  border: 0;
  background: #fff;
}
.source-preview-image-wrap {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  min-height: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
}
.source-preview-image {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: contain;
  border-radius: 6px;
  box-shadow: 0 4px 18px rgba(15,23,42,.12);
  background: #fff;
}
@media (max-width: 760px) {
  .source-preview-modal { padding: 8px; }
  .source-preview-dialog { width: 100%; height: 95vh; }
  body.app-shell .source-card #sourceFiles { max-height: 330px; }
}

/* ===== Batch V9 source list: one visible box per uploaded file ===== */
body.app-shell .source-card button.source-file-link {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid #e2e8f0;
  background: #fff;
  border-radius: var(--radius);
  padding: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
body.app-shell .source-card button.source-file-link:hover {
  border-color: #fde68a;
  box-shadow: 0 0 0 3px rgba(180,83,9,0.06);
}
body.app-shell .source-card #sourceFiles {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
}

/* V13 admin user document in-page preview */
.detail-file-preview-btn { width:100%; border:0; background:transparent; font:inherit; text-align:left; cursor:pointer; }
.detail-file-preview-btn:hover em { text-decoration:underline; }
#adminDocumentPreviewModal .source-preview-dialog { width:min(92vw, 1180px); height:min(88vh, 860px); max-width:1180px; max-height:88vh; }
#adminDocumentPreviewModal .source-preview-body { min-height:240px; }
@media (max-width: 720px) { #adminDocumentPreviewModal .source-preview-dialog { width:96vw; height:90vh; } }
