/* 关键词作战表 · 前台共用样式
 *
 * 施工依据：项目根目录 DESIGN.md（由 npx getdesign@latest add notion 生成的 Notion 设计规范）。
 * 落地口径见 docs/03「2026-09-25 阶段 7 前台骨架定案」：只取 Notion 的底子——
 * 暖白纸底、近黑正文、1px 细线卡片、8px 间距体系、Inter 字体，
 * 以及那一个 Notion 蓝只用在提交按钮与链接上；报告表格原有配色不动。
 *
 * 不引任何外链 CDN 与网络字体（原文任务书：别引国内不稳的外链 CDN）。
 * Inter 装了就用，没装就回落到系统字体——DESIGN.md 明说 NotionInter 可直接用 Inter 替代。
 */

:root {
  /* 颜色（DESIGN.md · Colors） */
  --primary: #0075de;
  --primary-active: #005bab;
  --on-primary: #ffffff;
  --canvas: #ffffff;
  --canvas-soft: #f6f5f4;   /* 签名色：暖白纸底 */
  --surface: #ffffff;
  --ink: rgba(0, 0, 0, 0.95);
  --ink-secondary: #31302e;
  --ink-muted: #615d59;
  --ink-faint: #a39e98;
  --hairline: #e6e6e6;
  --input-border: #dddddd;
  /* 语义色：DESIGN.md 说 Notion 自身没有专门的语义色阶，状态由贴纸色板承担。
     这里从贴纸色板里取，绿=成功、橙=进行中、红用于失败（贴纸色板没有红，
     取 accent-orange-deep 的同族深色，保证对比度 ≥ 4.5:1）。 */
  --ok: #1aae39;
  --ok-soft: #eaf7ed;
  --warn: #dd5b00;
  --warn-soft: #fdf0e7;
  --bad: #b3261e;
  --bad-soft: #fbeceb;
  --info-soft: #e7f1fb;

  /* 装饰用色：Notion 蓝的浅深阶（2026-09-25 用户定）。
     第一版用了 DESIGN.md 的贴纸色板（紫/粉/橙）加深靛蓝夜色带 #213183，
     用户看过预览后指出两个问题：夜色带「太沉」，且它与按钮的 Notion 蓝不同色相、互相打架；
     贴纸色与那个底色也不协调。改法：装饰一律用 primary 同一色相的浅深阶，
     同族配色不可能打架；「结构性强调色只有 Notion 蓝、只用在按钮与链接」那条仍然不破，
     这几档只出现在装饰图形与细带上。 */
  --blue-200: #c7e0f7;
  --blue-300: #9dc9ef;
  --blue-400: #6fb2ea;
  --blue-500: #3d90e0;
  /* 青：小节色标用，与蓝相邻不跳色（DESIGN.md 贴纸色板 accent-teal） */
  --sticker-teal: #2a9d99;

  /* 间距（DESIGN.md · Spacing System，基准 8px） */
  --xxs: 4px;
  --xs: 8px;
  --sm: 12px;
  --md: 16px;
  --lg: 24px;
  --xl: 28px;
  --xxl: 32px;

  /* 圆角（DESIGN.md · Border Radius Scale） */
  --r-xs: 4px;    /* 表单字段 */
  --r-sm: 5px;    /* 列表行、状态药丸 */
  --r-md: 8px;    /* 工具按钮、小卡片 */
  --r-lg: 12px;   /* 内容卡片 */
  --r-full: 9999px;

  /* 阴影（DESIGN.md · Elevation Level 1：多层近透明，若有似无） */
  --shadow-1:
    rgba(0, 0, 0, 0.01) 0 0.175px 1.041px,
    rgba(0, 0, 0, 0.02) 0 0.8px 2.925px,
    rgba(0, 0, 0, 0.027) 0 2.025px 7.847px,
    rgba(0, 0, 0, 0.04) 0 4px 18px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--canvas-soft);
  color: var(--ink);
  font-family: Inter, -apple-system, system-ui, "Segoe UI", "Microsoft YaHei", Helvetica, Arial, sans-serif;
  font-size: 16px;      /* body-md */
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* ---------- 页头（DESIGN.md · nav-bar：白底、细线、slim sticky） ---------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;          /* 手机上放不下时右边那组（邮箱、按钮）整体换到第二行，不把站点名挤断 */
  align-items: center;
  justify-content: space-between;
  gap: var(--xs) var(--md);
  padding: var(--sm) var(--lg);
  background: var(--canvas);
  border-bottom: 1px solid var(--hairline);
}
.nav .wordmark {
  white-space: nowrap;    /* 站点名不从词中间折行（用户 2026-09-29，同「关键词作 / 战表」那一类） */
  font-size: 20px;        /* title */
  font-weight: 600;
  letter-spacing: -0.125px;
}
.nav .who {
  font-size: 14px;        /* caption */
  color: var(--ink-muted);
  margin-right: var(--xs);
}

/* ---------- 版心 ---------- */
.wrap {
  max-width: 1080px;
  margin: 0 auto;
  padding: var(--lg);
}
.wrap-narrow {
  max-width: 420px;
  margin: 0 auto;
  padding: 56px var(--lg) var(--lg);
}

/* ---------- 标题层级（DESIGN.md · Typography Hierarchy） ---------- */
h1 { font-size: 40px; font-weight: 700; line-height: 1.1; letter-spacing: -1px; margin: 0 0 var(--xs); }
h2 { font-size: 26px; font-weight: 700; line-height: 1.23; letter-spacing: -0.625px; margin: 0 0 var(--sm); }
h3 { font-size: 22px; font-weight: 700; line-height: 1.27; letter-spacing: -0.25px; margin: 0 0 var(--xs); }
.lead { color: var(--ink-muted); font-size: 15px; margin: 0 0 var(--lg); }
.caption { font-size: 14px; line-height: 1.43; color: var(--ink-muted); }
.eyebrow {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.125px;
  color: var(--ink-muted);
  text-transform: none;
}

/* ---------- 卡片（DESIGN.md · feature-card：白底 12px 圆角 24px 内边距，默认只有细线） ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: var(--lg);
}
.card + .card { margin-top: var(--lg); }
.card-raised { box-shadow: var(--shadow-1); }
.card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sm);
  margin-bottom: var(--md);
}
/* 小节标题不从词中间折行（用户 2026-09-29：手机上折成「关键词作 / 战表」「我的任 / 务」不行，
   要折也得按意思折）。中文没有空格，浏览器在任意两个字之间都能断；标题一律不折，
   旁边放不下的说明文字整行换到下一行（上面的 flex-wrap）。 */
.card-head h2 { white-space: nowrap; }

/* ---------- 表单（DESIGN.md · text-input：白底、1px #ddd、4px 圆角、聚焦加 Level-1 阴影） ---------- */
.field { display: flex; flex-direction: column; gap: var(--xxs); }
.field > label { font-size: 14px; font-weight: 600; color: var(--ink-secondary); }
.field .hint { font-size: 12px; color: var(--ink-faint); }

input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
select {
  width: 100%;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 15px;            /* body-sm */
  border: 1px solid var(--input-border);
  border-radius: var(--r-xs);
  padding: 8px 10px;
}
/* 下拉框与输入框同高（输入框 15px 字 + 8px 上下内边距）；保留原生下拉箭头 */
select { height: 40px; cursor: pointer; }
input:focus,
select:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: var(--shadow-1);
}
input[aria-invalid="true"] { border-color: var(--bad); }

/* 一排平铺：ASIN + 目标 ACOS + 盈亏平衡 ACOS + 产品阶段（docs/03 2026-09-25 定：与 ASIN 平铺同一排；
   2026-09-28 加产品阶段下拉框，docs/03 第 32 段第二节） */
.row-inline {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1.4fr;
  gap: var(--md);
  align-items: start;
}

/* ASIN 列表（docs/03「2026-10-05 模块 3：04 竞对对比」段第 2 条；2026-10-12「工具页站点＋SPU」段第二节）：
   第 1 行「自己」= 站点下拉｜SPU｜ASIN；竞对行 =「竞对」字样（占站点＋SPU 两格，ASIN 框与上一行对齐）｜ASIN｜删除。
   宽度不铺满整行；手机上自己那行站点与 SPU 一行、ASIN 下一行占满（见下方 @media） */
.asinfield { margin-bottom: var(--md); }
.asinlist { display: flex; flex-direction: column; gap: var(--xs); max-width: 680px; }
.asinrow { display: grid; grid-template-columns: 112px 200px minmax(0, 1fr) 64px; gap: var(--xs); align-items: center; }
.asinrow .asintag { grid-column: 1 / span 2; color: var(--ink-muted); font-size: 14px; padding-left: var(--xxs); }
.asinrow-own .asininput { grid-column: 3; }
.asinactions { display: flex; align-items: center; gap: var(--sm); margin-top: var(--xs); }
.asinactions .btn-utility:disabled { opacity: 0.5; cursor: not-allowed; }

/* 文件选择：原生 input 太丑且各浏览器不一，包一层细线盒子 */
.filebox {
  display: flex;
  align-items: center;
  gap: var(--sm);
  border: 1px dashed var(--input-border);
  border-radius: var(--r-md);
  padding: var(--sm);
  background: var(--canvas);
}
.filebox .name { font-size: 14px; color: var(--ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 三份报表平铺一排：搜索词报告 + 广告位报告（可选）+ 投放报告（可选）（docs/03「2026-09-28 多报表」段第四节）；
   手机一格一行（见下方 @media）。文件名过长时省略号截断，不把「移除」按钮挤出盒子 */
.row-files {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--md);
  align-items: start;
}
.row-files .filebox .name { flex: 1 1 auto; min-width: 0; }

/* ---------- 按钮（DESIGN.md · button-primary 药丸；button-utility 8px 圆角细线） ---------- */
.btn {
  font: inherit;
  font-size: 16px;
  font-weight: 500;
  border-radius: var(--r-full);
  border: 1px solid transparent;
  padding: 10px 22px;
  cursor: pointer;
  transition: background-color .12s ease, transform .08s ease;
}
.btn-primary { background: var(--primary); color: var(--on-primary); }
.btn-primary:active:not(:disabled) { background: var(--primary-active); transform: scale(0.98); }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.btn-utility {
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  padding: 5px 14px;
  cursor: pointer;
  white-space: nowrap;    /* 按钮文字不折行：报告页手机上曾折成「返回工具 / 页」（2026-09-29） */
  display: inline-block;
}
.btn-utility:active { background: var(--canvas-soft); }

.btn-link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 14px;
  color: var(--primary);
  cursor: pointer;
  text-decoration: none;
}
.btn-link:hover { text-decoration: underline; }

/* ---------- 提示条 ---------- */
.notice {
  border-radius: var(--r-md);
  padding: var(--sm) var(--md);
  font-size: 14px;
  line-height: 1.43;
  margin-bottom: var(--md);
}
.notice-bad { background: var(--bad-soft); color: var(--bad); }
.notice-ok { background: var(--ok-soft); color: #14701f; }
.notice-warn { background: var(--warn-soft); color: #8a3a00; }
.notice-info { background: var(--info-soft); color: #0a4f96; }
.notice[hidden] { display: none; }

/* 字段级错误：说人话，不显示英文错误码 */
.err { font-size: 12px; color: var(--bad); min-height: 16px; }
.soft { font-size: 12px; color: var(--warn); min-height: 16px; }

/* ---------- 任务列表 ---------- */
/* 一屏看到 5 条（docs/03 2026-09-25 用户定）：列表高度按 5 行算，超出滚动。
   行高 48px 是 2026-09-25 在浏览器里实测的（12px 上下内边距 + 15px×1.5 行高 + 1px 分隔线），
   不是估的——原来按 64px 估，6 条总共才 287px、320px 的框全塞得下，一条都不用滚，
   「一屏 5 条」这条底线等于没生效。
   已知局限：失败原因很长而折行的那种行会更高，那时一屏就只看得到 4 条多一点。 */
.tasklist { border: 1px solid var(--hairline); border-radius: var(--r-md); overflow: hidden; background: var(--canvas); }
.tasklist-scroll { max-height: calc(5 * 48px); overflow-y: auto; }
.trow {
  display: grid;
  grid-template-columns: 170px 240px 110px 1fr auto;
  gap: var(--sm);
  align-items: center;
  padding: var(--sm) var(--md);
  border-bottom: 1px solid var(--hairline);
  font-size: 15px;
}
.trow:last-child { border-bottom: none; }
.trow-head {
  background: var(--canvas-soft);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.125px;
  color: var(--ink-muted);
  position: sticky;
  top: 0;
}
/* 站点 · SPU · ASIN：一行放不下时只截「站点 · SPU · 」那段（省略号），ASIN 始终完整；悬停看全（长列表每条一行） */
.trow .asin { font-variant-numeric: tabular-nums; white-space: nowrap; display: flex; min-width: 0; }
.trow .asin .tlhead { overflow: hidden; text-overflow: ellipsis; min-width: 0; white-space: pre; }
.trow .asin .tlasin { flex-shrink: 0; }
.trow .reason { color: var(--bad); font-size: 13px; }
.empty { padding: var(--xxl) var(--md); text-align: center; color: var(--ink-faint); font-size: 15px; }

/* 状态药丸（DESIGN.md · rounded.sm 5px，列表行/状态药丸那一档） */
.pill {
  display: inline-block;
  border-radius: var(--r-sm);
  padding: 2px 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.125px;
}
.pill-done { background: var(--ok-soft); color: #14701f; }
.pill-doing { background: var(--info-soft); color: #0a4f96; }
.pill-wait { background: var(--canvas-soft); color: var(--ink-muted); }
.pill-fail { background: var(--bad-soft); color: var(--bad); }

/* ---------- 登录页标语（用户 2026-09-25 定：主副调换，标语当大标题） ----------
 * 只设字距与间距，**故意不设 font-size**：让它继承 h1，这样手机那条
 * `h1{font-size:30px}` 才管得住它，不用在两处各写一遍字号。
 * DESIGN.md 的 heading-1 带 −1px 负字距，那是给拉丁字母调的，中文用会挤，放宽到 −0.3px。 */
.tagline {
  letter-spacing: -0.3px;
  /* 下面原本还有一条短线与一段小字，用户 2026-09-25 要求都去掉，只留标语本身。
     它们让出来的留白改由这里补：标语与增长柱子之间留一个 --lg。 */
  margin: 0;
}

/* 白卡片里的「登录／注册」小标题 */
.cardtitle {
  margin: 0 0 var(--md);
}

/* ---------- 报告页：报告正文放 iframe 里，与前台样式完全隔离 ---------- */
.reportframe {
  display: block;
  width: 100%;
  /* 撑满余下的视口：页头约 52px、标题行与提示约 90px、页脚约 70px */
  height: calc(100vh - 212px);
  min-height: 420px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: var(--surface);
}
.reportframe[hidden] { display: none; }
/* .btn-utility 的 display:inline-block 会盖掉 hidden：没取到报告（加载中、红字）时「下载报告」要真藏起来（2026-10-21 3d 实点发现） */
#downloadBtn[hidden] { display: none; }
@media (max-width: 720px) {
  .reportframe { height: calc(100vh - 240px); min-height: 320px; }
}

/* ---------- 报告页专用：全宽 + 只剩一层滚动（docs/03「2026-09-26 报告页改为全宽 + 窄屏等比缩放」） ----------
   为什么要单独一套：报告表格是 1700px 固定列宽的宽表，塞进通用的 .wrap（max-width:1080px）里
   永远差 700 多像素，横向滚动条与窗口多宽无关、必然出现。登录页与工具页是表单，继续用 1080px 的 .wrap，
   这里只覆盖报告页自己。页面本身不滚动：页头、标题行、页脚固定，滚动只发生在报告内部。 */
body.reportpage {
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
body.reportpage .wrap-report {
  max-width: none;            /* 取消 1080px 上限，报告拿到整个窗口宽 */
  /* .wrap 自带 margin:0 auto。在 flex 列容器里，交叉轴上的 auto 外边距会让子项
     收缩成内容宽再居中，把 max-width:none 整个抵消掉（2026-09-26 截图自查时实测，
     报告卡片只剩约 490px）。所以这里必须把 margin 归零并显式 width:100%。 */
  margin: 0;
  width: 100%;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;              /* 不写这一条，flex 子项不肯缩，iframe 会把页面顶长 */
  padding: var(--md) var(--md) 0;
}
body.reportpage .reportframe {
  height: auto;               /* 取代 calc(100vh - 212px)：交给 flex 算，页头页脚高度变了也不用改数 */
  min-height: 0;
  flex: 1 1 auto;
}
body.reportpage .foot {
  flex: 0 0 auto;
  margin-top: 0;
}

/* ---------- 页脚（DESIGN.md · footer：暖白底、caption 字号） ---------- */
.foot {
  margin-top: var(--xxl);
  padding: var(--lg);
  background: var(--canvas-soft);
  border-top: 1px solid var(--hairline);
  text-align: center;
  font-size: 14px;
  color: var(--ink-secondary);
}
.foot a { color: var(--ink-secondary); }

/* ---------- 手机 ---------- */
@media (max-width: 720px) {
  .wrap { padding: var(--md); }
  .row-inline { grid-template-columns: 1fr; }
  .row-files { grid-template-columns: 1fr; }
  .asinrow { grid-template-columns: 112px minmax(0, 1fr) 64px; }
  .asinrow-own .spuinput { grid-column: 2 / span 2; }
  .asinrow-own .asininput { grid-column: 1 / -1; }
  .asinrow .asintag { grid-column: 1; }
  .trow { grid-template-columns: 1fr auto; row-gap: var(--xxs); }
  .trow .when { order: 1; font-size: 13px; color: var(--ink-muted); }
  .trow .status { order: 2; justify-self: end; }
  .trow .asin { order: 3; font-weight: 600; }
  .trow .reason { order: 4; grid-column: 1 / -1; }
  .trow .act { order: 5; grid-column: 1 / -1; }
  /* 没有失败原因、没有「查看报告」的行：空格子不占一行（2026-09-28 修「进行中／已完成」错位） */
  .trow .reason:empty,
  .trow .act:empty { display: none; }
  .trow-head { display: none; }
  .tasklist-scroll { max-height: none; }
  h1 { font-size: 30px; letter-spacing: -0.5px; }
}


/* ============================================================
 * 装饰性配色（2026-09-25 用户定「两页都治」）
 * 依据 DESIGN.md：hero-band 夜色带 + decorative sticker palette。
 * 三条底线不破：① 贴纸色只做装饰，按钮与链接仍只用 Notion 蓝；
 * ② 夜色带整站只出现一次（登录页）；③ 报告表格的配色一个字不动。
 * ============================================================ */

/* ---------- 页头识别块：增长图标（三根递增的柱子），放在站点名前 ----------
 * 用户 2026-09-25 定：「kelcy 左边的 logo 可以试试用增长图标」。
 * 用内联 SVG 而不是背景图：颜色能直接写进标记、看得懂、不引任何外部文件。 */
.brandmark {
  display: inline-block;
  width: 22px;
  height: 22px;
  margin-right: 10px;
  vertical-align: -4px;
}
.brandmark .b1 { fill: var(--blue-300); }
.brandmark .b2 { fill: var(--blue-500); }
.brandmark .b3 { fill: var(--primary); }

/* ---------- 登录页顶区：浅蓝渐隐到纸底（2026-09-25 用户定，取代深靛蓝夜色带） ----------
 * 用户原话：背景色「有点太沉，跟下方的登录页蓝色不协调」。
 * 改成 Notion 蓝最浅的一档渐变到暖白纸底 canvas-soft，与页面底色无缝相接，
 * 文字回到近黑。DESIGN.md 那个「唯一暗色岛」的手法本轮不用了。 */
.hero {
  background: linear-gradient(180deg, #e9f2fc 0%, #f1f6fa 55%, var(--canvas-soft) 100%);
  color: var(--ink);
  padding: 48px var(--lg) 88px;
  text-align: center;
}
.hero h1 { color: var(--ink); }
/* 增长图形：五根递增的柱子，取代原来五个无含义的彩色方格（用户 2026-09-25 定）。
   配色是 primary 的浅深阶，与登录按钮同族。纯装饰，对读屏器只报一句说明。 */
.growth {
  display: block;
  width: 200px;
  max-width: 62%;
  height: auto;
  margin: var(--lg) auto 0;
}
/* 柱子的颜色统一由这里给，标记里不写死 hex，色阶只有一个出处 */
.growth .b1 { fill: var(--blue-200); }
.growth .b2 { fill: var(--blue-300); }
.growth .b3 { fill: var(--blue-400); }
.growth .b4 { fill: var(--blue-500); }
.growth .b5 { fill: var(--primary); }

/* 白卡片压在夜色带下沿：Notion 官网那个「浮起的白药丸」的做法 */
.wrap-narrow.lifted {
  margin-top: -64px;
  padding-top: 0;
}

/* ---------- 卡片顶部彩带 ---------- */
.card-stripe {
  position: relative;
  overflow: hidden;
}
.card-stripe::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: linear-gradient(90deg,
    var(--blue-300), var(--blue-500), var(--primary));
}

/* ---------- 小节色标：放在 h2 前，一个小节一色 ---------- */
.sicon {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 3px;
  margin-right: var(--xs);
  vertical-align: 2px;
}
.sicon-blue { background: var(--primary); }
.sicon-teal { background: var(--sticker-teal); }

/* ---------- 手机：夜色带与压边都要收一收 ---------- */
@media (max-width: 720px) {
  .hero { padding: var(--xxl) var(--md) 72px; }
  .wrap-narrow.lifted { margin-top: -56px; padding-left: var(--md); padding-right: var(--md); }
  .growth { width: 168px; max-width: 70%; }
  .nav .wordmark { font-size: 17px; }
  .brandmark { width: 18px; height: 18px; margin-right: 8px; vertical-align: -3px; }
}

/* ============================================================
 * 05 图片工作台（docs/03「2026-10-08 模块 4 甲」段「第 3 步前台细节」，用户 2026-10-09 同意）
 * 样子按样子图 Artifact（入口 A、分步乙）：步骤条 + 一屏一步。
 * 颜色守 DESIGN.md：动作只用 Notion 蓝；「标杆」的橙框借贴纸色 accent-orange（--warn）当标记
 * （不是按钮、不是结构色），与样子图一致。
 * ============================================================ */

/* 任务列表里的「05 工作台」按钮：与「查看报告」同一行；hl＝等用户操作（蓝），bad＝失败（红字） */
.trow .act .wbbtn { margin-left: var(--xs); }
.wbbtn-hl { border-color: var(--primary); color: var(--primary); background: var(--info-soft); }
.wbbtn-bad { color: var(--bad); border-color: var(--bad-soft); }

.wrap-wb [hidden] { display: none !important; }
.wbscreen h3 { font-size: 20px; font-weight: 600; letter-spacing: -0.125px; margin: 0 0 var(--xs); }
.wbtext { font-size: 15px; color: var(--ink-secondary); margin: 0 0 var(--sm); }
.wblist { font-size: 15px; color: var(--ink-secondary); margin: 0 0 var(--md); padding-left: 22px; }
.wbcost { font-size: 15px; margin: 0 0 var(--md); }
.wbhead { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--xs) var(--md); margin-bottom: var(--md); }
.wbhead h3 { margin: 0; white-space: nowrap; }
.wbcta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sm); margin-top: var(--md); }
.wbprogress { font-variant-numeric: tabular-nums; }
.wbprogress.bad { color: var(--bad); }
body.wb-busy .wbscreen button { pointer-events: none; opacity: .7; }

/* 步骤条 */
.wbsteps { display: flex; flex-wrap: wrap; align-items: center; gap: var(--xs); margin-bottom: var(--md); }
.wbstep {
  display: inline-flex; align-items: center; gap: var(--xs);
  font: inherit; font-size: 14px; color: var(--ink-muted);
  background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--r-full);
  padding: 5px 14px 5px 6px; cursor: pointer; white-space: nowrap;
}
.wbstep b { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--canvas-soft); color: var(--ink-muted); font-size: 12px; }
.wbstep.done b { background: var(--ok); color: #fff; }
.wbstep.cur { border-color: var(--primary); color: var(--primary); font-weight: 600; }
.wbstep.cur b { background: var(--primary); color: #fff; }
.wbstep:disabled { cursor: default; }
.wbstep.soon { color: var(--ink-faint); }
.wbstep small { font-size: 12px; color: var(--ink-faint); font-weight: 400; }
.wbsep { color: var(--ink-faint); }

/* 第 1 屏：清单 */
.cl { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--xs); }
.clrow { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; gap: var(--sm); align-items: start; border: 1px solid var(--hairline); border-radius: var(--r-md); padding: var(--sm); background: var(--surface); }
.clrow-edit { grid-template-columns: 28px minmax(0, 1fr); border-color: var(--primary); box-shadow: var(--shadow-1); }
.cln { font-variant-numeric: tabular-nums; color: var(--ink-faint); font-size: 15px; font-weight: 600; text-align: center; padding-top: 1px; }
.clname { font-size: 16px; display: flex; flex-wrap: wrap; gap: var(--xs); align-items: baseline; }
.clen { font-size: 14px; color: var(--ink-muted); }
.clwhy { font-size: 14px; color: var(--ink-secondary); margin-top: var(--xxs); }
.k { font-size: 13px; font-weight: 600; color: var(--ink-muted); margin: 0 0 var(--xs); }
.clwhy .k { margin: 0; }
.edited { font-size: 12px; font-weight: 600; color: var(--warn); }
.tags { display: flex; flex-wrap: wrap; gap: var(--xxs); margin-top: var(--xs); }
.tag { font-size: 12px; line-height: 1.5; padding: 1px 8px; border-radius: var(--r-xs); background: var(--canvas-soft); color: var(--ink-muted); max-width: 100%; overflow-wrap: anywhere; }
.tag-rv { background: var(--bad-soft); color: var(--bad); }
.clacts { display: flex; gap: var(--xxs); flex-wrap: nowrap; }
.clacts .btn-utility { padding: 4px 10px; }
.clacts .btn-utility:disabled, .wbcta .btn-utility:disabled { opacity: .4; cursor: not-allowed; }
.clform { display: flex; flex-direction: column; gap: var(--sm); min-width: 0; }
.clform textarea {
  width: 100%; font: inherit; font-size: 15px; color: var(--ink); background: var(--surface);
  border: 1px solid var(--input-border); border-radius: var(--r-xs); padding: 8px 10px; resize: vertical;
}
.clform textarea:focus { outline: none; border-color: var(--primary); box-shadow: var(--shadow-1); }
.clform [aria-invalid="true"] { border-color: var(--bad); }
.clform .wbcta { margin-top: 0; }

/* 第 2 屏：主图四项 */
.mainbox { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: var(--lg); align-items: start; }
.mainimg { margin: 0; }
.mainimg img { display: block; width: 100%; aspect-ratio: 1; object-fit: contain; background: #fff; border: 1px solid var(--hairline); border-radius: var(--r-lg); }
.mainimg figcaption { text-align: center; margin-top: var(--xxs); }
.mainchecks { display: flex; flex-direction: column; gap: var(--xs); }
.mainq { display: flex; flex-wrap: wrap; align-items: center; gap: var(--xs) var(--md); border: 1px solid var(--hairline); border-radius: var(--r-md); padding: var(--xs) var(--sm); margin: 0; }
.mainq legend { float: left; padding: 0; font-size: 15px; min-width: 220px; margin-right: auto; }
.mainq label { display: inline-flex; align-items: center; gap: 6px; font-size: 15px; cursor: pointer; }
.mainq input { accent-color: var(--primary); width: 16px; height: 16px; }
.mainq.todo { border-color: var(--warn); background: var(--warn-soft); }
.mk-sel { color: var(--primary); font-weight: 600; }
.mk-star { color: var(--warn); font-weight: 600; }

/* 第 2 屏：要素 × 竞对（div 网格，不用 table：手机上好改成一条一张卡片） */
.pk { border: 1px solid var(--hairline); border-radius: var(--r-md); overflow: hidden; background: var(--surface); }
.pkrow { display: grid; grid-template-columns: 200px repeat(var(--rivals, 4), minmax(0, 1fr)); border-bottom: 1px solid var(--hairline); }
.pkrow:last-child { border-bottom: none; }
.pkrow > div { padding: var(--xs); border-right: 1px solid var(--hairline); min-width: 0; }
.pkrow > div:last-child { border-right: none; }
.pkhead { background: var(--canvas-soft); font-size: 12px; font-weight: 600; color: var(--ink-muted); text-align: center; }
.pkhead .pkitem { text-align: left; }
.num { font-variant-numeric: tabular-nums; font-weight: 400; }
.pkrow.open { box-shadow: inset 3px 0 0 var(--primary); }
.pkitem { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; font-size: 14px; background: var(--canvas-soft); }
.pkrow.open .pkitem { background: var(--info-soft); }
.pkstat { font-size: 12px; font-weight: 600; color: var(--ink-muted); }
.pkstat.ok { color: var(--warn); }
.pkstat.todo { color: var(--ink-faint); }
.pkstat.need { color: var(--ink-secondary); }   /* 勾了 2 张以上、等用户点 ★：比「还没定」显眼 */
.pkacts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--xs) var(--sm); }
.nobench { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink-secondary); cursor: pointer; }
.nobench input { accent-color: var(--primary); }
.pkcell-label { display: none; }
.thumbs { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
.pkcell .caption { display: block; text-align: center; color: var(--ink-faint); }
.thumb { position: relative; width: 72px; display: flex; flex-direction: column; align-items: center; gap: 2px; }
.thumb-img { display: block; padding: 0; border: 2px solid var(--hairline); border-radius: var(--r-sm); background: #fff; cursor: pointer; line-height: 0; }
.thumb-img img { width: 64px; height: 64px; object-fit: contain; display: block; }
.thumb.sel .thumb-img { border-color: var(--primary); }
.thumb.star .thumb-img { border-color: var(--warn); box-shadow: 0 0 0 2px var(--warn-soft); }
.thumb-sm { width: 58px; }
.thumb-sm .thumb-img img { width: 50px; height: 50px; }
.thumb-no { font-size: 11px; color: var(--ink-faint); }
.thumb .mk { font-size: 11px; line-height: 1.2; }
.thumb-zoom, .thumb-star {
  position: absolute; top: 2px; width: 22px; height: 22px; border-radius: var(--r-full); border: 1px solid var(--hairline);
  background: rgba(255, 255, 255, .92); font-size: 11px; line-height: 1; cursor: pointer; padding: 0; display: grid; place-items: center;
}
.thumb-zoom { right: 2px; }
.thumb-star { left: 2px; color: var(--ink-faint); }
.thumb-star.on { color: #fff; background: var(--warn); border-color: var(--warn); }

/* 看大图（DESIGN.md Elevation Level 2：弹窗） */
.viewer { border: none; border-radius: var(--r-lg); padding: 0; max-width: min(720px, 94vw); box-shadow: rgba(0, 0, 0, .05) 0 23px 52px, var(--shadow-1); }
.viewer::backdrop { background: rgba(0, 0, 0, .45); }
.viewer-body { padding: var(--md); }
.viewer img { display: block; width: 100%; max-height: 70vh; object-fit: contain; background: #fff; }
.viewer [hidden] { display: none !important; }

@media (max-width: 720px) {
  .trow .act { display: flex; flex-wrap: wrap; gap: var(--xs); }
  .trow .act .wbbtn { margin-left: 0; }
  .wbhead h3 { white-space: normal; }
  .clrow, .clrow-edit { grid-template-columns: 22px minmax(0, 1fr); }
  .clacts { grid-column: 2; }
  .mainbox { grid-template-columns: 1fr; }
  .mainimg { max-width: 220px; margin: 0 auto; }
  .mainq legend { min-width: 0; width: 100%; }
  /* 手机：每条要素一张卡片，竞对一家一段，往下排，不横向滚动 */
  .pkhead { display: none; }
  .pkrow { grid-template-columns: 1fr; }
  .pkrow > div { border-right: none; }
  .pkcell { border-top: 1px solid var(--hairline); }
  .pkcell-empty { display: none; }   /* 收起的行里没勾图的竞对不占地方 */
  .pkcell-label { display: block; font-size: 12px; font-weight: 600; color: var(--ink-muted); margin-bottom: var(--xxs); }
  .thumbs { justify-content: flex-start; }
  .pkitem { flex-direction: row; flex-wrap: wrap; align-items: center; }
  .pkitem b { width: 100%; }
  /* 手机上整行宽，图与角上小按钮放大，手指好点 */
  .thumb { width: 92px; }
  .thumb-img img { width: 84px; height: 84px; }
  .thumb-zoom, .thumb-star { width: 30px; height: 30px; font-size: 14px; }
}

/* 第 2 屏做完：费用与「开始生成」 */
.wbgen { display: block; }

/* 第 3 屏：AI 改版建议（第 4 步，docs/03「模块 4 甲」段「第 4 步方案」）。「怎么答」的颜色与报告 05 一致 */
.resh { font-size: 16px; font-weight: 600; margin: var(--lg) 0 var(--xxs); }
.resissues { margin-top: var(--md); font-size: 14px; color: var(--ink-secondary); }
.resissues summary { cursor: pointer; color: var(--ink-muted); }
.resissues ul { margin: var(--xs) 0 0; padding-left: 20px; }
.how { display: inline-block; padding: 0 7px; border-radius: 9px; font-size: 12px; font-weight: 600; line-height: 18px; white-space: nowrap; }
.how-direct { background: var(--ok-soft); color: #1f7a33; }
.how-text { background: var(--info-soft); color: #1d4e89; }
.how-part { background: var(--warn-soft); color: #9c4a0e; }
.how-none { background: var(--bad-soft); color: var(--bad); }
.how-fail { background: var(--canvas-soft); color: var(--ink-muted); }
.resitems { list-style: none; margin: var(--xs) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--xs); }
.resitem { border: 1px solid var(--hairline); border-radius: var(--r-md); padding: var(--sm); background: var(--surface); font-size: 14px; }
.resitem-h { display: flex; flex-wrap: wrap; align-items: center; gap: var(--xxs) var(--xs); }
.resadv { margin-top: var(--xs); padding: var(--xs) var(--sm); background: var(--canvas-soft); border-radius: var(--r-sm); }
.resadv p { margin: 4px 0; }
.resadv .k, .rescard .k { display: block; margin: 0 0 2px; }
.reswarn { color: #9c4a0e; font-size: 13px; margin: 4px 0; }
.resform { display: flex; flex-direction: column; gap: var(--xs); margin-top: var(--xs); min-width: 0; }
.resform textarea {
  width: 100%; font: inherit; font-size: 14px; color: var(--ink); background: var(--surface);
  border: 1px solid var(--input-border); border-radius: var(--r-xs); padding: 8px 10px; resize: vertical;
}
.resform textarea:focus { outline: none; border-color: var(--primary); box-shadow: var(--shadow-1); }
.resform [aria-invalid="true"] { border-color: var(--bad); }
.resform .wbcta { margin-top: 0; }
/* 第 3 屏「改版工作清单」（用户 2026-10-09 选乙）：一行一张图，展开才见其余建议与 AI 判断 */
.rescards { display: flex; flex-direction: column; gap: var(--xs); margin-top: var(--xs); }
.rescard { border: 1px solid var(--hairline); border-radius: var(--r-md); padding: var(--xs) var(--sm); background: var(--surface); font-size: 14px; min-width: 0; }
.rescard-h { display: flex; gap: var(--sm); align-items: center; }
.rescard-img { padding: 0; border: 1px solid var(--hairline); border-radius: var(--r-sm); background: #fff; cursor: zoom-in; line-height: 0; flex: 0 0 auto; }
.rescard-img img { width: 56px; height: 56px; object-fit: contain; display: block; border-radius: var(--r-sm); }
.rescard-t { flex: 1 1 auto; min-width: 0; font-size: 15px; }
.rescard-sp { margin: 2px 0 0; font-size: 14px; color: var(--ink-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.resfold > summary { cursor: pointer; user-select: none; }
.resitem .resfold > summary { display: list-item; }
.resitem .resfold > summary.resitem-h > * { vertical-align: middle; }
.resitem .resfold > summary.resitem-h b { margin-right: 4px; }
.resedit { margin-top: var(--md); border: 1px solid var(--hairline); border-radius: var(--r-md); padding: var(--sm) var(--md); background: var(--surface); }
.resedit > summary { font-size: 15px; font-weight: 600; color: var(--ink); }
.resedit[open] > summary { margin-bottom: var(--xs); }
.rescard-more { margin-top: var(--xs); }
.rescard-more > summary { font-size: 13px; color: var(--primary); }
.resai { margin-top: var(--sm); }
.resai > summary { font-size: 13px; color: var(--ink-muted); }
.resstatus { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink-muted); white-space: nowrap; }
.resstatus select { font: inherit; font-size: 13px; padding: 3px 6px; border: 1px solid var(--input-border); border-radius: var(--r-xs); background: var(--surface); color: var(--ink); }
.resblock { margin-top: var(--sm); }
.resblock ul { margin: 2px 0 0; padding-left: 18px; }
.resblock p { margin: 2px 0 0; }
.resans li { margin-bottom: 4px; }
.resans .faded { color: var(--ink-faint); }
.ressug { padding: var(--xs) var(--sm); background: var(--canvas-soft); border-radius: var(--r-sm); }
.ressug p { margin: 4px 0; }
.ressug .en { font-family: Consolas, "SFMono-Regular", monospace; font-size: 13px; overflow-wrap: anywhere; }
.resnote { padding: 4px 8px; background: var(--warn-soft); border-radius: var(--r-xs); font-size: 13px; }
.ressug .clacts, .resadv .clacts { flex-wrap: wrap; margin-top: var(--xxs); }
@media (max-width: 720px) {
  .rescard-h { flex-wrap: wrap; }
  .rescard-t { flex-basis: calc(100% - 72px); }
  .rescard-h .resstatus { margin-left: 68px; }
}

/* ============================================================
   注册用户管理（docs/03「2026-10-20 注册用户管理」段第 7 条）
   ============================================================ */
/* .field 是 flex，会盖掉 hidden 属性：注册页的邀请码框在「登录」时要真藏起来 */
.field[hidden] { display: none; }
/* 页头「管理」入口（只管理员看得到）与邮箱、退出登录同一组 */
.nav #adminLink { margin-right: var(--xs); text-decoration: none; }
.nav #adminLink[hidden] { display: none; }

/* 任务列表：管理员多一列「提交人」。邮箱太长省略号截断、悬停看全（长列表每条一行） */
/* 提交人列收窄（110px，长邮箱省略号、悬停看全），不然 1000 宽时「查看报告」「05 页面诊断」两个按钮会被挤成两行、一行变高 */
.tasklist.with-owner .trow { grid-template-columns: 140px 110px 200px 84px 1fr auto; }
.trow .owner { color: var(--ink-muted); font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.trow-head .owner { font-size: 12px; }

/* 管理页 */
.adform { display: grid; grid-template-columns: 150px 120px minmax(0, 1fr) auto; gap: var(--sm); align-items: start; }
.adform .btn { margin-top: 26px; }
.adlist { border: 1px solid var(--hairline); border-radius: var(--r-md); overflow: hidden; background: var(--canvas); margin-top: var(--md); }
.adrow { display: grid; gap: var(--sm); align-items: center; padding: var(--sm) var(--md); border-bottom: 1px solid var(--hairline); font-size: 15px; }
.adrow:last-child { border-bottom: none; }
.adrow-head { background: var(--canvas-soft); font-size: 12px; font-weight: 600; letter-spacing: 0.125px; color: var(--ink-muted); }
.adrow > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.adlist-invite .adrow { grid-template-columns: 90px minmax(0, 1fr) minmax(0, 1.4fr) 110px 64px; }
/* 每行各自是一个 grid：列宽必须写死，表头才和内容对得齐（auto 会按各行自己的内容算） */
.adlist-user .adrow { grid-template-columns: minmax(0, 1fr) 100px 80px 330px 64px; }
.adrow .email { display: flex; align-items: center; }
.adrow .email .etext { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.adrow .email .tag { flex-shrink: 0; }
.adrow .code { font-variant-numeric: tabular-nums; font-weight: 600; letter-spacing: 1px; }
.adrow .muted { color: var(--ink-muted); font-size: 14px; }
.adrow .st-open { color: #14701f; }
.adrow .st-used { color: var(--ink-secondary); }
.adrow .st-expired, .adrow .st-revoked { color: var(--ink-faint); }
.adrow .act { text-align: right; overflow: visible; }
.adrow .act .btn-utility { padding: 3px 10px; }
.mods { display: flex; gap: 2px; overflow: visible !important; }
.mods label, .offsw { display: inline-flex; align-items: center; gap: 3px; font-size: 13px; color: var(--ink-secondary); padding: 2px 5px; border-radius: var(--r-sm); cursor: pointer; white-space: nowrap; }
.mods label:hover, .offsw:hover { background: var(--canvas-soft); }
.mods input, .offsw input { margin: 0; accent-color: var(--primary); }
.mods input:disabled + span, .offsw input:disabled + span { color: var(--ink-faint); }
.adrow .tag { display: inline-block; font-size: 12px; font-weight: 600; padding: 1px 6px; border-radius: var(--r-sm); background: var(--info-soft); color: #0a4f96; margin-left: var(--xxs); }
.adrow.is-off > span:first-child { color: var(--ink-faint); text-decoration: line-through; }

@media (max-width: 720px) {
  .tasklist.with-owner .trow { grid-template-columns: 1fr auto; }
  .tasklist.with-owner .trow .owner { order: 4; grid-column: 1 / -1; font-size: 13px; }
  .tasklist.with-owner .trow .reason { order: 5; }
  .tasklist.with-owner .trow .act { order: 6; }
  .adform { grid-template-columns: 1fr 1fr; }
  .adform .adnote { grid-column: 1 / -1; }
  .adform .btn { grid-column: 1 / -1; margin-top: 0; }
  .adrow-head { display: none; }
  .adlist-invite .adrow { grid-template-columns: 1fr auto; row-gap: var(--xxs); }
  .adlist-invite .adrow .note { grid-column: 1 / -1; order: 3; }
  .adlist-invite .adrow .stat { order: 4; }
  .adlist-invite .adrow .exp { order: 5; text-align: right; }
  .adlist-invite .adrow .act { order: 2; }
  .adlist-invite .adrow .note:empty { display: none; }
  .adlist-user .adrow { grid-template-columns: 1fr auto; row-gap: var(--xxs); }
  .adlist-user .adrow .email { order: 1; }
  .adlist-user .adrow .offcell { order: 2; }
  .adlist-user .adrow .reg { order: 3; }
  .adlist-user .adrow .icode { order: 4; text-align: right; }
  .adlist-user .adrow .mods { order: 5; grid-column: 1 / -1; flex-wrap: wrap; }
}
