/* 任意门 · 选课 —— 沿用同学 / 有 AI 设计系统令牌。无框架、无构建。 */
/* 颜色令牌按 WCAG 2.1 AA 校准过（2026-08-25 无障碍审查）。改任何一个值之前先算对比度：
   正文 ≥ 4.5:1，大字（≥24px 或 ≥18.66px 粗体）≥ 3:1，表单边框与图形 ≥ 3:1。
   成对使用的规矩：--p / --mint / --love-deep 是「能垫白字的实心色」，
   --pd / --sun-deep / --love-deep 是「能当正文的深色墨」，--ps / --suns / --mints / --loves 只做浅底。
   蓝色文字一律用 --pd，不要用 --p —— --p 在暖白底上只有 4.13:1，垫白字才够 4.61:1。 */
:root{
  --bg:#F4F2EF; --bg2:#ECE8E2; --surface:#FFFFFF; --raise:#FBFAF8;
  --ink:#1E1B18; --soft:#635F58; --mut:#6C6862;
  --p:#3A68FB; --pd:#2A52D8; --ps:#E8EEFF;
  --love:#FF6B5C; --love-deep:#B03626; --loves:#FFE7E2;
  --sun:#FFC53D; --suns:#FFF2D6; --sun-deep:#8A5A0B;
  --mint:#0C7A5B; --mints:#DCF3EB;
  --line:rgba(30,27,24,.10); --line-soft:rgba(30,27,24,.06);
  /* 只靠边框才能被认出来的控件（输入框、下拉、日期）用它，普通卡片仍用 --line */
  --line-strong:rgba(30,27,24,.48);
  --sh-soft:0 4px 14px -6px rgba(30,27,24,.12);
  --sh-card:0 12px 34px -16px rgba(30,27,24,.20);
  --r-sm:10px; --r-md:14px; --r-lg:20px; --r-xl:24px; --r-pill:999px;
  --sans:"Manrope","Noto Sans SC",-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;
  --mono:"Space Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--sans);
  font-size:16px;line-height:1.7;-webkit-font-smoothing:antialiased}
a{color:var(--pd);text-decoration:none}
button{font-family:inherit}
/* 焦点环。--p 对暖白底 4.13:1、对白 4.61:1、对深墨底 3.72:1 —— 三种底都过 3:1，
   所以一条规则就够，不需要给深色组件另写一套。offset 让环和元素之间留一条底色缝，
   哪怕元素自己就是蓝的（.btn），环也认得出来。别在任何地方写 outline:none 盖掉它。 */
:focus-visible{outline:2px solid var(--p);outline-offset:2px;border-radius:6px}
.wrap{max-width:1180px;margin:0 auto;padding:0 24px}

/* 视觉隐藏但读屏能念。跳转链接、活动区域、表单标签都靠它。 */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* 跳到主内容：默认藏起来，Tab 到才出现。首页顶部有吸顶的搜索与筛选，
   没有它键盘用户要按几十次 Tab 才够得到课程列表。 */
.skip{position:fixed;left:8px;top:8px;z-index:100;display:flex;gap:8px;
  transform:translateY(-200%);transition:transform .15s}
.skip:focus-within{transform:none}
.skip a{background:var(--ink);color:var(--bg);font-size:14px;font-weight:600;
  padding:10px 16px;border-radius:var(--r-md);box-shadow:var(--sh-card);
  display:inline-flex;align-items:center;min-height:44px}
/* 跳转落点本身不是控件，别给它画焦点框 —— tabindex=-1 只是为了让焦点真的搬过去 */
main[tabindex="-1"]:focus,main[tabindex="-1"]:focus-visible,
#grid[tabindex="-1"]:focus,#grid[tabindex="-1"]:focus-visible{outline:none}

/* ---------- nav ---------- */
.nav{position:sticky;top:0;z-index:40;background:rgba(244,242,239,.86);
  backdrop-filter:saturate(1.4) blur(12px);border-bottom:1px solid var(--line)}
.nav .wrap{display:flex;align-items:center;gap:20px;height:62px}
.brand{font-weight:800;letter-spacing:-.02em;font-size:18px;color:var(--ink)}
.brand span{color:var(--mut);font-weight:400;font-size:13px;margin-left:8px;letter-spacing:0}
.nav .sp{flex:1}
/* 导航链接在所有页面都要够 44px 高 —— 这条以前只写在 page-index/page-detail 里，
   faq / about / me / 404 四个页面漏掉了，所以搬到这里统一管。 */
.nav a.lnk{font-size:14.5px;color:var(--soft);font-weight:500;white-space:nowrap;
  display:inline-flex;align-items:center;min-height:44px}
.nav a.lnk:hover{color:var(--ink)}
.nav a.lnk[aria-current="page"]{color:var(--ink);font-weight:600}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;
  border-radius:var(--r-md);border:1px solid transparent;padding:9px 16px;
  font-size:14.5px;font-weight:600;cursor:pointer;transition:.15s;background:var(--p);color:#fff}
.btn:hover{background:var(--pd);box-shadow:var(--sh-soft)}
.btn:disabled{opacity:.42;cursor:not-allowed;box-shadow:none}
.btn.ghost{background:var(--surface);color:var(--ink);border-color:var(--line)}
.btn.ghost:hover{background:var(--raise)}
.btn.quiet{background:transparent;color:var(--soft);border-color:var(--line)}
.btn.sm{padding:6px 12px;font-size:13px;border-radius:var(--r-sm)}
.btn.on{background:var(--mint)}
.btn.on:hover{background:#095F47}

/* ---------- hero ---------- */
.hero{padding:54px 0 34px}
.kick{font-family:var(--mono);font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--pd);margin:0 0 16px}
h1{font-size:clamp(32px,5.2vw,52px);line-height:1.1;letter-spacing:-.022em;font-weight:800;
  margin:0 0 14px;text-wrap:balance}
h1 .th{font-weight:300;color:var(--soft)}
.lede{font-size:18px;color:var(--soft);max-width:56ch;margin:0;text-wrap:pretty}
.roundbar{display:flex;flex-wrap:wrap;gap:10px;margin-top:26px}
.pill{font-family:var(--mono);font-size:11.5px;padding:6px 13px;border-radius:var(--r-pill);
  border:1px solid var(--line);background:var(--surface);color:var(--soft)}
.pill.on{background:var(--ps);border-color:transparent;color:var(--pd)}
.pill.warn{background:var(--suns);border-color:transparent;color:var(--sun-deep)}

/* ---------- how ---------- */
.how{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin:34px 0 0}
.how div{background:var(--surface);border:1px solid var(--line-soft);border-radius:var(--r-lg);padding:18px 20px}
.how b{display:block;font-size:15px;margin-bottom:4px}
.how p{margin:0;font-size:13.5px;color:var(--soft);line-height:1.6}
.how i{font-family:var(--mono);font-style:normal;font-size:10.5px;letter-spacing:.12em;
  color:var(--mut);display:block;margin-bottom:9px}

/* ---------- filters ---------- */
.filters{position:sticky;top:62px;z-index:30;background:rgba(244,242,239,.94);
  backdrop-filter:blur(10px);padding:16px 0 14px;margin-top:44px;border-bottom:1px solid var(--line)}
.frow{display:flex;flex-wrap:wrap;gap:7px;align-items:center;margin-bottom:8px}
.frow:last-child{margin-bottom:0}
.flab{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--mut);width:58px;flex:none}
.chip{border:1px solid var(--line);background:var(--surface);color:var(--soft);
  padding:5px 12px;border-radius:var(--r-pill);font-size:13px;cursor:pointer;transition:.14s}
.chip:hover{color:var(--ink);border-color:var(--mut)}
.chip[aria-pressed="true"]{background:var(--ink);color:var(--bg);border-color:var(--ink)}

/* ---------- course grid ---------- */
.count{font-size:13.5px;color:var(--mut);margin:20px 0 14px;font-family:var(--mono)}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:16px;padding-bottom:80px}
.c{background:var(--surface);border:1px solid var(--line-soft);border-radius:var(--r-lg);
  padding:20px 20px 18px;display:flex;flex-direction:column;gap:12px;box-shadow:var(--sh-card)}
.c .top{display:flex;align-items:baseline;gap:10px}
.c .no{font-family:var(--mono);font-size:11px;color:var(--mut);flex:none}
.c h3{margin:0;font-size:17.5px;font-weight:700;letter-spacing:-.01em;line-height:1.32}
.c .sub{margin:0;font-size:13.5px;color:var(--soft);line-height:1.55}
.c .tags{display:flex;flex-wrap:wrap;gap:6px}
.tag{font-size:11.5px;padding:2px 9px;border-radius:var(--r-pill);white-space:nowrap;
  background:var(--bg2);color:var(--soft)}
.tag.online{background:var(--mints);color:var(--mint)}
.tag.live{background:var(--suns);color:var(--sun-deep)}
.tag.new{background:var(--ps);color:var(--pd)}
.c .dv{font-size:13.5px;color:var(--ink);background:var(--bg2);border-radius:var(--r-md);
  padding:9px 12px;line-height:1.5}
.c .dv em{font-style:normal;font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;
  color:var(--mut);display:block;margin-bottom:2px;text-transform:uppercase}
.stars{display:flex;gap:16px;font-size:12.5px;color:var(--soft);align-items:center}
.stars b{font-weight:500;color:var(--mut);margin-right:5px}
.st{letter-spacing:1px;color:var(--sun);font-size:13px}
.st .off{color:var(--line)}
.seedmark{font-family:var(--mono);font-size:10px;color:var(--mut);border:1px solid var(--line);
  padding:1px 6px;border-radius:var(--r-pill)}
.meter{margin-top:2px}
.meter .lab{display:flex;justify-content:space-between;font-size:12.5px;color:var(--soft);margin-bottom:5px}
.meter .lab b{font-family:var(--mono);color:var(--ink);font-variant-numeric:tabular-nums}
.track{height:7px;border-radius:var(--r-pill);background:var(--bg2);overflow:hidden}
.track i{display:block;height:100%;background:var(--p);border-radius:var(--r-pill);transition:width .4s}
.track i.ok{background:var(--mint)}
.acts{display:flex;gap:8px;margin-top:auto;padding-top:4px}
.acts .btn{flex:1}
.voted{font-size:12.5px;color:var(--mint);font-weight:600}

/* ---------- modal ---------- */
.mask{position:fixed;inset:0;background:rgba(30,27,24,.44);backdrop-filter:blur(3px);
  display:none;align-items:center;justify-content:center;z-index:60;padding:20px}
.mask.show{display:flex}
.modal{background:var(--surface);border-radius:var(--r-xl);max-width:520px;width:100%;
  max-height:88vh;overflow-y:auto;padding:28px;box-shadow:0 30px 80px -30px rgba(30,27,24,.5)}
.modal h2{margin:0 0 6px;font-size:22px;font-weight:700;letter-spacing:-.015em}
.modal .note{margin:0 0 20px;font-size:14px;color:var(--soft);line-height:1.6}
label{display:block;font-size:13.5px;font-weight:600;margin:16px 0 6px}
label .opt{font-weight:400;color:var(--mut);font-size:12.5px}
/* 输入框只靠边框才能被看出来是个控件 —— --line（1.2:1）根本看不见，
   所以表单边框用 --line-strong（3.1:1，WCAG 1.4.11）。字号 16px 是为了防 iOS 聚焦缩放。 */
input[type=text],input[type=tel],input[type=password],select{width:100%;padding:11px 13px;
  border-radius:var(--r-md);border:1px solid var(--line-strong);background:var(--raise);
  font-size:16px;font-family:inherit;color:var(--ink)}
/* 只改边框和底色，**不写 outline:none** —— 写了键盘用户就看不见焦点在哪 */
input:focus,select:focus{border-color:var(--p);background:var(--surface)}
input::placeholder{color:var(--mut);opacity:1}
.hint{font-size:12.5px;color:var(--mut);margin:6px 0 0;line-height:1.55}
.checkrow{display:flex;gap:9px;align-items:flex-start;margin-top:14px;font-size:13.5px;color:var(--soft)}
.checkrow input{margin-top:4px;accent-color:var(--p)}
.dates{display:flex;flex-wrap:wrap;gap:7px;margin-top:8px}
.dchip{border:1px solid var(--line);background:var(--raise);padding:7px 12px;border-radius:var(--r-md);
  font-size:13px;cursor:pointer;font-family:var(--mono)}
.dchip[aria-pressed="true"]{background:var(--ps);border-color:var(--p);color:var(--pd);font-weight:700}
.kids{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
.kid{border:1px solid var(--line);background:var(--raise);padding:8px 13px;border-radius:var(--r-md);
  font-size:13.5px;cursor:pointer}
.kid[aria-pressed="true"]{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.kid small{opacity:.7;margin-left:5px}
.mact{display:flex;gap:10px;margin-top:24px}
.mact .btn{flex:1}
.err{background:var(--loves);color:var(--love-deep);padding:10px 13px;border-radius:var(--r-md);
  font-size:13.5px;margin-top:14px;display:none}
.err.show{display:block}

/* ---------- toast ---------- */
.toast{position:fixed;left:50%;bottom:32px;transform:translateX(-50%) translateY(20px);
  background:var(--ink);color:var(--bg);padding:12px 20px;border-radius:var(--r-pill);
  font-size:14px;opacity:0;pointer-events:none;transition:.25s;z-index:80}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

/* ---------- generic page ---------- */
.page{padding:44px 0 90px}
.page h1{font-size:clamp(28px,4vw,40px)}
.sec{margin-top:38px}
.sec h2{font-size:21px;font-weight:700;margin:0 0 14px;letter-spacing:-.01em}
.panel{background:var(--surface);border:1px solid var(--line-soft);border-radius:var(--r-lg);
  padding:22px;box-shadow:var(--sh-card)}
.empty{color:var(--mut);font-size:14.5px}
table{border-collapse:collapse;width:100%;font-size:14px}
th,td{text-align:left;padding:11px 14px;border-bottom:1px solid var(--line-soft);vertical-align:top}
thead th{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--mut);font-weight:400;background:var(--bg2);white-space:nowrap}
td.n{font-family:var(--mono);font-variant-numeric:tabular-nums;white-space:nowrap}
.scroll{overflow-x:auto;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface)}
.foot{margin-top:70px;padding:24px 0 40px;border-top:1px solid var(--line);
  font-size:13px;color:var(--mut);line-height:1.8}

@media(max-width:760px){
  .wrap{padding:0 16px}
  .how{grid-template-columns:1fr}
  .grid{grid-template-columns:1fr}
  .filters{position:static}
  .flab{width:100%}
  /* 导航四项（选课 / 常见问题 / 关于 / 我的票）在 375px 上必须只占一行。
     最省宽度的一刀是砍掉品牌副标题 —— 它在手机上纯装饰，却是最宽的一块；
     再给链接 nowrap，文字内部就不会断成「常见问 / 题」。
     省下来的宽度不是白省的：换成链接的左右内边距，让「选课」「关于」这种两字项
     也够 44px 宽 —— 高度早就 44px 了，宽度以前只有 26px。
     算过：375px 下内容宽 343，导航实占约 292，还余 50。 */
  .nav .wrap{gap:0 4px}
  .brand{font-size:17px;min-height:44px;display:inline-flex;align-items:center}
  .brand span{display:none}
  .nav a.lnk{font-size:13.5px;padding:0 9px}

  /* 可点区域：手指最小 44px。这几条以前只写在 page-index / page-detail 里，
     me / faq / about / admin / 404 全都漏了 —— 搬到这里，全站一次到位。 */
  .btn{min-height:44px;padding:10px 16px}
  .btn.sm{min-height:44px;padding:8px 14px}
  .chip{min-height:44px;display:inline-flex;align-items:center;padding:6px 14px}
  /* 表格里的课程链接原来只有 19px 高；它是「我的票」页去详情页的唯一入口 */
  td a{display:inline-flex;align-items:center;min-height:44px}
}
/* 更窄的老机型（360 / 320）再收一档。375 走上面那一档，别把它拖进来 */
@media(max-width:360px){
  .nav .wrap{gap:0 2px}
  .brand{font-size:16px}
  .nav a.lnk{font-size:13px;padding:0 6px}
}

/* ==========================================================================
   动效降级。家长里有前庭功能敏感的人，系统开了「减少动态效果」就一律不动。
   位移/缩放类动画直接取消，只保留不引起眩晕的透明度变化。
   ========================================================================== */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important;
  }
  /* 位移是最容易引起不适的那一类，直接抹掉，不只是缩短时间 */
  .toast{transform:translateX(-50%) !important}
  .nudge{transform:none !important}
  .skip{transition:none;transform:none;top:-100vh}
  .skip:focus-within{top:8px}
}

/* ==========================================================================
   投票面板与留资卡（vote.js 用）
   手机上是从底部升起的 sheet，桌面是居中卡片 —— 拇指够得着的地方才是手机的主操作区。
   ========================================================================== */
.sheet{
  background:var(--surface);border-radius:var(--r-xl);width:100%;max-width:460px;
  padding:26px 24px 22px;box-shadow:0 30px 80px -30px rgba(30,27,24,.5);
  max-height:88vh;overflow-y:auto;
}
.sheet h2{margin:0 0 6px;font-size:21px;font-weight:700;letter-spacing:-.015em}
.sheet .note{margin:0 0 18px;font-size:14px;color:var(--soft);line-height:1.62}
.btn.wide{width:100%;margin-top:14px}

.grades{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:8px}
.gchip{
  border:1px solid var(--line);background:var(--raise);color:var(--ink);
  padding:14px 6px;border-radius:var(--r-md);font-size:15px;font-weight:600;
  cursor:pointer;transition:.14s;min-height:52px;font-family:inherit;
}
.gchip:hover:not(:disabled){border-color:var(--p);color:var(--pd);background:var(--ps)}
.gchip:disabled{opacity:.4;cursor:default}
.gchip.picking{background:var(--p);border-color:var(--p);color:#fff;opacity:1}
.kid.ghost{border-style:dashed;color:var(--soft)}

/* 留资卡：投完票之后才出现，永远可跳过 */
.nudge{
  position:fixed;left:0;right:0;bottom:0;z-index:70;padding:0 16px 16px;
  display:flex;justify-content:center;pointer-events:none;
  transform:translateY(18px);opacity:0;transition:.26s ease;
}
.nudge.show{transform:none;opacity:1}
.nudge .n-body{
  pointer-events:auto;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-xl);box-shadow:0 24px 60px -24px rgba(30,27,24,.42);
  padding:20px 20px 18px;width:100%;max-width:460px;
}
.n-t{margin:0 0 4px;font-size:16px;font-weight:700}
.n-s{margin:0 0 14px;font-size:13px;color:var(--soft);line-height:1.55}
.n-row{display:grid;grid-template-columns:1.3fr 1fr;gap:8px}
.n-row input{width:100%;padding:11px 12px;border-radius:var(--r-md);border:1px solid var(--line-strong);
  background:var(--raise);font-size:16px;font-family:inherit;color:var(--ink)}
.n-row input:focus{border-color:var(--p);background:var(--surface)}
.n-err{color:var(--love-deep);font-size:13px;min-height:18px;margin-top:6px}
.n-lab{font-size:12.5px;font-weight:600;color:var(--soft);margin:0 0 4px;display:block}
.n-act{display:flex;gap:8px;margin-top:4px}
.n-act .btn{flex:1;min-height:44px}

@media(max-width:600px){
  /* 手机：面板贴底升起，拇指区操作 */
  .mask{align-items:flex-end;padding:0}
  .sheet{max-width:none;border-radius:var(--r-xl) var(--r-xl) 0 0;padding:24px 18px calc(20px + env(safe-area-inset-bottom))}
  .grades{gap:7px}
  .gchip{min-height:56px;font-size:15.5px}
  .nudge{padding:0 10px calc(10px + env(safe-area-inset-bottom))}
  .n-row{grid-template-columns:1fr}
}
