/* 同舟 · 全站基础样式。模块专属样式请写在 static/<module>.css，并在模板 head block 中引入。
 *
 * 目录
 *   0. 设计变量（浅色 / 深色 / 树洞主题）
 *   1. 基础排版
 *   2. 顶栏与底部 Tab
 *   3. 通用组件（卡片、按钮、标签、徽章、表单、表格、首页）
 *   4. 新增通用类（.pagination .chip .kbd .stat .avatar .highlight .skeleton .toolbar .collapse 等）
 *   5. 焦点、动效与无障碍
 *   6. 手机与触控适配
 *   7. 深色模式（含树洞深色、模块硬编码颜色的兜底覆盖）
 *
 * 约定：颜色一律用变量；需要新颜色请先加变量，并同时给出深色值。
 * 对比度：正文/小字与背景均已按 WCAG AA（≥ 4.5:1）校验，改色时请复核。
 */

/* ============ 0. 设计变量 ============ */
:root {
  color-scheme: light;
  --bg: #FAF7F2;          /* 暖白 */
  --surface: #FFFFFF;
  --surface-2: #FBF9F6;   /* 表头、引用块等次级底色 */
  --input-bg: #FFFFFF;
  --text: #2B2B2B;
  --muted: #6B645A;       /* 原 #7A7368 在 --bg 上仅 4.39:1，加深到 5.47:1 */
  --line: #E8E1D6;
  --line-strong: #D6CCBD;
  --primary: #2F5D62;     /* 黛青 */
  --primary-hover: #244A4E;
  --primary-soft: #E3EDEC;
  --on-primary: #FFFFFF;  /* 实心主色按钮上的文字 */
  --accent: #E8A87C;      /* 杏色 */
  --on-accent: #3A2A1D;
  --red: #C0392B;
  --red-soft: #FBE9E7;
  --red-line: #E6B8B2;
  --on-red: #FFFFFF;
  --amber: #8A5A14;       /* 原 #B7791F 在 --amber-soft 上仅 3.3:1，加深到 5.4:1 */
  --amber-soft: #FDF3E1;
  --amber-ink: #7A5A1F;
  --green: #1E6B34;
  --green-soft: #E6F4EA;
  --gray-soft: #EFEDEA;
  --help: #6B5CA5;        /* 雾紫：求助入口、树洞 */
  --help-soft: #F4F2F8;
  --help-line: #E3DEEE;
  --hl-bg: #FCE7A8;       /* 搜索高亮 */
  --skeleton-a: #EFEBE4;
  --skeleton-b: #F7F4EF;

  /* 圆角 */
  --radius: 12px;
  --radius-sm: 8px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-pill: 999px;

  /* 间距（4px 基准） */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px; --sp-6: 32px;

  /* 字号 */
  --fs-xs: 12px; --fs-sm: 13px; --fs-base: 15px; --fs-md: 16px; --fs-lg: 18px; --fs-xl: 22px; --fs-2xl: 26px;

  /* 阴影：一层轻、一层悬停 */
  --shadow-1: 0 1px 2px rgba(43, 36, 24, .04), 0 1px 1px rgba(43, 36, 24, .03);
  --shadow-2: 0 6px 18px -6px rgba(43, 36, 24, .14), 0 2px 4px rgba(43, 36, 24, .05);
  --shadow-bar: 0 -1px 0 var(--line), 0 -6px 16px -10px rgba(43, 36, 24, .18);
  --focus: #2F5D62;
  --focus-ring: 0 0 0 3px rgba(47, 93, 98, .22);

  /* 动效 */
  --ease: cubic-bezier(.2, .7, .2, 1);
  --dur: .18s;

  /* 手机底部 Tab 高度（不含安全区） */
  --tabbar-h: 58px;
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

/* ============ 1. 基础排版 ============ */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-padding-top: 72px; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font: 15px/1.65 -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "Segoe UI", system-ui, sans-serif;
  padding-bottom: 72px;
  overflow-wrap: break-word;        /* 长英文单词、URL 不撑破布局 */
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}
a { color: var(--primary); text-decoration: none; text-underline-offset: 2px; }
a:hover { text-decoration: underline; }
img, video, svg, canvas { max-width: 100%; height: auto; }
pre { overflow-x: auto; white-space: pre-wrap; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: var(--sp-3); font-size: var(--fs-sm); }
code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .92em; }
hr { border: 0; border-top: 1px solid var(--line); margin: var(--sp-5) 0; }
::selection { background: var(--primary-soft); color: var(--text); }
.wrap { max-width: 960px; margin: 0 auto; padding: 0 16px; }
.main { padding-top: 20px; padding-bottom: 32px; min-height: 60vh; }
h1, h2, h3 { line-height: 1.35; margin: 0 0 12px; letter-spacing: .01em; }
h1, h2 { text-wrap: balance; }
h1 { font-size: var(--fs-xl); } h2 { font-size: var(--fs-lg); } h3 { font-size: var(--fs-md); }
p, li, dd { text-wrap: pretty; }
.muted { color: var(--muted); }
.small { font-size: var(--fs-sm); }

/* ============ 2. 顶栏 ============ */
.topbar { background: var(--surface); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 10; }
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) and (color: color-mix(in srgb, red 50%, blue)) {
  .topbar { background: color-mix(in srgb, var(--surface) 88%, transparent); -webkit-backdrop-filter: saturate(1.4) blur(12px); backdrop-filter: saturate(1.4) blur(12px); }
}
.topbar-inner { display: flex; align-items: center; gap: 20px; height: 56px; }
.logo { font-weight: 700; font-size: 19px; color: var(--primary); white-space: nowrap; letter-spacing: .02em; }
.logo:hover { text-decoration: none; }
.logo span { font-size: 12px; font-weight: 400; color: var(--muted); margin-left: 6px; letter-spacing: 0; }
.topnav { display: flex; gap: 4px; }
.topnav a { padding: 6px 12px; border-radius: var(--radius-sm); color: var(--text); transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease); }
.topnav a:hover { text-decoration: none; background: var(--gray-soft); }
.topnav a.on { background: var(--primary-soft); color: var(--primary); font-weight: 600; }
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.topbar-right > a.small { white-space: nowrap; max-width: 9em; overflow: hidden; text-overflow: ellipsis; }
.bell { position: relative; display: inline-flex; align-items: center; justify-content: center; min-width: 32px; min-height: 32px; border-radius: var(--radius-sm); }
.bell:hover { text-decoration: none; background: var(--gray-soft); }
.bell em { position: absolute; top: -2px; right: -6px; background: var(--red); color: var(--on-red); font-style: normal; font-size: 11px; font-weight: 600; line-height: 16px; min-width: 16px; text-align: center; border-radius: 10px; padding: 0 5px; box-shadow: 0 0 0 2px var(--surface); font-variant-numeric: tabular-nums; }

/* 底部 Tab（手机）：已处理 iPhone 底部安全区 */
.tabbar { display: none; position: fixed; bottom: 0; left: 0; right: 0; background: var(--surface); border-top: 1px solid var(--line); z-index: 10;
  padding-bottom: var(--safe-bottom); padding-left: env(safe-area-inset-left, 0px); padding-right: env(safe-area-inset-right, 0px); box-shadow: var(--shadow-bar); }
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) and (color: color-mix(in srgb, red 50%, blue)) {
  .tabbar { background: color-mix(in srgb, var(--surface) 90%, transparent); -webkit-backdrop-filter: saturate(1.4) blur(14px); backdrop-filter: saturate(1.4) blur(14px); }
}
.tabbar a { flex: 1; text-align: center; font-size: 11px; color: var(--muted); padding: 6px 0 8px; min-height: var(--tabbar-h);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; position: relative; transition: color var(--dur) var(--ease); }
.tabbar a:hover { text-decoration: none; }
.tabbar a i { display: block; font-style: normal; font-size: 20px; line-height: 1.3; transition: transform var(--dur) var(--ease); }
.tabbar a.on { color: var(--primary); font-weight: 600; }
.tabbar a.on::before { content: ""; position: absolute; top: 0; left: 50%; width: 24px; height: 3px; margin-left: -12px; border-radius: 0 0 3px 3px; background: var(--primary); }
.tabbar a:active i { transform: scale(.9); }
@media (max-width: 720px) {
  .topnav { display: none; }
  .tabbar { display: flex; }
  body { padding-bottom: calc(var(--tabbar-h) + var(--safe-bottom) + 16px); }
  .topbar-inner { gap: 12px; }
}
@media (min-width: 721px) { body { padding-bottom: 0; } }

.footer { padding: 24px 16px 32px; font-size: 13px; display: flex; flex-wrap: wrap; gap: 12px; align-items: center; border-top: 1px solid var(--line); color: var(--muted); }
.help-link { color: var(--help); font-weight: 600; }
.footer-credit { flex-basis: 100%; margin: 0; }

/* ============ 3. 通用组件 ============ */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; margin-bottom: 12px; box-shadow: var(--shadow-1);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease); }
.card h3 a { color: var(--text); }
.card h3 a:hover { color: var(--primary); }
/* 可点击卡片的悬停：整卡是链接时轻微上浮，含标题链接时只加深阴影 */
@media (hover: hover) {
  a.card:hover { text-decoration: none; border-color: var(--line-strong); box-shadow: var(--shadow-2); transform: translateY(-1px); }
  .card:has(h3 a):hover, .card:has(> a:only-child):hover { border-color: var(--line-strong); box-shadow: var(--shadow-2); }
}
a.card:active { transform: translateY(0); box-shadow: var(--shadow-1); }
.section { margin: 24px 0; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.section-head h2 { margin-bottom: 0; }
.section-head > a { white-space: nowrap; }
.grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr)); }
.grid > .card { margin-bottom: 0; }
.row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.spacer { flex: 1; }
.empty { text-align: center; padding: 32px 16px; color: var(--muted); }
.flash { background: var(--primary-soft); color: var(--primary); padding: 10px 14px; border-radius: var(--radius-md); margin-bottom: 14px; border: 1px solid color-mix(in srgb, var(--primary) 18%, transparent); }
.notice { background: var(--amber-soft); color: var(--amber-ink); padding: 10px 14px; border-radius: var(--radius-md); font-size: 13px; margin-bottom: 14px; border: 1px solid color-mix(in srgb, var(--amber) 18%, transparent); }

.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: 1px solid var(--line-strong); background: var(--surface); color: var(--text);
  padding: 8px 16px; border-radius: var(--radius-md); cursor: pointer; font: inherit; line-height: 1.4; text-align: center; vertical-align: middle;
  -webkit-user-select: none; user-select: none; touch-action: manipulation;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform .08s var(--ease); }
.btn:hover { text-decoration: none; border-color: var(--primary); }
.btn:active { transform: translateY(1px) scale(.985); }
.btn:disabled, .btn[disabled], .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; }
.btn-primary { background: var(--primary); color: var(--on-primary); border-color: var(--primary); box-shadow: 0 1px 2px rgba(0, 0, 0, .08); }
.btn-primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
.btn-primary:active { background: var(--primary-hover); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .18); }
.btn-ghost { background: transparent; }
.btn-ghost:hover { background: var(--gray-soft); }
.btn-sm { padding: 4px 12px; font-size: 13px; border-radius: var(--radius-sm); }
.btn-danger { color: var(--red); border-color: var(--red-line); }
.btn-danger:hover { border-color: var(--red); background: var(--red-soft); }
.linkbtn { background: none; border: none; color: var(--primary); cursor: pointer; padding: 0; font: inherit; border-radius: 4px; }
.linkbtn:hover { text-decoration: underline; }

.tag { display: inline-block; font-size: 12px; line-height: 1.6; padding: 1px 8px; border-radius: 999px; background: var(--gray-soft); color: var(--muted); margin-right: 4px; transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease); }
a.tag:hover { text-decoration: none; color: var(--primary); background: var(--primary-soft); }
.tag-primary { background: var(--primary-soft); color: var(--primary); }
.badge { display: inline-block; font-size: 12px; font-weight: 600; padding: 2px 8px; border-radius: 6px; line-height: 1.5; font-variant-numeric: tabular-nums; white-space: nowrap; }
.badge-red { background: var(--red-soft); color: var(--red); }
.badge-amber { background: var(--amber-soft); color: var(--amber); }
.badge-normal { background: var(--primary-soft); color: var(--primary); }
.badge-past { background: var(--gray-soft); color: var(--muted); }

/* 表单 */
.form { max-width: 560px; }
.form label { display: block; font-size: 14px; font-weight: 600; margin: 14px 0 6px; }
.form .hint { font-weight: 400; color: var(--muted); font-size: 12px; }
input[type=text], input[type=email], input[type=password], input[type=number], input[type=url], input[type=date], input[type=time], input[type=search], input[type=tel], input[type=datetime-local], select, textarea {
  width: 100%; padding: 9px 12px; border: 1px solid var(--line-strong); border-radius: var(--radius-md); background: var(--input-bg); font: inherit; color: var(--text);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
input::placeholder, textarea::placeholder { color: var(--muted); opacity: .85; }
textarea { min-height: 120px; resize: vertical; line-height: 1.6; }
input:hover, select:hover, textarea:hover { border-color: var(--muted); }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--primary-soft); border-color: var(--primary); }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; border-color: var(--primary); box-shadow: var(--focus-ring); }
input:disabled, select:disabled, textarea:disabled { opacity: .6; cursor: not-allowed; }
input[type=checkbox], input[type=radio] { accent-color: var(--primary); width: 18px; height: 18px; }
.form .actions { margin-top: 18px; display: flex; gap: 10px; flex-wrap: wrap; }
.check { display: flex; align-items: center; gap: 6px; font-weight: 400 !important; }
fieldset { border: 1px solid var(--line); border-radius: var(--radius-md); padding: var(--sp-3) var(--sp-4); margin: var(--sp-4) 0; }
legend { padding: 0 var(--sp-1); font-weight: 600; font-size: 14px; }

/* 表格：外面包一层 .table-scroll 即可在窄屏横向滚动 */
table.table { width: 100%; border-collapse: collapse; background: var(--surface); border-radius: var(--radius); overflow: hidden; }
.table th, .table td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); vertical-align: top; }
.table tr:last-child td { border-bottom: 0; }
.table th { font-size: 13px; color: var(--muted); font-weight: 600; background: var(--surface-2); white-space: nowrap; }
@media (hover: hover) { .table tbody tr:hover td { background: color-mix(in srgb, var(--primary-soft) 45%, transparent); } }
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); margin-bottom: 12px; }
.table-scroll > table.table { border-radius: 0; }
@media (max-width: 720px) {
  .table-scroll { overflow-x: auto; }
  .table-scroll > table { min-width: 560px; }
  .table td { overflow-wrap: anywhere; }
}

/* 首页 */
.hero { background: linear-gradient(135deg, #2F5D62, #3E7A7F); color: #fff; border-radius: var(--radius-lg); padding: 28px 24px; margin-bottom: 20px; box-shadow: var(--shadow-2); position: relative; overflow: hidden; }
.hero::after { content: ""; position: absolute; right: -60px; top: -60px; width: 220px; height: 220px; border-radius: 50%; background: radial-gradient(closest-side, rgba(232, 168, 124, .28), transparent); pointer-events: none; }
.hero > * { position: relative; z-index: 1; }
.hero h1 { font-size: 24px; color: #fff; }
.hero p { opacity: .92; margin: 0 0 16px; }
.hero form { display: flex; gap: 8px; max-width: 520px; }
.hero input { flex: 1; border: none; min-width: 0; }
.hero input:focus-visible { box-shadow: 0 0 0 3px rgba(255, 255, 255, .55); }
.hero .btn { background: var(--accent); border-color: var(--accent); color: #3a2a1d; }
.hero .btn:hover { filter: brightness(1.05); }
.hero :focus-visible { outline-color: #fff; }

/* 树洞主题（雾紫） */
body.theme-treehole { --bg: #F4F2F8; --primary: #6B5CA5; --primary-soft: #ECE8F6; --line: #E3DEEE;
  --primary-hover: #574A8C; --line-strong: #D3CBE4; --surface-2: #F8F6FB; --focus: #6B5CA5; --focus-ring: 0 0 0 3px rgba(107, 92, 165, .24);
  --muted: #655F70; --skeleton-a: #EAE6F2; --skeleton-b: #F5F3F9; }
body.theme-treehole .topbar, body.theme-treehole .tabbar { background: #FBFAFD; }
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) and (color: color-mix(in srgb, red 50%, blue)) {
  body.theme-treehole .topbar, body.theme-treehole .tabbar { background: color-mix(in srgb, #FBFAFD 90%, transparent); }
}

/* ============ 4. 新增通用类 ============ */

/* .pagination —— 通用分页
 *   <nav class="pagination" aria-label="分页">
 *     <a href="?page=1" rel="prev">‹ 上一页</a>
 *     <a href="?page=1">1</a>
 *     <a class="on" aria-current="page">2</a>      ← 当前页：.on 或 aria-current="page"
 *     <span class="gap">…</span>                    ← 省略号
 *     <span class="off">下一页 ›</span>             ← 不可点
 *     <span class="pagination-count">2 / 9</span>   ← 手机端可只留这个和上下页
 *   </nav>
 * 手机端会自动隐藏 .pagination-num（给数字页码加上这个类即可）。 */
.pagination { display: flex; align-items: center; justify-content: center; gap: 6px; flex-wrap: wrap; margin: 20px 0 8px; }
.pagination > a, .pagination > span { min-width: 36px; height: 36px; padding: 0 10px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm); font-size: 14px; font-variant-numeric: tabular-nums; }
.pagination > a { border: 1px solid var(--line); background: var(--surface); color: var(--text); transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease); }
.pagination > a:hover { text-decoration: none; border-color: var(--primary); color: var(--primary); }
.pagination > .on, .pagination > [aria-current="page"] { background: var(--primary); border-color: var(--primary); color: var(--on-primary); font-weight: 600; }
.pagination > .gap { color: var(--muted); min-width: 20px; padding: 0; }
.pagination > .off { color: var(--muted); opacity: .55; cursor: default; border: 1px solid var(--line); }
.pagination-count { color: var(--muted); }

/* .chip / .chip.on —— 可选中的小药丸（筛选条件、多选标签）
 *   <a class="chip" href="?tag=ml">机器学习</a>
 *   <a class="chip on" href="?tag=">全部 <b>12</b></a>   ← .on 或 aria-pressed="true" 表示选中
 *   <button type="button" class="chip" aria-pressed="false">只看已核实</button>
 *   <label class="chip"><input type="checkbox" name="t" value="cs"> CS</label>  ← 勾选后自动高亮
 * 一组放进 <div class="chips"> 自动换行。 */
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip { display: inline-flex; align-items: center; gap: 4px; min-height: 32px; padding: 4px 12px; border: 1px solid var(--line-strong); border-radius: var(--radius-pill);
  background: var(--surface); color: var(--text); font: inherit; font-size: 13px; line-height: 1.4; cursor: pointer; white-space: nowrap; position: relative;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease); }
.chip:hover { text-decoration: none; border-color: var(--primary); color: var(--primary); }
.chip:active { transform: scale(.97); }
.chip.on, .chip[aria-pressed="true"], .chip:has(input:checked) { background: var(--primary-soft); border-color: var(--primary); color: var(--primary); font-weight: 600; }
.chip input[type=checkbox], .chip input[type=radio] { width: 14px; height: 14px; margin: 0; }
.chip b { font-weight: 600; font-variant-numeric: tabular-nums; }

/* .kbd —— 键盘按键提示：按 <kbd class="kbd">/</kbd> 搜索（裸 <kbd> 也有同样样式） */
kbd, .kbd { display: inline-block; min-width: 1.6em; padding: 0 .4em; font: 600 12px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; text-align: center;
  color: var(--text); background: var(--surface); border: 1px solid var(--line-strong); border-bottom-width: 2px; border-radius: 5px; vertical-align: .1em; }

/* .stat / .stat-num —— 统计数字块
 *   <div class="stat-grid">
 *     <div class="stat"><span class="stat-num">128</span><span class="stat-label">已核实项目</span></div>
 *     <a class="stat hot" href="…"><span class="stat-num">3</span><span class="stat-label">7 天内截止</span></a>
 *   </div>
 * .stat.hot 数字变红，.stat.good 数字变绿；.stat-grid 自动铺满 2–4 列。 */
.stat-grid { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(min(130px, 100%), 1fr)); margin-bottom: 12px; }
.stat { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; text-align: center; color: var(--text);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 8px; box-shadow: var(--shadow-1);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
a.stat:hover { text-decoration: none; border-color: var(--primary); box-shadow: var(--shadow-2); }
.stat-num { display: block; font-size: 24px; font-weight: 700; line-height: 1.2; color: var(--primary); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.stat-label { font-size: 12px; color: var(--muted); }
.stat.hot .stat-num { color: var(--red); }
.stat.good .stat-num { color: var(--green); }

/* .avatar —— 圆形头像 / 首字
 *   <span class="avatar">A</span>   <span class="avatar avatar-sm">小</span>   <span class="avatar avatar-lg"><img src="…" alt=""></span>
 *   匿名代号用 .avatar.avatar-anon（雾紫）。 */
.avatar { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 32px; height: 32px; border-radius: 50%; overflow: hidden;
  background: var(--primary-soft); color: var(--primary); font-size: 14px; font-weight: 700; line-height: 1; text-transform: uppercase; vertical-align: middle;
  box-shadow: 0 0 0 2px var(--surface); }
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.avatar-sm { width: 24px; height: 24px; font-size: 11px; }
.avatar-lg { width: 48px; height: 48px; font-size: 20px; }
.avatar-anon { background: var(--help-soft); color: var(--help); }

/* .highlight / <mark> —— 搜索关键词高亮：{{ text | replace(q, '<mark>'~q~'</mark>') }} 或 <span class="highlight">…</span> */
mark, .highlight { background: var(--hl-bg); color: inherit; padding: 0 2px; border-radius: 3px; -webkit-box-decoration-break: clone; box-decoration-break: clone; }

/* .skeleton —— 加载占位（灰色块，有克制的流光；减少动效时静止）
 *   <div class="skeleton skeleton-text"></div>              一行文字
 *   <div class="skeleton skeleton-text" style="width:60%"></div>
 *   <div class="skeleton skeleton-block"></div>             卡片 / 图片区
 *   <span class="skeleton skeleton-circle"></span>          头像
 * 占位容器请加 aria-busy="true"，读屏会跳过。 */
.skeleton { display: block; background: linear-gradient(90deg, var(--skeleton-a) 0%, var(--skeleton-b) 50%, var(--skeleton-a) 100%); background-size: 200% 100%;
  border-radius: var(--radius-sm); animation: tz-shimmer 1.4s ease-in-out infinite; color: transparent !important; pointer-events: none; -webkit-user-select: none; user-select: none; }
.skeleton-text { height: .9em; margin: .45em 0; border-radius: 4px; }
.skeleton-block { height: 96px; border-radius: var(--radius); }
.skeleton-circle { width: 32px; height: 32px; border-radius: 50%; display: inline-block; }
@keyframes tz-shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }

/* .toolbar —— 列表顶部的操作条：搜索 / 筛选 / 排序 / 按钮，窄屏自动换行
 *   <div class="toolbar">
 *     <form class="toolbar-grow">…搜索框…</form>
 *     <div class="toolbar-group"><a class="chip on">最新</a><a class="chip">最热</a></div>
 *     <span class="spacer"></span>
 *     <a class="btn btn-primary btn-sm">发帖</a>
 *   </div> */
.toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin-bottom: 14px; }
.toolbar-group { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.toolbar-grow { flex: 1 1 220px; min-width: 0; }
.toolbar form { margin: 0; }
.toolbar-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; box-shadow: var(--shadow-1); }

/* .collapse —— 折叠面板（原生 <details>，无需 JS）
 *   <details class="collapse">
 *     <summary>为什么要填北京时间？</summary>
 *     <div class="collapse-body">…</div>
 *   </details>
 * 加 .collapse-card 变成带边框的卡片样式；多个连续放置会自动合并边框。 */
.collapse { margin: 0 0 8px; }
.collapse > summary { display: flex; align-items: center; gap: 8px; cursor: pointer; list-style: none; padding: 8px 0; min-height: 40px; font-weight: 600; border-radius: var(--radius-sm); -webkit-user-select: none; user-select: none; }
.collapse > summary::-webkit-details-marker { display: none; }
.collapse > summary::before { content: ""; flex: none; width: 7px; height: 7px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: rotate(-45deg); transition: transform var(--dur) var(--ease); margin: 0 4px 0 2px; }
.collapse[open] > summary::before { transform: rotate(45deg); }
.collapse > summary:hover { color: var(--primary); }
.collapse-body { padding: 0 0 8px 21px; }
.collapse-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 0 14px; }
.collapse-card + .collapse-card { margin-top: -1px; }
.collapse-card > summary { padding: 10px 0; }

/* 其他小工具类 */
.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.break-all { overflow-wrap: anywhere; word-break: break-word; }
.num { font-variant-numeric: tabular-nums; }
.divider { height: 1px; background: var(--line); border: 0; margin: 16px 0; }
.card-soft { background: var(--help-soft); border-color: var(--help-line); }      /* 雾紫柔和卡片，用于“树洞/关怀”入口 */
.card-soft h2, .card-soft h3, .card-soft .card-soft-link { color: var(--help); }

/* ============ 5. 焦点、动效与无障碍 ============ */
/* 键盘可见焦点：鼠标点击不显示，Tab 键导航时显示清晰的 2px 主色描边 */
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
a:focus-visible, .btn:focus-visible, .chip:focus-visible, .linkbtn:focus-visible, summary:focus-visible, button:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--radius-sm); }
.card:focus-within { border-color: var(--line-strong); }
.tabbar a:focus-visible { outline-offset: -4px; }
[hidden] { display: none !important; }

/* 页面载入：主体内容 0.24s 轻淡入（仅首帧，不影响后续交互） */
@keyframes tz-fade-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.main { animation: tz-fade-in .24s var(--ease) backwards; }
.flash { animation: tz-fade-in .3s var(--ease) backwards; }
details[open] > :not(summary) { animation: tz-fade-in .16s var(--ease) backwards; }

/* 尊重“减少动态效果”系统设置：关闭所有动画与过渡 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
  .main, .flash, details[open] > :not(summary) { animation: none !important; }
  .skeleton { animation: none !important; background: var(--skeleton-a); }
  a.card:hover, .btn:active, .chip:active { transform: none !important; }
}
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }

/* 高对比模式（Windows）下保留边框 */
@media (forced-colors: active) {
  .btn, .chip, .tag, .badge, .card { border: 1px solid CanvasText; }
  .tabbar a.on::before { background: Highlight; }
}

/* ============ 6. 手机与触控适配 ============ */
@media (max-width: 720px) {
  .main { padding-top: 16px; }
  h1 { font-size: 20px; }
  .card { padding: 14px; }
  .hero { padding: 22px 18px; border-radius: 14px; }
  .hero h1 { font-size: 21px; }
  .section { margin: 20px 0; }
  .footer { padding: 20px 16px 24px; }
  /* iOS 输入框字号 < 16px 会自动放大页面 */
  input[type=text], input[type=email], input[type=password], input[type=number], input[type=url], input[type=search], input[type=tel], input[type=date], input[type=time], select, textarea { font-size: 16px; }
  .card, .flash, .notice, .empty { overflow-wrap: anywhere; }
  .card h3, .card h3 a { overflow-wrap: anywhere; }
  .pagination .pagination-num { display: none; }
  .form .actions .btn { flex: 1 1 auto; }
}

/* 触控设备（或窄屏）：可点元素至少 44×44px */
@media (pointer: coarse), (max-width: 720px) {
  .btn, .btn-sm { min-height: 44px; }
  .btn-sm { padding: 6px 14px; }
  input[type=text], input[type=email], input[type=password], input[type=number], input[type=url], input[type=search], input[type=tel], input[type=date], input[type=time], input[type=datetime-local], select { min-height: 44px; }
  .linkbtn { min-height: 44px; display: inline-flex; align-items: center; padding: 0 4px; }
  .topnav a, .topbar-right > a, .bell { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; justify-content: center; }
  .pagination > a, .pagination > span { min-width: 44px; height: 44px; }
  .chip { min-height: 44px; padding: 6px 14px; }
  .collapse > summary { min-height: 44px; }
  /* 各模块的分段导航、页码、小药丸：保证 44px 高度（不改变原有配色） */
  .pg-subnav a, .ap-subnav a, .cm-tabs a, .th-tabs a, .adm-nav a, .ap-seg a { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
  .pg-pager-nums a, .cm-pager-nums a { min-width: 44px; height: 44px; }
  .th-react { min-height: 44px; }
  .check { min-height: 44px; }
  /* 视觉上很小的标签/药丸：用透明伪元素把点击区扩到 44px，不改变外观 */
  a.tag, .ap-chip, .form .th-need, .form .cm-tagopt, .th-report summary, .cm-replybox summary, .cm-report summary { position: relative; }
  a.tag::after, .ap-chip::after, .form .th-need::after, .form .cm-tagopt::after, .th-report summary::after, .cm-replybox summary::after, .cm-report summary::after {
    content: ""; position: absolute; left: -2px; right: -2px; top: 50%; height: 44px; transform: translateY(-50%); }
  .tabbar a { min-height: var(--tabbar-h); }
}
@media (hover: none) {
  /* 触屏上没有真正的悬停，避免点后卡在“悬停态” */
  a.card:hover { transform: none; }
}

/* ============ 7. 深色模式 ============ */
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --bg: #15171A;
    --surface: #1E2124;
    --surface-2: #25292D;
    --input-bg: #181B1E;
    --text: #E9E5DE;                 /* 14.3:1 */
    --muted: #A39C91;                /* 6.6:1 on bg，5.0:1 on gray-soft */
    --line: #33383D;
    --line-strong: #454B52;
    --primary: #86C1C6;              /* 8.0:1 on surface */
    --primary-hover: #A3D3D7;
    --primary-soft: #1F3A3D;
    --on-primary: #0E2224;           /* 实心主色按钮改用深色字 8.2:1 */
    --accent: #E8A87C;
    --on-accent: #1A1208;
    --red: #F1958A;                  /* 6.5:1 on red-soft */
    --red-soft: #3B2220;
    --red-line: #6B3530;
    --on-red: #2A0E0B;
    --amber: #E6B566;
    --amber-soft: #3A2E17;
    --amber-ink: #EBC27A;
    --green: #8FD3A5;
    --green-soft: #1D3526;
    --gray-soft: #2A2E33;
    --help: #B9ADEB;
    --help-soft: #221F2C;
    --help-line: #3A3450;
    --hl-bg: #5A4A16;
    --skeleton-a: #262A2F;
    --skeleton-b: #2F343A;
    --shadow-1: 0 1px 2px rgba(0, 0, 0, .3);
    --shadow-2: 0 8px 22px -8px rgba(0, 0, 0, .6), 0 2px 4px rgba(0, 0, 0, .3);
    --shadow-bar: 0 -1px 0 var(--line), 0 -6px 16px -10px rgba(0, 0, 0, .6);
    --focus: #A3D3D7;
    --focus-ring: 0 0 0 3px rgba(134, 193, 198, .3);
  }
  /* 树洞深色：夜里的雾紫 */
  body.theme-treehole {
    --bg: #17151D; --surface: #211E2A; --surface-2: #27232F; --input-bg: #1A1821;
    --primary: #B9ADEB; --primary-hover: #CEC5F2; --primary-soft: #2E2844; --on-primary: #1A1530;
    --line: #39334A; --line-strong: #4A4360; --muted: #A8A0B8;
    --focus: #CEC5F2; --focus-ring: 0 0 0 3px rgba(185, 173, 235, .3);
    --skeleton-a: #2A2635; --skeleton-b: #332E40;
  }
  body.theme-treehole .topbar, body.theme-treehole .tabbar { background: var(--surface); }
  @supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) and (color: color-mix(in srgb, red 50%, blue)) {
    body.theme-treehole .topbar, body.theme-treehole .tabbar { background: color-mix(in srgb, var(--surface) 88%, transparent); }
  }

  img:not([src$=".svg"]) { filter: brightness(.92); }
  .hero { background: linear-gradient(135deg, #1F3F43, #2C5A5E); }
  .hero .btn { color: var(--on-accent); }
  .btn-primary { box-shadow: none; }
  .btn-primary:active { box-shadow: inset 0 1px 2px rgba(0, 0, 0, .35); }

  /* —— 模块样式里写死的浅色，在这里统一兜底（用 html body 提高优先级，不改模块文件） —— */
  /* 实心主色上的白字 → 深色字 */
  html body .pg-pager-on, html body .ap-seg a.on, html body .ap-chip.done .ap-tick, html body .cm-pager-on { color: var(--on-primary); }
  html body .adm-nav a em { color: var(--on-red); }
  /* 白底 / 米底 → 深色表面 */
  html body .th-react, html body .th-gentle, html body .cm-tagopt span { background: var(--surface); }
  html body .form .th-need { background: var(--surface); }
  html body .th-need:has(input:checked) { background: var(--primary-soft); }
  html body .cm-tagopt input:checked + span { background: var(--primary-soft); }
  html body .th-react.on { background: var(--primary-soft); }
  html body .cm-linkcard { background: var(--surface-2); }
  html body .cm-pinned { background: #24211B; border-color: #4A3F2E; }
  html body .th-excerpt { color: color-mix(in srgb, var(--text) 85%, var(--bg)); }
  html body .th-guard-tag { background: #3A2A1C; color: #F0BE93; }
  html body .th-resource { background: #26213A; border-color: #3E3560; }
  html body .th-resource-title { color: #CBC0F3; }
  html body .pg-unverified { border-color: var(--red-line); }
  /* 雾紫关怀卡 */
  html body .cm-care { background: var(--help-soft); border-color: var(--help-line); }
  html body .cm-care b, html body .cm-care a { color: var(--help); }
  /* 绿色（录取 / 完成） */
  html body .ap-status .st-admitted, html body .ap-status .st-accepted, html body .ap-gentle-good { background: var(--green-soft); color: var(--green); }
  html body .ap-rec b.ok, html body .ap-stats .good b, html body .ap-col-admitted header, html body .ap-col-accepted header { color: var(--green); }
  html body .cm-tabs em { color: var(--on-accent); }
  /* 首页树洞入口卡用了内联浅紫色 */
  html body .section.card[style*="F4F2F8"] { background: var(--help-soft) !important; border-color: var(--help-line) !important; }
  html body [style*="color:#6B5CA5"], html body [style*="color: #6B5CA5"] { color: var(--help) !important; }
  /* 表单原生控件 */
  select option { background: var(--surface); color: var(--text); }
  input[type=date]::-webkit-calendar-picker-indicator, input[type=time]::-webkit-calendar-picker-indicator { filter: invert(.85); }
}

/* 打印：去掉导航与底栏 */
@media print {
  .topbar, .tabbar, .footer, .btn { display: none !important; }
  body { background: #fff; color: #000; padding: 0; }
  .card { box-shadow: none; break-inside: avoid; }
  a { color: inherit; }
}


/* ===== 核心组件（原 base.html 内联，O5 的 core-* 类） ===== */
/* 核心组件（搜索入口、首页卡片、统计块）；全站视觉见 style.css */
.core-search { display: flex; gap: 6px; }
.core-search input[type=search] { min-width: 0; flex: 1; }
.topbar-search { flex: 0 1 220px; }
.topbar-search input[type=search] { padding: 6px 10px; font-size: 13px; }
.topbar-search button { padding: 4px 10px; font-size: 13px; }
.m-only { display: none; }
.core-stats { display: grid; gap: 10px; grid-template-columns: repeat(4, minmax(0, 1fr)); margin: 0 0 16px; }
.core-stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px; text-align: center; color: var(--text); }
a.core-stat:hover { text-decoration: none; border-color: var(--primary); }
.core-stat b { display: block; font-size: 22px; color: var(--primary); line-height: 1.3; }
.core-stat span { font-size: 12px; color: var(--muted); }
.core-features { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
.core-feature { margin: 0; }
.core-feature .ico { font-size: 22px; }
.core-feature h3 { margin: 6px 0; }
.core-feature p { margin: 0 0 8px; font-size: 13px; color: var(--muted); }
.core-list { list-style: none; padding: 0; margin: 0; }
.core-list li { padding: 8px 0; border-bottom: 1px dashed var(--line); display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.core-list li:last-child { border-bottom: none; }
.core-list .grow { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.core-two { display: grid; gap: 12px; grid-template-columns: 1fr 1fr; }
.core-two > .card { margin-bottom: 0; }
.core-quick { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
.core-quick .btn { text-align: center; }
.core-err { text-align: center; padding: 40px 16px; }
.core-err .code { font-size: 56px; font-weight: 700; color: var(--primary); line-height: 1.1; }
mark { background: var(--amber-soft); color: inherit; padding: 0 1px; border-radius: 3px; }
@media (max-width: 720px) {
  .topbar-search { display: none; }
  .m-only { display: block; }
  .core-search.m-only { display: flex; }
  .core-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .core-two { grid-template-columns: 1fr; }
}

/* ---------- 首页：未登录主按钮 / 新用户三步上手 ---------- */
.core-hero-cta { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; }
.hero .core-cta-main { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 600; }
.hero .core-cta-sub { background: rgba(255, 255, 255, .14); border-color: rgba(255, 255, 255, .55); color: #fff; }
.hero .core-cta-sub:hover { background: rgba(255, 255, 255, .24); filter: none; }
.core-onboard .section-head { margin-bottom: 6px; }
.core-steps { list-style: none; margin: 0; padding: 0; }
.core-steps li { display: flex; gap: 10px; align-items: center; padding: 10px 0; border-bottom: 1px dashed var(--line); }
.core-steps li:last-child { border-bottom: none; }
.core-steps .grow { flex: 1; min-width: 0; }
.core-step-no { flex: none; width: 26px; height: 26px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; background: var(--primary-soft); color: var(--primary); }
.core-steps li.done .core-step-no { background: var(--green-soft); color: var(--green); }
.core-steps li.done b { color: var(--muted); text-decoration: line-through; text-decoration-color: var(--line-strong); }
@media (max-width: 720px) {
  .core-hero-cta .btn { flex: 1 1 100%; text-align: center; }
  .core-steps li { flex-wrap: wrap; }
  .core-steps li .btn { margin-left: 36px; }
}
