/* ============ 设计令牌 ============ */
:root {
  --bg: #0a0e1a;
  --surface: #101627;
  --surface-2: #16203a;
  --line: #232c45;
  --ink: #e9edf6;
  --ink-2: #9aa5bd;
  --ink-3: #7f8ba5; /* 最暗的文字色，三种底色上对比度都 ≥ 4.5:1（小字的无障碍下限） */
  /* 三个梯队的分类色（深色面板校验通过：ΔE 15.7+） */
  --t1: #199e70;
  --t2: #3987e5;
  --t3: #c98500;
  --star-todo: #2b3550;
  --star-todo-stroke: #3a4666;
  --bad: #e0566a;
  --font-display: "Songti SC", "Noto Serif CJK SC", "Noto Serif SC", STSong, SimSun, serif;
  --font-body: -apple-system, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Consolas, "Liberation Mono", monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  background:
    radial-gradient(ellipse 1200px 600px at 50% -100px, #131c33 0%, var(--bg) 60%),
    var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  line-height: 1.6;
  min-height: 100vh;
}

.mono { font-family: var(--font-mono); font-size: 0.92em; }
.sep { color: var(--ink-3); margin: 0 0.6em; }
a { color: var(--t2); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font-family: inherit; cursor: pointer; }
:focus-visible { outline: 2px solid var(--t2); outline-offset: 2px; }

/* ============ 双版本主题 ============ */
/* 梯队色 --t1/--t2/--t3 的唯一数据源是各厂商 courses.json 的 tiers.colorHex（JS 加载后注入）；
   这里的同值覆盖只为避免首屏闪色。
   OpenAI 版「极光」色系（validate_palette 深色底全项通过）：青 / 紫罗兰 / 玫红，
   与 Anthropic 版（绿 / 蓝 / 琥珀）色相族完全错开。 */
body[data-provider="openai"] {
  --t1: #12a5bd;
  --t2: #8b7cf7;
  --t3: #cf5990;
  --bg: #0a0d1c;
  background:
    radial-gradient(ellipse 1200px 600px at 50% -100px, #0c2431 0%, var(--bg) 60%),
    var(--bg);
}
body[data-provider="openai"] .site-header h1 {
  background: linear-gradient(180deg, #ffffff 30%, #a5dbe8 100%);
  -webkit-background-clip: text; background-clip: text;
}

/* ============ 页眉 ============ */
.site-header { text-align: center; padding: 56px 20px 8px; }
.switch-btn {
  position: absolute; top: 16px; right: 18px; z-index: 25;
  background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--line); border-radius: 999px;
  padding: 7px 18px; font-size: 13px;
}
.switch-btn:hover { color: var(--ink); border-color: var(--t2); }
.eyebrow {
  font-family: var(--font-mono);
  font-size: 12px; letter-spacing: 0.35em;
  color: var(--ink-3); margin-bottom: 18px;
}
.site-header h1 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(34px, 6vw, 56px);
  letter-spacing: 0.12em;
  background: linear-gradient(180deg, #ffffff 30%, #b9c8e8 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.subtitle { color: var(--ink-2); margin-top: 10px; font-size: 15px; }
.progress-line { margin-top: 18px; color: var(--ink-2); font-size: 14px; }
.progress-line .mono { color: var(--ink); }

/* ============ 视图切换 ============ */
.tabs { display: flex; justify-content: center; gap: 8px; margin: 26px 0 10px; flex-wrap: wrap; }
.tabs [role="tab"] {
  background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--line); border-radius: 999px;
  padding: 8px 22px; font-size: 14px;
}
.tabs [role="tab"][aria-selected="true"] {
  color: var(--ink); border-color: var(--t2);
  background: var(--surface-2);
}

main { max-width: min(1760px, 96vw); margin: 0 auto; padding: 0 16px; }

/* ============ 星图 ============ */
.starmap-wrap { width: 100%; max-width: 1560px; margin: 0 auto; }
#starmap { width: 100%; height: auto; display: block; }
/* 触屏：连点两下同一颗星（选中 → 打开）别被浏览器当成双击放大网页；双指缩放照常可用 */
#starmap, .zoom-bar button { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }

.region-label {
  font-family: var(--font-mono); font-size: 12px;
  letter-spacing: 0.3em; fill: #b8c2d6; /* 天区标题：介于课程名与计数之间的亮度（share.js 的 SVG_STYLE 同值） */
}
.constellation-line { stroke: #2a3454; }
.star-hit { fill: transparent; }
.star { cursor: pointer; }
/* 触屏放大到某个星座时，其余星座淡下去，视线集中在要点的那一座 */
#starmap g[data-course] { transition: opacity 0.3s ease; }
#starmap.zoomed g[data-course]:not(.focus) { opacity: 0.3; }
/* 窄屏两列布局：手机上约 0.9 倍，14 号课程名 ≈ 12.6px */
#starmap.compact .course-label { font-size: 14px; }
#starmap.compact .course-count { font-size: 12px; }
#starmap.compact .region-label { font-size: 13px; letter-spacing: 0.12em; }
/* 推荐的下一颗星：梯队色虚线圈，缓慢转动 */
.star-next-ring { fill: none; stroke-width: 1.3; stroke-dasharray: 3 3; opacity: 0.9;
  transform-box: fill-box; transform-origin: center; animation: next-spin 6s linear infinite; }
@keyframes next-spin { to { transform: rotate(360deg); } }
.star-selected-ring { fill: none; stroke: #ffffff; stroke-width: 1.4; animation: ring-pulse 1.4s ease-in-out infinite; }
@keyframes ring-pulse { 50% { stroke-opacity: 0.35; } }

.zoom-bar {
  position: sticky; z-index: 15;
  display: flex; align-items: center; gap: 10px;
  margin: 0 16px 8px; padding: 8px 12px;
  background: rgba(16, 22, 39, 0.94); border: 1px solid var(--line); border-radius: 10px;
  backdrop-filter: blur(6px); color: var(--ink); font-size: 13.5px;
}
.zoom-bar[hidden] { display: none; }
#zoom-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.zoom-bar button {
  flex: none; background: transparent; color: var(--ink);
  border: 1px solid var(--line); border-radius: 999px; padding: 4px 14px; font-size: 13px;
}
.zoom-bar button.primary { border-color: var(--t2); background: rgba(57, 135, 229, 0.16); }
.zoom-bar button.step { padding: 4px 11px; font-size: 15px; line-height: 1; }
.zoom-bar button[hidden] { display: none; }
.star circle.core { transition: r 0.25s ease, filter 0.25s ease; }
@keyframes flare {
  0%   { r: 4.5; }
  45%  { r: 11; }
  100% { r: 5.5; }
}
.star.flare circle.core { animation: flare 0.6s ease-out; }
@keyframes twinkle { 0%,100% { opacity: 0.5; } 50% { opacity: 0.12; } }
.dust.tw { animation: twinkle 4s ease-in-out infinite; }

/* 星座下的课程名与计数：比正文次级色更亮，深色星空上手机也看得清（share.js 的 SVG_STYLE 同值） */
.course-label { font-size: 13px; fill: #d3daea; }
.course-label.done { fill: var(--ink); font-weight: 600; }

/* 整座点亮的光环：缓慢呼吸 */
@keyframes halo-breathe { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
.constellation-halo { animation: halo-breathe 3.6s ease-in-out infinite; }
.course-count { font-family: var(--font-mono); font-size: 11px; fill: #8e9ab3; }

.map-legend {
  display: flex; gap: 22px; justify-content: center; flex-wrap: wrap;
  color: var(--ink-2); font-size: 13px; padding: 8px 0 4px;
}
.lg { display: inline-flex; align-items: center; gap: 7px; }
.lg .dot { width: 11px; height: 11px; border-radius: 50%; display: inline-block; }
.dot.done.t1 { background: var(--t1); box-shadow: 0 0 7px var(--t1); }
.dot.todo { background: var(--star-todo); border: 1px solid var(--star-todo-stroke); }
.lg.hint { color: var(--ink-3); }

/* ============ 学习助手条：下一颗星 + 到期温习 + 错题本 ============ */
.study-bar {
  display: flex; justify-content: center; flex-wrap: wrap; gap: 8px;
  max-width: 920px; margin: 0 auto 12px; padding: 0 16px;
}
.study-bar[hidden] { display: none; }
.study-bar button {
  background: var(--surface); color: var(--ink); max-width: 100%;
  border: 1px solid var(--line); border-radius: 999px; padding: 6px 16px; font-size: 13.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.study-bar button:hover { border-color: var(--ink-3); }
.study-bar .next-btn { border-color: var(--t1); }
.study-bar .wrong-btn { border-color: var(--bad); color: #f2b8c1; }
.study-bar .due-btn { border-color: var(--t2); }
.backup-hint {
  flex-basis: 100%; display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 6px 8px;
  font-size: 12.5px; color: var(--ink-2); text-align: center;
}
.study-bar .backup-hint button { padding: 4px 12px; font-size: 12.5px; }
.study-bar .backup-btn { border-color: var(--t3); }

/* ============ 项目视图 ============ */
.projects-track {
  display: flex; flex-direction: column; gap: 0;
  max-width: 920px; margin: 24px auto; position: relative;
}
.projects-track::before {
  content: ""; position: absolute; left: 47px; top: 40px; bottom: 40px;
  width: 2px; background: linear-gradient(180deg, var(--t1), var(--t2), var(--t3));
  opacity: 0.35;
}
.project-card {
  display: flex; gap: 22px; align-items: flex-start;
  padding: 22px 18px; position: relative;
}
.planet { flex: 0 0 96px; display: flex; justify-content: center; }
.project-body h3 { font-size: 17px; font-weight: 600; }
.project-body h3 .level {
  font-family: var(--font-mono); font-size: 11px; font-weight: 400;
  border: 1px solid var(--line); border-radius: 999px;
  padding: 2px 10px; margin-left: 10px; color: var(--ink-2); vertical-align: 2px;
}
.project-body .weeks { font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); }
.project-body p.desc { color: var(--ink-2); font-size: 14px; margin: 6px 0; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.chip {
  font-size: 12px; color: var(--ink-2);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; padding: 2px 10px;
}
.chip.done { color: var(--ink); border-color: var(--t1); }
.chip.extra { border-style: dashed; color: var(--ink-3); }
.project-status { font-family: var(--font-mono); font-size: 12px; margin-top: 8px; color: var(--ink-3); }
.project-status.done { color: var(--t1); }
.project-toggle { margin-top: 10px; }

/* ============ 列表视图 ============ */
.list-search { max-width: 1150px; margin: 20px auto 0; }
.list-search input {
  width: 100%; box-sizing: border-box; padding: 9px 14px; font-size: 16px; font-family: inherit;
  background: var(--surface); color: var(--ink); border: 1px solid var(--line); border-radius: 999px;
}
.list-search input:focus { outline: none; border-color: var(--t1); }
.list-empty { color: var(--ink-3); text-align: center; margin: 24px 0; }
.list-root { max-width: 1150px; margin: 20px auto 40px; display: grid; gap: 28px; }
@media (min-width: 1400px) {
  .list-root { grid-template-columns: 1fr 1fr; align-items: start; max-width: 1560px; }
}
.list-section h2 {
  font-family: var(--font-display); font-size: 20px; letter-spacing: 0.08em;
  margin-bottom: 12px; color: var(--ink);
}
.list-row {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 14px; border-bottom: 1px solid var(--line);
  font-size: 14px;
}
.list-row .status-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.status-dot.done { box-shadow: 0 0 6px currentColor; background: currentColor; }
.status-dot.doing { background: transparent; border: 2px solid currentColor; }
.status-dot.todo { background: var(--star-todo); border: 1px solid var(--star-todo-stroke); }
.list-row .name { flex: 1; min-width: 0; }
.list-row .name .en { color: var(--ink-3); font-size: 12px; display: block; }
.list-row.achievement { color: var(--ink-3); }
.list-row.achievement.got { color: var(--ink); }
.ach-icon { width: 18px; text-align: center; flex: none; }
.list-row .meta { font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); white-space: nowrap; }
.tier-chip {
  font-family: var(--font-mono); font-size: 11px;
  border-radius: 999px; padding: 1px 9px; flex: none;
  border: 1px solid currentColor;
}
details.course-k { border-bottom: 1px solid var(--line); }
details.course-k summary { cursor: pointer; list-style: none; }
details.course-k summary::-webkit-details-marker { display: none; }
details.course-k summary .list-row { border-bottom: none; }
.k-items { padding: 0 14px 10px 36px; }
.k-item {
  display: flex; align-items: center; gap: 10px;
  font-size: 13.5px; color: var(--ink-2); padding: 5px 0;
  cursor: pointer; background: none; border: none; text-align: left; width: 100%;
}
.k-item .status-dot { width: 8px; height: 8px; }
.k-item .kdate { margin-left: auto; font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); }

/* ============ 热力图 ============ */
.heatmap-panel {
  max-width: min(1560px, 92vw); margin: 44px auto 0; padding: 26px 28px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
}
.heatmap-panel h2 {
  font-family: var(--font-display); font-size: 20px; letter-spacing: 0.08em;
}
#heatmap-total { color: var(--ink-2); font-size: 13px; margin: 4px 0 14px; }
.heatmap-scroll { overflow-x: auto; padding-bottom: 6px; }
#heatmap { display: flex; justify-content: center; }
#heatmap svg { display: block; width: 100%; max-width: 1300px; min-width: 760px; height: auto; }
.hm-label { font-family: var(--font-mono); font-size: 10px; fill: var(--ink-3); }
.hm-legend-label { font-family: var(--font-mono); font-size: 11px; fill: var(--ink-3); }
.hm-fallback { color: var(--ink-2); font-size: 14px; padding: 18px 0; }

/* ============ 视图条 / 工具提示 / 页脚 ============ */
.view-bar {
  position: sticky; top: 0; z-index: 20;
  display: flex; justify-content: center; align-items: center; flex-wrap: wrap; gap: 8px 16px;
  background: rgba(16, 22, 39, 0.92); border-bottom: 1px solid var(--line);
  backdrop-filter: blur(6px);
  color: var(--ink-2); padding: 8px 16px; font-size: 13.5px; text-align: center;
}
.view-bar-actions { display: inline-flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.view-bar button {
  background: transparent; color: var(--ink);
  border: 1px solid var(--line); border-radius: 999px; padding: 3px 14px; font-size: 12.5px;
}
.view-bar button:hover { border-color: var(--ink-3); }
.view-bar button.primary { border-color: var(--t2); background: rgba(57, 135, 229, 0.16); }
.view-bar button.quiet { color: var(--ink-3); }
/* 看别人的星图时视图条换成暖色，一眼看出「这不是我的」 */
body[data-view="shared"] .view-bar { background: rgba(42, 36, 18, 0.94); border-bottom-color: #5c4a1a; color: #ecd9a0; }

.tooltip {
  position: fixed; z-index: 30; pointer-events: none;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 8px; padding: 7px 12px;
  font-size: 12.5px; color: var(--ink); max-width: 260px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);
}
.tooltip .tt-sub { color: var(--ink-2); font-size: 11.5px; }

.site-footer {
  text-align: center; color: var(--ink-3); font-size: 13px;
  padding: 36px 16px 44px;
}
.footer-note { margin: 10px 0 0; font-size: 12px; opacity: .8; }

/* 成就解锁提示条：顶部居中，盖在弹窗之上（放底部在手机上会挡住测验结果页的按钮） */
.toast {
  position: fixed; left: 50%; top: 12px; transform: translateX(-50%); z-index: 60;
  display: flex; align-items: center; gap: 10px; max-width: calc(100vw - 32px);
  background: var(--surface-2); border: 1px solid var(--t3); border-radius: 12px;
  padding: 10px 12px 10px 16px; font-size: 14px; color: var(--ink);
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6);
}
.toast[hidden] { display: none; }
.toast button {
  flex: none; background: transparent; color: var(--ink);
  border: 1px solid var(--line); border-radius: 999px; padding: 3px 12px; font-size: 12.5px;
}
.toast button.primary { border-color: var(--t2); background: rgba(57, 135, 229, 0.16); }
.toast button.quiet { border: none; color: var(--ink-3); font-size: 18px; padding: 0 4px; }

/* ============ 知识点详情 / 测验弹窗 ============ */
.k-modal {
  position: fixed; inset: 0; z-index: 40;
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.k-modal[hidden] { display: none; }
.k-modal-backdrop { position: absolute; inset: 0; background: rgba(4, 7, 15, 0.72); }
.k-modal-box {
  position: relative; width: min(600px, 100%);
  max-height: min(84vh, 720px); overflow-y: auto;
  background: linear-gradient(180deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line); border-radius: 16px;
  padding: 30px 30px 26px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
}
.k-modal-close {
  position: absolute; top: 10px; right: 14px;
  background: none; border: none; color: var(--ink-3);
  font-size: 24px; line-height: 1; padding: 6px;
}
.k-modal-close:hover { color: var(--ink); }
.k-modal-body:focus { outline: none; }

.kd-head h2 { font-family: var(--font-display); font-size: 24px; margin: 10px 0 2px; letter-spacing: 0.04em; }
.kd-status { font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); }
.kd-status.done { color: var(--t1); }
.kd-summary { color: var(--ink-2); font-size: 14.5px; margin: 16px 0 4px; }
.kd-summary.empty { color: var(--ink-3); font-style: italic; }
.kd-actions { margin-top: 22px; display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
.kd-btn {
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: 999px;
  padding: 9px 26px; font-size: 14.5px;
}
.kd-btn:hover { border-color: var(--ink-3); }
.kd-btn.primary { border-color: var(--t2); background: rgba(57, 135, 229, 0.12); }
.kd-btn.primary:hover { background: rgba(57, 135, 229, 0.22); }
.kd-hint { font-size: 12.5px; color: var(--ink-3); }
.kd-links { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 10px; font-size: 13.5px; }
.kq-result .kd-links { justify-content: center; margin-top: 20px; color: var(--ink-3); }
.kq-report { display: block; margin-top: 8px; font-size: 12px; color: var(--ink-3); }
.kq-report:hover { color: var(--ink-2); }
.kd-passed { font-family: var(--font-mono); font-size: 12.5px; color: var(--t1); }

/* 分享弹窗 */
.sh-field { display: flex; flex-direction: column; gap: 6px; margin-top: 16px; }
.sh-label { font-size: 12.5px; color: var(--ink-3); }
.sh-input {
  width: 100%; background: var(--bg); color: var(--ink);
  border: 1px solid var(--line); border-radius: 10px; padding: 9px 12px; font-size: 14px;
}
.sh-input:focus { border-color: var(--t2); outline: none; }
.sh-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
.sh-note { margin-top: 12px; }
.sh-image { margin-top: 14px; display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
.sh-image img { width: 100%; border-radius: 10px; border: 1px solid var(--line); }
a.kd-btn { display: inline-block; text-decoration: none; }

.kq-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 14px; }
.kq-progress { color: var(--ink-3); font-size: 13px; }
.kq-title { font-size: 15px; color: var(--ink-2); font-weight: 400; }
.kq-q { font-size: 16px; font-weight: 600; line-height: 1.65; margin-bottom: 16px; }
.kq-options { display: flex; flex-direction: column; gap: 8px; }
.kq-opt {
  display: flex; gap: 12px; align-items: flex-start; text-align: left; width: 100%;
  background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 14px; font-size: 14px; line-height: 1.55;
}
.kq-opt:not(:disabled):hover { border-color: var(--t2); color: var(--ink); }
.kq-opt:disabled { cursor: default; opacity: 0.55; }
.kq-opt.correct { border-color: var(--t1); color: var(--ink); background: rgba(25, 158, 112, 0.12); opacity: 1; }
.kq-opt.wrong { border-color: var(--bad); color: var(--ink); background: rgba(224, 86, 106, 0.10); opacity: 1; }
.kq-letter { flex: none; color: var(--ink-3); }
.kq-explain {
  margin: 16px 0; padding: 12px 14px; border-radius: 10px;
  font-size: 13.5px; color: var(--ink-2); line-height: 1.7;
  background: var(--surface); border-left: 3px solid var(--t1);
}
.kq-explain.wrong { border-left-color: var(--bad); }
.kq-explain strong { color: var(--ink); margin-right: 8px; }

.kq-result { text-align: center; padding: 18px 6px 6px; }
.kq-result h2 { font-family: var(--font-display); font-size: 24px; margin: 12px 0; }
.kq-note { color: var(--ink-2); font-size: 14px; max-width: 420px; margin: 0 auto 20px; }
.kq-star {
  font-size: 54px; line-height: 1;
  text-shadow: 0 0 24px currentColor;
  animation: star-pop 0.7s ease-out;
}
@keyframes star-pop {
  0%   { transform: scale(0.3); opacity: 0; }
  60%  { transform: scale(1.25); }
  100% { transform: scale(1); opacity: 1; }
}
.kq-result .kd-btn { margin: 0 6px; }

/* 测验全对后的撒花：不铺满屏幕，只在刚点亮的那颗星周围迸发一小圈纸屑。
   容器 fixed 铺满视口只为承载定位，纸屑本身用星星的视口坐标定点。 */
.confetti-burst { position: fixed; inset: 0; z-index: 50; pointer-events: none; overflow: hidden; }
.confetti-bit {
  position: absolute; width: var(--w); height: var(--h);
  background: var(--c); border-radius: var(--br);
  opacity: 0;
  animation: confetti-fly var(--dur) cubic-bezier(0.17, 0.7, 0.35, 1) var(--delay) forwards;
}
@keyframes confetti-fly {
  0%   { transform: translate(-50%, -50%) scale(0.5) rotate(0deg); opacity: 0; }
  15%  { opacity: 1; }
  65%  { opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1) rotate(var(--rot)); opacity: 0; }
}
/* 一圈扩散的光环，点出「亮的是这颗」 */
.confetti-ring {
  position: absolute; width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.75);
  animation: confetti-ring 0.62s ease-out forwards;
}
@keyframes confetti-ring {
  0%   { transform: translate(-50%, -50%) scale(0.4); opacity: 0.9; }
  100% { transform: translate(-50%, -50%) scale(4.6); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .dust.tw, .star.flare circle.core, .constellation-halo, .kq-star { animation: none; }
  .confetti-burst { display: none; }
  .star-selected-ring, .star-next-ring { animation: none; }
}

@media (max-width: 640px) {
  .site-header { padding-top: 36px; }
  .switch-btn { position: static; display: block; margin: 0 auto 14px; }
  .projects-track::before { left: 39px; }
  .planet { flex-basis: 80px; }
  /* 手机上一行放不下全部：留进度数（3 / 8），藏掉梯队标签——天区在星图上已经看得到 */
  .list-row .tier-chip { display: none; }
}
