/* 岭南学院就业指导系统 —— 共享设计系统。中大红 #9E1F2F + 灰。各页面复用这些类。 */
:root {
  --red: #9e1f2f;
  --red-dark: #7a1623;
  --red-light: #f7eaec;
  --ink: #25201f;
  --muted: #837b79;
  --line: #e7e3e2;
  --bg: #f7f6f5;
  --card: #ffffff;
  --accent: #b8893f;
  --ok: #2f7d4f;
  --warn: #b4791b;
  --err: #b3261e;
  --radius: 12px;
  /* 圆角三档。原来 6/8/10/12/14/16 六种混着用，同一屏里卡片、弹层、按钮各圆各的。
     标签与徽章用 6，可点的控件用 8，容器用 12，胶囊用 999，只此四种。 */
  --r-chip: 6px;
  --r-ctl: 8px;
  --shadow: 0 1px 2px rgba(40,20,20,.05), 0 4px 16px rgba(40,20,20,.045);
  --shadow-lift: 0 2px 6px rgba(40,20,20,.07), 0 10px 28px rgba(40,20,20,.07);

  /* 中性按钮。红是主色，但一屏里十几个红描边按钮就没有主次了——次级操作走这套灰。 */
  --btn-line: #d9d4d3;
  --btn-hover: #f2efee;
  --ink-2: #55504e;      /* 次级文字，比 --muted 深，用在次级按钮与表头 */

  /* 控件高度。桌面 36，移动端 44（拇指触摸下限）。输入框、按钮、下拉、分段标签
     全部对齐这一个值，筛选行才排得齐。 */
  --ctl-h: 36px;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei",
    "PingFang SC", "Hiragino Sans GB", sans-serif;
  color: var(--ink); background: var(--bg); line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* 基准字号。原来没设，走浏览器默认 16px：正文各处都显式写了 13/14px，只有按钮和
     输入框在继承 16px，于是按钮 46px 高、.btn-sm 29px 高，同一行里高矮差一截。 */
  font-size: 14px;
}
/* 键盘可见焦点。原来只有输入框有焦点样式，按钮、标签页、卡片按钮全靠浏览器默认的
   蓝框，在红灰配色里格外扎眼。:focus-visible 只在键盘操作时出现，不影响鼠标点击。 */
:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; border-radius: 4px; }

/* 溢出容器的滚动条。默认那条系统灰杠又宽又重（问卷页表格下面那根），收细、变淡，
   滚动仍然可见但不抢戏。只管页面内部的滚动容器：html/body 的主滚动条留给浏览器，
   那是用户熟悉的东西，换了反而找不着。 */
body *:not(.pv-mask) {
  scrollbar-width: thin; scrollbar-color: #cfc9c7 transparent;
}
body *::-webkit-scrollbar { height: 9px; width: 9px; }
body *::-webkit-scrollbar-track { background: transparent; }
body *::-webkit-scrollbar-thumb { background: #d5cfcd; border-radius: 999px; }
body *::-webkit-scrollbar-thumb:hover { background: #b9b1af; }

/* 右缘渐隐：由 common.js 的 markScrollable 给真正横向溢出的容器打上，滑到最右自动去掉。
   没有它的话，表格被卡片边缘齐齐切断，看着就像"这张表只有这么宽"，
   手机上尤其严重——老师根本不知道操作列还在右边。 */
.is-scroll-x { box-shadow: inset -22px 0 14px -14px rgba(40,20,20,.16); }
a { color: var(--red); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---------- 顶栏 + 导航 ---------- */
.topbar {
  display: flex; align-items: center; gap: 24px;
  padding: 14px 28px; color: #fff;
  background: linear-gradient(135deg, var(--red) 0%, var(--red-dark) 100%);
}
.brand { display: flex; align-items: center; gap: 12px; }
.logo {
  width: 42px; height: 42px; display: grid; place-items: center;
  background: rgba(255,255,255,.15); border-radius: 10px; font-weight: 700; font-size: 20px;
}
.brand-title { font-weight: 700; font-size: 16px; }
.brand-sub { font-size: 12px; opacity: .85; }
.mainnav { display: flex; gap: 4px; flex: 1; }
.nav-link {
  color: #fff; opacity: .85; padding: 8px 14px; border-radius: 8px;
  font-size: 14px; text-decoration: none;
}
.nav-link:hover { opacity: 1; background: rgba(255,255,255,.12); text-decoration: none; }
.nav-link.active { opacity: 1; background: rgba(255,255,255,.2); font-weight: 600; }
.user-box { display: flex; align-items: center; gap: 12px; }
.uname { font-size: 14px; }

/* ---------- 布局 ---------- */
.page { max-width: 1180px; margin: 0 auto; padding: 24px 28px; }
.page-narrow { max-width: 720px; margin: 0 auto; padding: 24px 28px; }
.row { display: flex; gap: 16px; }
.grid { display: grid; gap: 16px; }
.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow); padding: 20px;
}
.card + .card { margin-top: 16px; }
.section-title { font-size: 16px; font-weight: 700; margin-bottom: 14px; letter-spacing: .01em; }
.muted { color: var(--muted); }
.page-head { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 18px; }
.page-head h1 { font-size: 21px; letter-spacing: .01em; }

/* ---------- 按钮 ----------
   三级，靠红的多少分主次：
     .btn         实心红   一屏一个，页面此刻最该做的那件事
     .btn-outline 中性灰   其余所有操作（编辑、查看、导出、下架……）
     .btn-danger  灰边红字 删除一类不可逆操作，悬停才转红
   2026-09-08 把 .btn-outline 从红描边改成中性：招聘管理、学生管理这些页面一列里
   四五个红描边按钮排下来，整屏都是红框，主按钮反而看不见了。 */
.btn, .btn-ghost, .btn-outline, .btn-danger, .btn-sm {
  font: inherit; font-size: 14px; line-height: 1.4; cursor: pointer;
  border-radius: var(--r-ctl); padding: 0 16px; min-height: var(--ctl-h);
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 1px solid transparent; white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s;
}
.btn { background: var(--red); color: #fff; }
.btn:hover { background: var(--red-dark); }
.btn:disabled, .btn-outline:disabled, .btn-danger:disabled { opacity: .5; cursor: not-allowed; }
.btn-outline:disabled:hover { background: #fff; border-color: var(--btn-line); }
.btn-ghost { background: rgba(255,255,255,.15); color: #fff; border-color: rgba(255,255,255,.35); }
.btn-ghost:hover { background: rgba(255,255,255,.28); }
.btn-outline { background: #fff; color: var(--ink-2); border: 1px solid var(--btn-line); }
.btn-outline:hover { background: var(--btn-hover); border-color: #c6bfbd; color: var(--ink); }
/* 次级里也需要一点主色的场合（我的目标岗位这种带态度的入口）加 .accent */
.btn-outline.accent { color: var(--red); border-color: #e3bcc2; }
.btn-outline.accent:hover { background: var(--red-light); border-color: var(--red); }
.btn-danger { background: #fff; color: var(--err); border: 1px solid var(--btn-line); }
.btn-danger:hover { background: #fdeceb; border-color: #eab6b2; }
.btn-sm { padding: 0 11px; min-height: 28px; font-size: 13px; gap: 4px; }

/* ---------- 表单 ---------- */
.field { margin-bottom: 16px; }
.field label { display: block; font-size: 14px; font-weight: 600; margin-bottom: 6px; }
.field .hint { font-size: 12px; color: var(--muted); margin-top: 4px; }
input[type=text], input[type=password], input[type=email], input[type=number],
input[type=date], select, textarea {
  width: 100%; font: inherit; font-size: 14px; color: var(--ink);
  padding: 7px 12px; min-height: var(--ctl-h);
  border: 1px solid var(--btn-line); border-radius: var(--r-ctl); background: #fff;
}
select { padding-right: 8px; }
/* 文件选择框。浏览器原生那个灰底方按钮跟站内任何东西都不像，出现在上传简历、
   批量导入学生、上传海报三处。::file-selector-button 只换按钮部分，
   点开的仍是系统文件对话框，行为一点不变。 */
input[type=file] {
  width: auto; max-width: 100%; font-size: 13px; color: var(--ink-2);
  padding: 0; border: 0; background: none; min-height: var(--ctl-h);
  display: inline-flex; align-items: center;
}
input[type=file]::file-selector-button {
  font: inherit; font-size: 13px; cursor: pointer; margin-right: 10px;
  padding: 0 12px; min-height: 28px; border-radius: var(--r-ctl);
  border: 1px solid var(--btn-line); background: #fff; color: var(--ink-2);
  transition: background .15s, border-color .15s;
}
input[type=file]::file-selector-button:hover { background: var(--btn-hover); border-color: #c6bfbd; }
input::placeholder, textarea::placeholder { color: #a9a29f; }
textarea { min-height: 96px; padding: 9px 12px; resize: vertical; line-height: 1.6; }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--red); box-shadow: 0 0 0 3px var(--red-light); }
.check-row { display: flex; align-items: center; gap: 8px; margin: 6px 0; font-size: 14px; }
.check-row input { width: auto; }

/* ---------- 表格 ---------- */
table.data { width: 100%; border-collapse: collapse; font-size: 14px; }
table.data th, table.data td {
  text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line);
  vertical-align: middle;   /* 默认 baseline：同行里高矮不一的格子（勾选框、按钮组、
                               两行文字）各自贴基线，看着像没对齐 */
}
table.data th {
  background: #faf8f8; font-weight: 600; color: var(--ink-2); font-size: 13px;
  border-bottom-color: #ded9d8;
}
table.data tbody tr:hover td { background: #fbf9f9; }
table.data tbody tr:last-child td { border-bottom: none; }
/* 操作列：按钮排一行不折，列本身不参与谁更宽的争抢 */
table.data td.acts, table.data th.acts { white-space: nowrap; width: 1%; }
table.data td.acts > * + * { margin-left: 6px; }

/* 表格横滚容器。用它包住宽表，滚动条按上面的细样式走，右缘再加一层渐隐，
   提示右边还有内容——否则老师根本不知道操作列被推到视野外去了。 */
.tbl-wrap { overflow-x: auto; }
.tbl-wrap.faded {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
          mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
}
/* 列被挤窄时，中文会逐字拆行，"回收数"变成"回收/数"、日期断成"2026-07-/13"。
   表头和这几类短内容一律不折行，宁可整表横滚也不要拆字。 */
table.data th { white-space: nowrap; }
table.data .nowrap { white-space: nowrap; }
/* 列多的宽表加 .wide。不设 min-width：短字段都标了 .nowrap，浏览器算出来的最小内容
   宽度自然就是它们的总和，表撑到那个宽度就会溢出容器、由 .tbl-wrap 横滚，不会再被
   挤到拆字。写死一个数字反而会在内容不多时白白撑出滚动条。 */
/* 横滚时把操作列钉在右边缘。不钉住的话按钮被推到视野外，老师得先横向拖一段才找得到
   「编辑」——比列被挤扁更难发现。背景要实心，否则滚过去的内容会透在按钮底下。 */
.tbl-wrap table.data.wide td.acts,
.tbl-wrap table.data.wide th.acts {
  position: sticky; right: 0; z-index: 1;
  box-shadow: -10px 0 8px -8px rgba(40, 20, 20, .14);
}
.tbl-wrap table.data.wide td.acts { background: #fff; }
.tbl-wrap table.data.wide th.acts { background: #faf8f8; }
.tbl-wrap table.data.wide tbody tr:hover td.acts { background: #fbf9f9; }
.badge, .tag, .badge-ok, .badge-warn { white-space: nowrap; }

/* ---------- chip / 标签 ----------
   一屏里能出现的着色只有三类：中性（事实）、状态色（成败）、主色（选中）。
   .tag 原来是粉底红字，跟状态徽章、实习/全职标签挤在一行时三种颜色打架，
   现在退成中性；红留给这条被选中了。 */
.chip {
  display: inline-block; padding: 4px 12px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--btn-line); background: #fff; font-size: 13px; margin: 3px;
  transition: background .15s, border-color .15s;
}
.chip:hover { background: var(--btn-hover); }
.chip.active { background: var(--red); color: #fff; border-color: var(--red); }
.chip.active:hover { background: var(--red-dark); }
.tag {
  display: inline-block; padding: 2px 8px; border-radius: var(--r-chip); font-size: 12px;
  background: #f2efee; color: var(--ink-2); border: 1px solid transparent;
}
.tag-accent { background: var(--red-light); color: var(--red-dark); }
/* 面向对象格（见 common.js 的 Fmt.target）。标签之间自己换行，整格不许超过 18em，
   否则一条班级串就能把同行的操作列顶出屏幕。 */
.tgt { display: inline-flex; flex-wrap: wrap; gap: 4px; align-items: center; max-width: 18em; }
.tgt-more { font-size: 12px; color: var(--muted); white-space: nowrap; }
/* 实习 / 全职。老师端管理表与学生端卡片共用，两者靠描边颜色区分，不引入红灰以外的色相 */
.nat-tag { display: inline-block; padding: 1px 8px; border-radius: 6px; font-size: 12px;
  border: 1px solid var(--red); color: var(--red-dark); background: #fff; white-space: nowrap; }
.nat-tag.full { border-color: var(--muted); color: var(--muted); }
.badge { display: inline-block; padding: 2px 8px; border-radius: var(--r-chip); font-size: 12px;
  background: #f0eeed; color: var(--ink-2); }
.badge-ok { background: #e7f3ec; color: var(--ok); }
.badge-warn { background: #fbf1de; color: var(--warn); }
.badge-err { background: #fdeceb; color: var(--err); }

/* ---------- 提示条 ---------- */
.alert { padding: 10px 14px; border-radius: var(--r-ctl); font-size: 13.5px;
  line-height: 1.6; margin-bottom: 14px; }
.alert-err { background: #fdeceb; color: var(--err); border: 1px solid #f3c9c6; }
.alert-ok { background: #e7f3ec; color: var(--ok); border: 1px solid #c5e3d0; }
.alert-info { background: var(--red-light); color: var(--red-dark); border: 1px solid #eccdd1; }

/* ---------- 进度条（宣讲报名 / 收集进度） ---------- */
.progress { position: relative; height: 8px; border-radius: 999px; background: #eae6e5; overflow: hidden; }
.progress .bar { display: block; height: 100%; border-radius: 999px; background: var(--red); transition: width .3s; }
.progress .bar.ok { background: var(--ok); }
/* 达标线。原来是 2px 一根竖线顶出条子上下各 2px，看着像条子破了个口；
   改成贴着条子内壁的一根细线，加白描边保证压在填充色上也看得见。 */
.progress .mark {
  position: absolute; top: 0; bottom: 0; width: 2px; background: var(--accent);
  box-shadow: 0 0 0 1px rgba(255,255,255,.85);
}
.progress-meta { display: flex; justify-content: space-between; gap: 12px;
  font-size: 12px; color: var(--muted); margin-top: 6px; }

/* ---------- 数字卡（项目概览等） ----------
   顺序是 标签 → 数值+单位 → 补充说明。原来把单位当第三行的补充说明写，
   "课题总容量 / 15 / 人"里那个"人"单独占一行，读起来断成三截。 */
.stat-grid { display: flex; flex-wrap: wrap; gap: 10px; }
.stat {
  flex: 1 1 132px; min-width: 132px; padding: 12px 14px;
  background: #faf8f8; border: 1px solid var(--line); border-radius: 10px;
}
.stat-label { font-size: 12px; color: var(--muted); }
.stat-value { font-size: 22px; font-weight: 700; line-height: 1.25; margin-top: 2px; }
.stat-unit { font-size: 13px; font-weight: 400; color: var(--muted); margin-left: 2px; }
.stat-hint { font-size: 11.5px; color: var(--muted); margin-top: 2px; }

/* ---------- 空态 / 加载 ---------- */
.empty { text-align: center; color: var(--muted); padding: 36px 16px; font-size: 13.5px; }
.spinner { display: inline-block; width: 22px; height: 22px; border: 3px solid var(--line);
  border-top-color: var(--red); border-radius: 50%; animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- 登录页 ---------- */
.login-wrap { min-height: 100%; display: grid; place-items: center; padding: 24px;
  background: linear-gradient(135deg, var(--red) 0%, var(--red-dark) 100%); }
.login-card { width: 100%; max-width: 400px; background: #fff; border-radius: 16px; padding: 32px; box-shadow: var(--shadow); }
.login-card h1 { font-size: 20px; margin-bottom: 4px; }
.login-card .sub { color: var(--muted); font-size: 13px; margin-bottom: 22px; }

/* ---------- 图标（见 common.js 的 Ico） ---------- */
.ico { width: 14px; height: 14px; flex: 0 0 auto; display: inline-block; vertical-align: -2px; }
.ico-lg { width: 16px; height: 16px; }
.detail-badges .badge, .li-meta span { display: inline-flex; align-items: center; gap: 5px; }

/* ---------- 站点页脚（访问量，所有登录后页面底部） ---------- */
.site-footer {
  display: flex; align-items: center; justify-content: center;
  gap: 10px; flex-wrap: wrap;
  margin-top: 8px; padding: 18px 28px 26px;
  border-top: 1px solid var(--line);
  color: var(--muted); font-size: 13px;
}
.site-footer b { color: var(--ink); font-weight: 600; }
.site-footer .sf-sep { opacity: .5; }
@media (max-width: 720px) {
  .site-footer { gap: 6px; padding: 14px 16px 20px; font-size: 12px; }
  .site-footer .sf-sep { display: none; }
  .site-footer .sf-name { flex: 1 0 100%; text-align: center; }
}

@media (max-width: 720px) {
  /* 小屏：导航换到第二行，整行横向滚动，保证所有入口可达、可点 */
  .topbar { flex-wrap: wrap; gap: 10px; padding: 12px 16px; }
  .mainnav {
    order: 3; flex: 1 0 100%;
    overflow-x: auto; flex-wrap: nowrap;
    -webkit-overflow-scrolling: touch;
    /* 右侧渐隐提示：暗示导航还能横向滚动 */
    -webkit-mask-image: linear-gradient(to right, #000 92%, transparent);
            mask-image: linear-gradient(to right, #000 92%, transparent);
  }
  .mainnav .nav-link { flex: 0 0 auto; white-space: nowrap; padding: 10px 14px; }
  .user-box { margin-left: auto; }
  .page, .page-narrow { padding: 16px; }
  .card { padding: 16px; }

  /* 页头：窄屏允许换行。否则标题和右侧的按钮/说明挤在一行，
     标题会被压成一列一个字（"企业宣讲"竖排）。 */
  .page-head { flex-wrap: wrap; gap: 8px; }

  /* 防 iOS 聚焦缩放：表单控件字号 >=16px 时 Safari 不会自动放大页面 */
  input[type=text], input[type=password], input[type=email], input[type=number],
  input[type=date], input[type=file], select, textarea { font-size: 16px; }
  /* 触摸目标下限 44px：桌面上控件统一 36，手机上一律撑回 44 */
  :root { --ctl-h: 44px; }
  .segtab > button, .tab { min-height: 38px; }

  /* 主操作按钮整宽、够高，便于单手拇指点按 */
  .btn-block-mobile { display: block; width: 100%; text-align: center; }
  .btn-sm { min-height: 34px; padding: 0 12px; }

  /* 长表格/宽网格横向可滚，避免撑破视口 */
  table.data { min-width: 0; }
}

/* ---------- 问卷作答（survey_fill）移动端触摸硬化 ---------- */
@media (max-width: 720px) {
  /* 单选/多选：整行 label 可点，行高够 44px 触摸目标，选项间留白 */
  .q-block { padding: 18px 0; }
  .q-title { font-size: 16px; line-height: 1.5; }
  .opt {
    min-height: 44px; padding: 8px 10px; margin: 8px 0;
    border: 1px solid var(--line); border-radius: 8px; background: #fff;
    align-items: center; font-size: 15px; gap: 12px;
  }
  .opt input[type=radio], .opt input[type=checkbox] {
    width: 22px; height: 22px; flex: 0 0 auto; margin: 0;
  }
  .opt .otherbox { flex: 1 0 100%; max-width: none; margin-left: 0; }

  /* 量表矩阵：窄屏必须放弃 survey_fill 里那条 min-width:420px，否则 1-5 分量表
     只露出前 3 列，右边两列要横滑才看得到——学生根本不会想到去滑，等于选不了高分。
     改成按视口分配列宽：首列题干占 36%，其余各列留住 32px 的触摸宽度。
     列数特别多的量表仍会超出，此时外层 .grid-scroll 的横滚作为兜底。 */
  .grid-scroll .grid-tbl { min-width: 0; width: 100%; }
  .grid-tbl th, .grid-tbl td { padding: 10px 2px; }
  .grid-tbl th:not(:first-child), .grid-tbl td:not(:first-child) { min-width: 32px; }
  .grid-tbl th:first-child, .grid-tbl td:first-child {
    max-width: none; width: 36%; padding-right: 8px;
  }
  .grid-tbl input[type=radio] { width: 22px; height: 22px; }

  /* 分类网格：拖拽/点选块加大，单元格触摸区更宽 */
  .gchip { padding: 8px 12px; font-size: 14px; }
  .cls-cell { min-width: 84px; padding: 8px; }
  table.cls-grid th, table.cls-grid td { padding: 8px; }

  /* 排序题：上/下移按钮做成正方触摸块 */
  .rank-item { gap: 10px; }
  .rank-item .btn-sm { min-width: 40px; min-height: 40px; padding: 0; font-size: 16px; }

  /* 分节标题、题干与作答区留足垂直节奏 */
  .sec-head { margin: 26px 0 8px; }
}

/* ---------- 账户页内置使用说明（折叠栏目） ---------- */
.guide details {
  border: 1px solid var(--line); border-radius: 8px;
  margin-bottom: 8px; overflow: hidden; background: #fff;
}
.guide summary {
  padding: 13px 14px; cursor: pointer; font-weight: 600; color: var(--ink);
  list-style: none; min-height: 44px; box-sizing: border-box;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.guide summary::-webkit-details-marker { display: none; }
.guide summary::after { content: "+"; color: var(--muted); font-weight: 700; font-size: 18px; }
.guide details[open] > summary::after { content: "\2212"; }
.guide details[open] > summary { border-bottom: 1px solid var(--line); background: #faf8f8; }
.guide .gbody { padding: 12px 14px; color: var(--ink); line-height: 1.65; }
.guide .gbody p { margin: 0 0 8px; }
.guide .gbody ul { margin: 4px 0 8px; padding-left: 20px; }
.guide .gbody li { margin: 4px 0; }
.guide .gbody > :last-child { margin-bottom: 0; }
.guide .gtip { color: var(--muted); font-size: 13px; }

/* ---------- 项目模块：左侧项目栏 + 右侧主体 ---------- */
/* 栏窄、主体宽，是因为项目本身没几个，真正要看的是某个项目的内容。 */
.proj-shell { display: grid; grid-template-columns: 196px minmax(0, 1fr); gap: 20px; align-items: start; }
.proj-rail { position: sticky; top: 16px; }
.rail-head {
  font-size: 12px; color: var(--muted); font-weight: 600;
  padding: 0 10px 8px; letter-spacing: .06em;
}
.rail-item {
  display: block; padding: 10px 12px; margin-bottom: 6px;
  background: #fff; border: 1px solid var(--line); border-radius: 8px;
  color: var(--ink); text-decoration: none; cursor: pointer; width: 100%; text-align: left;
  font: inherit;
}
.rail-item:hover { text-decoration: none; border-color: var(--red); }
.rail-item.active { background: var(--red-light); border-color: var(--red); }
.rail-name { font-weight: 600; font-size: 14px; }
.rail-sub { font-size: 12px; color: var(--muted); margin-top: 3px;
  display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.rail-add { border-style: dashed; color: var(--red); text-align: center; font-weight: 600; }

/* ---------- 阶段 ---------- */
.stage-badge {
  display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: 12px;
  background: #f0eeed; color: var(--muted); border: 1px solid var(--line); white-space: nowrap;
}
.stage-badge.on { background: var(--red); color: #fff; border-color: var(--red); }
.stage-badge.done { background: #e7f3ec; color: var(--ok); border-color: #c5e3d0; }
/* 六格阶段条：让学生一眼看出整件事走到哪了，以及后面还有什么 */
.stage-track { display: flex; margin-top: 16px; flex-wrap: wrap; }
.stage-step {
  flex: 1 1 0; min-width: 74px; text-align: center; font-size: 12px;
  color: var(--muted); padding: 7px 2px 0; border-top: 3px solid var(--line);
}
.stage-step.past { border-top-color: #dbb9be; color: var(--ink); }
.stage-step.now { border-top-color: var(--red); color: var(--red); font-weight: 700; }

/* ---------- 时间线 ---------- */
.tl { list-style: none; padding: 0; margin: 0; }
.tl li { position: relative; padding: 0 0 20px 22px; border-left: 2px solid var(--line); }
.tl li:last-child { border-left-color: transparent; padding-bottom: 0; }
.tl li::before {
  content: ""; position: absolute; left: -8px; top: 4px; width: 13px; height: 13px;
  border-radius: 50%; background: #fff; border: 2px solid var(--line);
}
.tl li.now::before { border-color: var(--red); background: var(--red); }
.tl li.done::before { border-color: var(--ok); background: var(--ok); }
.tl-date { font-size: 12px; color: var(--muted); }
.tl-title { font-weight: 600; }
.tl-body { font-size: 14px; color: var(--muted); margin-top: 2px; }

/* ---------- 课题卡 ---------- */
.topic-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(272px, 1fr)); gap: 14px; }
.topic-card {
  border: 1px solid var(--line); border-radius: var(--radius); background: #fff;
  padding: 15px; cursor: pointer; transition: .15s; text-align: left; font: inherit; color: var(--ink);
}
.topic-card:hover { border-color: var(--red); box-shadow: var(--shadow); }
.topic-card.picked { border-color: var(--red); background: var(--red-light); }
.topic-card.full { opacity: .62; }
.tc-title { font-weight: 700; font-size: 15px; line-height: 1.45; margin-bottom: 7px; }
/* 导师单独一行。之前是"导师：陈明（某某公司）"整串塞进 meta 里，公司名一长就整段折到
   下一行，把城市顶到行首，读起来像断了。姓名再单独 nowrap，三个字的名字不该被拆开。 */
.tc-mentor { font-size: 12px; color: var(--muted); line-height: 1.5; margin-bottom: 4px; }
.tc-mentor b { color: var(--ink); font-weight: 600; white-space: nowrap; }
.tc-meta { font-size: 12px; color: var(--muted); display: flex; flex-wrap: wrap; gap: 3px 10px; }
.tc-meta span { white-space: nowrap; }

/* 志愿条：吸在底部，选课题时始终看得到已选了几个 */
.wish-bar {
  position: sticky; bottom: 0; z-index: 20; margin-top: 16px;
  background: #fff; border: 1px solid var(--red); border-radius: var(--radius);
  padding: 12px 16px; box-shadow: 0 -2px 16px rgba(40,20,20,.09);
}
.wish-item {
  display: flex; align-items: center; gap: 8px; padding: 5px 0; font-size: 14px;
}
.wish-no {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; background: var(--red);
  color: #fff; font-size: 12px; display: grid; place-items: center; font-weight: 700;
}

/* ---------- 意愿征集：课题方向与组队 ---------- */
/* 方向卡竖排而不是像课题那样铺成网格：选中的要能"排到最上面"，一列里上下移动看得清楚，
   网格里位置一跳人就找不着自己刚点的是哪张。 */
.dir-list { display: flex; flex-direction: column; gap: 10px; }
.dir-card {
  display: flex; align-items: flex-start; gap: 12px; width: 100%; text-align: left;
  border: 1px solid var(--line); border-radius: var(--radius); background: #fff;
  padding: 13px 15px; cursor: pointer; font: inherit; color: var(--ink);
  transition: border-color .15s, background .15s, box-shadow .15s;
}
.dir-card:hover { border-color: var(--red); box-shadow: var(--shadow); }
.dir-card.picked { border-color: var(--red); background: var(--red-light); }
.dir-card.locked { cursor: default; }
.dir-card.locked:hover { border-color: var(--line); box-shadow: none; }
.dir-card[disabled] { opacity: .55; cursor: not-allowed; }
/* 志愿序号。没选中时是个空圈，选中后填成红底白字的 1 / 2 */
.dir-rank {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%; margin-top: 1px;
  display: grid; place-items: center; font-size: 13px; font-weight: 700;
  background: #fff; color: var(--muted); border: 1px solid var(--line);
}
.dir-card.picked .dir-rank { background: var(--red); color: #fff; border-color: var(--red); }
.dir-name { display: block; font-weight: 700; font-size: 15px; line-height: 1.45; }
.dir-eg { display: block; font-size: 13px; color: var(--muted); line-height: 1.6; margin-top: 3px; }
.dir-meta { display: block; font-size: 12px; color: var(--muted); margin-top: 5px; }

/* 还没组队时的三个入口：建组 / 单独报意愿 / 不参加。
   三选一，所以横排成同级的三张卡，而不是一个按钮加两段补充说明。
   整张卡就是按钮，触摸目标够大；窄屏收成一列。 */
.opt-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.opt-tile {
  display: flex; flex-direction: column; align-items: flex-start; gap: 5px;
  text-align: left; font: inherit; cursor: pointer;
  padding: 14px 15px; border: 1px solid var(--btn-line); border-radius: var(--radius);
  background: #fff; color: var(--ink);
  transition: background .15s, border-color .15s;
}
.opt-tile:hover { background: var(--btn-hover); border-color: #c6bfbd; }
/* 推荐路径描一道主色。三张卡都长一样的话，同学分不出哪条是正常流程。 */
.opt-tile.rec { border-color: #e3bcc2; }
.opt-tile.rec:hover { background: var(--red-light); border-color: var(--red); }
.opt-tile.rec .opt-name { color: var(--red-dark); }
.opt-name { font-weight: 600; font-size: 14px; line-height: 1.45; }
.opt-desc { font-size: 12.5px; color: var(--muted); line-height: 1.6; }
@media (max-width: 700px) {
  .opt-row { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   课题卡：一份校友导师课题摆出来的样子。
   学生端反选（几份里挑一份）与老师端配对板（待派的课题）共用，不各画一套——
   两边描述的是同一件东西，两套样式迟早长歪。

   跟 .dir-card 的区别是这里**整张卡不可点**：卡里字多，随手一点就定下一个课题
   太容易误触，所以底下单独放按钮，而且要两步（选这个 → 确认）。
   ============================================================ */
.of-list { display: flex; flex-direction: column; gap: 12px; }
.of-card {
  border: 1px solid var(--line); border-radius: var(--radius); background: #fff;
  padding: 14px 16px;
}
/* 定下来的那一份。描主色 + 浅红底，一眼能从几张里认出来 */
.of-card.on { border-color: var(--red); background: var(--red-light); }
.of-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 10px; flex-wrap: wrap;
}
.of-title { font-weight: 700; font-size: 15px; line-height: 1.45; }
.of-who { font-size: 13px; color: var(--ink-2); line-height: 1.6; margin-top: 3px; }
.of-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
/* 正文按"字段名 + 内容"两列排。窄屏收成上下两行——20 个字的标签挤在左边，
   右边只剩一句话宽，读起来比不分列还累。 */
.of-rows { margin-top: 10px; border-top: 1px dashed var(--line); padding-top: 9px; }
.of-row { display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: 10px; padding: 4px 0; }
.of-k { font-size: 12.5px; color: var(--muted); line-height: 1.7; }
.of-v { font-size: 13.5px; line-height: 1.7; white-space: pre-wrap; }
.of-foot {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 11px; padding-top: 10px; border-top: 1px dashed var(--line);
}
.of-foot .grow { flex: 1; min-width: 0; }
@media (max-width: 700px) {
  .of-row { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}

/* 反选流程条（老师端）。四格，走到哪一格标主色。
   不用 .segtab：那个是"切页签"，点一下换视图；这个是"当前走到哪一步"，
   长得像但点下去会改数据，混成一种控件老师会误点。 */
.ph-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.ph-step {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line);
  background: #fff; font-size: 13px; color: var(--muted);
}
.ph-step.on { border-color: var(--red); background: var(--red-light); color: var(--red-dark); font-weight: 600; }
.ph-step.past { color: var(--ink-2); }
.ph-arrow { color: var(--line); font-size: 13px; }

/* 组员行 */
.mem-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 0;
  border-bottom: 1px dashed var(--line); font-size: 14px;
}
.mem-row:last-child { border-bottom: none; }
.mem-row .grow { flex: 1; min-width: 0; }
.mem-sub { font-size: 12px; color: var(--muted); }

/* 搜同学的结果面板 */
.roster-box { position: relative; }
.roster-list {
  margin-top: 8px; border: 1px solid var(--line); border-radius: var(--radius);
  max-height: 268px; overflow-y: auto; background: #fff;
}
.roster-list:empty { display: none; }
.roster-item {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px; font-size: 14px;
  border-bottom: 1px solid var(--line);
}
.roster-item:last-child { border-bottom: none; }
.roster-item .grow { flex: 1; min-width: 0; }

/* ---------- 弹层（项目模块用；前缀 dlg- 是有意的：
   .modal-box / .modal-mask 这些通用名已被 teacher/surveys.html、
   teacher/companies.html、company/messages.html 各自的页内样式占着，
   共享样式表再用同名，没被页面重新声明的属性就会漏进去把人家的弹层弄坏） */
.dlg-mask {
  display: none; position: fixed; inset: 0; background: rgba(0,0,0,.55);
  z-index: 50; align-items: center; justify-content: center;
}
.dlg-box {
  background: #fff; border-radius: 10px; width: min(720px, 94vw); max-height: 88vh;
  display: flex; flex-direction: column; overflow: hidden;
}
.dlg-head {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
.dlg-body { padding: 16px; overflow: auto; }

/* ---------- 页内标签页 ----------
   全站两种写法合并成一种：招聘/学生/企业/简历四页各自抄了一份一模一样的 .seg，
   项目页又是另一套下划线 .tabs。这里统一成分段控件，.tabs/.tab 只是它的别名，
   两处标记都不用改。选中态用白底红字，不用实心红——实心红是主按钮的位置。 */
.segtab, .tabs {
  display: inline-flex; padding: 3px; gap: 2px; margin-bottom: 16px;
  background: #efebea; border: 1px solid var(--line); border-radius: 10px;
  max-width: 100%; overflow-x: auto; scrollbar-width: none;
}
.segtab::-webkit-scrollbar, .tabs::-webkit-scrollbar { display: none; }
.segtab > button, .tab {
  flex: 0 0 auto; font: inherit; font-size: 14px; cursor: pointer; white-space: nowrap;
  padding: 0 16px; min-height: 32px; border-radius: 7px;
  border: 1px solid transparent; background: transparent; color: var(--ink-2);
  display: inline-flex; align-items: center; transition: background .15s, color .15s;
}
.segtab > button:hover, .tab:hover { color: var(--ink); background: rgba(255,255,255,.6); }
.segtab > button.active, .tab.active {
  background: #fff; color: var(--red); font-weight: 600;
  border-color: var(--line); box-shadow: 0 1px 2px rgba(40,20,20,.06);
}

/* 正文段落块（项目介绍、安全须知这类多段文本） */
.prose { white-space: pre-wrap; line-height: 1.75; font-size: 14.5px; }

@media (max-width: 860px) {
  /* 窄屏项目栏横过来做成一排可滑的胶囊，别占掉半屏高度 */
  /* minmax(0,1fr) 不能写成 1fr：网格项默认 min-width:auto，不会收缩到小于内容宽度。
     标签条现在是"一行不折、自己横滚"，1fr 会被它按内容撑开，整页跟着横向溢出。 */
  .proj-shell { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .proj-rail { position: static; display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; }
  .rail-head { display: none; }
  .rail-item { flex: 0 0 auto; margin-bottom: 0; min-width: 132px; }
  .stage-step { min-width: 56px; font-size: 11px; }
}

/* ---------- 老师端「学生视角」 ---------- */
/* 预览横幅：钉在最顶上，滚到哪儿都看得见。
   用 fixed 不用 sticky：全站的 html, body 都是 height:100%，sticky 的容纳块因此只有
   一屏高，往下滚过一屏横幅就跟着划走了。fixed 脱离文档流，高度得由 JS 补成 body 的
   padding-top（横幅会换行，高度不是定值），见 common.js 的 mountPreviewBar。
   颜色刻意用琥珀而不是站点的红——红是这个站的常规主色，横幅用红就淹在页面里了。 */
.pv-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 90;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 9px 20px; font-size: 13.5px; line-height: 1.5;
  color: #4a3407; background: #ffe8b8; border-bottom: 1px solid #e0b755;
}
.pv-bar b { color: #7a1623; }
.pv-tag {
  flex: 0 0 auto; padding: 3px 10px; border-radius: 999px;
  background: #7a5410; color: #fff; font-size: 12px; font-weight: 700; letter-spacing: .5px;
}
.pv-acts { margin-left: auto; display: flex; gap: 8px; flex: 0 0 auto; }
.pv-acts .btn-ghost {
  background: rgba(122,84,16,.12); color: #4a3407; border-color: rgba(122,84,16,.4);
}
.pv-acts .btn-ghost:hover { background: rgba(122,84,16,.22); }

/* 选班弹层 */
.pv-mask {
  position: fixed; inset: 0; z-index: 200; display: grid; place-items: center;
  background: rgba(28,20,19,.5); padding: 20px;
}
.pv-modal {
  background: #fff; border-radius: var(--radius); box-shadow: 0 18px 48px rgba(0,0,0,.28);
  width: min(520px, 100%); max-height: min(640px, 88vh);
  display: flex; flex-direction: column; gap: 10px; padding: 20px;
}
.pv-modal-head { display: flex; align-items: center; justify-content: space-between; font-size: 17px; }
.pv-modal input[type="text"] { width: 100%; }
.pv-list { overflow-y: auto; border: 1px solid var(--line); border-radius: 10px; }
.pv-item {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  width: 100%; text-align: left; font: inherit; cursor: pointer;
  padding: 11px 14px; background: #fff; border: 0; border-bottom: 1px solid var(--line);
}
.pv-item:last-child { border-bottom: 0; }
.pv-item:hover { background: var(--red-light); }
.pv-cls { font-weight: 600; }
.pv-meta { color: var(--muted); font-size: 13px; white-space: nowrap; }

@media (max-width: 860px) {
  .pv-bar { padding: 8px 14px; font-size: 12.5px; }
  .pv-acts { margin-left: 0; width: 100%; }
}
/* 手机上横幅三行就吃掉小半屏。收起解释句，只留"正在以谁的身份看"——那句加上琥珀底色
   和左边的标签，已经够说清"这不是真实后台"了。 */
@media (max-width: 560px) { .pv-why { display: none; } }

/* 独占方向（营销与增长这类绑着别的活动、规则跟其他方向不一样的）在列表里单独一种样子。
   跟别的方向长得一样的话，同学多半直接点下去，到提交才被人数规则拦住。 */
.dir-card.dir-special { border-color: var(--accent); background: #fdf9f2; }
.dir-card.dir-special.picked { border-color: var(--accent); background: #f9efdc; }
.dir-note {
  display: block; margin-top: 4px; font-size: 12.5px; line-height: 1.6;
  color: #7a5410; background: #fff6e2; border-left: 3px solid var(--accent);
  padding: 6px 10px; border-radius: 0 6px 6px 0;
}
