/* ============ 应用层：外壳 / 登录 / 工作台 / 编辑器 / 预览 / 后台 ============ */

/* ---------------- 顶栏 ---------------- */
.appbar {
  position: sticky; top: 0; z-index: 500;
  height: 56px; background: var(--blur-bg);
  -webkit-backdrop-filter: saturate(4) blur(18px);
  backdrop-filter: saturate(4) blur(18px);
  border-bottom: 1px solid transparent;
  transition: box-shadow .15s, border-color .15s;
}
/* 滚动后才分层：静止时顶栏是"隐形"的，内容从它下面穿过 */
body.is-scrolled .appbar { box-shadow: 0 4px 10px rgba(116, 116, 116, .08); }
.appbar-in { height: 56px; display: flex; align-items: center; gap: 14px; }
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15.5px; color: var(--ink); }
.brand:hover { text-decoration: none; }
.brand-mark {
  width: 26px; height: 26px; border-radius: 8px; flex: none;
  background: linear-gradient(135deg, var(--brand), color-mix(in srgb, var(--brand) 52%, #fff));
  box-shadow: 0 0 8px var(--focus-30);
}
.brand-sub { font-size: 12px; color: var(--muted); font-weight: 400; }
.appbar nav { display: flex; gap: 4px; }
.navlink {
  padding: 6px 12px; border-radius: 7px; font-size: 14px; color: var(--ink-2);
}
.navlink:hover { background: var(--fill); text-decoration: none; }
.navlink.on { background: var(--focus-10); color: var(--brand-dark); font-weight: 500; }
.avatar {
  width: 26px; height: 26px; border-radius: 50%; background: var(--focus-10); color: var(--brand-dark);
  display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 12px; flex: none;
}
.popover {
  position: absolute; right: 0; top: calc(100% + 8px); width: 250px;
  background: #fff; border: 0; border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 8px; z-index: 600;
}
.popover-item { display: block; width: 100%; text-align: left; padding: 8px 10px; border-radius: 7px; background: none; border: 0; font-size: 13px; color: var(--ink-2); }
.popover-item:hover { background: var(--fill); }
.popover-sep { height: 1px; background: var(--line-2); margin: 6px 2px; }

/* ---------------- 登录页 ----------------
   结构指纹：名录式 × 素白纸 × 纯排版（不对称双栏：左「证据」右「动作」）
   1) 一整张白纸，只用 1px 竖线 + 两侧内边距分区。不用同色底差：
      --bg 与 --card 只差 1.08:1，那个区间学不出来，别在里面雕刻；
   2) 左栏不用装饰性编号，用「规格表 + 模板名录」这种可核对的信息替掉营销条目；
   3) 全页只有一条强调色（品牌红），只出现在标识、聚焦环与主按钮上；
   4) 层次靠 1px 规线，不靠投影——纸是平的。
   间距刻度：4 / 8 / 12 / 16 / 24 / 32 / 40
*/
.auth-page {
  /* 组件层令牌：全部由既有基色/语义色派生，不引入新品牌色 */
  --auth-paper: var(--card);
  --auth-rule: color-mix(in srgb, var(--ink) 12%, transparent);
  --auth-rule-soft: color-mix(in srgb, var(--ink) 7%, transparent);
  --auth-quiet: color-mix(in srgb, var(--ink) 42%, var(--muted));
  --auth-danger-ink: color-mix(in srgb, var(--danger) 70%, var(--ink));
  --auth-placeholder: color-mix(in srgb, var(--muted) 72%, var(--ink));
  /* 输入框边界：填充式在白纸上只有 1.08:1，等于"聚焦后才存在"，所以改为可辨的描边边界 */
  --auth-field-line: color-mix(in srgb, var(--ink) 55%, var(--card));
  --auth-field-line-hover: color-mix(in srgb, var(--ink) 72%, var(--card));
  --auth-on-action: var(--card);        /* 主按钮上的文字色（白） */
  --auth-pad: 16px;              /* 页面左右留白：顶栏与纸共用，保证两条左沿严格对齐 */
  --auth-dur-1: 200ms;   /* 控件反馈 */
  --auth-dur-2: 320ms;   /* 一次性入场 */
  --auth-dur-spin: 900ms;
  --auth-ease: cubic-bezier(.22, .68, .32, 1);

  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
}

/* 顶栏：只放标识与一句事实，给页面一个上沿 */
.auth-rail { border-bottom: 1px solid var(--auth-rule-soft); flex: none; }
.auth-rail-in {
  /* 1120 是纸的宽度：顶栏内容与纸的左右沿对齐，不是"大约对齐" */
  width: 100%; max-width: calc(1120px + 2 * var(--auth-pad)); margin: 0 auto;
  padding: 0 var(--auth-pad);
  height: 52px; display: flex; align-items: center; gap: 8px;
}
.auth-mark { display: inline-flex; flex: none; color: var(--brand); }
.auth-wordmark {
  font-size: 14.5px; font-weight: 600; letter-spacing: .01em; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.auth-rail-note { display: none; margin-left: auto; font-size: 12.5px; color: var(--auth-quiet); white-space: nowrap; }

.auth-main {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 24px var(--auth-pad) 32px;
}

/* 一张纸：外框 + 分区，不是一个漂浮的卡 */
.auth-sheet {
  width: 100%; max-width: 1120px;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "pitch" "side" "facts";
  background: var(--auth-paper);
  border: 1px solid var(--auth-rule);
  border-radius: var(--radius);
  overflow: hidden;
  animation: authIn var(--auth-dur-2) var(--auth-ease) both;
}
@keyframes authIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ---- 左栏上段：标题。一句话说完，不靠 <br /> 断行 ---- */
.auth-pitch { grid-area: pitch; padding: 24px 16px 0; }
.auth-h1 {
  font-size: 26px; line-height: 1.2; font-weight: 700; letter-spacing: -.01em;
  color: var(--ink); text-wrap: balance;
  max-width: 12em;   /* 收行宽：单行 11 字，任何断点都不出现"第二行更长"的参差 */
}
.auth-lead {
  margin-top: 12px; font-size: 14px; line-height: 1.75;
  color: var(--ink-2); max-width: 34em;
}

/* ---- 左栏下段：证据（规格表 + 模板名录） ---- */
.auth-facts {
  grid-area: facts; padding: 24px 16px 24px;
  /* 内容自上而下紧凑排，余量落在纸的底部（读作下边距）；
     不用 space-between —— 那会把余量全塞进两段之间，洞从底部挪到腰部 */
  display: grid; gap: 32px; align-content: start;
}

/* base.css 重置了 h/p/ul/ol，唯独漏了 dl：浏览器默认 margin 1em 会偷偷把间距顶开 */
.spec { display: grid; margin: 0; }
.spec-row {
  display: grid; grid-template-columns: 68px minmax(0, 1fr); gap: 12px;
  align-items: baseline; padding: 8px 0;
  border-top: 1px solid var(--auth-rule-soft);
}
.spec-row:last-child { border-bottom: 1px solid var(--auth-rule-soft); }
.spec-row dt { font-size: 12.5px; color: var(--auth-quiet); letter-spacing: .02em; white-space: nowrap; }
.spec-row dd { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--ink); }

.tpl { display: grid; gap: 8px; }
.tpl-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.tpl-head-title { font-size: 12.5px; font-weight: 600; color: var(--ink-2); letter-spacing: .08em; }
.tpl-head-count { font-size: 12px; color: var(--auth-quiet); font-variant-numeric: tabular-nums; }
/* 名录而非胶囊墙：两列定宽、点线引导、末条通栏收尾（7 是奇数，不留半格空位） */
.tpl-list { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 24px; }
.tpl-row {
  display: flex; align-items: baseline; gap: 8px; min-width: 0;
  /* 12px 不是 8px：2 列排版下每列只有 4 行，8px 只吸收 24px，底部仍留 82px；
     12px 让 4 行吸收 40px，底部落到 ~55px（目标 60） */
  padding: 12px 0;
}
.tpl-name { font-size: 13px; color: var(--ink); white-space: nowrap; }
/* 点线必须真正连到标签：设上限会在中间留一段空白，视觉上裂成"两簇孤立词"。
   末行不画线，所以不会出现 430px 长线那种量级问题 */
.tpl-dots { flex: 1 1 auto; min-width: 12px; height: 0; border-bottom: 1px dotted var(--auth-rule); align-self: center; }
.tpl-tag { font-size: 11.5px; color: var(--auth-quiet); white-space: nowrap; }
.tpl-row:last-child:nth-child(odd) { grid-column: 1 / -1; }
/* 通栏那条不画引导线：一条 430px 的点线是其他行的 3 倍长，像画错了 */
.tpl-row:last-child:nth-child(odd) .tpl-dots { display: none; }
/* 末行：不画线，但标签要压在名录右沿（与两列标签同一条竖线），否则右边空 400px 像少排一项 */
.tpl-row:last-child:nth-child(odd) { justify-content: space-between; gap: 8px; }

/* ---- 右栏：动作。表单区 + 条款底脚，同属右侧分区，竖线从顶贯到底 ---- */
.auth-side {
  grid-area: side; display: flex; flex-direction: column;
  background: var(--auth-paper);
  border-top: 1px solid var(--auth-rule);
}
.auth-card { padding: 24px 16px; }
.auth-h2 { font-size: 18px; font-weight: 700; letter-spacing: -.01em; color: var(--ink); }
.auth-sub { margin-top: 8px; font-size: 13px; line-height: 1.65; color: var(--ink-2); }
.auth-form { margin-top: 24px; display: grid; gap: 16px; }
/* base.css 的 .field 是 6px 缝，落到本页的 4/8 刻度上 */
.auth-form .field { gap: 8px; }

/* 白底 + 可辨描边：边界不再依赖"聚焦后才出现"的填充色 */
.auth-input {
  height: 44px; padding: 0 12px; font-size: 14px;
  background: var(--card); border-color: var(--auth-field-line);
}
.auth-input:hover, .auth-input:not(:focus):hover { border-color: var(--auth-field-line-hover); }
/* 卡密用等宽：分组的 4 段等距，肉眼能数清是不是 16 位 */
.auth-input-code {
  font-family: ui-monospace, "SFMono-Regular", Consolas, "Courier New", monospace;
  font-size: 14.5px; letter-spacing: .1em;
}
.auth-input-code::placeholder { letter-spacing: .06em; }
.auth-input::placeholder { color: var(--auth-placeholder); }

/* 聚焦：品牌描边 + 2px 外扩环，与 hover（只加深描边）明确区分 */
.auth-input:focus, .auth-input:focus-visible {
  outline: 2px solid var(--brand-dark); outline-offset: 1px;
  border-color: var(--brand-dark); background: var(--card); box-shadow: none;
}
.auth-input.err { border-color: var(--danger); }
.auth-input.err:focus, .auth-input.err:focus-visible { outline-color: var(--danger); border-color: var(--danger); }

.auth-help { font-size: 12px; line-height: 1.55; color: var(--auth-quiet); }

.auth-err-line {
  display: flex; align-items: flex-start; gap: 4px;
  font-size: 12.5px; line-height: 1.5; color: var(--auth-danger-ink);
}
.auth-err-line .auth-ico { flex: none; margin-top: 1px; }

/* 整块报错：满框 + 浅底，不用单侧彩条，状态靠图标 + 文字承载 */
.auth-alert {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 12px; border-radius: var(--radius-sm);
  background: var(--danger-soft);
  border: 1px solid color-mix(in srgb, var(--danger) 26%, transparent);
  color: var(--auth-danger-ink);
  font-size: 13px; line-height: 1.6;
}
.auth-alert .auth-ico { flex: none; margin-top: 1px; }

/* 主按钮：品牌亮红配白字只有 3.68:1，不达 AA；填色改用 --brand-dark（实测 5.42:1），
   亮红退到标识与聚焦环上。
   禁用态用"不可用"语汇：虚框 + 透明底 + 灰字，而不是一个和次级按钮同款的实心灰块。 */
.auth-submit {
  height: 48px; gap: 8px;
  font-size: 15px; font-weight: 600; letter-spacing: .02em;
  background: var(--brand-dark); border-color: var(--brand-dark); color: var(--auth-on-action);
  opacity: 1;
  transition: background var(--auth-dur-1) var(--auth-ease), border-color var(--auth-dur-1) var(--auth-ease),
    color var(--auth-dur-1) var(--auth-ease), box-shadow var(--auth-dur-1) var(--auth-ease),
    transform var(--auth-dur-1) var(--auth-ease);
}
.auth-submit:hover:not(:disabled) {
  background: color-mix(in srgb, var(--brand-dark) 78%, var(--ink));
  border-color: color-mix(in srgb, var(--brand-dark) 78%, var(--ink)); color: var(--auth-on-action); opacity: 1;
}
.auth-submit:active:not(:disabled) { box-shadow: var(--shadow-inset); transform: translateY(1px); }
.auth-submit:focus-visible { outline: 2px solid var(--brand-dark); outline-offset: 2px; }
.auth-submit:disabled, .auth-submit:disabled:hover {
  background: transparent; border: 1px dashed var(--auth-field-line); color: var(--ink-2);
  opacity: 1; cursor: not-allowed; transform: none; box-shadow: none;
}
/* 提交中：按钮此时是 disabled，但必须读出"正在校验"*/
.auth-submit[aria-busy="true"], .auth-submit[aria-busy="true"]:hover {
  background: var(--brand-dark); border: 1px solid var(--brand-dark);
  color: var(--auth-on-action); cursor: progress;
}
.auth-spinner { width: 16px; height: 16px; flex: none; animation: authSpin var(--auth-dur-spin) linear infinite; }
@keyframes authSpin { to { transform: rotate(360deg); } }

/* 提交条件：节点常驻、只换文字，高度用 min-height 锁死（删节点会让半页内容上跳） */
.auth-cta-hint {
  margin: 8px 0 0; min-height: 18px; text-align: center;
  font-size: 12px; line-height: 1.5; color: var(--auth-quiet);
}

/* 客服入口：从 PDF 模板点进来、手里还没有激活码的人是唯一会用到它的，
   所以放得很轻——不打扰正常登录，但一定看得见 */
.kefu-hint {
  margin: 10px 0 0; text-align: center;
  font-size: 12.5px; line-height: 1.6; color: var(--auth-quiet);
}
.linkbtn {
  border: 0; background: none; padding: 0; margin: 0 0 0 2px;
  color: var(--brand); font: inherit; font-weight: 500;
  text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}
.linkbtn:hover { color: var(--brand-dark); }

/* 客服弹窗 */
.kefu-modal { max-width: 380px; }
.kefu-qr {
  width: 200px; height: 200px; margin: 0 auto 16px;
  border: 1px solid var(--line-2); border-radius: 10px;
  background: #fff; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.kefu-qr img { width: 100%; height: 100%; object-fit: contain; display: block; }
.kefu-qr-empty {
  padding: 12px; text-align: center; line-height: 1.8;
  font-size: 12px; color: var(--muted);
}
.kefu-qr-empty code { font-size: 11px; background: var(--bg); padding: 2px 5px; border-radius: 4px; }
.kefu-steps {
  margin: 0; padding-left: 20px;
  font-size: 13.5px; line-height: 1.9; color: var(--ink);
}

/* ===== 手机端底部抽屉：把「规则 / 能力 / 模板」从页面里收起来 =====
   桌面端这些内容平铺在左栏，是卖点；手机上它们把登录表单之后的页面拉得很长，
   而对已经买了卡密的人来说毫无用处。所以窄屏改为按需滑出。 */
.sheet-entry, .sheet-mask, .sheet { display: none; }

@media (max-width: 680px) {
  /* 移进抽屉后，页面上不再重复展示。
     必须带 .auth-sheet 前缀提高特异性：基础样式里 .auth-terms 有 display:grid，
     且定义在本段之后，同特异性会被它反向覆盖（踩过一次）。 */
  .auth-sheet .auth-terms, .auth-sheet .auth-facts { display: none; }

  .sheet-entry {
    display: flex; align-items: center; justify-content: center; gap: 5px;
    width: 100%; margin-top: 12px; padding: 10px;
    border: 1px dashed var(--line); border-radius: 10px;
    background: #fbfcfe; color: var(--muted); font: inherit; font-size: 13px;
  }
  .sheet-entry i { font-style: normal; font-size: 11px; }

  .sheet-mask {
    display: block; position: fixed; inset: 0; z-index: 2000;
    background: rgba(15, 23, 42, .38);
    opacity: 0; pointer-events: none; transition: opacity .24s;
  }
  .sheet-mask.open { opacity: 1; pointer-events: auto; }

  .sheet {
    display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 2001;
    max-height: 82vh; overflow-y: auto;
    background: #fff; border-radius: 16px 16px 0 0;
    box-shadow: 0 -8px 30px rgba(15, 23, 42, .16);
    transform: translateY(100%);
    transition: transform .28s cubic-bezier(.4, 0, .2, 1);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .sheet.open { transform: translateY(0); }

  /* 顶部拖拽条：很多用户的第一反应是往下滑，给个视觉抓手，点它也能关 */
  .sheet-bar { display: flex; justify-content: center; padding: 10px 0 6px; }
  .sheet-bar i { width: 36px; height: 4px; border-radius: 2px; background: var(--line); }

  .sheet-body { padding: 4px 20px 26px; }
  .sheet-h { margin: 16px 0 8px; font-size: 14px; font-weight: 600; color: var(--ink); }
  .sheet-h:first-child { margin-top: 4px; }
  .sheet-count { margin-left: 6px; font-size: 12px; font-weight: 400; color: var(--muted); }
  .sheet-p { margin: 0 0 6px; font-size: 13px; line-height: 1.75; color: var(--muted); }
  .sheet .spec { margin: 0; }
  .sheet .tpl { margin-top: 0; }
}

/* 底部：真实约束条款。与表单区之间固定 32px（由 .auth-card 的下内边距给出），
   不靠 margin-top:auto —— 那样同一条分隔线在不同视口会上下漂 30px */
.auth-terms {
  flex: 1 1 auto; align-content: start;
  padding: 16px 16px 24px;
  border-top: 1px solid var(--auth-rule-soft);
  display: grid; gap: 4px;
  font-size: 12px; line-height: 1.65; color: var(--auth-quiet);
}
.auth-terms b { font-size: 12px; font-weight: 600; color: var(--ink-2); }

/* 预览页「导出 PDF 前请注意」的三步编号仍复用这条规则，勿删 */
.pitch-dot {
  width: 22px; height: 22px; border-radius: 7px; flex: none; margin-top: 2px;
  background: var(--brand-soft); color: var(--brand); display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700;
}

@media (min-width: 640px) {
  .auth-page { --auth-pad: 24px; }
  .auth-rail-in { height: 56px; }
  .auth-rail-note { display: inline; }
  .auth-main { padding: 32px var(--auth-pad) 40px; }
  .auth-pitch { padding: 32px 32px 0; }
  .auth-facts { padding: 32px 32px 32px; }
  .auth-card { padding: 32px 32px; }
  .auth-terms { padding: 16px 32px 24px; }
  .spec-row { grid-template-columns: 76px minmax(0, 1fr); }
}

/* 768–1100：双栏但收窄。名录在此区间也排单列：
   双列时每列约 153px，点线只剩 15px（比文字短，引导关系反转） */
@media (min-width: 768px) {
  .auth-sheet {
    grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr);
    grid-template-areas: "pitch side" "facts side";
    grid-template-rows: auto 1fr;
  }
  .auth-side { border-top: 0; border-left: 1px solid var(--auth-rule); }
}

@media (min-width: 900px) {
  .auth-h1 { font-size: 29px; }
}

@media (min-width: 1100px) {
  .auth-page { --auth-pad: 32px; }
  .auth-rail-in { height: 60px; }
  .auth-main { padding: 40px var(--auth-pad) 48px; }
  .auth-sheet { min-height: min(560px, calc(100vh - 178px)); }
  .auth-pitch { padding: 40px 40px 0; }
  .auth-facts { padding: 40px 40px 40px; }
  .auth-card { padding: 40px 40px 32px; }
  .auth-terms { padding: 16px 40px 24px; }
  /* 列间距 40 > 行间距 24：横竖两个断点不再等长，否则只能靠对齐线判断"换栏了" */
  .tpl-list { column-gap: 40px; }
  .auth-h1 { font-size: 32px; }
  .auth-h2 { font-size: 22px; }
  .auth-lead { font-size: 14.5px; }
}

/* 名录双列只在 >1100 成立：421 与 768 的 facts 可用宽都约 387，
   按 980 判会出现"同宽不同判"——421 双列（列宽 165、点线只剩 37–50，比它引导的标签还短），
   768 却单列。430（iPhone Pro Max 竖屏）正落在那个洞里 */
@media (max-width: 1099px) {
  .tpl-list { grid-template-columns: minmax(0, 1fr); }
  .tpl-row:last-child:nth-child(odd) { grid-column: auto; }
  /* 单列时末行不是通栏条：点线照画，并把 gap/justify 复位成与其余 6 行同一刻度 */
  .tpl-row:last-child:nth-child(odd) .tpl-dots { display: block; }
  .tpl-row:last-child:nth-child(odd) { justify-content: normal; gap: 8px; }
}

@media (max-width: 359px) {
  .auth-pitch, .auth-facts, .auth-card, .auth-terms { padding-left: 16px; padding-right: 16px; }
  .auth-h1 { font-size: 22px; }
}

@media (prefers-reduced-motion: reduce) {
  .auth-sheet { animation: none; }
  .auth-spinner { animation: none; }
  .auth-input, .auth-submit { transition: none; }
  .auth-submit:active:not(:disabled) { transform: none; }
}

/* ---------------- 工作台 ---------------- */
.page { padding: 24px 0 60px; }
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 18px; flex-wrap: wrap; }
.page-title { font-size: 21px; font-weight: 700; }
.page-desc { color: var(--muted); font-size: 13px; margin-top: 3px; }

.stat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 20px; }
.stat-card { background: #fff; border: 0; border-radius: var(--radius); padding: 14px 16px; box-shadow: var(--shadow-sm); }
.stat-card b { display: block; font-size: 22px; letter-spacing: -.3px; }
.stat-card span { font-size: 12.5px; color: var(--muted); }

.resume-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(272px, 1fr)); gap: 14px; }
/* 分页点只在窄屏出现（横滑时才有意义），桌面端网格一览无余不需要 */
.resume-dots { display: none; }
.resume-card { background: #fff; border: 0; border-radius: var(--radius); padding: 16px; display: flex; flex-direction: column; gap: 12px; box-shadow: var(--shadow-sm); transition: box-shadow .15s, transform .15s; }
.resume-card:hover { box-shadow: var(--shadow); transform: translateY(-2px); }
.resume-title { font-size: 15.5px; font-weight: 600; display: flex; align-items: center; gap: 8px; }
.rc-meta { font-size: 12px; color: var(--muted); display: flex; gap: 10px; flex-wrap: wrap; }
/* 缩略图：撑满卡片宽度，高度由 A4 比例定（宽 → 高），缩放比由 JS 按实际宽度算。
   原来写死 height:118px + scale(0.3)，只露出页面 35%，看着像预览坏了。
   width:100% 不能省：里面的 .rc-thumb-scale 是绝对定位、不撑父容器，
   没有它就只剩边框宽度（实测会塌成 2px）。 */
.rc-thumb {
  width: 100%;
  aspect-ratio: 210 / 297;
  border-radius: 8px; border: 1px solid var(--line-2); overflow: hidden;
  background: #fff; position: relative;
}
.rc-thumb-scale {
  width: 210mm; min-height: 297mm; background: #fff; transform-origin: top left; position: absolute; top: 0; left: 0;
}
.rc-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.progress { height: 5px; border-radius: 999px; background: var(--line-2); overflow: hidden; }
.progress > i { display: block; height: 100%; background: linear-gradient(90deg, var(--brand), #63a0ff); border-radius: 999px; transition: width .3s; }

/* ---------------- 编辑器 ---------------- */
/* 与 .wrap 同元素：只用 longhand，否则简写会把 .wrap 的左右 20px 内边距清成 0，窄屏就贴边了 */
.editor-shell { max-width: 780px; margin: 0 auto; padding-top: 22px; padding-bottom: 120px; }
.editor-head { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.title-input {
  border: 1px solid transparent; background: transparent; font-size: 19px; font-weight: 700;
  padding: 4px 8px; border-radius: var(--radius-sm); width: 100%; color: var(--ink);
  transition: background .15s, border-color .15s, box-shadow .15s;
  /* 去掉左侧返回链接后，靠负边距把标题文字拉回与下方卡片同一条左基准线 */
  margin-left: -8px;
}
/* 平时隐形、悬停才浮出白底：标题输入框不该抢标题本身的视觉重量 */
.title-input:hover { background: color-mix(in srgb, #fff 70%, transparent); }
.title-input:focus {
  outline: none; background: #fff; border-color: var(--focus-color);
  box-shadow: 0 0 2px 3px var(--focus-shadow);
}
.title-input::placeholder { color: var(--muted-2); font-weight: 500; }

.stepbar { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; font-size: 13px; color: var(--muted); }
.step { display: inline-flex; align-items: center; gap: 7px; }
.step i {
  width: 21px; height: 21px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-style: normal; background: #e8ecf3; color: var(--muted); font-weight: 600;
}
.step.on i { background: var(--brand); color: #fff; }
/* 步骤条右侧只放进度信息 */
.stepbar-right { display: flex; align-items: center; gap: 10px; }
.audit-trigger { gap: 6px; }
.audit-count {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11.5px; font-weight: 600; color: #fff; background: var(--muted-2);
}
.audit-count.error { background: var(--danger); }
.audit-count.warn { background: #d98516; }
.audit-count.tip { background: var(--muted-2); }
.audit-count.ok { background: var(--ok); }

/* 体检入口在底部操作条里：比主 CTA 轻一档，不抢「下一步」 */
.bottom-audit { background: #fff; }

/* 体检弹窗 */
.audit-head { display: inline-flex; align-items: baseline; gap: 6px; }
.audit-score { font-size: 20px; color: var(--ok); letter-spacing: -.02em; }
.audit-score.low { color: var(--danger); }
.audit-list { display: grid; gap: 2px; margin: 0 -6px; }
.audit-row {
  display: flex; gap: 10px; align-items: flex-start; text-align: left;
  padding: 10px 8px; border: 0; border-radius: var(--radius-sm);
  background: transparent; transition: background .15s;
}
.audit-row:hover { background: var(--fill); }
.audit-row b { display: block; font-size: 13.5px; font-weight: 600; margin-bottom: 3px; color: var(--ink); }
.audit-row .text-sm { display: block; line-height: 1.55; }
.audit-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; margin-top: 7px; }
.audit-dot.error { background: var(--danger); }
.audit-dot.warn { background: #d98516; }
.audit-dot.tip { background: var(--muted-2); }
.audit-go { font-size: 12px; color: var(--brand); flex: none; margin-top: 2px; opacity: .5; transition: opacity .15s; }
.audit-row:hover .audit-go { opacity: 1; }
.audit-row:hover b { color: var(--brand); }
.audit-ok { display: grid; gap: 4px; padding: 8px 0 4px; }

/* 跳转定位：滚动时避开吸顶栏，落点闪一下 */
.sec-card { scroll-margin-top: 74px; }
.sec-card.flash { box-shadow: 0 0 0 3px var(--focus-30), var(--shadow); }

.step.on { color: var(--brand-dark); font-weight: 500; }
.step-line { flex: 1; height: 1px; background: var(--line); }

.sec-card { background: #fff; border: 0; border-radius: var(--radius); margin-bottom: 12px; overflow: hidden; box-shadow: var(--shadow-sm); }
.sec-card.hidden-sec { opacity: .62; }
.sec-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; background: #fbfcfe; border-bottom: 1px solid var(--line-2); }
.sec-head.off { border-bottom-color: transparent; }
.sec-title { font-size: 14.5px; font-weight: 600; }
.sec-tools { display: flex; gap: 5px; align-items: center; }
.sec-body { padding: 14px; display: grid; gap: 14px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 560px) { .grid-2 { grid-template-columns: 1fr; } }

.item-row { border: 0; border-radius: var(--radius-sm); padding: 12px; background: var(--bg); }
/* 灰底容器里的控件必须翻白：填充式输入框的前提是「容器比控件浅」，同色会糊成一片 */
.item-row .input, .item-row .textarea, .item-row .select { background: var(--card); }
.item-row .input:hover, .item-row .textarea:hover, .item-row .select:hover { border-color: var(--focus-30); }
.item-row + .item-row { margin-top: 10px; }
.item-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; gap: 8px; }
.item-idx { font-size: 12.5px; color: var(--muted); font-weight: 500; }
.item-body { display: grid; gap: 12px; }
.add-btn {
  width: 100%; margin-top: 10px; height: 38px; border: 1px dashed #c3cddc; border-radius: 10px;
  background: #fbfcfe; color: var(--brand); font-size: 13.5px; font-weight: 500;
}
.add-btn:hover { background: var(--brand-soft); border-color: #9dbcf5; }

/* ---------- 自定义模块 ---------- */
/* 标题变成输入框：用户自己起名，但视觉上仍要像标题而不是表单字段，
   所以平时无边框、悬停才出边界，聚焦时才变成正常的输入框 */
.sec-title-input {
  font-size: 14.5px; font-weight: 600; color: inherit;
  border: 1px solid transparent; border-radius: 6px;
  background: transparent; padding: 3px 7px; margin-left: -7px;
  width: 180px; max-width: 58%;
}
.sec-title-input::placeholder { color: var(--muted); font-weight: 400; }
.sec-title-input:hover { border-color: var(--line); }
.sec-title-input:focus { outline: none; border-color: var(--brand); background: #fff; }

.add-module {
  background: #fff; border-radius: var(--radius); box-shadow: var(--shadow-sm);
  padding: 14px; margin-bottom: 12px;
}
.add-module-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.add-module-head b { font-size: 14px; font-weight: 600; }
.add-module-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip-btn {
  height: 32px; padding: 0 12px; border-radius: 999px;
  border: 1px dashed #c3cddc; background: #fbfcfe; color: var(--brand);
  font-size: 13px; font-weight: 500;
}
.chip-btn:hover:not(:disabled) { background: var(--brand-soft); border-color: #9dbcf5; }
.chip-btn:disabled { color: var(--muted); border-color: var(--line); cursor: not-allowed; }
.add-module-row { display: flex; gap: 8px; margin-top: 10px; }
.add-module-row .input { flex: 1; min-width: 0; }

/* ---------- 用户反馈 ---------- */
/* 顶栏入口：平时低调（灰字），悬停才变品牌色，不跟「我的简历」抢注意力 */
.feedback-entry { position: relative; color: var(--muted); }
.feedback-entry:hover { color: var(--brand); background: var(--brand-soft); }
/* 有未读回复时的小红点 */
.fb-dot {
  position: absolute; top: 4px; right: 4px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--danger);
}

/* 弹窗内的两个页签 */
.fb-tabs { display: flex; gap: 20px; }
.fb-tab {
  position: relative; border: 0; background: none; padding: 0;
  font-size: 14px; font-weight: 500; color: var(--muted);
}
.fb-tab.on { color: var(--brand); }
.fb-tab-dot {
  position: absolute; top: -1px; right: -9px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--danger);
}

/* 我的反馈：用户侧列表 */
.fb-mine-list { display: grid; gap: 10px; }
.fb-mine-item { border: 1px solid var(--line-2); border-radius: var(--radius-sm); padding: 12px; }
.fb-mine-top { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.fb-mine-content {
  font-size: 13.5px; line-height: 1.6; color: var(--ink);
  white-space: pre-wrap; word-break: break-word;
}
.fb-empty { text-align: center; padding: 26px 0; display: grid; gap: 10px; justify-items: center; }

/* 平台回复：两侧共用，未读时底色更暖一点 */
.fb-reply {
  margin-top: 10px; padding: 10px 12px; border-radius: var(--radius-sm);
  background: var(--brand-soft); border-left: 3px solid var(--brand);
}
.fb-reply b { display: block; font-size: 12px; color: var(--brand-dark); margin-bottom: 4px; }
.fb-reply p {
  font-size: 13.5px; line-height: 1.6; margin: 0;
  white-space: pre-wrap; word-break: break-word;
}
.fb-reply.is-unread { background: #fff4ee; }

/* 管理端回复框 */
.fb-reply-box { display: grid; grid-template-columns: 1fr auto; gap: 8px; align-items: end; margin-top: 10px; }
.fb-reply-box .textarea { min-height: 58px; }
@media (max-width: 560px) { .fb-reply-box { grid-template-columns: 1fr; } }

/* 管理后台页签 */
.admin-tabs { display: flex; gap: 4px; margin-bottom: 14px; border-bottom: 1px solid var(--line-2); }
.admin-tab {
  position: relative; border: 0; background: none;
  padding: 8px 14px 10px; margin-bottom: -1px;
  font-size: 14px; font-weight: 500; color: var(--muted);
  border-bottom: 2px solid transparent;
}
.admin-tab:hover { color: var(--ink); }
.admin-tab.on { color: var(--ink); border-bottom-color: var(--brand); }
.tab-badge {
  display: inline-block; margin-left: 6px; min-width: 17px; height: 17px; line-height: 17px;
  padding: 0 5px; border-radius: 9px;
  background: var(--danger); color: #fff;
  font-size: 11px; font-style: normal; text-align: center; font-weight: 500;
}
/* 中性计数（发卡总数这种），不用红色警示 */
.tab-badge-neutral { background: var(--fill); color: var(--muted); }

/* 发卡记录 */
.dispatch-form { padding: 12px; background: var(--bg); border-radius: var(--radius-sm); }
.dispatch-row { display: grid; grid-template-columns: 1fr 120px auto; gap: 8px; }
.dispatch-code {
  margin-top: 12px; padding: 12px; border-radius: var(--radius-sm);
  background: #e8f7ef; border: 1px solid #b7e4c9;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.dispatch-code code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 15px; font-weight: 600; letter-spacing: .04em;
  color: var(--ok); background: #fff; padding: 4px 10px; border-radius: 6px;
}
@media (max-width: 560px) { .dispatch-row { grid-template-columns: 1fr; } }

/* chip 选中态：实心品牌色，一眼看出选了哪个类型 */
.chip-btn.on { background: var(--brand); border: 1px solid var(--brand); color: #fff; }
.chip-btn.on:hover:not(:disabled) { background: var(--brand-dark); border-color: var(--brand-dark); }

.fb-modal { max-width: 520px; }
.fb-types { display: flex; gap: 8px; flex-wrap: wrap; }
.fb-count { display: block; text-align: right; margin-top: 4px; }
.fb-ok { text-align: center; padding: 20px 0 8px; }
.fb-ok b { display: block; font-size: 15px; font-weight: 500; margin-bottom: 6px; }

/* 管理后台：待处理反馈数变红，一眼看到有事要做 */
.stat-alert b { color: var(--danger); }

.fb-list { display: grid; gap: 10px; }
.fb-item {
  border: 1px solid var(--line-2); border-radius: var(--radius-sm);
  padding: 12px; background: #fff;
}
/* 已处理的整块退后，扫视时不会和待处理混在一起 */
.fb-item.done { opacity: .55; background: var(--bg); }
.fb-item-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.fb-item-body {
  font-size: 13.5px; line-height: 1.65; color: var(--ink);
  white-space: pre-wrap; word-break: break-word;
}
.fb-item-foot { margin-top: 8px; }

.links-row { display: grid; grid-template-columns: .9fr 1.6fr auto; gap: 8px; align-items: center; }
@media (max-width: 560px) { .links-row { grid-template-columns: 1fr; } }

.photo-box { display: flex; gap: 14px; align-items: flex-start; flex-wrap: wrap; }
/* 照片开关与照片模块同组，靠右对齐；窄屏换行到下方 */
.photo-switch { margin-left: auto; max-width: 210px; }
.photo-preview.is-off { opacity: .45; }
.photo-preview {
  width: 84px; height: 112px; border: 0; border-radius: var(--radius-sm); overflow: hidden;
  background: var(--fill); display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: 12px; flex: none;
}

.autosave {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 78px; z-index: 400;
  font-size: 12.5px; color: var(--muted); background: rgba(255,255,255,.94); border: 1px solid var(--line);
  padding: 5px 12px; border-radius: 999px; box-shadow: var(--shadow-sm);
}
.bottombar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 450;
  background: rgba(255,255,255,.86); -webkit-backdrop-filter: saturate(4) blur(18px); backdrop-filter: saturate(4) blur(18px); border-top: 1px solid var(--line-2);
  padding: 10px 0; padding-bottom: calc(10px + env(safe-area-inset-bottom));
}
/* 挤在右边不好看：底部条只有「提示 + 状态 + 主按钮」，整组水平居中 */
.bottombar-in { display: flex; align-items: center; justify-content: center; gap: 12px; }

/* ---------------- 预览页 ---------------- */
.preview-shell { padding: 12px 0 12px; }
.tpl-bar { display: flex; gap: 8px; overflow-x: auto; padding: 4px 0 10px; -webkit-overflow-scrolling: touch; }
.tpl-chip {
  flex: none; text-align: left; padding: 9px 13px; border-radius: var(--radius); border: 1px solid transparent;
  background: var(--fill); min-width: 150px; transition: background .15s, color .15s;
}
.tpl-chip b { display: block; font-size: 13.5px; }
.tpl-chip span { font-size: 11.5px; color: var(--muted); }
.tpl-chip:hover { background: #e8eaed; }
.tpl-chip.on { background: var(--focus-10); }
.tpl-chip.on b { color: var(--brand-dark); }

/* 模板选择（PC 侧栏版）：262px 栏宽放 7 个，两列紧凑格子比长条更省高度 */
.tpl-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; }
.tpl-opt {
  min-width: 0; text-align: left; padding: 6px 8px; border-radius: var(--radius-sm);
  border: 1px solid transparent; background: var(--fill); transition: background .15s, color .15s;
}
.tpl-opt b {
  display: block; font-size: 12.5px; font-weight: 600; line-height: 1.35; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tpl-opt span {
  display: block; font-size: 11px; line-height: 1.35; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tpl-opt:hover { background: #e8eaed; }
.tpl-opt.on { background: var(--focus-10); }
.tpl-opt.on b { color: var(--brand-dark); }
/* 7 是奇数：最后一个通栏，避免右下角空一格 */
.tpl-grid .tpl-opt:last-child:nth-child(odd) { grid-column: 1 / -1; }
/* 只在下面一行说明「当前选中」的风格与适合人群，比每格都挂两行文字省一半高度 */
.tpl-hint { margin-top: 8px; line-height: 1.45; }
/* 模板入口按屏幕宽度二选一：PC 用侧栏，窄屏用顶部横向条（侧栏此时是抽屉） */
@media (min-width: 901px) {
  .preview-shell .tpl-bar { display: none; }
  .preview-shell .preview-head { display: none; }   /* 整条收进右侧栏 */
}
@media (max-width: 900px) {
  .tpl-picker-card { display: none; }
  .preview-shell .side-head { display: none; }       /* 窄屏改用顶部操作条（.side-head 基础样式在本块之后，必须提特异性） */
}

.preview-stage { display: flex; gap: 18px; align-items: flex-start; }
/* 画布不再做白色卡片，也**不再自己滚动**：
   整页适配时一张 A4 就该完整落地，不需要滚动条；
   需要看细节时放大，改由页面主滚动条接管 —— 只有一条，不会出现"内层滚到底、外层才动"的双滚动条。
   min-height 保证纸张不满屏时仍撑住版面高度，纸张靠 margin:auto 居中（溢出时 auto 自动归零，不会裁掉顶部）。 */
.preview-canvas {
  flex: 1; min-width: 0; background: transparent; border: 0; border-radius: 0;
  /* 下边距要容得下纸张投影（0 10px 26px -6px 最多外扩 30px），
     否则 overflow 会把它切成一条硬边 */
  padding: 20px 20px 32px; min-height: calc(100vh - 148px);
  display: flex;
  /* 默认（整页/适应宽度）纸张不溢出，不会出现滚动条。
     手动放大后纸张必然横向溢出 —— 必须允许横向滚动，否则右边一截会被侧栏盖住，
     用户既看不到也拖不出来。纵向仍交给页面主滚动条（画布没有 max-height）。 */
  overflow-x: auto;
  overflow-y: hidden;
}
/* 放大状态：空白处显示"缩小"光标，提示点一下能退回去 */
.preview-canvas.is-zoomed { cursor: zoom-out; }
.preview-canvas.is-zoomed .paper-frame { cursor: auto; }
/* 原生横向滚动条藏在纸张下面，放大后常常滚出视口 → 不用它，改用底部常驻的那条 */
.preview-canvas::-webkit-scrollbar { height: 0; width: 0; }

/* 底部常驻横向滚动条：fixed 在视口底，宽度/位置由 JS 对齐到画布，
   只在纸张横向溢出时出现（滚动、缩放、拖拽都双向同步） */
.canvas-hbar {
  position: fixed; bottom: 26px; height: 26px; z-index: 60;
  border-radius: 999px;
  /* 轮廓用 box-shadow 而不是 border：border 会吃掉内容高，滑块就变细了 */
  background: rgba(255, 255, 255, .96);
  box-shadow:
    0 0 0 1px rgba(16, 24, 40, .1),
    inset 0 0 0 1px rgba(255, 255, 255, .8),
    0 4px 12px rgba(16, 24, 40, .14);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  cursor: pointer;
}
/* 轨道底色再垫一层浅灰，白纸上也能看出这是一条"可拖的槽" */
/* 垂直 10px = (26 - 6) / 2 → 槽高 6px；水平各留 2.5% → 槽宽 = 轨道 95%。
   滑块扫过处深色，未扫到处是灰色槽 */
.canvas-hbar::before {
  content: ""; position: absolute; inset: 10px 2.5%; border-radius: 999px;
  background: rgba(20, 24, 31, .07);
}
.canvas-hbar-thumb {
  position: absolute; top: 10px; bottom: 10px; border-radius: 999px;
  background: #8290a3; transition: background .15s;
  box-shadow: 0 1px 2px rgba(16, 24, 40, .18);
}
.canvas-hbar:hover .canvas-hbar-thumb { background: #627084; }
.paper-frame {
  position: relative; flex: none; margin: auto;
  /* 参考 zibll 的文章模块（.main-shadow）：无方向柔光 + spread 扩范围，
     不做向下偏移 —— 纸张是"平铺浮在灰底上"，不是"被灯从上方照出长影" */
  box-shadow: 0 0 12px 2px rgba(116, 116, 116, .12);
}
.paper-frame > .cv-page { position: absolute; top: 0; left: 0; }

/* 侧栏不吸顶、不做内部滚动：任何额外的滚动条都是干扰。
   默认「整页」模式下页面根本不滚动，吸顶也没意义 */
.side-panel { width: 262px; flex: none; display: grid; gap: 10px; align-self: flex-start; }

/* 侧栏顶部的简历头：只留「返回编辑 ←→ 下载」一行操作。
   简历名不再显示 —— 用户是从工作台点进这份简历的，页面里再写一遍名字是零信息，
   却占着侧栏最贵的首屏位置。语义上仍保留一个视觉隐藏的 h1，屏幕阅读器和浏览器
   标签页不会丢上下文 */
.side-head { display: grid; }
.side-head-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.side-back { font-size: 12.5px; color: var(--ink-2); }
.side-back:hover { color: var(--brand); }
.side-head-top .btn { flex: none; }

/* 分段控件：整页 / 适应宽度 */
.seg { display: flex; gap: 3px; padding: 3px; background: var(--fill); border-radius: var(--radius-sm); }
.seg-btn {
  flex: 1; padding: 5px 8px; border: 0; border-radius: 6px; background: transparent;
  font-size: 12.5px; color: var(--ink-2); transition: all .16s; white-space: nowrap;
}
.seg-btn { border-radius: 4px; }
.seg-btn:hover { color: var(--ink); }
.seg-btn.on { background: #fff; color: var(--brand-dark); font-weight: 600; box-shadow: 0 1px 3px rgba(116,116,116,.14); }

/* 卡片内的分区线：把「正文字号」和「预览比例」并进一张卡，省掉一整个卡片的
   标题、内边距和栏间距（约 70px），又不至于挤成一片分不清 */
.card-sep { height: 1px; background: var(--line-2); margin: 12px -14px; }
.card-sub {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  font-size: 12.5px; font-weight: 600; color: var(--ink-2); margin-bottom: 7px;
}
.card-sub-val { font-weight: 400; font-size: 11.5px; color: var(--muted); }
.card-sub-link { font-weight: 400; font-size: 11.5px; color: var(--brand); cursor: pointer; }
.card-sub-link:hover { text-decoration: underline; }

/* 折叠卡：导出说明平时收起来，给侧栏省下 80px 高度 */.tip-card summary {
  cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between;
  font-size: 13.5px; font-weight: 600; color: var(--ink);
}
.tip-card summary::-webkit-details-marker { display: none; }
.tip-card summary::after { content: "＋"; color: var(--muted); font-weight: 500; font-size: 12px; }
.tip-card[open] summary::after { content: "－"; }
.tip-card[open] summary { margin-bottom: 8px; }
.panel-card { background: #fff; border: 0; border-radius: var(--radius); padding: 14px; box-shadow: var(--shadow-sm); }
.panel-card h4 { font-size: 13.5px; margin-bottom: 10px; }
.kv { display: flex; justify-content: space-between; font-size: 12.5px; color: var(--ink-2); padding: 3px 0; }
.kv b { font-weight: 600; }
.zoom-row { display: flex; align-items: center; gap: 8px; }
.zoom-row input[type="range"] { flex: 1; accent-color: var(--brand); }

@media (max-width: 900px) {
  /* 简历优先：竖排时画布在上、设置在下。
     原来是 column-reverse（设置压在上面），侧栏一高就把简历挤到屏幕外只剩个小图 */
  .preview-stage { flex-direction: column; }
  .side-panel { width: 100%; grid-template-columns: 1fr 1fr; }
  /* 竖排后高度由内容决定，不再撑满一屏。
     ⚠️ 必须显式 width:100%：stage 是 align-items:flex-start，竖排时画布宽度会退化成"纸宽"，
     而纸宽又由 autoFitScale 读画布宽度算出 —— 互相喂，最后收敛成一张邮票 */
  .preview-canvas { min-height: 0; padding: 20px 14px; border-radius: 0; width: 100%; align-self: stretch; }
}
@media (max-width: 640px) {
  .side-panel { grid-template-columns: 1fr; }
}

/* ---------------- 管理后台 ---------------- */
.admin-card { background: #fff; border: 0; border-radius: var(--radius); box-shadow: var(--shadow-sm); }
.admin-head { padding: 14px 16px; border-bottom: 1px solid var(--line-2); display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.admin-body { padding: 14px 16px; }
.table-scroll { overflow-x: auto; }
table.grid { width: 100%; border-collapse: collapse; font-size: 13px; }
table.grid th, table.grid td { text-align: left; padding: 9px 10px; border-bottom: 1px solid var(--line); white-space: nowrap; }
table.grid th { color: var(--muted); font-weight: 500; font-size: 12.5px; background: var(--fill); }
table.grid tbody tr:hover { background: var(--fill); }
.code-cell { font-family: "SFMono-Regular", Consolas, monospace; letter-spacing: .4px; }
.filter-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.filter-row .input, .filter-row .select { width: auto; min-width: 130px; }

.gen-box { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.codes-out {
  margin-top: 12px; max-height: 210px; overflow: auto; padding: 10px 12px; border-radius: 8px;
  background: #0f1720; color: #d7e3f4; font-family: Consolas, monospace; font-size: 12.5px; line-height: 1.85; white-space: pre-wrap;
}

/* ============================================================ 移动端适配
   断点：<=900（平板竖屏）、<=680（手机）、<=420（小屏手机）
   原则：可收缩的地方必须写 min-width:0 / flex:none，否则 flex 子项会被压成逐字竖排。
============================================================== */

/* ---------------- 顶栏 ---------------- */
.appbar-in { min-width: 0; }
.brand { white-space: nowrap; flex: none; }
.userbtn { min-width: 0; }
.userbtn > span:last-child { min-width: 0; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 移动端专属元素的桌面默认态（必须写在媒体查询之前，否则会覆盖媒体查询里的显示规则） */
.panel-toggle { display: none; }
.bottom-status { display: none; }

@media (max-width: 900px) {
  .stat-grid { grid-template-columns: repeat(3, 1fr); gap: 10px; }
  .stat-card { padding: 12px 14px; }
  .stat-card b { font-size: 20px; }
}

@media (max-width: 680px) {
  .wrap { padding: 0 14px; }
  .appbar, .appbar-in { height: 52px; }
  .appbar-in { gap: 8px; }
  .brand-sub { display: none; }
  .appbar nav { display: none; }              /* 收进头像下拉，避免竖排挤压 */
  .userbtn { padding: 3px; border-color: transparent; background: transparent; }
  .userbtn > span:last-child { display: none; }  /* 手机上只留头像，邮箱收进下拉 */
  .page { padding-top: 16px; padding-bottom: 48px; }
  .page-head { margin-bottom: 14px; }
  .page-title { font-size: 19px; }
  .stat-grid { gap: 8px; }
  .stat-card { padding: 10px 12px; }
  .stat-card b { font-size: 18px; }
  .stat-card span { font-size: 11.5px; }
  .resume-card:hover { transform: none; }
  /* 简历列表改成横向滑动，一次一张：
     - scroll-snap 让松手后自动吸附到整张，不需要 JS 接管手势
     - 卡片留 88% 宽，右边露出下一张的一条边，提示"还能滑"
     - 负边距 + 同值 padding，让卡片能贴到屏幕边缘，而不是被 .wrap 的 14px 困住 */
  .resume-grid {
    display: flex;
    grid-template-columns: none;
    gap: 12px;
    margin-inline: -14px;
    padding-inline: 14px;
    scroll-padding-inline: 14px;
    overflow-x: auto;
    overscroll-behavior-x: contain;  /* 滑到头不带着整页左右晃 */
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .resume-grid::-webkit-scrollbar { display: none; }
  .resume-card {
    flex: 0 0 88%;
    scroll-snap-align: start;
  }
  /* 只有一份时占满，不留"右边还有"的假象 */
  .resume-card:only-child { flex-basis: 100%; }

  /* 横滑分页点：滑到第几张。选中态拉长成小胶囊，比单纯变色更容易看出位置 */
  .resume-dots { display: flex; justify-content: center; gap: 6px; margin-bottom: 10px; }
  .resume-dots i {
    width: 6px; height: 6px; border-radius: 3px;
    background: var(--line); transition: width .2s, background .2s;
  }
  .resume-dots i.on { width: 16px; background: var(--brand); }
  /* 缩略图的高度由 aspect-ratio 决定，不再写死高度 —— 写死就会重新变成裁切 */

  /* ---- 编辑器 ---- */
  .editor-shell { padding-top: 14px; padding-bottom: 130px; }
  .editor-head { gap: 8px; margin-bottom: 12px; }
  .title-input { font-size: 16px; padding: 4px 6px; }
  .stepbar { gap: 6px; font-size: 12px; flex-wrap: wrap; }
  .stepbar .step i { width: 18px; height: 18px; font-size: 11px; }
  .stepbar .step-line { min-width: 8px; }
  .stepbar > .grow { display: none; }         /* 完整度移到下方提示，避免一行塞爆 */
  .stepbar-right { width: 100%; order: 9; justify-content: flex-end; }
  .sec-head { padding: 10px 12px; gap: 6px; }
  .sec-body { padding: 12px; gap: 12px; }
  .sec-tools { gap: 4px; }
  .icobtn { width: 28px; height: 28px; }
  .autosave { display: none; }                /* 不再浮在表单上遮挡输入框 */
  .bottom-audit { flex: none; padding: 0 12px; height: 40px; }
  .bottombar { padding-top: 8px; padding-bottom: calc(8px + env(safe-area-inset-bottom)); }
  .bottombar-in { gap: 8px; }
  .bottombar-in .btn { height: 40px; }
  .bottombar-in .bottom-hint { display: none; }
  .bottombar-in .bottom-status { display: inline; font-size: 12px; color: var(--muted); }
  .bottombar-in .btn-primary { flex: 1 1 auto; min-width: 0; }

  /* ---- 预览 ---- */
  .preview-shell { padding-top: 12px; padding-bottom: 28px; }
  /* 简历名去掉后只剩两组操作，够一行就别占两行 */
  .preview-head { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px; }
  .preview-head .row { width: auto; min-width: 0; }
  .preview-head .page-title {
    font-size: 15px; flex: 1 1 auto; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .preview-head .btn { flex: none; }
  /* 操作行靠右：主按钮（下载）落在右下角，和桌面端侧栏里它的位置一致 */
  .preview-head .row:last-child { justify-content: flex-end; }
  .tpl-chip { min-width: 128px; padding: 8px 11px; }
  .tpl-chip b { font-size: 13px; }

  /* 关键：竖排时必须 stretch，否则画布按 A4 纸宽撑开整页。
     手机上不按「整页」缩：屏太矮，整页适配会把字压到看不清，改为适应宽度 + 页面纵向滚动 */
  .preview-stage { flex-direction: column; align-items: stretch; gap: 12px; }
  .preview-canvas {
    display: block; width: 100%; align-self: stretch;
    padding: 16px 12px; min-height: 0; border-radius: 0;
  }
  .side-panel { width: 100%; }
  .side-panel { display: none; }              /* 默认收起，点「排版设置」展开 */
  .side-panel.is-open { display: grid; }
  .panel-toggle { display: inline-flex; }

  /* ---- 管理后台 ---- */
  .admin-head, .admin-body { padding: 12px; }
  .gen-box { gap: 8px; }
  .gen-box .input { flex: 1 1 120px; min-width: 0 !important; width: auto; }
  .gen-box .btn { flex: none; }
  .filter-row .input, .filter-row .select { flex: 1 1 45%; min-width: 0; }
  .stat-card span { line-height: 1.35; }
  table.grid { font-size: 12.5px; }
  table.grid th, table.grid td { padding: 8px; }
}

@media (max-width: 420px) {
  .stat-card { padding: 9px 10px; }
  .stat-card b { font-size: 17px; }
  .stat-card span { font-size: 11px; }
  .resume-title { font-size: 14.5px; }
  .rc-actions .btn { flex: 1 1 auto; }
}

@media (max-width: 360px) {
  .stat-grid { grid-template-columns: 1fr 1fr; }
  .stat-card:nth-child(3) { display: none; }  /* 极窄屏优先保住前两个关键指标 */
}

/* ============================================================ 新建简历：选岗位 + 预设预览 */
.occ-group { margin-bottom: 20px; }
.occ-group-title {
  font-size: 13px; font-weight: 600; color: var(--ink-2); letter-spacing: .04em;
  margin-bottom: 10px; padding-left: 2px;
  display: flex; align-items: center; gap: 8px;
}
.occ-group-title::after { content: ""; flex: 1; height: 1px; background: var(--line); }

.occ-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(212px, 1fr)); gap: 12px; }
.occ-card {
  text-align: left; padding: 14px; border-radius: var(--radius);
  border: 1px solid transparent; background: #fff;
  display: flex; flex-direction: column; gap: 6px;
  box-shadow: var(--shadow-sm);
  transition: box-shadow .15s, transform .15s;
}
.occ-card:hover { box-shadow: var(--shadow); transform: translateY(-2px); }
.occ-card:disabled { opacity: .55; cursor: not-allowed; transform: none; box-shadow: none; }
.occ-card.on { border-color: var(--brand); background: var(--brand-soft); box-shadow: 0 0 0 3px var(--focus-10); }
.occ-name { font-size: 15px; font-weight: 600; color: var(--ink); }
.occ-desc { font-size: 12.5px; color: var(--muted); line-height: 1.55; }
.occ-tags { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
.occ-tag {
  font-size: 11.5px; padding: 2px 8px; border-radius: 999px;
  background: #f1f4f9; color: var(--ink-2); border: 1px solid var(--line-2);
}
.occ-card.on .occ-tag { background: #fff; border-color: #cfe0fb; color: var(--brand-dark); }

.occ-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 26px; padding-top: 16px; border-top: 1px solid var(--line);
  flex-wrap: wrap;
}

.btn.disabled, a.btn[aria-disabled="true"] { opacity: .5; pointer-events: none; }

.preset-hint { margin-bottom: 12px; }
.preset-hint .row-between { gap: 10px; align-items: flex-start; }

.preset-list { display: grid; gap: 4px; font-size: 12.5px; color: var(--ink-2); }
.preset-list li { position: relative; padding-left: 14px; }
.preset-list li::before { content: "·"; position: absolute; left: 4px; color: var(--brand); font-weight: 700; }

/* 新建页：桌面不显示底部操作条（用右侧栏按钮） */
.newbar { display: none; }

@media (max-width: 680px) {
  .occ-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
  .occ-card { padding: 12px 11px; }
  .occ-name { font-size: 14px; }
  .occ-desc { font-size: 11.5px; }
  .occ-tag { font-size: 11px; padding: 1px 7px; }
  .occ-foot { margin-top: 18px; }
  .occ-foot .text-sm { width: 100%; }

  /* 新建预览：底部固定操作条 */
  .newbar {
    display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 450;
    background: rgba(255,255,255,.96); backdrop-filter: blur(8px);
    border-top: 1px solid var(--line);
    padding-top: 8px; padding-bottom: calc(8px + env(safe-area-inset-bottom));
  }
  .newbar .btn { height: 40px; }
  .newbar .btn-primary { flex: 1 1 auto; min-width: 0; }
  /* 给固定条留出空间，避免遮住 A4 底部 */
  .preview-stage { padding-bottom: 76px; }
}

@media (max-width: 360px) {
  .occ-grid { grid-template-columns: 1fr; }
}

/* ============================================================ 回收站 */
.trash-list { display: grid; gap: 10px; }
.trash-row {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px;
  border: 0; border-radius: var(--radius-sm); background: var(--bg);
}
.trash-title { font-size: 14px; font-weight: 600; margin-bottom: 3px; color: var(--ink); }
.trash-expiring { color: var(--danger); font-weight: 500; }

@media (max-width: 680px) {
  .trash-row { flex-wrap: wrap; }
  .trash-row > .row { width: 100%; }
  .trash-row > .row .btn { flex: 1 1 auto; }
}

/* 删除方式选择 */
.del-options { display: grid; gap: 10px; margin-top: 14px; }
.del-opt {
  text-align: left; padding: 14px; border-radius: var(--radius-sm); border: 1px solid transparent;
  background: var(--bg); display: grid; gap: 3px; transition: border-color .15s, background .15s;
}
.del-opt:hover { border-color: var(--brand); background: var(--brand-soft); }
.del-opt b { font-size: 14px; }
.del-opt span { font-size: 12.5px; color: var(--muted); }
.del-opt.danger:hover { border-color: var(--danger); background: var(--danger-soft); }
.del-opt.danger b { color: var(--danger); }


@media (max-width: 560px) {
  .photo-switch {
    margin-left: 0; width: 100%; max-width: none;
    padding-top: 10px; border-top: 1px dashed var(--line);
  }
}
