/* =============================================================
   煤朋友 CoalPal · 设计基元（电脑版 / 手机版共用）
   -------------------------------------------------------------
   ★ 这个文件不出现任何 @media (max-width/min-width) ★
     凡是「取决于屏幕有多宽」的规则，一律不属于这里 —— 它们分别属于
     desktop.css（电脑端）和 mobile.css（手机端）。本文件只放三样东西：

       1. 设计变量（配色 / 圆角 / 阴影 / 字号阶梯 / 容器宽度）
       2. 全局重置与基础排版
       3. 与屏幕宽度无关的组件外皮（背景、边框、形状、静态字号）

     这样拆分的目的：改品牌色、改圆角、改字号，仍然**只需要改一处**；
     而版式上真正做到「两套独立」。反过来说 —— 如果你要在这里加一条
     max-width 断点，请停下来先想清楚：它其实应该写进版本文件。

   ★ 加载顺序 ★ tokens.css → desktop.css 或 mobile.css
     两个版本文件排在后，覆盖率优先。

   ★ 不引任何 CDN，离线可用；不使用内联脚本（配合严格 CSP）★
   ============================================================= */

:root {
  --bg: #faf8f4;
  --card: #ffffff;
  --text: #17171b;
  --text-soft: #57544d;
  --text-mute: #8d8880;
  --line: #eae6df;
  --line-soft: #f4f1ea;

  /* ---------- 品牌色：煤黑 + 暖橙 ----------
     取自 static/img/logo-icon.jpg：抱着的煤块是黑，围巾和嘴巴是橙。

     ★ 为什么橙要拆成两个变量（改配色时最容易踩的一脚）★
       --brand-orange (#f0a02c) 在白底上只有 2.15:1 的对比度。
       拿它当按钮底、配白字，同样只有 2.15:1 —— 屏幕稍暗就糊成一片。
       所以按用途拆开：
         --brand-orange       大面积填充色，**必须**配煤黑文字（8:1）
         --brand-orange-deep  悬停 / 按下时再深一档
         --accent-text        白底上的橙色**文字**（链接、强调），5.1:1 达 AA
       换成别的品牌色时，请重新量一次对比度，不要直接把装饰色当主字色。

     命名沿用历史：--accent 仍是「交互色」，只是值变亮了，
     它现在只出现在边框、填充、勾选态上；凡是当文字用的地方一律走
     --accent-text。

     ★ 邮件正文里还有一份品牌色拷贝 ★
       邮件客户端不吃 CSS 变量，见 app/mailer.py 顶部的 BRAND_*。
       改这里的橙，那边要一起改。 */
  --brand-ink: #17171b;
  --brand-orange: #f0a02c;
  --brand-orange-deep: #dd9312;

  --accent: #f0a02c;          /* 填充 / 边框 / 选中态 */
  --accent-text: #a65a00;     /* 白底上的橙色文字（AA） */
  --accent-soft: #fff6e8;     /* 极浅橙底 */
  --accent-dark: #8f4e06;

  --ok: #15803d;
  --ok-soft: #f0fdf4;
  --warn: #b45309;
  --warn-soft: #fffbeb;
  --err: #b91c1c;
  --err-soft: #fef2f2;
  --radius: 12px;
  --radius-sm: 8px;
  --shadow: 0 1px 3px rgba(16, 16, 20, .06), 0 8px 24px -12px rgba(16, 16, 20, .12);

  /* 内容栏宽度。★ 两个值，不是断点 ★
     --maxw       正文/表单类页面的舒适阅读宽度（约 60-70 个汉字/行）
     --maxw-wide  确实需要横向空间的页面（首屏、匹配结果、后台表格）
     哪个页面用哪个，由模板的 body class 决定（body.page-wide），
     与屏幕宽度无关 —— 手机版两个都失效，一律满宽。 */
  --maxw: 780px;
  --maxw-wide: 1080px;

  /* 触控目标最小边长。手机版大量引用它（见 mobile.css），
     放在公共层是为了让「44px」这个数字只有一个出处。 */
  --tap-min: 44px;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
               "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  font-size: 15px;
  line-height: 1.7;
}

a { color: var(--accent-text); text-decoration: none; }

/* ---------- 排版基元 ---------- */

h1 { font-size: 26px; line-height: 1.4; margin: 0 0 12px; letter-spacing: -.01em; }
h2 { font-size: 19px; margin: 28px 0 10px; }
h3 { font-size: 16px; margin: 22px 0 8px; }

.display-title { font-size: 30px; line-height: 1.35; margin: 0 0 14px; letter-spacing: -.02em; }
.lede { font-size: 16px; color: var(--text-soft); margin: 0 0 22px; }
.muted { color: var(--text-mute); }
.soft { color: var(--text-soft); }
.small { font-size: 13px; }
.tiny { font-size: 12px; }
.center { text-align: center; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }

/* ---------- 卡片 ---------- */

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px;
  margin-bottom: 16px;
  box-shadow: var(--shadow);
}
.card-tight { padding: 16px; }
.card h2 { margin: 0 0 12px; font-size: 18px; }
.card h3 { margin: 20px 0 8px; font-size: 15px; }
.card p:last-child { margin-bottom: 0; }

/* ---------- 站头 / 页脚：只放「皮」，摆法在版本文件里 ---------- */

.site-header {
  display: flex;
  align-items: center;
  gap: 16px;
  background: var(--card);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 20;
}

/* ---------- 站头品牌 ----------
   站名只以「名称 logo 图片」呈现，不再有文字节点（图里已经带了
   CoalPal / 煤朋友 两行字，再写一遍文字会重复且对不齐）。

   ★ height 写死、width 交给 auto ★
     字标原始比例 385×199（约 1.93:1），定高之后宽度自动算出来，
     日后换一张比例不同的字标也不用动 CSS。
   ★ 用 <img> 而不是 background-image ★
     只有 <img> 带 alt —— 图挂了或读屏朗读时，站名仍然读得出来；
     背景图在这两种情况下就只是一个空白方块。 */
.brand { display: flex; align-items: center; }
.brand:hover { text-decoration: none; }

.site-nav { display: flex; align-items: center; }
.site-nav a { color: var(--text-soft); }

.nav-cta {
  border-radius: 999px;
  background: var(--brand-orange);
  color: var(--brand-ink) !important;
  font-weight: 600;
}

.inline-form { display: inline; }
.link-btn {
  background: none; border: none; padding: 0; cursor: pointer;
  font: inherit; color: var(--text-soft);
}

.env-banner {
  background: var(--warn-soft);
  border-bottom: 1px solid #fde68a;
  color: var(--warn);
  font-size: 13px;
  text-align: center;
}

.site-footer {
  border-top: 1px solid var(--line);
  background: var(--card);
}
/* 页脚导航：字号比正文小一档、间距放宽，避免看起来像正文里混进一堆链接 */
.footer-links { margin: 0 0 14px; font-size: 13px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.footer-links a { color: var(--text-soft); }
/* 页脚品牌行：小图标 + 中英文名，和备案号并排。
   图标做圆角并压到 16px —— 原始图是方形的 app 图标，
   不裁圆角放在一行小字里会显得很重。alt 留空：紧接着的文字已经写了站名，
   读屏软件不需要把同一个名字念两遍。 */
.footer-brand { display: inline-flex; align-items: center; gap: 6px; }
.footer-brand-icon { width: 16px; height: 16px; border-radius: 4px; display: block; }
.footer-sep { color: var(--line); }
.footer-note { margin: 0 0 6px; font-size: 12px; color: var(--text-mute); line-height: 1.7; }
.footer-legal { margin: 12px 0 0; font-size: 12px; color: var(--text-mute); display: flex; gap: 12px; flex-wrap: wrap; }

/* 备案号是链接（指向工信部备案系统）：颜色跟随页脚小字，
   只加一条细下划线提示可点 —— 用 --accent-text 会在这里过于抢眼。 */
.footer-legal a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--line);
  text-underline-offset: 3px;
}

/* ---------- 「切换电脑版 / 手机版」入口 ----------
   ★ 默认隐藏，由 device.js 给 <html> 打上 js-on 后显示 ★
     这个按钮只能靠 JS 生效（要写 cookie 并重载）。脚本没加载时把它显示出来，
     用户点了没反应，比看不见更糟。所以「JS 在不在」由 JS 自己声明。 */
.footer-switch { margin: 14px 0 0; }
.layout-switch {
  font-size: 12px; color: var(--text-mute);
  text-decoration: underline; text-underline-offset: 3px;
  display: none;
}
html.js-on .layout-switch { display: inline; }

/* ★ 锁定版式的页面（后台）永远不显示这个入口 ★
   服务端已经不再渲染它（base.html 里 `{% if not layout_locked %}`），
   这里再兜一道：HTML 缓存、模板回退、手改页面等任何原因让它漏出来时，
   也不会把一个「切过去就没有样式」的入口递给用户。 */
html[data-layout-locked] .layout-switch { display: none !important; }

/* ---------- 徽标 / 标签 ---------- */

.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px;
  background: var(--line-soft);
  color: var(--text-soft);
  white-space: nowrap;
}
.badge-accent { background: var(--accent-soft); color: var(--accent-dark); }
.badge-ok { background: var(--ok-soft); color: var(--ok); }
.badge-warn { background: var(--warn-soft); color: var(--warn); }
.badge-err { background: var(--err-soft); color: var(--err); }

/* ---------- 表单 ---------- */

label { display: block; font-size: 14px; font-weight: 550; margin-bottom: 6px; }

input[type=text], input[type=email], input[type=tel], input[type=number],
input[type=password], input[type=date], select, textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font: inherit;
  color: var(--text);
  background: #fff;
  transition: border-color .15s, box-shadow .15s;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
input::placeholder { color: #b5aea3; }

.field { margin-bottom: 16px; }
.field-hint { font-size: 12px; color: var(--text-mute); margin: 6px 0 0; }

/* ---------- 邮箱「固定后缀」输入框 ----------
   学号输入框 + 固定的 @域名 后缀拼成一个整体。
   后缀是纯展示（域名由服务端拼接），因此用 pointer-events:none
   避免用户误以为可以点击编辑。 */
.input-suffix { display: flex; align-items: stretch; }
.input-suffix input {
  flex: 1 1 auto;
  min-width: 0;              /* 允许 input 收缩，否则长后缀会把布局撑破 */
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
.input-suffix .suffix {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-left: none;
  border-top-right-radius: var(--radius-sm);
  border-bottom-right-radius: var(--radius-sm);
  background: #f4f1ea;
  color: var(--text-mute);
  font-size: 14px;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}
/* 聚焦时让后缀边框也跟着变色，视觉上是一个整体 */
.input-suffix input:focus + .suffix { border-color: var(--accent); }

/* ---------- 输入格式即时校验提示（app.js 动态写入） ----------
   .field-error 默认隐藏，JS 写入文字后自动显示（内容为空则收起），
   因此不需要 JS 去操作 display，避免出现「残留一个空提示块」。 */
.field-error {
  display: none;
  font-size: 12px;
  color: var(--err);
  margin: 6px 0 0;
}
.field-error:not(:empty) { display: block; }
input.input-invalid { border-color: var(--err); }
.input-suffix input.input-invalid + .suffix { border-color: var(--err); }

/* ---------- 按钮 ---------- */

.btn {
  display: inline-block;
  padding: 10px 20px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  /* 暖橙底 + 煤黑字（约 8:1）。反过来「橙底白字」只有 2.15:1，
     在户外或低亮度屏上基本看不清 —— 换品牌色时最容易踩的一脚。 */
  background: var(--brand-orange);
  color: var(--brand-ink);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  transition: background .15s;
}
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-block { display: block; width: 100%; }
.btn-ghost {
  background: #fff; color: var(--text-soft); border-color: var(--line);
}
.btn-danger { background: var(--err); }
.btn-sm { padding: 6px 12px; font-size: 13px; }

.btn-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

/* ---------- 选项卡片（问卷） ---------- */

.option-list { display: flex; flex-direction: column; gap: 8px; }
.option {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color .15s, background .15s;
  background: #fff;
  margin-bottom: 0;
  font-weight: 400;
}
.option input { margin: 3px 0 0; flex: 0 0 auto; accent-color: var(--accent); }
.option span { flex: 1; }
.option:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.option-multi:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }

/* 勾选确认 */
.check-row {
  display: flex; align-items: flex-start; gap: 10px;
  margin-bottom: 12px;
  font-size: 14px;
  font-weight: 400;
}
.check-row input { margin: 4px 0 0; flex: 0 0 auto; accent-color: var(--accent); }
.check-row label { margin: 0; font-weight: 400; }

/* 横向单选组（如「希望匹配到的对象」）。
   做成卡片式按钮而不是原生 radio 列表：几个选项是平级的、
   选中的那个需要一眼看出来，原生圆点在小屏上太细。 */
.radio-row { display: flex; gap: 10px; flex-wrap: wrap; }
.radio-item {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 14px; border: 1px solid var(--line);
  border-radius: var(--radius-sm); cursor: pointer;
  font-size: 14px; font-weight: 400; margin: 0;
  background: var(--card);
}
.radio-item input { margin: 0; flex: 0 0 auto; accent-color: var(--accent); }
/* 两行文案（标题 + 说明）的选项：给足宽度、对齐到顶部。
   两个意向各自带一句说明，单行版会把文字挤成尴尬的窄条。 */
.radio-item-wide {
  align-items: flex-start;
  padding: 10px 14px;
  line-height: 1.45;
}
.radio-item-wide input { margin-top: 3px; }

/* 选中态：靠 :has() 给整块加高亮（现代浏览器均支持；
   不支持的浏览器只是少了高亮，圆点仍能正确显示选中状态） */
.radio-item:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-text);
  font-weight: 600;
}

/* ---------- 提示条 ---------- */

.alert {
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  margin-bottom: 16px;
  border: 1px solid transparent;
}
.alert-err { background: var(--err-soft); color: var(--err); border-color: #fecaca; }
.alert-ok { background: var(--ok-soft); color: var(--ok); border-color: #bbf7d0; }
.alert-warn { background: var(--warn-soft); color: var(--warn); border-color: #fde68a; }
.alert-info { background: #f0f6ff; color: #1d4ed8; border-color: #bfdbfe; }
.alert-err h2 { color: var(--err); }

/* ---------- 步骤条 ---------- */

.steps { display: flex; gap: 0; margin: 0 0 24px; counter-reset: step; }
.step {
  flex: 1; text-align: center; position: relative;
  font-size: 12px; color: var(--text-mute);
  padding-top: 30px;
}
.step::before {
  counter-increment: step;
  content: counter(step);
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 24px; height: 24px; line-height: 24px;
  border-radius: 50%;
  background: var(--line-soft); color: var(--text-mute);
  font-size: 12px; font-weight: 600;
}
.step.done::before { background: var(--ok); color: #fff; }
.step.active::before { background: var(--brand-orange); color: var(--brand-ink); }
.step.active { color: var(--accent-text); font-weight: 600; }
.step.done { color: var(--ok); }
.step:not(:last-child)::after {
  content: ''; position: absolute; top: 11px; left: calc(50% + 16px);
  right: calc(-50% + 16px); height: 1px; background: var(--line);
}
.step.done:not(:last-child)::after { background: #bbf7d0; }

/* ---------- 进度条 ---------- */

.progress-wrap { margin: 0 0 18px; }
.progress-bar {
  height: 6px; background: var(--line-soft); border-radius: 999px; overflow: hidden;
}
.progress-fill {
  height: 100%; background: var(--accent); border-radius: 999px;
  transition: width .3s ease;
}
.progress-text { font-size: 12px; color: var(--text-mute); margin-top: 6px; }

/* ---------- 倒计时 ---------- */

.countdown { display: flex; gap: 8px; justify-content: center; margin: 18px 0 0; }
.countdown-cell {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  text-align: center;
}
.countdown-num { font-weight: 700; line-height: 1.2; font-variant-numeric: tabular-nums; }
.countdown-unit { font-size: 11px; color: var(--text-mute); }

/* ---------- 信息表 ---------- */

.info-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.info-table th, .info-table td {
  text-align: left; padding: 9px 12px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
}
.info-table th { color: var(--text-soft); font-weight: 550; }
.info-table tr:last-child th, .info-table tr:last-child td { border-bottom: none; }

/* ---------- 数据表（table.data）----------
   ★ 这张表前台和后台都在用，所以它属于「共用层」★
     后台：核验列表 / 用户列表 / 举报列表 / 审计 / 配对记录 / 邮件测试
     前台：templates/legal/privacy.html 的「三、信息的可见性一览」（5 列 ✅/❌ 矩阵）

     ★★ 曾经被错放进 desktop.css，是一次真实的可见事故 ★★
       当时按「它原本写在 style.css 的『运营后台』注释块下面」来判断归属，
       结果手机上看隐私政策时，这张表既没有表格样式、也没有下面那层
       .table-wrap 的横向滚动兜底，直接以浏览器默认样式渲染 ——
       页面没有报错，只是「某一块凭空没了样式」。
       判断一条规则放哪份文件，依据是**哪些页面会用到它**，不是它原本
       被写在哪个注释段下面。同类错误的自查脚本见 tests/test_layout_css.py。 */
table.data { width: 100%; border-collapse: collapse; font-size: 13px; }
table.data th, table.data td {
  padding: 9px 10px; border-bottom: 1px solid var(--line-soft);
  text-align: left; vertical-align: top;
}
table.data th { color: var(--text-soft); font-weight: 600; background: #fbf9f5; }

/* ★ 横向滚动兜底（手机的救命层）★
   宽表在窄屏上只滚动它自己，不要撑宽整页。
   ★ 关于「当初那次事故」的准确说法 ★
     事故的真实表现是**这张表在手机版下完全没有样式**（没有 border-collapse、
     没有单元格内边距、th 没有底色），以浏览器默认表格渲染；缺 `.table-wrap`
     是同一批规则里的连带损失。
     实测（Chromium，390px 视口）：privacy 那张 5 列表格即使**没有**这层包裹，
     文档宽度也没有被撑破（表格 356px，自适应换行挤下来了）。
     所以这层兜底的作用是**防止更宽的内容**（列更多、或含邮箱这类不可断行的长串）
     把整页撑宽 —— 别把它描述成「加了它才不出横向滚动条」。
   overscroll-behavior-x 防止滚到尽头后把整页/返回手势带走。 */
.table-wrap { overflow-x: auto; overscroll-behavior-x: contain; }

/* ★ 首列固定 ★
   横滚时最左列（「信息项」这类行名）始终可见，否则滚到右边就不知道
   自己在看谁那一行。必须给不透明的底色 —— 否则会透出从它下面滚过的内容。 */
table.data th:first-child,
table.data td:first-child {
  position: sticky; left: 0; z-index: 1;
  background: var(--card);
}
table.data th:first-child { background: #fbf9f5; }

/* ---------- 匹配结果 ---------- */

.match-card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 16px;
  background: var(--card);
  box-shadow: var(--shadow);
}
.match-head {
  background: linear-gradient(135deg, var(--accent-soft), #fff);
  border-bottom: 1px solid var(--line);
}
.match-score { font-weight: 750; color: var(--accent-text); line-height: 1.1; }
.match-score-label { font-size: 12px; color: var(--text-mute); }
.match-name { font-size: 20px; font-weight: 650; margin: 12px 0 4px; }

.reason-list { list-style: none; padding: 0; margin: 0; }
.reason-list li {
  position: relative;
  padding: 10px 0 10px 24px;
  border-bottom: 1px dashed var(--line);
  font-size: 14px;
  line-height: 1.7;
}
.reason-list li:last-child { border-bottom: none; }
.reason-list li::before {
  content: '✦';
  position: absolute; left: 2px; top: 10px;
  color: var(--accent); font-size: 12px;
}

.contact-box {
  background: var(--ok-soft);
  border: 1px solid #bbf7d0;
  border-radius: var(--radius-sm);
  padding: 16px;
  margin-top: 16px;
}
.contact-box .contact-item { font-size: 15px; margin: 6px 0; }
.contact-box .contact-label { color: var(--text-soft); font-size: 13px; }

.locked-box {
  background: var(--line-soft);
  border: 1px dashed var(--line);
  border-radius: var(--radius-sm);
  padding: 16px;
  margin-top: 16px;
  font-size: 14px;
  color: var(--text-soft);
  text-align: center;
}

/* ---------- 破冰任务卡 ---------- */

.task-list { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }
.task {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: #fff;
}
.task-day {
  flex: 0 0 34px;
  font-size: 12px; font-weight: 700; color: var(--accent-text);
  padding-top: 2px;
}
.task-title { font-size: 14px; font-weight: 600; margin-bottom: 2px; }
.task-detail { font-size: 13px; color: var(--text-soft); }

/* ---------- 折叠问答（落地页三个说明框）----------

   ★ 为什么是原生 <details>/<summary> 而不是自己写 JS ★
     ① 本站 CSP 是 `script-src 'self'`，模板里的内联脚本会被直接拦掉；
     ② 脚本没加载（网络/被拦/禁 JS）时，原生折叠**照样能展开** ——
        用 JS 实现的话，脚本一出问题这三块内容就永远打不开了；
     ③ 键盘与屏幕阅读器天然可用。
   收起时该块只有一行行问题，读起来像目录；点开才出答案。 */
.faq { margin-top: 4px; }
.faq-item { border-top: 1px solid var(--line-soft); }
.faq-item:last-child { border-bottom: 1px solid var(--line-soft); }
.faq-item > summary {
  display: flex; align-items: baseline; gap: 10px;
  padding: 13px 2px; cursor: pointer;
  font-size: 15px; font-weight: 600; color: var(--text);
  list-style: none;                 /* Firefox 去掉默认三角 */
}
.faq-item > summary::-webkit-details-marker { display: none; }  /* Chrome/Safari */
/* 右侧 ＋/－：默认三角太小，展开态也不明显 */
.faq-item > summary::after {
  content: "＋"; margin-left: auto; padding-left: 12px;
  color: var(--accent-text); font-weight: 700;
}
.faq-item[open] > summary::after { content: "－"; }
.faq-item[open] > summary { color: var(--accent-text); }
.faq-step {
  flex: 0 0 auto; font-size: 12px; font-weight: 700;
  color: var(--text-mute); font-variant-numeric: tabular-nums;
}
.faq-body {
  padding: 0 2px 14px; font-size: 14px; line-height: 1.75; color: var(--text-soft);
}
.faq-body p { margin: 0; }

/* ---------- 「我的信息」里的问卷清单 ----------

   一行一份问卷：左边名字 + 状态徽标 + 一句说明，右边一个按钮。
   ★ 为什么不用表格 ★
     表格的「说明」列会被挤成很窄的一条（.info-table 的 th 占 38%），
     而这里的说明是一整句人话；卡片行读起来更像待办清单，也更好按。 */
.q-row {
  display: flex; align-items: center; gap: 12px;
  justify-content: space-between;
  padding: 12px 0;
  border-top: 1px solid var(--line-soft);
}
.q-row:first-of-type { border-top: none; }
.q-name { font-size: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.q-desc { font-size: 13px; color: var(--text-soft); margin-top: 3px; line-height: 1.6; }
.q-action { flex: 0 0 auto; }

/* ---------- 品牌块（关于我们页） ----------
   图标 + 中英文名 + 标语。单独成块是因为「我们叫什么、图标长什么样」
   是那一页最该被记住的一件事，混在段落里会被直接读过去。 */
.brand-block {
  display: flex; gap: 18px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px 22px;
  margin-bottom: 16px;
  box-shadow: var(--shadow);
}
.brand-block-icon { width: 84px; height: 84px; border-radius: 18px; display: block; flex: 0 0 auto; }
.brand-block-text { min-width: 0; }
.brand-block-name {
  margin: 0; font-size: 24px; font-weight: 750; letter-spacing: -.01em;
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}
.brand-block-en {
  font-size: 14px; font-weight: 600; letter-spacing: .02em;
  color: var(--accent-text);
}
.brand-block-sub { margin: 6px 0 0; font-size: 14px; color: var(--text-soft); }

/* ---------- 「联系我们」页的负责人邮箱 ----------
   这是本页唯一的联系方式，所以刻意做得比正文大得多、且可点击。
   字号用 clamp：小屏不至于把邮箱挤成两行（邮箱是一整个词，不能折行），
   大屏又能足够醒目。 */
/* 边框用饱和的橙而不是浅橙底：这张卡是整页唯一要用户动手的目标，
   浅橙（#fff6e8）描边在白卡上几乎看不见，等于没画。 */
.card-accent { border-color: var(--accent); }
.contact-email-label { margin: 14px 0 2px; font-size: 13px; color: var(--text-mute); }
.contact-email {
  margin: 0;
  line-height: 1.25;
  /* 邮箱是长单词，窄屏必须允许断开，否则会撑破卡片造成横向滚动 */
  word-break: break-all;
}
.contact-email a {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: clamp(17px, 4.4vw, 26px);
  font-weight: 700;
  color: var(--accent-text);
  text-decoration: none;
  letter-spacing: -0.2px;
}

.big-num { font-size: 28px; font-weight: 700; }

/* ---------- 首屏宣传图 ----------
   撑满所在栏宽度。
   ★ 不裁切 ★
     图里自带站名和标语，object-fit: cover 裁一刀正好会把它们切掉，
     所以只做等比缩放，让它自然高一些。
   ★ display:block 去不掉 ★
     <img> 默认是行内元素，底部会多出几个像素的基线空隙，
     表现为图片下方一条莫名其妙的留白。 */
.hero { padding: 0 0 8px; }
.hero-banner { margin: 0; }
.hero-banner img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
}

/* ---------- 联系方式编辑器（类型下拉 + 值，可多行） ----------
   三处共用（注册第二步 / 隐私控制中心 / 联系方式页），见 partials/contact_rows.html。
   列宽与折行规则两套版式不同，见 desktop.css / mobile.css。 */
.contact-rows { display: flex; flex-direction: column; gap: 8px; }
.contact-row { display: grid; gap: 8px; align-items: center; }
.contact-row select,
.contact-row input { width: 100%; margin: 0; }
.contact-row .btn { white-space: nowrap; }

/* ---------- 收件箱（开发用） ---------- */

.mail-item {
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 14px; margin-bottom: 10px; background: #fff;
}
.mail-item pre {
  white-space: pre-wrap; word-break: break-word;
  font-size: 12px; background: var(--line-soft);
  padding: 10px; border-radius: 6px; margin: 8px 0 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* ---------- 已接入的学校（按城市分组的小卡）----------

   ★ 为什么按城市分组 ★
     学校一多，一长条平铺没人看得完；按地区分组后学生只看自己那一组，
     而且"还没开到我们这儿"一眼可见。
   ★ 为什么做成胶囊卡而不是列表行 ★
     学校是一项"有没有"的信息，不是需要逐条比较的数据 ——
     胶囊能并排铺开，十几所也占不了半屏；列表行会拉成一条长龙。
   ★ 卡里三段信息的顺序固定：缩写 → 全名 → 人数 ★
     缩写用来扫读，全名用来确认（避免认成别的校区），人数是"这里有人"的信号。
     ★ 中文简称那一段已按需求撤掉（2026-10-14）★ 对应的 `.school-short` 类
     一并删掉了 —— 留着一条没有任何模板使用的规则，下一个人只会困惑它管什么。
     后台开关卡片显示简称走的是 `.flag-school-head`，与这里无关。
   ★ 人数可能不存在 ★ 低于门槛的学校不显示（新站点上写"已加入 3 人"是反向宣传），
     所以这块样式必须容忍少一个子元素。 */
.school-group { margin-top: 14px; }
.school-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.school-city {
  font-size: 12px; font-weight: 650; letter-spacing: .05em;
  color: var(--text-mute); margin-bottom: 8px;
}
.school-chip {
  display: inline-flex; align-items: baseline; gap: 7px; flex-wrap: wrap;
  padding: 9px 14px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--line-soft);
  color: var(--text); text-decoration: none;
  font-size: 14px; line-height: 1.35;
}
.school-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px; font-weight: 700; letter-spacing: .06em;
  color: var(--accent-text);
}
.school-full { font-size: 12.5px; color: var(--text-soft); }
.school-count { font-size: 12px; color: var(--text-mute); }

/* ---------- 运营开关：按学校分块（后台总览）----------
   每所学校一块，块之间用一条细线分隔。第一块不要这条线，否则卡片
   标题下面会先出现一道"无来源"的分隔线。 */
.flag-school {
  padding-top: 18px; margin-top: 18px;
  border-top: 1px solid var(--line-soft);
}
.flag-school:first-of-type { padding-top: 0; margin-top: 0; border-top: none; }
.flag-school-head {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin: 0 0 10px; font-size: 16px;
}
.flag-school-head .school-full { font-weight: 400; }

/* ---------- 空状态 ---------- */

.empty { text-align: center; padding: 40px 20px; color: var(--text-mute); }
.empty-icon { font-size: 32px; margin-bottom: 10px; opacity: .5; }

/* ---------- 错误页 ---------- */

.error-page { text-align: center; }
.error-code { font-size: 56px; font-weight: 750; color: var(--line); line-height: 1; }

/* 减少动画偏好。
   ★ 这不是断点 ★ 与屏幕宽度无关，所以留在公共层。
     prefers-reduced-motion 命中时两个版本都要关掉动效。 */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
