/* Shared visual tokens: mist blue, soft mineral surfaces and system fonts. */
:root {
  --bs-primary: #3d638c;
  --bs-primary-rgb: 61, 99, 140;
  --bs-primary-text-emphasis: #2c4b6d;
  --bs-primary-bg-subtle: #eaf0f7;
  --bs-primary-border-subtle: #c1d2e4;
  --bs-link-color: var(--bs-primary);
  --bs-link-color-rgb: var(--bs-primary-rgb);
  --bs-link-hover-color: var(--bs-primary-text-emphasis);
  --bs-link-hover-color-rgb: 44, 75, 109;

  --brand-accent: #c1712f;
  --brand-accent-rgb: 193, 113, 47;
  --brand-ink: #25364b;
  --brand-bg: #f7f9fc;

  --bs-border-radius: .55rem;
  --bs-border-radius-sm: .4rem;
  --bs-border-radius-lg: .75rem;
  --bs-border-radius-xl: 1rem;

  --bs-body-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "PingFang SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
  --bs-body-color: var(--brand-ink);
  --bs-secondary-color: #657487;
  --bs-border-color: #dce4ee;
  --bs-body-line-height: 1.7;
  --bs-success-rgb: 61, 99, 140;

  --shadow-sm: 0 1px 2px rgba(20, 30, 30, .06);
  --shadow-md: 0 6px 20px -6px rgba(20, 30, 30, .16);
}

body {
  font-size: 15px;
  background: var(--brand-bg);
}

/* ── 导航栏 ───────────────────────────────────────────────────────────────
 * 之前是纯色平边、下面一条硬边框——Bootstrap 默认写法，谁的项目都长这样。
 * 换成白底 + 极浅的投影，边界感照样在，但不那么生硬。 */
.navbar {
  background: #fff !important;
  border-bottom: 0 !important;
  box-shadow: 0 1px 0 rgba(20, 30, 30, .06), var(--shadow-sm);
  padding-top: .7rem;
  padding-bottom: .7rem;
}

.navbar-brand {
  font-weight: 700;
  letter-spacing: -.01em;
  display: flex;
  align-items: center;
  gap: .5rem;
}

/* 图标块本身是渐变方块，里面那支笔是内联 SVG data URI——
   跟 favicon 同一个图形，站徽和浏览器标签页标一致。
   上次只做了方块没填图案，看起来像个空色块，这次把图案补上。 */
.navbar-brand::before {
  content: "";
  display: inline-block;
  width: 1.7rem;
  height: 1.7rem;
  border-radius: .45rem;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath d='M10 23 L20 9 L24 12 L14 26 L9 27 Z' fill='%23fbfaf8'/%3E%3Cpath d='M18 11.5 L21.5 14' stroke='%233d638c' stroke-width='1.6'/%3E%3C/svg%3E") center/62% no-repeat,
    linear-gradient(155deg, var(--bs-primary), #2c4b6d);
  flex: 0 0 auto;
}

.navbar-nav .nav-link {
  color: var(--bs-secondary-color);
  position: relative;
  transition: color .12s;
}

.navbar-nav .nav-link:hover { color: var(--bs-body-color); }

.navbar-nav .nav-link.active {
  color: var(--bs-primary);
}

.navbar-nav .nav-link.active::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -.7rem;
  height: 2px;
  background: var(--bs-primary);
  border-radius: 2px;
}

/* ── 卡片 / 按钮 / 表单：全站通用的质感 ───────────────────────────────────
 * 默认 Bootstrap 卡片只有一条 1px 灰边，扁平得像线框图。加一层很轻的
 * 投影，边框颜色也调淡——层次感来自阴影而不是描边，纸感更强。
 *
 * 编辑器那几个面板（.group-card）也是 .card，一并受益，不用单独处理。 */
.card {
  border-color: rgba(20, 30, 30, .08);
  box-shadow: var(--shadow-sm);
}

.card-header {
  background: rgba(61, 99, 140, .035);
  border-bottom-color: rgba(20, 30, 30, .08);
}

/* 按钮：默认 Bootstrap 按钮是纯色平涂，换成极轻的投影和更明确的按下反馈。
 * 幅度很小——这是一个要反复点「保存」「下一步」的表单产品，按钮乱跳
 * 或者阴影太重反而分散注意力。 */
.btn {
  font-weight: 500;
  transition: box-shadow .12s, transform .05s;
}

.btn-primary, .btn-success {
  box-shadow: var(--shadow-sm);
}

.btn:active { transform: translateY(1px); }

/* Bootstrap 5.3 把每个 .btn-* 的颜色编译成写死的十六进制值，不是引用
 * --bs-primary——只改根变量对按钮毫无作用，这里是唯一管用的地方。
 * .text-primary / .border-primary / 链接颜色不在此列：那几个是真的
 * 引用变量，改根变量已经生效，见文件顶部的设计基调。 */
.btn-primary {
  --bs-btn-bg: var(--bs-primary);
  --bs-btn-border-color: var(--bs-primary);
  --bs-btn-hover-bg: var(--bs-primary-text-emphasis);
  --bs-btn-hover-border-color: var(--bs-primary-text-emphasis);
  --bs-btn-active-bg: var(--bs-primary-text-emphasis);
  --bs-btn-active-border-color: var(--bs-primary-text-emphasis);
  --bs-btn-disabled-bg: var(--bs-primary);
  --bs-btn-disabled-border-color: var(--bs-primary);
  --bs-btn-focus-shadow-rgb: var(--bs-primary-rgb);
}

.btn-outline-primary {
  --bs-btn-color: var(--bs-primary);
  --bs-btn-border-color: var(--bs-primary);
  --bs-btn-hover-bg: var(--bs-primary);
  --bs-btn-hover-border-color: var(--bs-primary);
  --bs-btn-active-bg: var(--bs-primary);
  --bs-btn-active-border-color: var(--bs-primary);
  --bs-btn-disabled-color: var(--bs-primary);
  --bs-btn-disabled-border-color: var(--bs-primary);
  --bs-btn-focus-shadow-rgb: var(--bs-primary-rgb);
}

.btn-lg { border-radius: var(--bs-border-radius-lg); }

/* 输入框聚焦：默认的蓝色光晕换成品牌色，弱化到刚好看得见就好 */
.form-control:focus, .form-select:focus {
  border-color: rgba(var(--bs-primary-rgb), .5);
  box-shadow: 0 0 0 .2rem rgba(var(--bs-primary-rgb), .15);
}

/* 同样是「颜色写死在组件变量里」的一员：完成度进度条 */
.progress {
  --bs-progress-bar-bg: var(--bs-primary);
}

/* 单选框 / 复选框 / 开关：勾选态同样是写死的默认蓝 */
.form-check-input:checked {
  background-color: var(--bs-primary);
  border-color: var(--bs-primary);
}

.form-check-input:focus {
  border-color: rgba(var(--bs-primary-rgb), .5);
  box-shadow: 0 0 0 .2rem rgba(var(--bs-primary-rgb), .15);
}

/* 三栏各自独立滚动，页面本身不滚。
   之前用 position: sticky，但元素比视口高时浏览器会先把它滚完再吸住，
   表现就是右侧跟着轻微移动。改成各栏独立滚动容器后没有这个问题。

   这套只属于编辑器页，所以挂在 body.app-shell 上（见 index.html）。
   写成全局的话，后台、登录、安装那些普通页面会被一起锁死没法滚——
   而且只在宽屏下复现，窄窗口正常，很难想到是这里。 */
@media (min-width: 992px) {
  /* html 给个高度让 body 的 height:100% 有参照。
     单独给 html 设高度不会挡住滚动，挡滚动的是下面那条 overflow。 */
  html { height: 100%; }

  body.app-shell {
    height: 100%;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }

  .navbar { flex: 0 0 auto; }

  .app-body {
    flex: 1 1 auto;
    min-height: 0;        /* 不加这行 flex 子项不会收缩，滚动条会跑到 body 上 */
    overflow: hidden;
  }

  .pane {
    height: 100%;
    overflow-y: auto;
    overscroll-behavior: contain;   /* 滚到底不带动其他栏 */
  }

  /* 预览栏自己不滚，交给里面的纸面滚——这样卡片外框始终留在视野里 */
  .pane-flush { overflow: hidden; }

  .preview-wrap,
  .preview-wrap > .card { height: 100%; }
  .preview-wrap > .card > .card-body { min-height: 0; overflow: hidden; }
}

.output-pre {
  max-height: 40vh;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-all;
}

/* 表单组 */
.group-card {
  margin-bottom: 1rem;
}

.group-card .card-header {
  font-weight: 600;
}

.field-help {
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
}

/* 法定数值锁定标记 */
/* 付款后锁定的字段 */
.lock-tag {
  margin-left: .35rem;
  font-size: .8em;
  cursor: help;
}

.is-locked .form-label,
.is-locked .form-check-label { opacity: .75; }

/* ── 后台：近 30 天迷你条形图 ─────────────────────────────────────────── */
/* 纯 CSS 条形图：柱高是服务端算好的百分比，不需要图表库。
   min-height 保证 0 那天也有个看得见的底线，不是完全消失看着像缺数据。 */
.mini-chart {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 3rem;
}

.mini-bar {
  flex: 1 1 0;
  min-height: 2px;
  border-radius: 1px 1px 0 0;
  opacity: .85;
  transition: opacity .1s;
}

.mini-bar:hover { opacity: 1; }

.legal-tag {
  font-size: 0.7rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--bs-secondary-color);
  border: 1px solid var(--bs-border-color);
  border-radius: 3px;
  padding: 0 4px;
  margin-left: 6px;
  white-space: nowrap;
}

/* repeat 组的单个条目 */
.repeat-item {
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  padding: 0.75rem;
  margin-bottom: 0.75rem;
  position: relative;
}

.repeat-item-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  margin-bottom: .85rem;
}

.repeat-item-head .repeat-index { flex: 0 0 auto; margin-right: .25rem; }

.repeat-item-head .btn {
  flex: 0 1 auto;
  max-width: 100%;
  margin-left: 0 !important;
  padding: .3rem .65rem !important;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.repeat-index {
  font-weight: 600;
  color: var(--bs-secondary-color);
}

/* schema 里标 __ELIDED__ 的占位 */
.elided {
  border: 1px dashed var(--bs-warning-border-subtle);
  background: var(--bs-warning-bg-subtle);
  border-radius: var(--bs-border-radius);
  padding: 0.6rem 0.75rem;
  font-size: 0.85rem;
  color: var(--bs-secondary-color);
}

.finding {
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--bs-border-color);
}

.finding:last-child {
  border-bottom: none;
}

.finding-legal {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.75rem;
  color: var(--bs-secondary-color);
}

/* 隐藏：由 when / applies_to 控制 */
[hidden] {
  display: none !important;
}

.field-hint {
  font-size: 0.78rem;
  color: var(--bs-secondary-color);
  min-height: 0;
}

.field-hint:empty {
  display: none;
}

/* 界面语言切换：全部并排，不用下拉 */
.lang-switcher {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  border: 1px solid var(--bs-border-color);
  border-radius: 999px;
  padding: 2px;
}

.lang-pill {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--bs-secondary-color);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .12s, color .12s;
}

.lang-pill:hover {
  color: var(--bs-body-color);
  background: var(--bs-tertiary-bg);
}

.lang-pill.active {
  background: var(--bs-primary);
  color: #fff;
  font-weight: 600;
}

/* ── 实时预览 ─────────────────────────────────────────────────────────── */

.doc-page {
  height: 100%;
  overflow-y: auto;
  padding: 2rem 2.2rem;
  background: #fff;
  color: #1a1a1a;
  font-family: "Times New Roman", Georgia, serif;
  font-size: 12.5px;
  line-height: 1.65;
  text-align: justify;
}

.doc-title {
  font-size: 15px;
  font-weight: 700;
  text-align: center;
  text-transform: uppercase;
  margin: 0 0 1.4rem;
  line-height: 1.4;
}

.doc-clause {
  font-size: 12.5px;
  font-weight: 700;
  text-align: center;
  margin: 1.5rem 0 0;
}

.doc-heading {
  font-size: 12.5px;
  font-weight: 400;
  text-align: center;
  margin: 0 0 .6rem;
}

.doc-p, .doc-item { margin: 0 0 .6rem; }
.doc-lead { margin: 1rem 0 .4rem; font-weight: 600; }
.doc-n { font-weight: 600; }
.doc-date { margin-top: 2rem; text-align: left; }
.doc-annex { font-size: 12.5px; font-weight: 700; text-align: center; margin: 2rem 0 .5rem; }

/* 未填字段：既让预览成形，也当待办清单 */
.doc-page .ph {
  background: #fff3cd;
  color: #8a6d00;
  border-radius: 2px;
  padding: 0 2px;
  font-family: inherit;
  white-space: nowrap;
}

.doc-sign { display: flex; gap: 2rem; margin-top: 1.5rem; }
.doc-sign-group { flex: 1; }
.doc-sign-cap { font-weight: 600; margin-bottom: 1.6rem; font-size: 11.5px; }
.doc-sign-line { border-bottom: 1px solid #333; margin-bottom: .25rem; height: 1.4rem; }
.doc-sign-name { font-size: 11px; color: #555; margin-bottom: 1.2rem; }

@media (prefers-color-scheme: dark) {
  .doc-page { background: #f7f7f5; }
}

/* 变体选择：摊开成一排单选按钮，比下拉更能说明支持范围 */
.radio-group {
  display: flex;
  flex-wrap: wrap;
  gap: .15rem 1.1rem;
  padding-top: .15rem;
}

.radio-group .form-check {
  margin-bottom: 0;
  min-height: auto;
}

.radio-group .form-check-label {
  font-size: .88rem;
  cursor: pointer;
}

.radio-group .form-check-input { cursor: pointer; }

/* 双语：2×N 表格，一行一条款，左葡右英——对应 Word 里的 2×1 表格排版 */
.doc-bi {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

/* 外框 + 中间分隔线，行间不画横线——看起来就是方框里的两栏连续正文，
   但对齐由表格行保证，不需要靠补空行去凑 */
.doc-bi { border: 1px solid #222; }

.doc-bi .doc-col {
  width: 50%;
  vertical-align: top;
  padding: .15rem .8rem;
  border: 0;
}

.doc-bi .doc-col:first-child { border-right: 1px solid #222; }

.doc-bi .doc-title,
.doc-bi .doc-clause,
.doc-bi .doc-heading {
  margin: 0 0 .3rem;
}

.doc-bi .doc-clause { font-weight: 700; text-align: center; }
.doc-bi .doc-heading { text-align: center; }
.doc-bi .doc-title  { font-weight: 700; text-align: center; text-transform: uppercase; }
.doc-bi .doc-item:last-child,
.doc-bi .doc-p:last-child { margin-bottom: 0; }

.doc-page.is-bilingual { padding: 1rem; font-size: 11px; }

/* 开关与标签同排 */
.form-switch .form-check-label {
  font-size: .88rem;
  cursor: pointer;
  padding-left: .1rem;
}

.form-switch .form-check-input { cursor: pointer; }

/* 开关横排：文字在前、开关在后，紧贴且左对齐。
   覆盖 Bootstrap form-switch 的左内边距与负外边距，否则会缩进。 */
.switch-row {
  display: flex;
  align-items: center;
  gap: .55rem;
  padding-left: 0;
}

.switch-row .form-check-input {
  margin: 0;
  flex: 0 0 auto;
}

/* 预览区不可选中——只挡顺手复制，不构成真正的保护 */
.doc-page {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}


/* ── 底部操作栏 ────────────────────────────────────────────────────────── */
/* 校验、完成度、下载放这里，右栏整个撤掉，表单与预览各得一半宽度 */

.action-bar {
  flex: 0 0 auto;
  z-index: 5;
  background: #fff !important;
  border-top: 0 !important;
  box-shadow: 0 -1px 0 rgba(20, 30, 30, .08), 0 -6px 16px -8px rgba(20, 30, 30, .12);
}

.action-row {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding-block: .5rem;
}

.action-progress {
  flex: 1 1 auto;
  min-width: 0;
}

.action-progress .field-hint {
  margin-top: .2rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.action-buttons {
  display: flex;
  gap: .5rem;
  flex: 0 0 auto;
}

.check-badge {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* 校验详情：默认折叠，有阻断项时自动展开 */
.findings-panel {
  max-height: 32vh;
  overflow-y: auto;
  padding: .5rem 1rem;
  border-bottom: 1px solid var(--bs-border-color);
  background: var(--bs-body-bg);
}

.download-status {
  padding: 0 1rem .4rem;
  min-height: 0;
}

.download-status:empty { display: none; }

/* 附件：物品清单与验房记录 */
.doc-room {
  font-weight: 700;
  margin: .9rem 0 .2rem;
}

.doc-group {
  font-size: .92em;
  color: #555;
  margin: .4rem 0 .15rem;
}

table.doc-inv {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: .4rem;
  font-size: .95em;
}

table.doc-inv th,
table.doc-inv td {
  border: 1px solid #999;
  padding: 1px 5px;
  text-align: left;
  vertical-align: top;
}

table.doc-inv th { background: #f2f2f0; font-weight: 600; }
table.doc-inv .c-qty  { width: 8%;  text-align: center; }
table.doc-inv .c-cond { width: 22%; }
table.doc-inv .c-obs  { width: 30%; }

/* 双语版清单：每张 fabric/equipment 表整个当一行内容配对（跟房间标题、
   分组标题一样，是 _bilingual_annex_rows 逐行配对的一个单元），表格
   本身还是完整的 table.doc-inv，不拆散成一行一个小表。 */

/* ── 物品清单与验房 ────────────────────────────────────────────────────── */

.inv-room {
  border-top: 1px solid var(--bs-border-color);
  padding-top: .5rem;
  margin-top: .5rem;
}

.inv-room:first-of-type { border-top: 0; margin-top: 0; }

.inv-items {
  margin: .35rem 0 .2rem;
}

.inv-row {
  display: grid;
  grid-template-columns: 1fr 3.2rem 6.5rem 1fr;
  gap: .3rem;
  align-items: center;
  padding: .1rem 0;
}

.inv-row:not(.on) { grid-template-columns: 1fr; }

.inv-check { margin: 0; min-height: auto; }
.inv-check .form-check-label { font-size: .84rem; cursor: pointer; }
.inv-row:not(.on) .form-check-label { color: var(--bs-secondary-color); }

.inv-qty, .inv-cond, .inv-obs {
  font-size: .8rem;
  padding-block: .1rem;
}

.inv-qty { text-align: center; }

.inv-kind-label {
  font-size: .78rem;
  font-weight: 600;
  color: var(--bs-secondary-color);
  margin: .5rem 0 .1rem;
}

/* 双语时名称是两个真正的 grid 行（各占一行，见 form.js 的行内
   grid-row），不是拿 flex 包一层再当一个格子塞进去——那样删除按钮
   没法跟第二行（英语）对齐，因为对 grid 来说那一整块只是一个格子。 */
.inv-row-custom { align-items: start; row-gap: .3rem; }
/* 具体在哪一行、哪一列由 form.js 用行内 style 定位——单语言时贴着
   唯一的名称输入框，双语时贴着第二行（英语）名称输入框，不跟数量/
   状态/备注同一行抢位置。 */
.inv-custom-remove {
  text-align: right;
  padding: .1rem .3rem 0 0;
  text-decoration: none;
  line-height: 1;
  white-space: nowrap;
}
.inv-add-custom { margin: .1rem 0 .4rem; }

/* ── 首页 ─────────────────────────────────────────────────────────────── */

/* 常见问题：原生 <details>，浏览器自带展开箭头样式差异很大，
   自己画一个统一的、跟卡片同一套描边+投影语言。 */
.faq-item {
  background: #fff;
  border: 1px solid rgba(20, 30, 30, .08);
  border-radius: var(--bs-border-radius);
  box-shadow: var(--shadow-sm);
  padding: .85rem 1.1rem;
  margin-bottom: .6rem;
}

.faq-item summary {
  cursor: pointer;
  font-weight: 600;
  list-style: none;         /* 去掉默认三角，自己画一个，别看着像两套系统 */
}

.faq-item summary::-webkit-details-marker { display: none; }

.faq-item summary::before {
  content: "+";
  display: inline-block;
  width: 1.1em;
  color: var(--bs-primary);
  font-weight: 700;
}

.faq-item[open] summary::before { content: "−"; }

/* 主张区：给一块很浅的品牌色底，跟下面的卖点列表区分开，
   页面一打开就有「这不是随便一个模板」的感觉。 */
.hero-band {
  background:
    radial-gradient(ellipse 60% 100% at 50% 0%, rgba(var(--bs-primary-rgb), .08), transparent),
    linear-gradient(180deg, rgba(var(--bs-primary-rgb), .045), transparent 70%);
  border-bottom: 1px solid rgba(20, 30, 30, .06);
}

/* 卖点卡片左边的图标：从裸 emoji 换成一个有底色的圆角方块，
   视觉上有个「锚点」，几张卡片排在一起才不会看着像一串纯文字。 */
.adv-icon {
  flex: 0 0 auto;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: .6rem;
  background: rgba(var(--bs-primary-rgb), .09);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
}

/* ── 首页：空白模板的第一页 ───────────────────────────────────────────── */

/* 左栏那一列卡片比右边这张纸矮，滚动时让纸跟着停在视野里 */
@media (min-width: 992px) {
  .preview-sticky { position: sticky; top: 1.5rem; }
}

/* 里面那张纸是真实 A4 尺寸再等比缩小——直接把字号改小会让行宽、断行
   全变样，看到的就不是买到的那一页了。缩放系数由 a4-preview.js 算并写进
   transform：纯 CSS 做不到，scale() 要无单位数，而 calc(100cqw / 794)
   得到的是长度。

   外框**不是**完整的 210×297：整页高度会让它比左边那列卡片高出一大截，
   空隙被撑得很开。下半截本来就压在渐隐带下面看不清，截短一点看不出来，
   两栏反而齐整。纸的内容仍是原比例，只是这个窗口小于一整页。 */
.a4-frame {
  position: relative;
  aspect-ratio: 210 / 260;
  overflow: hidden;
  border: 1px solid var(--bs-border-color);
  border-radius: .5rem;
  background: #fff;
  box-shadow: 0 .5rem 1.5rem rgba(0, 0, 0, .08);
}

.a4-scale {
  width: 794px;
  transform-origin: top left;
}

/* 预览里这张纸不滚动也不自己撑高：它只是第一页，剩下的由渐隐带交代 */
.a4-frame .a4-page {
  height: 1123px;          /* 794 × 297/210 */
  overflow: hidden;
  padding: 2.4rem 2.6rem;
}

/* 下半截渐隐：既暗示「还有后文」，也给悬浮按钮一个能看清的底 */
.a4-fade {
  position: absolute;
  inset: auto 0 0 0;
  height: 55%;
  background: linear-gradient(to bottom,
              rgba(255, 255, 255, 0) 0%,
              rgba(255, 255, 255, .92) 45%,
              rgba(255, 255, 255, 1) 100%);
  pointer-events: none;
}

.a4-cta {
  position: absolute;
  left: 50%;
  bottom: 8%;
  transform: translateX(-50%);
  width: min(22rem, 86%);
  text-align: center;
}

.a4-cta-price {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.1;
  margin-bottom: .5rem;
  color: #1a1a1a;
}

/* 渐隐带是白的，这一小块文字固定用深色——跟着主题变会在浅色纸上看不见 */
.a4-cta-terms .form-check-label,
.a4-cta-terms .form-check-label a { color: #444; }

.a4-frame #templateStatus { color: #444; }
.a4-frame #templateStatus.text-danger { color: var(--bs-danger) !important; }

/* 窄屏：纸缩得太小就读不清了，再压扁一点，把版面留给下面的内容 */
@media (max-width: 575.98px) {
  .a4-frame { aspect-ratio: 210 / 235; }
  .a4-cta-price { font-size: 1.6rem; }
}

/* 左栏卡片与右边那张纸底部对齐。
   纸的高度是 A4 比例定死的，卡片的高度由文案长短决定，两边不会自然一样齐。
   与其去调某一条文案的字数（换个语言就又不齐了），不如让卡片之间的空隙
   吸收这点差额：space-between 只动间距，不拉伸卡片本身。
   左栏比右栏高时没有余量可分，space-between 什么也不做，正好。 */
@media (min-width: 992px) {
  .adv-col {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }
  .adv-col > .card { margin-bottom: 0; }
}

/* ── 首页：证件扫描板块的示意卡片 ─────────────────────────────────────── */
/* 纯静态示意，不是真实运行结果——用来在不跑一遍真实识别流程的前提下
   说明「拖进来 / 识别出」这个动作长什么样，参考了同行 renda.app 首页
   的做法，但没有照抄它的视觉，只是同样的「文件名 → 状态」两栏结构。

   卡片高度不跟右边文字列强行对齐（试过用 flex-fill 撑高、内容居中，
   三行内容配一个跟文字列一样高的卡片，上下就会空出两大块，反而更难看）。
   改成加一个拖拽区提示和一行结果小结，让卡片自己有内容撑起该有的高度。 */
.scan-mock-header {
  padding: .85rem 1.25rem;
  border-bottom: 1px solid var(--bs-border-color);
  font-weight: 600;
  font-size: .95rem;
  display: flex;
  align-items: center;
  gap: .5rem;
  background: rgba(var(--bs-primary-rgb), .05);
  border-radius: var(--bs-card-inner-border-radius, .5rem) var(--bs-card-inner-border-radius, .5rem) 0 0;
}

/* 这块本来只是示意图，但示意的动作（上传证件）本站真能做，与其摆着好看，
   不如直接做成去编辑页的入口——见 home.html 里的说明。 */
.scan-mock-drop {
  display: block;
  border: 1px dashed var(--bs-border-color);
  border-radius: .5rem;
  padding: 1.25rem;
  text-align: center;
  color: var(--bs-secondary-color);
  font-size: .85rem;
  margin-bottom: 1rem;
  text-decoration: none;
  transition: border-color .15s, background-color .15s;
}

.scan-mock-drop:hover,
.scan-mock-drop:focus-visible {
  border-color: var(--bs-primary);
  background: rgba(var(--bs-primary-rgb), .04);
  color: var(--bs-secondary-color);
}

.scan-mock-drop-icon {
  font-size: 1.3rem;
  margin-bottom: .35rem;
}

.scan-mock-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: .85rem 0;
  border-bottom: 1px solid var(--bs-border-color);
}

.scan-mock-footer {
  padding-top: 1rem;
  font-size: .8rem;
  color: var(--bs-secondary-color);
  text-align: center;
}

.scan-mock-name {
  font-size: .9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── 证件扫描对话框 ───────────────────────────────────────────────────── */

.scan-dialog {
  width: min(28rem, calc(100vw - 2rem));
  border: 0;
  border-radius: .75rem;
  padding: 1.25rem;
  box-shadow: 0 1rem 3rem rgba(0, 0, 0, .25);
  color: var(--bs-body-color);
  background: var(--bs-body-bg);
}

.scan-dialog::backdrop { background: rgba(0, 0, 0, .45); }

.scan-close-form {
  float: right;
  margin: -.25rem -.25rem 0 0;
}

/* label 包着隐藏的 file input，按钮要自己表现得像按钮 */
.scan-dialog label.btn { cursor: pointer; }

/* 识别失败时展开的原始文本。等宽字体是必要的：
   看的就是「有没有对齐成机读区那种定长的样子」 */
.scan-diag {
  font-size: 11px;
  line-height: 1.4;
  white-space: pre-wrap;
  word-break: break-all;
  margin: .4rem 0 0;
  max-height: 12rem;
  overflow: auto;
}

/* 识别结果里每个字段的可信度标记 */
.scan-ok   { color: var(--bs-success); font-size: 11px; white-space: nowrap; }
.scan-warn { color: var(--bs-warning-text-emphasis, #997404); font-size: 11px; white-space: nowrap; }

/* 识别结果表：字段名不参与撑宽，把宽度让给可编辑的值 */
.scan-dialog .scan-name { width: 5.5rem; }
.scan-dialog td { padding: .25rem .3rem; }

/* ── Site composition ────────────────────────────────────────────────── */
body { -webkit-font-smoothing: antialiased; }
h1, h2, h3, .h4, .h5, .h6 { letter-spacing: -.025em; line-height: 1.3; }
h1 { text-wrap: balance; }
a { text-underline-offset: .2em; }
:focus-visible { outline: 3px solid #6389b0; outline-offset: 4px; }
.navbar > .container-fluid { gap: 1.25rem; padding-inline: clamp(1rem, 3vw, 3rem); }
.navbar { padding-block: .7rem; }
.navbar-brand { font-size: 1rem; white-space: normal; max-width: 24rem; margin: 0; padding-block: 0; }
.navbar-brand::before { width: 1.8rem; height: 1.8rem; border-radius: .55rem; }
.site-nav { margin-left: auto !important; gap: 1.4rem !important; }
.navbar-nav .nav-link { font-size: .875rem; white-space: nowrap; }
.navbar-nav .nav-link.active::after { bottom: -.45rem; left: 25%; right: 25%; }
.nav-tools { flex-wrap: wrap; }
.lang-switcher { background: #f0f4f9; border-color: transparent; padding: 2px; }
.lang-pill { padding: 1px 8px; font-size: .72rem; line-height: 1.5; }
.lang-pill.active { background: white; color: var(--bs-primary); box-shadow: 0 1px 5px #25364b15; }
.card { border-radius: 1rem; box-shadow: 0 4px 18px -10px #25364b20; }
.card-body { padding: 1rem; }
.card-header { padding: .6rem 1rem; }
.btn { --bs-btn-padding-x: 1.1rem; --bs-btn-padding-y: .45rem; --bs-btn-font-size: .9rem; border-radius: .65rem; }
.btn-sm { --bs-btn-padding-x: .75rem; --bs-btn-padding-y: .35rem; --bs-btn-font-size: .8rem; }
.btn-lg { --bs-btn-padding-x: 1.6rem; --bs-btn-padding-y: .65rem; --bs-btn-font-size: 1rem; }
.btn-primary { box-shadow: 0 4px 10px #3d638c18; }
.btn-outline-secondary { --bs-btn-color: #586b80; --bs-btn-border-color: #cedae7; --bs-btn-hover-bg: #eaf0f7; --bs-btn-hover-color: #25364b; --bs-btn-hover-border-color: #a8bed6; }
.btn-success { --bs-btn-bg: #3d638c; --bs-btn-border-color: #3d638c; --bs-btn-hover-bg: #2c4b6d; --bs-btn-hover-border-color: #2c4b6d; --bs-btn-active-bg: #2c4b6d; --bs-btn-active-border-color: #2c4b6d; }
.form-label { font-weight: 500; margin-bottom: .4rem; }
.form-control, .form-select { font-size: .925rem; padding: .45rem .7rem; border-color: #d6e0ec; background-color: #fcfdff; }
.form-control-sm, .form-select-sm { font-size: .825rem; padding-block: .35rem; }
.form-text, .field-help, .field-hint { line-height: 1.6; }
.alert { border-radius: .75rem; }
.list-group { --bs-list-group-border-color: #dce4ee; --bs-list-group-action-hover-bg: #f0f4fa; border-radius: 1rem; }
.list-group-item { padding: .75rem 1rem; }
.table { --bs-table-bg: transparent; --bs-table-border-color: #e1e7f0; }
.table th { color: #657487; font-weight: 500; font-size: .8rem; }
.table > :not(caption) > * > * { padding: .6rem; }
.nav-tabs { gap: .5rem; --bs-nav-tabs-border-color: #dce4ee; --bs-nav-tabs-link-active-color: #3d638c; }
footer { background: #edf2f8; border-color: #dfe7f1 !important; line-height: 1.9; }
body:not(.app-shell) > .container > h1 { font-size: clamp(1.65rem, 3vw, 2.25rem); margin-bottom: .8rem !important; }

/* Landing page: compact heading, paper preview and quiet feature cards. */
.hero-band { background: radial-gradient(ellipse at 15% 10%, #e2ebf8, transparent 55%), radial-gradient(ellipse at 90% 90%, #e8eef8, transparent 55%), #f0f5fb; border-bottom-color: #e0e8f3; }
.hero-band > .container { padding-block: clamp(1.5rem, 3vw, 2.5rem) !important; }
.hero-band h1 { max-width: 58rem; margin-inline: auto; font-size: clamp(1.65rem, 3.2vw, 2.6rem); font-weight: 600 !important; letter-spacing: -.045em; line-height: 1.2; }
.hero-band .lead { max-width: 40rem; margin-inline: auto; font-size: 1.05rem; line-height: 1.65; }
.hero-band .display-5 { font-size: 2.8rem; letter-spacing: -.05em; }
.hero-band .h3 { font-size: 1.4rem; font-weight: 400; }
.home-content { padding-block: 2rem !important; }
.adv-col { display: flex; flex-direction: column; gap: 1rem; justify-content: flex-start; }
.adv-col .card { margin-bottom: 0; background: transparent; border: 0; box-shadow: none; }
.adv-col .card-body { padding: 0 !important; gap: .75rem !important; }
.adv-col .h6 { font-size: 1.05rem; margin-bottom: .35rem !important; }
.adv-col .small { font-size: .875rem; line-height: 1.55; }
.adv-icon { width: 2.8rem; height: 2.8rem; border-radius: .85rem; background: #e8eff8; }
.a4-frame { border-color: #d7e1ed; border-radius: 1rem; box-shadow: 0 16px 40px -20px #2c4b6d3d; }
.scan-feature { padding: 1.25rem 1rem; border-radius: 1.5rem; background: #edf2f9; margin-top: 1.5rem; }
.scan-feature h2 { font-size: 1.75rem; }
.scan-mock-drop { background: #f6f9fd; border-color: #c2d3e6; padding: 1rem; }
.faq-item { padding: .75rem 1rem; border-color: #dfe6f0; box-shadow: none; border-radius: .85rem; }
.faq-item summary { display: flex; gap: .65rem; font-weight: 500; }
.faq-item summary::before { flex-shrink: 0; }
.faq-item[open] { background: #eff4fa; border-color: #cbd9ea; }
.faq-item p { padding-left: 1.8rem; line-height: 1.9; }
.pricing-page > h1, .pricing-page > p { text-align: center; }
.pricing-page > .row { margin-top: 1rem; --bs-gutter-x: 1rem; }
.pricing-page .card-body { padding: 1.25rem; }
.pricing-page .border-primary { background: #edf3fb; border-color: #abc2de !important; }
.pricing-page .display-6 { font-size: 3rem; letter-spacing: -.05em; padding-block: .4rem; color: var(--bs-primary); }
.pricing-page .display-6 > span { display: inline-block; margin-left: .35rem; font-size: 1rem; letter-spacing: normal; line-height: 1.5; white-space: nowrap; }
.auth-page { padding-top: 1rem; padding-bottom: 2rem; }
.auth-page .card-body { padding: 1.25rem; }
.auth-page h1 { font-size: 1.7rem; margin-bottom: 1rem !important; }

.captcha-image {
  height: calc(1.5em + .75rem + 2px); /* 跟 .form-control 默认高度对齐 */
  border-radius: var(--bs-border-radius);
  border: 1px solid var(--bs-border-color);
  flex-shrink: 0;
}

/* Editor keeps independent scrolling and a neutral document surface. */
.app-shell { background: #edf2f8; }
.app-body { padding-inline: 1.25rem; }
.group-card .card-header { background: #f6f9fd; padding-block: .55rem; }
.group-card .card-body { padding: .85rem; }
.repeat-item { background: #fafcff; border-color: #dfe7f1; padding: .65rem; }
.preview-wrap > .card { border-radius: .85rem; overflow: hidden; }
.preview-wrap .card-header { padding: .5rem 1rem !important; background: #f6f9fd; }
.action-row { padding: .5rem 1rem; }
.pane { scrollbar-width: thin; scrollbar-color: #c4d1e2 transparent; }
@media (min-width: 992px) {
  .adv-col { justify-content: space-between; }
  .app-body > .row > .pane:first-child { width: 40%; }
  .app-body > .row > .pane:last-child { width: 60%; }
}
@media (max-width: 1199.98px) {
  .navbar > .container-fluid { flex-wrap: wrap; gap: .4rem; }
  .site-nav { order: 3; width: 100%; margin: 0 !important; justify-content: center; padding-top: .35rem; border-top: 1px solid #edf1f7; }
  .nav-tools { margin-left: auto; }
}
@media (max-width: 767.98px) {
  .navbar { padding-block: .7rem; }
  .navbar-brand { font-size: .9rem; max-width: 100%; }
  .nav-tools { width: 100%; justify-content: space-between; gap: .5rem !important; }
  .site-nav { justify-content: space-between; gap: .75rem !important; overflow-x: auto; padding-bottom: .5rem; }
  .navbar-nav .nav-link { font-size: .8rem; }
  .navbar-nav .nav-link.active::after { bottom: -.3rem; }
  .home-content { padding-inline: 1.25rem; }
  .scan-feature { padding: 1rem .4rem; margin-top: 2rem; }
  .action-row { flex-wrap: wrap; gap: .65rem; }
  .action-progress { flex-basis: 65%; }
  .action-buttons { width: 100%; flex-wrap: wrap; }
  .action-buttons .btn { flex: 1 1 auto; }
  .app-body { padding-inline: .75rem; }
  .inv-row { grid-template-columns: minmax(0, 1fr) 3rem 6rem; }
  .inv-obs { grid-column: 1 / -1; }
  .auth-page .card-body, .pricing-page .card-body { padding: 1rem; }
  .doc-page { padding: 1.25rem; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition: none !important; }
}

/* Compact section rhythm; document and print spacing stay independent. */
.hero-band .mb-4 { margin-bottom: 1rem !important; }
.hero-band > .container > .mb-4 { margin-bottom: 0 !important; }
.home-content > .mb-5 { margin-bottom: 1.75rem !important; }
.home-content > .row { --bs-gutter-x: 1.25rem; --bs-gutter-y: 1rem; }
body:not(.app-shell) > .container.py-5 { padding-block: 2rem !important; }
.auth-page > .card.mt-5 { margin-top: 1.5rem !important; }
footer { margin-top: 2rem !important; padding-block: 1.25rem !important; line-height: 1.7; }

.navbar .account-box .btn-sm { --bs-btn-padding-y: .2rem; }
.adv-col .adv-icon { width: 2.25rem; height: 2.25rem; font-size: 1rem; border-radius: .65rem; }
