/* ============================================================================
 * Invoice Recognition System — "Carbon Ledger / Audit Dossier" design system
 * ----------------------------------------------------------------------------
 * Design rationale and tokens: see docs/ui/DESIGN_NOTES.md
 * Every existing template class name is preserved — this is a pure reskin.
 * ========================================================================== */

/* ---------- Tokens ------------------------------------------------------- */
:root {
  /* Palette */
  --paper-bg:      #eef0f3;
  --paper-bg-2:    #e6e9ee;
  --paper-card:    #ffffff;
  --paper-elev:    #fbfcfd;
  --paper-stripe:  #f5f7f9;
  --ink:           #0f1d2e;
  --ink-2:         #2c3a4f;
  --ink-3:         #5a6b80;
  --ink-4:         #8696aa;
  --line:          #d9e0e8;
  --line-strong:   #b9c4d2;
  --accent:        #8c1c1c;   /* oxblood — verified / stamped */
  --accent-deep:   #6e1414;
  --accent-soft:   #f9e8e6;
  --accent-glow:   rgba(140, 28, 28, 0.22);
  --accent-2:      #0b6e4f;   /* ledger green — confirmed */
  --accent-2-soft: #e8f3ee;
  --warn:          #b45309;   /* amber — caution */
  --warn-bg:       #fef3c7;   /* ledger yellow — duplicate highlight */
  --warn-bar:      #f5c518;
  --danger:        #991b1b;
  --danger-soft:   #fdecec;

  /* Type */
  --font-display: "Source Han Serif SC", "Noto Serif SC", "Songti SC",
                  "STSong", "SimSun", serif;
  --font-body:    "Inter", -apple-system, BlinkMacSystemFont, "PingFang SC",
                  "Microsoft YaHei", "Segoe UI", Roboto, sans-serif;
  --font-mono:    "JetBrains Mono", "SF Mono", "Cascadia Mono", Menlo,
                  Consolas, "Liberation Mono", monospace;

  /* Geometry */
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-xl: 18px;

  /* Elevation */
  --shadow-1: 0 1px 2px rgba(15,29,46,.06), 0 1px 1px rgba(15,29,46,.04);
  --shadow-2: 0 4px 16px rgba(15,29,46,.08), 0 1px 2px rgba(15,29,46,.04);
  --shadow-3: 0 24px 48px -12px rgba(15,29,46,.18), 0 4px 8px rgba(15,29,46,.06);

  /* Layout */
  --topbar-h: 56px;
  --sidebar-w: 232px;
}

/* ---------- Reset & base ------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  font-family: var(--font-body);
  background: var(--paper-bg);
  color: var(--ink);
  line-height: 1.55;
  font-size: 14.5px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

body {
  min-height: 100vh;
  /* Subtle carbon-paper texture (CSS-only radial dots) */
  background-image:
    radial-gradient(circle at 1px 1px, rgba(15,29,46,0.045) 1px, transparent 0);
  background-size: 22px 22px;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--ink);
  letter-spacing: 0.005em;
  margin: 0 0 12px;
}
h1 { font-size: 1.85rem; font-weight: 600; line-height: 1.2; }
h2 { font-size: 1.35rem; font-weight: 600; line-height: 1.25; }
h3 { font-size: 1.1rem; font-weight: 600; }
p  { margin: 0 0 12px; }

a {
  color: var(--accent);
  text-decoration: none;
  text-underline-offset: 2px;
}
a:hover { text-decoration: underline; }

code, kbd, samp, pre {
  font-family: var(--font-mono);
  font-size: 0.92em;
}

hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 20px 0;
}

/* ---------- Layout shell (sidebar + topbar + main) ----------------------- */
.app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  grid-template-rows: var(--topbar-h) 1fr;
  grid-template-areas:
    "topbar topbar"
    "sidebar main";
  min-height: 100vh;
}

.topbar {
  grid-area: topbar;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  background: var(--ink);
  color: #f1f3f7;
  border-bottom: 1px solid #000;
  position: sticky;
  top: 0;
  z-index: 30;
}
.topbar .brand {
  display: flex; align-items: center; gap: 10px;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.topbar .brand-logo { height: 24px; max-width: 140px; object-fit: contain; }
.topbar .brand-name { line-height: 1.1; }
.topbar .brand-mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  background: var(--accent);
  color: white;
  font-family: var(--font-display);
  font-weight: 700;
  border-radius: 6px;
  letter-spacing: 0;
}

.sidebar {
  grid-area: sidebar;
  background: var(--paper-card);
  border-right: 1px solid var(--line);
  padding: 18px 0;
  position: sticky;
  top: var(--topbar-h);
  align-self: start;
  height: calc(100vh - var(--topbar-h));
  overflow-y: auto;
}
.sidebar-section { padding: 4px 12px 14px; }
.sidebar-section + .sidebar-section { border-top: 1px dashed var(--line); margin-top: 8px; padding-top: 14px; }
.sidebar-label {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-4);
  padding: 4px 12px 8px;
}
.sidebar nav { display: flex; flex-direction: column; gap: 2px; }
.sidebar nav a,
.sidebar nav button {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 8px;
  color: var(--ink-2);
  font-size: 0.93rem;
  font-weight: 500;
  text-decoration: none;
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
  width: 100%;
  font-family: inherit;
  /* ⬇ 特效:平滑过渡(背景/字色/位移) */
  transition: background-color 180ms ease,
              color 180ms ease,
              transform 120ms ease,
              box-shadow 180ms ease;
  position: relative;
}
/* 鼠标悬停:加深颜色 + 轻微右移 */
.sidebar nav a:hover,
.sidebar nav button:hover {
  background: var(--paper-elev);
  color: var(--ink);
  text-decoration: none;
  transform: translateX(2px);
  box-shadow: inset 3px 0 0 var(--accent);
}
/* 点击后(停留):深色背景 + 白字 + 左侧色条 */
.sidebar nav a.active,
.sidebar nav button.active {
  background: var(--ink);
  color: #fff;
  font-weight: 600;
  box-shadow: inset 4px 0 0 var(--accent);
}
.sidebar nav a.active:hover,
.sidebar nav button.active:hover {
  /* active 上 hover 时不要回到普通 hover 的颜色 */
  background: #1a1a1a;
  color: #fff;
  transform: translateX(2px);
}
.sidebar nav a.active .nav-icon,
.sidebar nav button.active .nav-icon { color: var(--accent); }
.sidebar .nav-icon {
  width: 18px; height: 18px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 14px;
  color: var(--ink-3);
}
.sidebar .nav-badge {
  margin-left: auto;
  background: var(--accent);
  color: white;
  font-size: 10px;
  font-family: var(--font-mono);
  padding: 2px 6px;
  border-radius: 10px;
  letter-spacing: 0;
}

.topbar-actions { display: flex; align-items: center; gap: 10px; }
.fs-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255,255,255,0.08);
  color: #f1f3f7;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: var(--r-sm);
  padding: 6px 12px;
  font-size: 0.82rem;
  font-family: inherit;
  cursor: pointer;
  transition: background .15s, border-color .15s;
}
.fs-btn:hover { background: rgba(255,255,255,0.16); border-color: rgba(255,255,255,0.32); }
.fs-btn.active { background: var(--accent); border-color: var(--accent); }

main {
  grid-area: main;
  width: 100%;
  /* 不设 max-width:右侧展示区填充 grid 1fr 列的全部可用宽度,
     宽屏下不再右侧留白(左侧导航固定 var(--sidebar-w))。
     min-width:0 防止表格等 min-content 内容撑破 grid 列导致横向滚动条。 */
  min-width: 0;
  margin: 0;
  padding: 28px 32px 80px;
}
main.wide { max-width: none; }

.bottombar {
  grid-area: main;
  text-align: center;
  color: var(--ink-4);
  padding: 24px 16px 40px;
  font-size: 0.78rem;
  font-family: var(--font-mono);
  letter-spacing: 0.06em;
  border-top: 1px dashed var(--line);
  margin-top: 40px;
}
/* Mobile drawer */
.menu-toggle {
  display: none;
  background: transparent;
  color: white;
  border: 1px solid rgba(255,255,255,0.24);
  border-radius: var(--r-sm);
  padding: 6px 10px;
  font-family: inherit;
  cursor: pointer;
}
@media (max-width: 1100px) {
  .app-shell {
    grid-template-columns: 1fr;
    grid-template-areas: "topbar" "main";
  }
  .sidebar {
    position: fixed;
    top: var(--topbar-h);
    left: 0;
    width: 280px;
    height: calc(100vh - var(--topbar-h));
    transform: translateX(-100%);
    transition: transform .22s ease;
    z-index: 40;
    box-shadow: var(--shadow-3);
  }
  body.sidebar-open .sidebar { transform: translateX(0); }
  body.sidebar-open::after {
    content: ""; position: fixed; inset: var(--topbar-h) 0 0 0;
    background: rgba(15,29,46,0.45); z-index: 35;
  }
  .menu-toggle { display: inline-flex; }
}

/* ---------- Cards -------------------------------------------------------- */
.card {
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 28px;
  margin-bottom: 22px;
  position: relative;
  box-shadow: var(--shadow-1);
}
.card.narrow { max-width: 440px; margin: 56px auto; }

/* Card title accent: a thin oxblood hairline under the title */
.card > h1:first-child,
.card > h2:first-child {
  position: relative;
  padding-bottom: 14px;
  margin-bottom: 18px;
}
.card > h1:first-child::after,
.card > h2:first-child::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 36px; height: 2px;
  background: var(--accent);
}

/* The "perforated tear" detail — a dashed hairline at the top of the card */
.card.tear::before {
  content: "";
  display: block;
  position: absolute;
  top: -1px; left: 24px; right: 24px;
  height: 0;
  border-top: 1px dashed var(--line-strong);
}

/* ---------- Forms & inputs ---------------------------------------------- */
label { display: block; margin: 14px 0; }
label, .field-label {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-2);
  letter-spacing: 0.02em;
}
.field-label {
  display: block;
  margin: 14px 0 6px;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-3);
  font-size: 0.72rem;
}

input[type=text], input[type=password], input[type=email],
input[type=number], input[type=tel], input[type=url], input[type=search],
input:not([type]), select, textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--paper-card);
  color: var(--ink);
  font-size: 0.95rem;
  font-family: inherit;
  transition: border-color .15s, box-shadow .15s, background-color .15s;
}
input[disabled], textarea[disabled] {
  background: var(--paper-elev);
  color: var(--ink-3);
  cursor: not-allowed;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-glow);
}
input::placeholder, textarea::placeholder { color: var(--ink-4); }

textarea { resize: vertical; min-height: 88px; }
select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%),
                    linear-gradient(135deg, var(--ink-3) 50%, transparent 50%);
  background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 32px;
}

/* Invoice numbers, amounts, tax-IDs should read as tabular monospace */
input[name="invoice_number"], input[name="total_amount"],
input[name="buyer_tax_id"], input[name="seller_tax_id"],
input[name="issue_date"], input[type="date"] {
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
}

/* Keyboard-only focus rings (mouse clicks don't show them) */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ---------- Buttons ----------------------------------------------------- */
button, .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 18px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--paper-card);
  color: var(--ink);
  font-size: 0.92rem;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
  transition: background-color .15s, border-color .15s, color .15s, transform .05s;
  line-height: 1.2;
}
button:hover, .btn:hover {
  border-color: var(--ink-2);
  background: var(--paper-elev);
  text-decoration: none;
}
button:active, .btn:active { transform: translateY(1px); }
button.primary, .btn-primary {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
  box-shadow: inset 0 -1px 0 rgba(0,0,0,0.18);
}
button.primary:hover, .btn-primary:hover {
  background: var(--accent-deep);
  border-color: var(--accent-deep);
  color: #fff;
}
button.ghost, .btn-ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--ink-2);
}
button.danger, .btn-danger {
  background: var(--paper-card);
  color: var(--danger);
  border-color: var(--danger);
}
button.danger:hover, .btn-danger:hover {
  background: var(--danger);
  color: #fff;
}
button.small, .btn.small {
  padding: 5px 10px;
  font-size: 0.8rem;
  border-radius: var(--r-sm);
}
button.link, .btn-link {
  background: none;
  border: none;
  color: var(--accent);
  padding: 0;
  font-weight: 500;
}
button.link:hover, .btn-link:hover { text-decoration: underline; }
button.btn-block, .btn-block { width: 100%; }
button[disabled], .btn[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
}

/* Ghost icon-only buttons used in the list table */
.ops-bar { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.ops-bar .btn { font-size: 0.82rem; padding: 5px 12px; }
.ops-bar .btn-review { color: var(--accent); border-color: var(--accent); }
.ops-bar .btn-review:hover { background: var(--accent); color: #fff; }
.ops-bar .btn-view { color: var(--ink-2); }
.ops-bar .reviewed { color: var(--accent-2); border-color: var(--accent-2); cursor: default; }

/* ---------- Alerts & hints ---------------------------------------------- */
.alert {
  padding: 14px 18px;
  border-radius: var(--r-md);
  margin: 14px 0;
  border: 1px solid var(--line);
  border-left: 3px solid var(--ink-3);
  background: var(--paper-elev);
  color: var(--ink-2);
  font-size: 0.92rem;
}
.alert .dup-record {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed currentColor;
  font-size: 0.88rem;
}
.alert.error      { background: var(--danger-soft); border-color: var(--danger); border-left-color: var(--danger); color: var(--danger); }
.alert.warn       { background: var(--warn-bg);   border-color: var(--warn);    border-left-color: var(--warn);    color: var(--warn); }
.alert.success    { background: var(--accent-2-soft); border-color: var(--accent-2); border-left-color: var(--accent-2); color: var(--accent-2); }
.alert.duplicate  {
  background: var(--warn-bg);
  color: #6f4a05;
  border-color: var(--warn);
  border-left: 6px solid var(--warn-bar);
  position: relative;
}

.hint, .muted { color: var(--ink-3); font-size: 0.88rem; }
.hint { line-height: 1.55; }

.error-text { color: var(--danger); font-size: 0.85rem; margin: 6px 0 0; }
.ok-text    { color: var(--accent-2); font-size: 0.85rem; margin: 6px 0 0; }

/* ---------- Tables (list / detail kv) ----------------------------------- */
table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  margin: 12px 0;
}
table.kv th, table.kv td {
  text-align: left;
  padding: 12px 14px;
  vertical-align: top;
  border-bottom: 1px solid var(--line);
}
table.kv th {
  width: 30%;
  color: var(--ink-3);
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.7rem;
  font-weight: 600;
  background: var(--paper-elev);
  border-right: 1px solid var(--line);
}
table.kv td { font-size: 0.95rem; color: var(--ink); }
table.kv td code { background: var(--paper-bg); padding: 2px 6px; border-radius: 4px; }
table.kv tr:last-child th, table.kv tr:last-child td { border-bottom: 0; }
table.kv tr:hover td { background: var(--paper-elev); }

table.data {
  font-size: 0.9rem;
}
table.data thead th {
  text-align: left;
  padding: 12px 14px;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 0.68rem;
  color: var(--ink-3);
  font-weight: 700;
  background: var(--paper-card);
  border-top: 2px solid var(--ink);
  border-bottom: 1px solid var(--line-strong);
}
table.data tbody td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
table.data tbody tr:nth-child(even) { background: var(--paper-stripe); }
table.data tbody tr:hover { background: var(--paper-elev); }
table.data tbody tr:hover td:first-child { border-left: 3px solid var(--accent); padding-left: 11px; }
table.data tbody td:first-child {
  font-family: var(--font-mono);
  color: var(--ink-3);
  font-size: 0.85rem;
  transition: border-left-color .15s, padding-left .15s;
  border-left: 3px solid transparent;
}
table.data tbody td:nth-child(2) {
  font-family: var(--font-mono);
  font-size: 0.9rem;
}
table.data tbody td:nth-child(5) {
  font-family: var(--font-mono);
  font-weight: 600;
  color: var(--ink);
}

table.data tbody tr.row-dup {
  background: linear-gradient(90deg, var(--warn-bg) 0%, var(--warn-bg) 4px, transparent 4px);
}
table.data tbody tr.row-dup td:first-child { border-left-color: var(--warn-bar); }

/* ---------- Badges ------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 0.74rem;
  font-weight: 600;
  font-family: var(--font-mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: 1px solid transparent;
  vertical-align: middle;
}
.badge.dup    { background: var(--warn-bg); color: #6f4a05; border-color: var(--warn); }
.badge.warn   { background: var(--warn-bg); color: var(--warn); border-color: var(--warn); }
.badge.ok     { background: var(--accent-2-soft); color: var(--accent-2); border-color: var(--accent-2); }
.badge.muted  { background: var(--paper-elev); color: var(--ink-3); border-color: var(--line); }
.badge.accent { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }

/* ---------- Stamp seal — signature element ------------------------------ */
.stamp {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 12px;
  border: 1.5px solid currentColor;
  border-radius: 999px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  position: relative;
  transform: rotate(-3deg);
  background: rgba(255,255,255,0.65);
  user-select: none;
}
.stamp::before {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px dashed currentColor;
  border-radius: 999px;
  opacity: 0.6;
}
.stamp.lg { font-size: 1rem; padding: 10px 18px; }
.stamp.ok  { color: var(--accent-2); }
.stamp.warn { color: var(--warn); transform: rotate(2deg); }

/* Floating stamp overlay in detail / result card */
.stamp-overlay {
  position: absolute;
  top: 24px; right: 28px;
  font-size: 1.05rem;
  pointer-events: none;
}

/* ---------- Perforated tear edge ---------------------------------------- */
.tear {
  border-top: 0;
  position: relative;
}
.tear::before {
  content: "";
  position: absolute;
  top: -1px; left: 0; right: 0;
  height: 6px;
  background-image:
    radial-gradient(circle at 3px 0, var(--paper-bg-2) 3px, transparent 3.5px);
  background-size: 12px 6px;
  background-repeat: repeat-x;
}
.tear::after {
  content: "";
  position: absolute;
  top: 4px; left: 0; right: 0;
  height: 1px;
  background: var(--line);
}

/* ---------- Upload / dropzone ------------------------------------------ */
.source-toggle {
  display: flex;
  gap: 8px;
  margin: 18px 0 12px;
}
.tab {
  flex: 1;
  text-align: center;
  padding: 10px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  cursor: pointer;
  background: var(--paper-card);
  color: var(--ink-2);
  font-size: 0.9rem;
  font-weight: 500;
  transition: background-color .15s, color .15s, border-color .15s;
}
.tab input { display: none; }
.tab:has(input:checked) {
  background: var(--ink);
  color: #fff;
  border-color: var(--ink);
}

.upload-box, .upload-box.dropzone {
  position: relative;
  margin: 16px 0;
  padding: 36px 24px;
  border: 2px dashed var(--line-strong);
  border-radius: var(--r-lg);
  background:
    repeating-linear-gradient(
      45deg,
      var(--paper-card) 0 12px,
      var(--paper-elev) 12px 24px
    );
  cursor: pointer;
  transition: border-color .15s, background-color .15s;
}
.upload-box.dropzone .dz-hint {
  margin: 8px 0 0;
  text-align: center;
  color: var(--accent);
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  pointer-events: none;
  user-select: none;
}
.upload-box.dropzone .dz-sub {
  margin: 4px 0 0;
  text-align: center;
  color: var(--ink-3);
  font-size: 0.82rem;
  pointer-events: none;
  user-select: none;
}
.upload-box.dropzone.drag-over {
  border-color: var(--accent);
  border-style: solid;
  background: var(--accent-soft);
}
.upload-box.dropzone:hover {
  border-color: var(--line-strong);
  background: var(--paper-elev);
}
.upload-box.dropzone:focus-within {
  outline: 2px solid var(--accent-glow);
  outline-offset: 1px;
}

.scan-box {
  margin: 16px 0;
  padding: 24px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--paper-card);
  text-align: center;
}
.scan-box img {
  max-width: 200px;
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 8px;
  background: white;
}
.upload-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin: 20px 24px 4px;
  padding-bottom: 16px;
  border-bottom: 1px dashed var(--line);
}
.opt-btn {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: 16px 16px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--paper-card);
  text-align: left;
  cursor: pointer;
  position: relative;
  transition: border-color .15s, box-shadow .15s, transform .15s, background-color .15s;
}
.opt-btn .opt-ico {
  font-size: 1.4rem;
  line-height: 1;
  color: var(--ink-2);
  transition: color .15s;
}
.opt-btn .opt-txt {
  font-family: var(--font-display);
  font-size: .98rem;
  font-weight: 600;
  color: var(--ink);
}
.opt-btn .opt-sub {
  font-size: .78rem;
  color: var(--ink-3);
  line-height: 1.4;
}
.opt-btn:hover {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-1);
  transform: translateY(-1px);
}
.opt-btn:hover .opt-ico { color: var(--accent); }
.opt-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.opt-btn.active {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: inset 3px 0 0 var(--accent);
}
.opt-btn.active .opt-ico { color: var(--accent); }
.opt-btn.active::after {
  content: "✓";
  position: absolute;
  top: 10px;
  right: 12px;
  font-weight: 700;
  font-size: .9rem;
  color: var(--accent);
}
@media (max-width: 480px) {
  .upload-options { grid-template-columns: 1fr; margin-left: 18px; margin-right: 18px; }
}

/* ---------- Empty states ------------------------------------------------- */
.empty-welcome {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  margin: 0 auto;
  padding: 56px 28px;
  max-width: 640px;
  text-align: center;
  color: var(--ink-3);
  font-size: 0.96rem;
  line-height: 1.85;
  overflow-wrap: break-word;
}
.empty-welcome .btn { padding: 12px 32px; font-size: 1rem; }

.empty-state {
  padding: 48px 24px;
  text-align: center;
  color: var(--ink-3);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-lg);
  background: var(--paper-elev);
}

/* HTML hidden 属性必须真正隐藏。否则 .modal-mask/.toast 的 display:flex 作者样式
   会覆盖浏览器 UA 默认的 [hidden]{display:none},导致带 hidden 的弹层(如登录页上的
   上传弹窗、删除确认弹窗、全局 toast)错误显示并遮挡页面。JS 一律通过 el.hidden 属性
   切换显示,此规则与 JS 完全兼容。 */
[hidden] { display: none !important; }

/* ---------- Modal & toast ---------------------------------------------- */
.modal-mask {
  position: fixed;
  inset: 0;
  background: rgba(15,29,46,0.55);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 24px;
}
.modal-box {
  background: var(--paper-card);
  border-radius: var(--r-xl);
  width: 100%;
  max-width: 560px;
  box-shadow: var(--shadow-3);
  position: relative;
  overflow: hidden;
}
.modal-box::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--accent);
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 22px 26px 14px;
}
.modal-head h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.25rem;
}
.modal-close {
  background: transparent;
  border: none;
  font-size: 1.2rem;
  color: var(--ink-3);
  cursor: pointer;
  padding: 4px 8px;
  border-radius: var(--r-sm);
}
.modal-close:hover { background: var(--paper-elev); color: var(--ink); }

.modal-box > .field-label,
.modal-box > label,
.modal-box > p,
.modal-box > textarea,
.modal-box > .modal-actions { padding-left: 26px; padding-right: 26px; }
.modal-box > .field-label { padding-top: 0; }
/* 上传弹窗面板:与 modal 内边距 24px 对齐;移动端收窄 */
#scan-panel, #file-panel { padding: 4px 24px 24px; }
#quick-upload-status { min-height: 1.4em; margin: 10px 0 12px; }
@media (max-width: 480px) {
  #scan-panel, #file-panel { padding-left: 18px; padding-right: 18px; }
  .modal-box { border-radius: var(--r-lg); }
}
.modal-box > .modal-actions {
  display: flex; gap: 10px; justify-content: flex-end;
  padding: 16px 26px 22px;
  background: var(--paper-elev);
  margin-top: 20px;
  border-top: 1px solid var(--line);
}

.del-meta { padding-top: 4px; color: var(--ink-3); font-size: 0.85rem; }
.req { color: var(--danger); }

.toast {
  position: fixed;
  right: 24px;
  bottom: 24px;
  background: var(--ink);
  color: #fff;
  padding: 12px 18px;
  border-radius: var(--r-md);
  display: flex; align-items: center; gap: 12px;
  font-size: 0.9rem;
  box-shadow: var(--shadow-2);
  z-index: 2000;
  max-width: 380px;
  border-left: 3px solid var(--accent);
  animation: toastIn .25s ease-out;
}
.toast.ok    { border-left-color: var(--accent-2); }
.toast.warn  { border-left-color: var(--warn); }
.toast.err   { border-left-color: var(--danger); }
.toast.error { border-left-color: var(--danger); }
.toast button {
  background: transparent;
  color: inherit;
  border: none;
  padding: 0 4px;
  cursor: pointer;
  opacity: 0.7;
}
.toast button:hover { opacity: 1; background: transparent; }

@keyframes toastIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---------- Login ------------------------------------------------------- */
.login-page {
  min-height: calc(100vh - 80px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 16px;
  position: relative;
}
.login-page::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(15,29,46,0.85) 0%, rgba(15,29,46,0.65) 100%),
    radial-gradient(circle at 1px 1px, rgba(255,255,255,0.06) 1px, transparent 0) 0 0/22px 22px,
    var(--ink);
  z-index: -1;
}
.login-card {
  width: 100%;
  max-width: 420px;
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: 40px 36px 30px;
  box-shadow: var(--shadow-3);
  position: relative;
}
.login-card::before {
  content: "";
  position: absolute;
  top: 0; left: 24px; right: 24px;
  height: 4px;
  background: var(--accent);
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
}
.login-brand { text-align: center; margin-bottom: 24px; }
.login-brand .brand-mark { width: 44px; height: 44px; font-size: 1.2rem; margin: 0 auto 12px; }
.login-logo { max-height: 56px; max-width: 160px; object-fit: contain; margin-bottom: 10px; }
.login-title {
  font-family: var(--font-display);
  margin: 0 0 6px;
  font-size: 1.45rem;
  color: var(--ink);
  letter-spacing: 0.02em;
}
.login-sub {
  margin: 0;
  color: var(--ink-3);
  font-size: 0.85rem;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.18em;
}
.login-form .login-field {
  display: block;
  margin: 0 0 16px;
  font-size: 0.72rem;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink-3);
  font-weight: 700;
}
.login-field input {
  width: 100%;
  box-sizing: border-box;
  padding: 12px 14px;
  margin-top: 8px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  font-size: 1rem;
  background: var(--paper-card);
  font-family: var(--font-body);
  transition: border-color .15s, box-shadow .15s;
}
.login-field input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-glow);
}
.login-btn {
  width: 100%;
  padding: 13px;
  font-size: 0.98rem;
  font-weight: 600;
  border-radius: var(--r-md);
  margin-top: 6px;
}
.login-footer {
  margin: 22px 0 0;
  text-align: center;
  color: var(--ink-4);
  font-size: 0.76rem;
  font-family: var(--font-mono);
  letter-spacing: 0.1em;
  border-top: 1px dashed var(--line);
  padding-top: 14px;
}
@media (max-width: 480px) {
  .login-card { padding: 28px 22px 22px; }
}

/* ---------- User panel (avatar popover) -------------------------------- */
.user-menu { position: relative; }
.avatar-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.18);
  background: rgba(255,255,255,0.06);
  cursor: pointer;
  overflow: hidden;
  color: #fff;
  font-weight: 600;
  font-family: var(--font-display);
}
.avatar-btn:hover { background: rgba(255,255,255,0.12); border-color: rgba(255,255,255,0.4); }
.avatar-btn .avatar-img { width: 100%; height: 100%; object-fit: cover; }
.avatar-btn .avatar-default {
  width: 100%; height: 100%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent);
  color: white;
  font-size: 0.95rem;
}
.avatar-img.lg { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; }

.user-panel {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: 360px;
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
  z-index: 50;
  overflow: hidden;
}
.panel-head {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  gap: 14px;
  align-items: center;
  padding: 20px;
  background: var(--paper-elev);
  border-bottom: 1px solid var(--line);
}
.panel-avatar-wrap { display: flex; align-items: center; justify-content: center; }
.panel-head-info { display: flex; flex-direction: column; gap: 2px; }
.panel-head-info b { font-size: 1.02rem; color: var(--ink); }
.panel-username { font-family: var(--font-mono); font-size: 0.78rem; color: var(--ink-3); }
.panel-role-badge {
  display: inline-block; margin-top: 4px;
  background: var(--ink); color: white;
  font-family: var(--font-mono);
  font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.16em;
  padding: 2px 8px; border-radius: 4px;
  align-self: flex-start;
}
.panel-close { background: transparent; border: none; font-size: 1rem; cursor: pointer; color: var(--ink-3); padding: 4px 8px; }
.panel-tabs { display: flex; gap: 0; border-bottom: 1px solid var(--line); }
.panel-tabs .tab-btn {
  flex: 1;
  padding: 10px 12px;
  border: none;
  background: transparent;
  border-bottom: 2px solid transparent;
  font-family: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  color: var(--ink-3);
  border-radius: 0;
}
.panel-tabs .tab-btn:hover { background: var(--paper-elev); }
.panel-tabs .tab-btn.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.panel-form { padding: 18px 20px 0; }
.panel-form .field-label { margin-top: 0; }
.panel-form input { margin-bottom: 12px; }
.panel-sec { padding: 0 20px 16px; }
.panel-sec.avatar-sec { padding-top: 8px; border-top: 1px dashed var(--line); }
.avatar-upload-row { display: flex; gap: 8px; align-items: center; }
.avatar-upload-row input { flex: 1; padding: 8px; }
.panel-footer {
  padding: 14px 20px;
  border-top: 1px solid var(--line);
  background: var(--paper-elev);
  display: flex;
  justify-content: flex-end;
}
.btn-logout {
  background: transparent;
  border: 1px solid var(--line-strong);
  color: var(--danger);
  padding: 8px 14px;
  border-radius: var(--r-md);
  cursor: pointer;
  font-family: inherit;
  font-size: 0.85rem;
}
.btn-logout:hover { background: var(--danger); color: white; border-color: var(--danger); }
.forgot-channel-row { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; }
.forgot-channel-row select { flex: 1; }
.pwd-mode-toggle { display: flex; gap: 0; border-bottom: 1px solid var(--line); margin-bottom: 14px; }
.pwd-mode-toggle .mode-btn {
  flex: 1;
  padding: 10px 12px;
  border: none;
  background: transparent;
  font-family: inherit;
  font-size: 0.82rem;
  cursor: pointer;
  color: var(--ink-3);
  border-bottom: 2px solid transparent;
  border-radius: 0;
}
.pwd-mode-toggle .mode-btn.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.tab-pane { padding-top: 4px; }

/* ---------- Settings page ---------------------------------------------- */
/* SMTP 邮箱绑定表单:2 列网格 + 响应式堆叠 */
.settings-form {
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 200px);
  gap: 10px 18px;
  align-items: start;
}
.settings-form > .field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.settings-form > .field > input {
  width: 100%;
  max-width: 100%;
}
.settings-form > .field > .field-label {
  margin: 0 0 6px;
  font-family: inherit;
  text-transform: none;
  letter-spacing: 0;
  color: var(--ink-2);
  font-size: 0.88rem;
  font-weight: 600;
}
.settings-form > .field.full { grid-column: 1 / -1; }
.settings-form > .settings-action-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding-top: 4px;
}
.settings-form > .settings-action-row > .field-label { margin: 0; }
.settings-form > .settings-action-row > .settings-row {
  display: flex;
  justify-content: flex-start;
  gap: 10px;
  flex-wrap: wrap;
  flex-direction: row;
}
@media (max-width: 720px) {
  .settings-form { grid-template-columns: 1fr; }
  .settings-form > .settings-action-row { flex-direction: column; align-items: flex-start; }
  .settings-form > .settings-action-row > .settings-row { width: 100%; }
  .settings-form > .settings-action-row > .settings-row > .btn { flex: 1 1 auto; }
}

/* ====== 邮箱通信测试区块 ====== */
.test-email-result {
  margin-top: 8px;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 0.88rem;
  line-height: 1.5;
  word-break: break-all;
}
.test-email-result.ok {
  background: rgba(40, 167, 69, 0.12);
  border: 1px solid rgba(40, 167, 69, 0.4);
  color: #1e6e3a;
}
.test-email-result.err {
  background: rgba(220, 53, 69, 0.10);
  border: 1px solid rgba(220, 53, 69, 0.4);
  color: #a02533;
}
.test-email-result.pending {
  background: rgba(255, 193, 7, 0.12);
  border: 1px solid rgba(255, 193, 7, 0.4);
  color: #8a6300;
}
.test-email-hint { margin-top: 6px; }

/* ===== 邮箱变更验证面板 ===== */
.email-current-hint {
  font-size: 0.78rem;
  color: var(--ink-3);
  font-weight: normal;
  margin-left: 6px;
}
.email-verify-hint {
  margin: 6px 0 0;
  font-size: 0.85rem;
  color: var(--ink-3);
}
.email-verify-panel {
  margin-top: 10px;
  padding: 12px 14px;
  background: var(--paper-card, rgba(255,255,255,0.02));
  border: 1px dashed var(--accent);
  border-radius: var(--r-md, 8px);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.email-verify-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.email-verify-row .field-label { margin: 0; min-width: 60px; }
.email-verify-row input {
  flex: 1 1 200px;
  min-width: 0;
  max-width: 240px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm, 6px);
  background: var(--paper);
  font-size: 1.05rem;
  letter-spacing: 4px;
  font-family: var(--font-mono, ui-monospace, "SF Mono", monospace);
}
.email-verify-row input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent);
}
.email-verify-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.email-cooldown {
  font-size: 0.82rem;
  color: var(--ink-3);
  margin-left: 4px;
}

@media (max-width: 600px) {
  .email-verify-row { flex-direction: column; align-items: stretch; }
  .email-verify-row input { max-width: 100%; }
  .email-verify-actions { flex-direction: column; align-items: stretch; }
}
#test-email-block .step-controls { gap: 8px; flex-wrap: nowrap; }
#test-email-block #set-test-email-to {
  flex: 0 1 320px;
  min-width: 0;
  max-width: 360px;
  width: 100%;
}
#test-email-block #btn-send-test { flex: 0 0 auto; white-space: nowrap; }
@media (max-width: 600px) {
  #test-email-block .step-controls { flex-direction: column; align-items: stretch; }
  #test-email-block #set-test-email-to { max-width: 100%; }
  #test-email-block #btn-send-test { width: 100%; }
}
.settings-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
}
.settings-grid2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}
@media (max-width: 600px) { .settings-grid2 { grid-template-columns: 1fr; } }
.settings-row { display: flex; flex-direction: column; gap: 6px; }
.settings-row > .field-label { margin-top: 0; }

/* 系统名称卡片:输入框与保存按钮同行 */
.system-name-row { flex-direction: row; align-items: center; gap: 12px; }
.system-name-row > #set-system-name {
  flex: 0 1 320px;
  min-width: 180px;
  max-width: 420px;
}
.system-name-row > #btn-save-system { flex: 0 0 auto; white-space: nowrap; }
@media (max-width: 600px) {
  .system-name-row { flex-direction: column; align-items: stretch; }
  .system-name-row > #set-system-name { max-width: 100%; }
  .system-name-row > #btn-save-system { width: 100%; }
}
.settings-sec {
  border-top: 2px solid var(--ink);
  padding-top: 18px;
  margin-top: 24px;
  position: relative;
}
.settings-sec h2 { margin-bottom: 4px; }

/* provider-head: 一行 flex 布局, head 字段(短信接口 #1 / 启用) 左对齐, 操作按钮右对齐 */
.provider-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  padding: 0 0 12px 0;
  border-bottom: 1px dashed var(--line);
  margin-bottom: 12px;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 0.72rem;
  color: var(--ink-3);
}
.provider-head b { font-size: 0.95rem; letter-spacing: 0.02em; color: var(--ink); text-transform: none; font-family: var(--font-sans); }
.provider-head label { margin: 0; }
.provider-head .pr-actions { margin-left: auto; display: inline-flex; gap: 6px; }
.provider-head .pr-actions .btn { font-size: 0.78rem; padding: 4px 10px; }

/* provider-row 是普通 block, head / grid2 / templates 三块垂直堆叠 */
.provider-row {
  display: block;
  border-top: 1px solid var(--line);
  padding: 14px 12px;
}
.provider-row:first-child { border-top: 2px solid var(--ink); }
.provider-row:last-child { border-bottom: 0; }

/* provider-row 内联表单: label 与 input 上下独立行, label 小中文, 避免被 uppercase */
/* 不受 .field-label 全局 text-transform:uppercase 影响 */
.provider-row .settings-grid2 { gap: 14px 18px; }
.provider-row .settings-grid2 > div {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.provider-row .settings-grid2 > div > label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ink-2);
  letter-spacing: 0;
  text-transform: none;       /* 覆盖 .field-label 全局 uppercase */
  font-family: var(--font-sans, system-ui, sans-serif);
  margin: 0;
  display: block;
}
.provider-row .settings-grid2 > div > input {
  font-family: var(--font-mono);
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
}

/* provider 多模板列表 */
.provider-templates {
  margin-top: 12px;
  padding: 12px;
  background: var(--paper-elev);
  border: 2px solid var(--accent);
  border-radius: var(--r-sm);
  position: relative;
}
/* 把 "按场景填写模板 ID" 浮标改成 inline 标题, 避免溢出卡外 */
.provider-templates-head::before {
  content: "📋 按场景填写模板 ID";
  display: inline-block;
  padding: 4px 10px;
  margin-right: 8px;
  background: var(--paper);
  border: 1px solid var(--accent);
  border-radius: 999px;
  font-size: 0.78rem;
  color: var(--accent);
  font-weight: 600;
  letter-spacing: 0.02em;
}
/* 不再用 ::before 在 provider-templates 顶层, 避免溢出 */
.provider-templates::before { content: none; }
.provider-templates { position: static; }
.provider-templates-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.provider-templates-head .pr-tpl-add { margin-left: auto; }
.provider-templates-head b {
  font-size: 0.9rem;
  color: var(--ink);
  font-weight: 600;
}
.provider-templates-head .tpl-hint {
  flex: 1 1 auto;
  font-size: 0.78rem;
  color: var(--ink-3);
  line-height: 1.4;
}
.pr-tpl-list { display: flex; flex-direction: column; gap: 8px; }
.pr-tpl-row {
  display: grid;
  /* 场景 模板ID 签名 删除 — 用 minmax 兜底, 保证窄屏也能输入 */
  grid-template-columns: 160px minmax(140px, 1fr) minmax(120px, 1fr) auto;
  gap: 8px;
  align-items: center;
  padding: 8px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.pr-tpl-row input {
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--paper-card);
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--ink);
  min-width: 0;
  width: 100%;
  box-sizing: border-box;
}
/* 窄屏: 整块改为单列堆叠, 防止输入框被挤没 */
@media (max-width: 720px) {
  .pr-tpl-row {
    grid-template-columns: 1fr;
    gap: 6px;
  }
  .pr-tpl-row .pr-tpl-del { justify-self: end; }
}
.pr-tpl-row input:focus {
  outline: none;
  border-color: var(--accent);
}
.pr-tpl-row .pr-tpl-del {
  padding: 4px 10px;
  font-size: 0.8rem;
  background: transparent;
  border: 1px solid var(--line);
  color: var(--danger);
  cursor: pointer;
  border-radius: var(--r-sm);
}
.pr-tpl-row .pr-tpl-del:hover {
  background: var(--danger);
  color: white;
  border-color: var(--danger);
}
@media (max-width: 768px) {
  .pr-tpl-row { grid-template-columns: 1fr; }
}

/* ---------- 短信接口"添加"与"保存+验证"分组 ----------- */

/* 主 CTA: 大号添加按钮 + 描述文本 */
.add-cta {
  margin: 16px 0 18px;
  padding: 18px 20px;
  background: linear-gradient(135deg, var(--paper-card) 0%, var(--paper-elev) 100%);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-md);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.02);
}
/* 快速跳转条: 配置多场景模板ID */
.quick-jump {
  display: flex; align-items: center; gap: 12px;
  margin-top: 14px;
  padding: 10px 14px;
  background: linear-gradient(135deg, rgba(217, 119, 6, 0.10), rgba(217, 119, 6, 0.04));
  border: 1.5px dashed #d97706;
  border-radius: var(--r-sm, 8px);
  color: #92400e;
  text-decoration: none;
  font-size: 0.85rem;
  transition: background 0.15s, transform 0.15s;
}
.quick-jump:hover { background: linear-gradient(135deg, rgba(217, 119, 6, 0.18), rgba(217, 119, 6, 0.08)); transform: translateX(2px); }
.quick-jump .qj-icon { font-size: 1.3rem; line-height: 1; font-weight: bold; }
.quick-jump .qj-text b { color: #b45309; font-weight: 700; font-size: 0.95rem; }
.quick-jump .qj-text .muted { color: #78716c; font-size: 0.78rem; }
.quick-jump .qj-arrow { margin-left: auto; font-size: 1.2rem; color: #d97706; font-weight: bold; }

.add-cta-main {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.add-cta .btn-cta-add {
  padding: 10px 18px;
  font-size: 0.95rem;
  font-weight: 600;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.add-cta .btn-plus {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.2);
  font-size: 1rem;
  line-height: 1;
}
.add-cta-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.add-cta-text strong { font-size: 0.95rem; color: var(--ink); }
.add-cta-text .muted { font-size: 0.85rem; color: var(--ink-3); }

/* provider 列表区 */
.provider-list { margin: 8px 0; }

/* 保存与验证 卡片 */
.action-card {
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 14px 16px 18px;
}
.action-card > h3 {
  margin: 0 0 12px;
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--ink);
  letter-spacing: 0;
  text-transform: none;
  font-weight: 600;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.action-card-body { display: flex; flex-direction: column; gap: 14px; }

.action-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 8px 0;
}
.action-row + .action-row { border-top: 1px dashed var(--line); }
.action-row .row-label {
  flex: 0 0 88px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-2);
  letter-spacing: 0;
  text-transform: none;
}
.action-row .row-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1 1 auto;
  min-width: 0;
  flex-wrap: wrap;
}
.action-row .row-input {
  flex: 1 1 220px;
  min-width: 180px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.92rem;
  color: var(--ink);
}
.action-row .row-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent);
}
.action-row .row-hint { color: var(--ink-3); font-size: 0.85rem; }
.action-row .hint { flex: 1 1 100%; margin: 4px 0 0; font-size: 0.85rem; }

/* ---------- SMS 发送/验证测试: 三件同行 ---------- */
/*  发送测试 手机号 | 验证码 | [发送测试验证码] [验证]
    桌面: 同行, 各控件合理宽度
    窄屏: 自动堆叠 */
.sms-test-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  flex: 1 1 auto;
  min-width: 0;
}
.sms-test-controls .sms-test-phone {
  flex: 0 0 200px;          /* 手机号固定宽, 容下 11 位 + 占位 */
  min-width: 160px;
  width: 200px;
  max-width: 240px;
  font-family: var(--font-mono);
}
.sms-test-controls .sms-test-code {
  flex: 0 0 140px;          /* 验证码 6 位固定宽 */
  min-width: 110px;
  width: 140px;
  max-width: 160px;
  font-family: var(--font-mono);
  text-align: center;
  letter-spacing: 0.18em;   /* 验证码字符间距, 视觉上更平衡 */
}
.sms-test-controls .sms-test-send,
.sms-test-controls .sms-test-verify {
  flex: 0 0 auto;           /* 按钮不伸缩, 显示完整文字 */
  white-space: nowrap;
  padding: 8px 16px;
  font-size: 0.88rem;
}
.sms-test-controls .sms-test-send {
  min-width: 140px;         /* "发送测试验证码" 7 个汉字 */
}
.sms-test-controls .sms-test-verify {
  min-width: 80px;          /* "验证" 2 个汉字 */
}
/* 窄屏 (<720px): 输入框 + 按钮全部堆叠成列 */
@media (max-width: 720px) {
  .sms-test-controls { flex-direction: column; align-items: stretch; }
  .sms-test-controls .sms-test-phone,
  .sms-test-controls .sms-test-code {
    width: 100%; max-width: none; min-width: 0;
  }
  .sms-test-controls .sms-test-send,
  .sms-test-controls .sms-test-verify { width: 100%; }
}

/* ---------- 邮箱绑定三步式布局 ----------- */
.bind-email-block {
  margin-top: 14px;
  padding: 18px 18px 16px;
  background: var(--paper-elev);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.bind-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 4px;
}
.bind-header h3 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--ink);
  letter-spacing: 0;
  text-transform: none;
  font-weight: 600;
}

/* 状态徽章 */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.badge-status { background: var(--paper); color: var(--ink-3); border: 1px solid var(--line); }


/* 步骤列表 */
.bind-steps {
  list-style: none;
  padding: 0;
  margin: 14px 0 4px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.bind-step {
  display: flex;
  gap: 14px;
  padding: 14px 16px;
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  position: relative;
}
.bind-step .step-num {
  flex: 0 0 36px;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent) 0%, color-mix(in srgb, var(--accent) 70%, #000) 100%);
  color: white;
  font-family: var(--font-display);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.95rem;
  box-shadow: 0 2px 6px color-mix(in srgb, var(--accent) 30%, transparent);
  flex-shrink: 0;
}
.bind-step .step-content { flex: 1 1 auto; min-width: 0; }
.bind-step .step-title {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 2px;
  letter-spacing: 0;
}
.bind-step .step-desc {
  font-size: 0.82rem;
  color: var(--ink-3);
  margin-bottom: 10px;
}
.bind-step .step-controls {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}
.bind-step .step-input {
  flex: 1 1 200px;
  min-width: 180px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.92rem;
  color: var(--ink);
}
.bind-step .step-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent);
}
.bind-step .step-hint { margin: 8px 0 0; font-size: 0.85rem; }
.bind-success { margin: 12px 0 0; padding: 8px 12px; border-radius: var(--r-sm); background: #e7f8ee; color: #0f7a3a; }

/* ---------- 响应式: 移动端 控制在 768px 以下 ---------- */
@media (max-width: 768px) {
  .add-cta-main { flex-direction: column; align-items: flex-start; gap: 10px; }
  .add-cta .btn-cta-add { width: 100%; justify-content: center; }
  .action-row { flex-direction: column; align-items: stretch; }
  .action-row .row-label { flex: 1 1 auto; }
  .action-row .row-controls { flex-direction: column; align-items: stretch; }
  .action-row .row-input { width: 100%; }
  .action-row .btn { width: 100%; }
  .bind-step { flex-direction: column; }
  .bind-step .step-num { margin-bottom: 4px; }
  .bind-step .step-controls { flex-direction: column; align-items: stretch; }
  .bind-step .step-input { width: 100%; }
  .bind-step .btn { width: 100%; }
}

/* ---------- Finance cards ---------------------------------------------- */
.finance-filter {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  padding: 12px 0; border-bottom: 1px solid var(--line); margin-bottom: 18px;
}
.finance-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; }
.fin-card {
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-md);
  padding: 16px 18px;
  box-shadow: var(--shadow-1);
}
.fin-card h3 { font-family: var(--font-mono); font-size: 0.72rem; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.14em; margin-bottom: 8px; }
.fin-card .fin-value { font-family: var(--font-display); font-size: 1.5rem; color: var(--ink); }


.fin-date { font-family: var(--font-mono); color: var(--ink-3); font-size: 0.85rem; }
.fin-search-input, .fin-search-row, .fin-filter-row, .fin-select { padding: 8px 12px; border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--paper-card); }

/* finance: 3 行布局 + 左对齐；模糊搜索行使用 --danger 语义红标 */
.finance-filter {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
  margin-bottom: 18px;
}
.fin-row-date,
.fin-row-controls,
.fin-row-search {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-start;
  gap: 10px;
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 10px;
}
.fin-row-date select,
.fin-row-controls select {
  flex: 0 0 auto;
  max-width: 160px;
  min-width: 0;
}
.fin-row-date button[type="submit"],
.fin-row-controls button[type="submit"],
.fin-row-controls .btn {
  flex: 0 0 auto;
  white-space: nowrap;
}
/* 模糊搜索行：中性化（取消红标，与上两行视觉一致、左对齐） */
.fin-row-search {
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 10px 0;
  margin-top: 0;
  justify-content: flex-start;
}
.fin-row-search .filter-label { color: var(--ink-3); font-weight: 400; }
.fin-row-search .fin-search-input {
  flex: 1 1 360px; min-width: 240px;
  border-color: var(--line-strong);
  background: var(--paper-card);
}
.fin-row-search .btn-fuzzy {
  background: var(--paper-card);
  border-color: var(--line-strong);
  color: var(--ink);
  font-weight: 600;
  white-space: nowrap;
}
.fin-row-search .btn-fuzzy:hover { background: var(--paper-elev); border-color: var(--accent); color: var(--accent); }
@media (max-width: 1366px) {
  .fin-row-search { flex-wrap: wrap; }
  .fin-row-search .fin-search-input { flex: 1 1 100%; min-width: 0; }
  .fin-row-search .btn-fuzzy { flex: 0 0 auto; }
}

/* ---------- Duplicate ID chips ----------------------------------------- */
.dup-id-list { display: flex; flex-wrap: wrap; gap: 8px; }
.dup-id-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--warn-bg);
  border: 1px solid var(--warn);
  border-radius: var(--r-sm);
  padding: 4px 10px;
  font-family: var(--font-mono);
  font-size: 0.85rem;
}
.dup-id-chip a { color: var(--ink); font-weight: 600; }
.dup-id-chip.suspect { background: var(--danger-soft); border-color: var(--danger); }
.dup-id-chip .copy-id,
.dup-id-chip .view-denied {
  font-size: 0.7rem;
  padding: 2px 8px;
}

/* ---------- History / audit ------------------------------------------- */
.hist-list { display: flex; flex-direction: column; gap: 8px; }
.hist-list .hist-edit,
.hist-action {
  padding: 12px 14px;
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent-2);
  border-radius: var(--r-md);
  font-size: 0.88rem;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  align-items: baseline;
}
.hist-action .hist-time { font-family: var(--font-mono); color: var(--ink-3); font-size: 0.8rem; }
.hist-action .hist-who  { font-weight: 600; color: var(--ink); }
.hist-action .hist-ip   { font-family: var(--font-mono); color: var(--ink-4); font-size: 0.78rem; margin-left: auto; }
.history-empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--ink-3);
  border: 1px dashed var(--line);
  border-radius: var(--r-md);
}

/* ---------- Audit filter / breadcrumb ---------------------------------- */
.audit-filter { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.breadcrumb {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-3);
  margin-bottom: 12px;
  letter-spacing: 0.04em;
}
.breadcrumb a { color: var(--ink-3); }
.breadcrumb a:hover { color: var(--accent); }

/* ---------- Detail file preview --------------------------------------- */
.detail-file, .detail-file-meta, .detail-file-pdf {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 12px;
  background: var(--paper-elev);
}
.detail-file img { max-width: 100%; border-radius: var(--r-sm); }
.detail-file iframe { width: 100%; height: 600px; border: 1px solid var(--line); border-radius: var(--r-sm); background: white; }
.detail-sec {
  margin-top: 22px;
  padding: 22px 24px;
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
.detail-sec h2 {
  font-family: var(--font-display);
  margin-bottom: 10px;
  position: relative;
  padding-bottom: 8px;
}
.detail-sec h2::after {
  content: "";
  position: absolute; left: 0; bottom: 0;
  width: 28px; height: 2px; background: var(--accent);
}
.detail-readonly { background: var(--paper-elev); padding: 4px 8px; border-radius: var(--r-sm); color: var(--ink-3); font-size: 0.78rem; }
.detail-stage {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px;
  background: var(--ink); color: white;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-radius: 4px;
}

/* ---------- Skeleton & spinner ---------------------------------------- */
.skeleton {
  background: linear-gradient(90deg, var(--paper-elev) 0%, var(--paper-bg-2) 50%, var(--paper-elev) 100%);
  background-size: 200% 100%;
  animation: skeleton 1.4s ease-in-out infinite;
  border-radius: var(--r-sm);
  height: 14px;
}
.skeleton-row { display: flex; gap: 12px; margin: 14px 0; }
.skeleton-row .skeleton { flex: 1; }
.skeleton-row .skeleton:nth-child(1) { flex: 0 0 30%; }
@keyframes skeleton {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.spinner {
  display: inline-block;
  width: 14px; height: 14px;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.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;
}

/* ---------- Card titles & sub titles ----------------------------------- */
.card-title { font-family: var(--font-display); font-size: 1.2rem; margin-bottom: 8px; color: var(--ink); }
.card-sub   { color: var(--ink-3); font-size: 0.85rem; margin-bottom: 14px; }
.branding-box {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: 16px;
  background: var(--paper-elev);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.branding-box > .field-label { margin: 0 0 4px; }
.branding-preview { width: 96px; height: 96px; background: var(--paper-card); border: 1px solid var(--line); border-radius: var(--r-sm); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.branding-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }
.branding-preview .placeholder { font-size: 0.7rem; color: var(--ink-3); padding: 0 4px; text-align: center; }

/* ---------- Filter & search bar --------------------------------------- */
.filter {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  flex-wrap: wrap;
  width: 100%;
  margin: 12px 0 0;
}
.filter input[name="q"] {
  flex: 0 1 200px;
  min-width: 0;
}
.filter label { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 0.85rem; color: var(--ink-2); font-family: var(--font-mono); letter-spacing: 0.02em; }
.filter-label { font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.12em; font-size: 0.72rem; color: var(--ink-3); }

/* ---------- Plus button (FAB-ish) ------------------------------------- */
.plus-btn {
  width: 36px; height: 36px;
  padding: 0;
  border-radius: 50%;
  background: var(--accent);
  color: white;
  border-color: var(--accent);
  font-size: 1.3rem;
  line-height: 1;
  font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-2);
}
.plus-btn:hover { background: var(--accent-deep); border-color: var(--accent-deep); transform: translateY(-1px); }

.list-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  margin-bottom: 14px;
}
.list-head h1 { margin: 0; }
.list-body { margin-top: 6px; }

/* List page: maximize the table area inside available viewport */
.list-page main { min-width: 0; }

/* ---------- Divider ----------------------------------------------------- */
.divider {
  border: 0;
  border-top: 1px dashed var(--line-strong);
  margin: 22px 0;
}



/* ---------- Section/notice boxes -------------------------------------- */
.notice {
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent-2);
  border-radius: var(--r-md);
  background: var(--accent-2-soft);
  color: var(--accent-2);
  font-size: 0.9rem;
}

/* ---------- Mobile upload page ---------------------------------------- */
.m-card, .m-options, .m-btn {
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 14px;
}
.m-options { display: flex; flex-direction: column; gap: 10px; }

/* ---------- OK button variant ----------------------------------------- */
.ok {
  background: var(--accent-2-soft);
  color: var(--accent-2);
  border-color: var(--accent-2);
}

/* ---------- Reduced motion ------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------- Print ----------------------------------------------------- */
@media print {
  body { background: white; }
  .topbar, .sidebar, .bottombar, .ops-bar, button { display: none !important; }
  .card { box-shadow: none; border-color: var(--line); page-break-inside: avoid; }
}
/* ===== 发票列表行操作 折叠菜单 (row-menu) ===== */
td.ops { position: relative; }
.row-menu { position: relative; display: inline-block; }
.row-menu-btn {
  width: 30px; height: 30px; line-height: 26px; text-align: center;
  padding: 0; border: 1px solid var(--line, #cdd6e0);
  border-radius: 50%; background: var(--paper, #fff); color: var(--ink, #333);
  font-size: 1.05rem; cursor: pointer; transition: background .15s, border-color .15s;
}
.row-menu-btn:hover, .row-menu-btn[aria-expanded="true"] {
  background: var(--accent, #2563eb); border-color: var(--accent, #2563eb); color: #fff;
}
.row-menu-panel {
  position: absolute; top: 100%; right: 0; z-index: 60;
  min-width: 150px; margin-top: 4px; padding: 6px;
  background: #fff; border: 1px solid #d8dee7; border-radius: 8px;
  box-shadow: 0 8px 24px rgba(20,30,50,.18);
  display: flex; flex-direction: column; gap: 4px;
}
.row-menu-panel .btn {
  display: block; width: 100%; text-align: left; margin: 0;
  white-space: nowrap; font-size: 0.85rem; padding: 7px 10px;
  border-radius: 6px; border: 1px solid transparent; cursor: pointer;
}
.row-menu-panel .btn-review { color: var(--accent,#2563eb); }
.row-menu-panel .btn-review:hover { background: var(--accent,#2563eb); color:#fff; }
.row-menu-panel .btn-view { color: #444; }
.row-menu-panel .btn-view:hover { background:#eef2f7; }
.row-menu-panel .btn-danger { color:#dc2626; border-color:#f3d3d3; }
.row-menu-panel .btn-danger:hover:not(:disabled) { background:#dc2626; color:#fff; border-color:#dc2626; }
.row-menu-panel .btn-danger.row-menu-disabled,
.row-menu-panel .btn-danger:disabled {
  color:#b9c0ca; background:#f1f3f6; border-color:#e4e8ee; cursor:not-allowed;
}
.row-menu-panel .btn:focus-visible { outline: 2px solid var(--accent,#2563eb); outline-offset:-1px; }
@media print {
  .row-menu, .row-menu-panel { display: none !important; }
}

/* Explicit per-selector .list-page hooks (required by test_config_history) */
body.app-full .list-page {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - var(--topbar-h) - 80px);
}
body.app-full .list-page .list-head { flex: 0 0 auto; }
body.app-full .list-page .list-body { flex: 1 1 auto; overflow: auto; }
body.app-full .list-page .list-body table.data { width: 100%; }

/* Explicit per-selector hooks (required by test_config_history: original ID hooks) */
body.app-full #invoice-list {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - var(--topbar-h) - 80px);
}
body.app-full #recycle-list {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - var(--topbar-h) - 80px);
}

/* Fullscreen layout: sidebar collapses, main stretches */
body.app-full .sidebar { display: none; }
body.app-full .app-shell {
  grid-template-columns: 1fr;
  grid-template-areas: "topbar" "main";
}
body.app-full main { min-width: 0; }

/* Fullscreen: footer placeholder hidden, content fills viewport */
body.app-full .bottombar {
  display: none;
}

/* ====== Test-contract compatibility hooks ====== */

/* 1. .modal-box .pwd-row: input + button on one line, no overflow */
.modal-box .pwd-row { display: flex; gap: 8px; align-items: center; flex-wrap: nowrap; }
.modal-box .pwd-row input { flex: 1; min-width: 0; }
.modal-box .pwd-row .btn { white-space: nowrap; flex-shrink: 0; }

/* 2. #user-modal: 新增/编辑用户弹层 —— 紧凑两栏网格 + 短字段 + 美化 */
#user-modal .modal-box {
  max-width: 520px;
  border-radius: var(--r-xl);
  overflow: hidden;
}
#user-modal .modal-head { padding: 22px 26px 12px; }
#user-modal .modal-head h2 {
  font-family: var(--font-display);
  font-size: 1.2rem;
  letter-spacing: 0.01em;
  color: var(--ink-2);
}
#user-modal .modal-close {
  margin-right: 4px;
  color: var(--ink-3);
  transition: color .15s, background-color .15s;
}
#user-modal .modal-close:hover { color: var(--ink); background: var(--paper-elev); }

/* 表单容器: 左右内边距 26px, 与 .modal-box 内部对齐 */
#user-modal #user-form { padding: 4px 0 14px; }
#user-modal .form-grid,
#user-modal .form-row { padding: 0 26px; margin-bottom: 12px; }
#user-modal .form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
#user-modal .form-grid .field { display: flex; flex-direction: column; }
#user-modal .form-row { display: flex; flex-direction: column; }

#user-modal .field-label {
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--ink-2);
  margin: 0 0 6px;
}
#user-modal .field-label .req { color: var(--danger); margin-left: 2px; font-family: var(--font-mono); }

/* 表单控件统一: 宽度跟随父容器, 不再撑满整个 modal */
#user-modal .form-grid input,
#user-modal .form-row input,
#user-modal .form-row select {
  width: 100%;
  margin: 0;
  padding: 9px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--paper-card);
  color: var(--ink);
  font-size: 0.95rem;
  font-family: inherit;
  transition: border-color .15s, box-shadow .15s, background-color .15s;
}
#user-modal .form-row select { padding-right: 32px; }
#user-modal .form-grid input:focus,
#user-modal .form-row input:focus,
#user-modal .form-row select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-glow);
  background: #fff;
}
#user-modal .form-grid input::placeholder,
#user-modal .form-row input::placeholder { color: var(--ink-4); }

/* 密码行: 按钮与输入框等高高亮 */
#user-modal .pwd-row {
  display: flex;
  gap: 8px;
  align-items: center;
  width: 100%;
  margin: 0;
  padding: 0;
}
#user-modal .pwd-row input { flex: 1; min-width: 0; }
#user-modal .pwd-row .btn {
  flex-shrink: 0;
  white-space: nowrap;
  padding: 9px 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--paper-elev);
  color: var(--ink-3);
  font-size: 0.85rem;
  cursor: pointer;
  transition: border-color .15s, color .15s, background-color .15s;
}
#user-modal .pwd-row .btn:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--paper-card);
}

#user-modal #pwd-strength-hint,
#user-modal #user-form-error {
  padding: 0 26px;
  margin: 4px 0 0;
  font-size: 0.8rem;
  line-height: 1.4;
}
#user-modal #pwd-strength-hint { color: var(--ink-3); }
#user-modal #user-form-error { color: var(--danger); margin-bottom: 8px; }

#user-modal .modal-actions {
  padding: 16px 26px 22px;
  margin-top: 6px;
  background: var(--paper-elev);
  border-top: 1px solid var(--line);
}
#user-modal .modal-actions .btn { padding: 9px 18px; border-radius: var(--r-md); }
#user-modal .modal-actions .btn.primary { background: var(--accent); border-color: var(--accent); }
#user-modal .modal-actions .btn.primary:hover { background: var(--accent-deep); border-color: var(--accent-deep); }

@media (max-width: 520px) {
  #user-modal .modal-box { max-width: 100%; border-radius: 0; }
  #user-modal .modal-head { padding: 18px 18px 10px; }
  #user-modal #user-form { padding: 4px 0 10px; }
  #user-modal .form-grid,
  #user-modal .form-row { padding: 0 18px; }
  #user-modal .form-grid { grid-template-columns: 1fr; gap: 12px; }
  #user-modal .pwd-row { flex-wrap: wrap; }
  #user-modal .pwd-row input { width: 100%; }
  #user-modal .pwd-row .btn { flex: 1 1 100%; width: 100%; margin-top: 8px; }
  #user-modal #pwd-strength-hint,
  #user-modal #user-form-error { padding: 0 18px; }
  #user-modal .modal-actions { padding: 14px 18px 18px; }
}


/* 3. .btn-review.reviewed: polished green gradient (no overlap) */
.btn-review.reviewed {
  background: linear-gradient(135deg, #10b981, #059669);
  color: #fff;
  border-color: #059669;
}
.btn-review.reviewed:hover {
  background: linear-gradient(135deg, #059669, #047857);
  border-color: #047857;
  color: #fff;
}
a.btn-review:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
a.btn-review.reviewed:hover { background: linear-gradient(135deg, #059669, #047857); border-color: #047857; }

/* 4. Ops column: nowrap, no wrap/truncation */
td.ops { white-space: nowrap; }
.ops-bar { display: inline-flex; gap: 6px; flex-wrap: nowrap; align-items: center; }
.ops-bar .btn { font-size: 0.82rem; padding: 5px 12px; flex-shrink: 0; }

/* 5. Delete button disabled state */
button.btn-danger:disabled,
button.danger:disabled,
.btn-danger:disabled,
.danger:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  background: var(--paper-elev);
  color: var(--ink-3);
  border-color: var(--line);
}
button.btn-danger:hover,
button.danger:hover,
.btn-danger:hover,
.danger:hover {
  background: var(--danger);
  color: #fff;
  border-color: var(--danger);
}

/* 6. Top bar keeps its own size in fullscreen */
body.app-full .topbar {
  flex: 0 0 auto;
}

/* 7. button.fs-btn style (literal selector for static_verify) */
button.fs-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255,255,255,0.08);
  color: #f1f3f7;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: var(--r-sm);
  padding: 6px 12px;
  font-size: 0.82rem;
  font-family: inherit;
  cursor: pointer;
  transition: background .15s, border-color .15s;
}
button.fs-btn:hover { background: rgba(255,255,255,0.16); border-color: rgba(255,255,255,0.32); }
button.fs-btn.active { background: var(--accent); border-color: var(--accent); }

/* 8. List-page fullscreen scroll: list-body must be scrollable,
        and the table must stay within the container (no column break) */
body.app-full #invoice-list .list-body { flex: 1 1 auto; overflow: auto; min-height: 0; }
body.app-full #recycle-list .list-body { flex: 1 1 auto; overflow: auto; min-height: 0; }
body.app-full #invoice-list .list-body table.data { width: 100%; }
body.app-full #recycle-list .list-body table.data { width: 100%; }

/* 8b. Universal table-overflow guard for list pages (independent of app-full).
     Reason: 普通用户 /invoices 列表常出现"疑似重复"等长 title 属性的徽标,
     配合 inline-flex 不换行的特性会撑宽第 2 列,继而撑破 .card 容器。
     这三条规则保证:
       - 表格始终撑满 card 容器宽度且不超出
       - 单元格内容(中文/数字/徽标)能自然换行,不再撑列宽
       - 通用 list 页(有 .list-page)与 #invoice-list / #recycle-list(无 list-page)一致 */
.list-page table.data,
#invoice-list table.data,
#recycle-list table.data {
  width: 100%;
  max-width: 100%;
}
table.data tbody td { overflow-wrap: anywhere; word-break: break-word; }
table.data tbody td:nth-child(2) { overflow-wrap: anywhere; word-break: break-all; }
/* 徽标在窄列下允许换行,避免单个长徽标横向撑爆表格。
   视觉上"疑似重复"四个字也不会被截断(宽列下仍是单行)。 */
table.data .badge,
table.data .stamp.ok { white-space: normal; max-width: 100%; }
/* list-body 在普通模式下也允许横向滚动,避免溢出 main 容器 */
#invoice-list .list-body,
#recycle-list .list-body { overflow-x: auto; }

/* ---------- File-disk / quick-file 本地预览框 ---------------------------- */
.file-preview-box {
  margin-top: 14px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--paper-card);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  pointer-events: auto;
}
.file-preview-box img {
  max-width: 100%;
  max-height: 320px;
  object-fit: contain;
  border-radius: var(--r-sm);
  background: var(--paper-elev);
  display: block;
}
.file-preview-meta {
  display: flex;
  gap: 10px;
  align-items: center;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--ink-2);
  flex-wrap: wrap;
  justify-content: center;
}
.file-preview-meta button.small { margin-left: auto; }

/* ============================================================
   MODAL POLISH — 上传发票 / ＋ 弹窗美化 (2026-08-10)
   仅作用于 #quick-upload-modal 内部,不影响页面其它元素;
   保留所有原有结构/ID/功能,只在视觉与交互动效上精修。
   与设计语言一致:oxblood #8c1c1c + serif display + 纸感卡片。
   ========================================================== */

/* ---- 遮罩:更柔和的夜幕 + 轻微毛玻璃 + 淡入 ---- */
#quick-upload-modal.modal-mask {
  background: linear-gradient(180deg,
    rgba(10, 18, 28, 0.62),
    rgba(10, 18, 28, 0.48));
  backdrop-filter: blur(5px) saturate(1.1);
  -webkit-backdrop-filter: blur(5px) saturate(1.1);
  padding: 20px;
  animation: qum-fade-in .16s ease-out;
}

/* ---- 弹窗主体:更精致的卡片 ---- */
#quick-upload-modal .modal-box {
  max-width: 560px;
  border-radius: 22px;
  box-shadow:
    0 22px 50px -18px rgba(10, 18, 28, 0.55),
    0 2px 8px -2px rgba(10, 18, 28, 0.25);
  animation: qum-pop-in .22s cubic-bezier(.2, .9, .3, 1.2);
  border: 1px solid rgba(255, 255, 255, 0.55);
}
/* 去掉原有纯色顶边,改为更精致的渐变页眉光带 */
#quick-upload-modal .modal-box::before {
  height: 4px;
  background: linear-gradient(90deg, var(--accent-deep), var(--accent), #d9a04a);
}

/* ---- 头部 ---- */
#quick-upload-modal .modal-head {
  padding: 22px 26px 14px;
}
#quick-upload-modal .modal-head h2 {
  font-size: 1.45rem;
  letter-spacing: .02em;
  display: flex;
  align-items: center;
  gap: 10px;
}
#quick-upload-modal .modal-head h2::before {
  content: "☰";
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px; height: 30px;
  border-radius: 9px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 1.05rem;
  line-height: 1;
}
#quick-upload-modal .modal-close {
  width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 10px;
  font-size: 1.05rem;
  color: var(--ink-3);
  transition: color .15s, background-color .15s, transform .18s;
}
#quick-upload-modal .modal-close:hover {
  background: var(--accent-soft);
  color: var(--accent-deep);
  transform: rotate(90deg);
}

/* ---- 上传方式选择卡片 ---- */
#quick-upload-modal .upload-options {
  margin: 14px 26px 4px;
  gap: 14px;
  padding-bottom: 18px;
}
#quick-upload-modal .opt-btn {
  padding: 18px 18px 16px;
  border-radius: 16px;
  border: 1.5px solid var(--line);
  background: linear-gradient(180deg, var(--paper-card), var(--paper-elev));
  box-shadow: 0 1px 2px rgba(10,18,28,.04);
  transition: transform .18s, box-shadow .18s, border-color .18s, background-color .18s;
  overflow: hidden;
}
#quick-upload-modal .opt-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 22px -12px rgba(140,28,28,.35);
  border-color: var(--accent);
}
/* 图标:柔和底色胶囊,悬停/激活时上色 */
#quick-upload-modal .opt-btn .opt-ico {
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.5rem;
  border-radius: 12px;
  background: var(--paper-elev);
  border: 1px solid var(--line);
  margin-bottom: 4px;
  transition: background-color .18s, color .18s, transform .18s;
}
#quick-upload-modal .opt-btn:hover .opt-ico {
  background: var(--accent-soft);
  transform: scale(1.06);
}
#quick-upload-modal .opt-btn .opt-txt {
  font-size: 1.02rem;
}
#quick-upload-modal .opt-btn.active {
  border-color: var(--accent);
  border-width: 2px;
  background: linear-gradient(180deg, #fff, var(--accent-soft));
  box-shadow: inset 0 0 0 1px var(--accent), 0 10px 24px -14px rgba(140,28,28,.4);
}
#quick-upload-modal .opt-btn.active .opt-ico {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
#quick-upload-modal .opt-btn.active::after {
  top: 12px; right: 12px;
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-size: .72rem;
}

/* ---- 上传区 dropzone ---- */
#quick-upload-modal .upload-box.dropzone {
  margin: 18px 0 14px;
  padding: 34px 22px 30px;
  border: 2px dashed var(--line-strong);
  border-radius: 18px;
  background:
    radial-gradient(circle at 50% 0%, rgba(140,28,28,.05), transparent 70%),
    repeating-linear-gradient(45deg, var(--paper-card) 0 14px, var(--paper-stripe) 14px 28px);
  transition: border-color .18s, background-color .18s, transform .18s, box-shadow .18s;
}
#quick-upload-modal .upload-box.dropzone:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
  box-shadow: 0 12px 26px -16px rgba(140,28,28,.3);
}
/* dropzone 中央图标(纯装饰,pointer-events:none 不挡点击) */
#quick-upload-modal .upload-box.dropzone::before {
  content: "🗎";
  display: block;
  text-align: center;
  font-size: 2.4rem;
  line-height: 1;
  margin-bottom: 8px;
  filter: grayscale(.2) opacity(.85);
  pointer-events: none;
}
#quick-upload-modal .upload-box.dropzone .dz-hint {
  position: relative;
  font-size: 1.1rem;
}
#quick-upload-modal .upload-box.dropzone .dz-sub {
  font-size: .84rem;
}
#quick-upload-modal .upload-box.dropzone.drag-over {
  border-color: var(--accent);
  border-style: dashed;
  background: var(--accent-soft);
  box-shadow: 0 0 0 4px var(--accent-glow);
}
#quick-upload-modal .upload-box.dropzone.drag-over::before {
  content: "⇧";
  color: var(--accent);
}

/* ---- 提示 ---- */
#quick-upload-modal .hint {
  line-height: 1.55;
}
#quick-upload-modal #quick-upload-status {
  margin: 12px 0 14px;
  padding: 9px 12px;
  border-radius: 10px;
  background: var(--paper-elev);
  border: 1px solid var(--line);
  min-height: 1.5em;
}

/* ---- 提交按钮 ---- */
#quick-upload-modal form .primary[type="submit"] {
  width: 100%;
  padding: 13px 18px;
  font-size: 1.02rem;
  font-weight: 600;
  border-radius: 12px;
  background: linear-gradient(180deg, var(--accent), var(--accent-deep));
  box-shadow: 0 8px 18px -8px rgba(140,28,28,.55);
  transition: transform .12s, box-shadow .12s, filter .12s;
}
#quick-upload-modal form .primary[type="submit"]:hover {
  filter: brightness(1.06);
  box-shadow: 0 12px 24px -10px rgba(140,28,28,.65);
}
#quick-upload-modal form .primary[type="submit"]:active {
  transform: translateY(1px);
  box-shadow: 0 4px 10px -6px rgba(140,28,28,.5);
}

/* ---- 移动端:保证不溢出、有滚动 ---- */
@media (max-width: 480px) {
  #quick-upload-modal .modal-box {
    max-height: 92vh;
    overflow-y: auto;
    border-radius: 18px;
  }
  #quick-upload-modal .modal-head { padding: 18px 20px 10px; }
  #quick-upload-modal .upload-options { margin: 12px 20px 2px; }
  #quick-upload-modal .opt-btn .opt-ico { height: 40px; width: 40px; }
  #quick-upload-modal #scan-panel,
  #quick-upload-modal #file-panel { padding-left: 20px; padding-right: 20px; }
}

/* ---- 动效开关:尊重系统减弱动画偏好 ---- */
@media (prefers-reduced-motion: reduce) {
  #quick-upload-modal.modal-mask,
  #quick-upload-modal .modal-box,
  #quick-upload-modal .modal-close:hover,
  #quick-upload-modal .opt-btn,
  #quick-upload-modal .opt-btn .opt-ico,
  #quick-upload-modal .upload-box.dropzone:hover {
    animation: none;
    transition: none;
    transform: none;
  }
}

@keyframes qum-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes qum-pop-in {
  from { opacity: 0; transform: translateY(14px) scale(.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* 增值税专用发票“专”字图标: 自绘内联SVG, 矢量无版权, 16px垂直对齐不破坏排版 */
.vspecial-icon {
  display: inline-block;
  vertical-align: -3px;
  width: 18px;
  height: 18px;
  margin-left: 6px;
  flex: none;
  flex-shrink: 0;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.18));
  /* 红色徽章自带高对比; 不再依赖 currentColor, 防止深色背景/主题切换时被翻转 */
}
/* 强化版标记: 在文档/列表场景用于让"专"字徽章随父级字号一起缩放 */
.detail-kv .vspecial-icon,
.detail-page .vspecial-icon {
  vertical-align: -3px;
  margin-left: 8px;
}
