
/* ===== Source: main.css ===== */
/* ============================================
   1. Design tokens
   ============================================ */
:root {
  color-scheme: light;
  --hgu-visual-left: 0px;
  --hgu-visual-width: 100vw;
  --hgu-visual-center: 50vw;
  --glass: rgba(255, 255, 255, .25);
  --bg: #E1ECF2;
  --text: #4a7c59;
  --text-light: rgba(76, 175, 80, .15);
  --subtext: #333;
  /* 地图上四个悬浮按钮（通知 / 反馈 / 分享 / 定位）的图标与文本色 = 主文本色。
     单独做一个 token 而不是直接写 var(--text)：--text 会被抽屉内的页面主题覆盖
     （.tools-fixed-header-layer > [data-header-for=...] 等），在这些按钮上就会变色。 */
  --hgu-idle-chrome: var(--text);
  --border: rgba(255, 255, 255, .4);
  --shadow: 0 2px 8px rgba(0, 0, 0, .1);
  --drawer-surface: rgba(255, 255, 255, 0.5);

  /* Unified surface, radius, blur, shadow and motion tokens */
  --hgu-surface-glass: var(--glass);
  --hgu-surface-glass-soft: rgba(255, 255, 255, 0.18);
  --hgu-surface-glass-strong: rgba(255, 255, 255, 0.62);
  --hgu-surface-solid: rgba(255, 255, 255, 0.88);
  --hgu-border-soft: var(--border);
  --hgu-shadow-card: var(--shadow);
  --hgu-shadow-raised: 0 8px 24px rgba(0, 0, 0, 0.14);
  --hgu-shadow-floating: 0 12px 34px rgba(0, 0, 0, 0.18);
  --hgu-shadow-modal: 0 14px 42px rgba(0, 0, 0, 0.28);

  --hgu-radius-xs: 4px;
  --hgu-radius-sm: 6px;
  --hgu-radius-md: 8px;
  --hgu-radius-lg: 10px;
  --hgu-radius-xl: 12px;
  --hgu-radius-default: 14px;
  --hgu-radius-2xl: 16px;
  --hgu-radius-polished: 18px;
  --hgu-radius-3xl: 20px;
  --hgu-radius-4xl: 24px;
  --hgu-radius-5xl: 28px;
  --hgu-radius-pill: 999px;
  --hgu-radius-round: 50%;
  --hgu-radius-drawer: 32px 32px 0 0;
  --hgu-radius-corner-badge: 8px 0 8px 0;

  --hgu-blur-xs: 2px;
  --hgu-blur-sm: 4px;
  --hgu-blur-md: 5px;
  --hgu-blur-panel: 6px;
  --hgu-blur-lg: 8px;
  --hgu-blur-xl: 10px;
  --hgu-blur-2xl: 12px;
  --hgu-blur-floating: 18px;
  --hgu-blur-3xl: 20px;
  /* 底部悬浮栏专用模糊度：压在内容/地图上，5px(--hgu-blur-md) 时底下文字边缘还能认出轮廓，
     单独抬到 11px（用户要求「略微增加」；改这一处对双栏同时生效） */
  --hgu-blur-dock: 11px;

  --radius: 14px;
  --radius-xs: 6px;
  --radius-sm: 10px;
  --radius-md: 14px;
  --radius-lg: 18px;
  --radius-xl: 24px;
  --radius-pill: 999px;

  --motion-fast: 160ms;
  --motion-base: 240ms;
  --motion-slow: 360ms;
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-standard: cubic-bezier(0.22, 0.61, 0.36, 1);

  /* 抽屉内页面切换（见 .tools-sub-page / .tools-home-content）：
     旧页面用 out 快速渐隐，新页面等 out 之后再花 in 快速渐显 ——
     两段加起来 ≈270ms，比原来的 300ms 滑入还快一点，但没有硬切。
     JS 里（navigation.js 的首页/学习视图切换）会读这两个值来对齐定时器，
     改这里即可整体调快/调慢。 */
  --page-switch-out: 100ms;
  --page-switch-in: 170ms;

  /* 抽屉内容区的左右内边距（.tools-content-container 的 padding）。
     ★ 必须是唯一定义：页面在「流内（可见）」和「绝对定位（已隐藏/离场）」两种状态下，
       百分比宽度分别按 content box 和 padding box 计算，差的就是这两倍内边距。
       下面 .tools-home-content.hidden / .tools-sub-page:not(.active) 用 left/right
       钉住同一对内边距，保证切页时页面宽度 0 跳变。改这里即可整体调宽/调窄。 */
  --drawer-inline-pad: 20px;

  /* ================== 地图「图层胶囊栏」的几何 ==================
     ★ 一条总原则（改任何值之前先读）：
       **悬浮栏本身的位置不动** —— 它永远待在 --hgu-bottom-dock-bottom 那个位置。
       要腾地方的是「它上方那一串」：胶囊栏、水印、定位按钮、楼层栏、图例。
       --hgu-bottom-band-lift 只抬高上面那一串，**不含悬浮栏**。
       反过来做（把栏高算进悬浮栏的 bottom）会把悬浮栏一起顶上去，用户明确否掉过。 */
  --hgu-layer-rail-h: 20px;
  /* ★ 实测过的硬约束：实缝不能取消 —— 悬浮栏渲染出来总高 48px、且它的顶边比
     「CSS bottom + 高度」还高 48px（父容器 flex 拉伸溢出）。而开关行比悬浮栏宽得多
     （4 颗 300px+ vs 悬浮栏 270px），横向避不开，只能整体抬上去。
     8px 实缝的口径是"几像素就够"：
     开关行高 = 悬浮栏高度的一半（45 / 2 ≈ 20px）；开关行与上方各元素的间隙
     由 JS 按实测矩形串起来，同样只留 8~12px。 */
  --hgu-layer-rail-gap: 8px;
  /* 栏底 = 悬浮栏底距 20px + 悬浮栏总高 48px + 实缝。JS 读的就是这一条
     （navigation.js 的 getLayerRailBaseBottom），所以别只改上面两个而漏掉它。 */
  --hgu-layer-rail-bottom: calc(20px + 48px + var(--hgu-layer-rail-gap));
  /* 服务卡片态：栏底 = 卡片上沿 + 8px 呼吸位（由 JS 按实测卡片高写内联 bottom） */
  --hgu-layer-rail-raise: 8px;
  --hgu-layer-rail-bottom-raised: calc(var(--hgu-layer-rail-bottom) + var(--hgu-layer-rail-raise));

  /* 悬浮栏**自己的**站位：**始终不变**，不随胶囊开关出现而抬高 */
  --hgu-bottom-dock-bottom: 20px;

  /* 悬浮栏**上方**那一串（水印 / 定位按钮 / 楼层栏 / 图例）的整体抬高量。
     增量 = 开关行高 ×2（行本身 + 让出来的留白）+ 实缝；悬浮栏自己不吃这个值。 */
  --hgu-bottom-band-lift: calc(var(--hgu-layer-rail-h) * 2 + var(--hgu-layer-rail-gap));
  --hgu-chrome-bottom-watermark: calc(72px + var(--hgu-bottom-band-lift));
  --hgu-chrome-bottom-location: calc(80px + var(--hgu-bottom-band-lift));
  --hgu-chrome-bottom-legend: calc(140px + var(--hgu-bottom-band-lift));
  /* 右上角 通知/反馈/分享 按钮组的站位（贴着状态栏下方）。
     取 env() 与 APP 下发的 --hgu-android-safe-top 的较大者：
     前者在部分 OEM WebView（小米/MIUI/HyperOS 常见）会返回 0，导致按钮被状态栏遮挡；
     后者是原生 WindowInsets 的权威状态栏高度（px÷density，与 env() 同口径），
     二者取 max 不会重复叠加。非 APP 环境没有该变量，自动退回 env()。
     ★ 只有这一组按钮避让状态栏；地图页与抽屉页仍伸进状态栏，保持沉浸效果。 */
  --hgu-top-actions-top: calc(max(env(safe-area-inset-top, 0px), var(--hgu-android-safe-top, 0px)) + 14px);

  /* 分享弹窗收起（向下飞出）的时长：JS 读它来决定什么时候补 .is-hidden，
     与下面 .share-fullscreen 的 visibility 延迟、.share-fullscreen-body 的
     transform 过渡时长三者必须一致。 */
  --share-out-ms: 460ms;

  --color-blue: #007bff;
  --study-cyan: #008fa8;
  --study-cyan-rgb: 0, 143, 168;
  --color-orange: #ff9800;
  --color-brown: #C6A65D;
  --color-red: #b71c1c;
  --color-lightred: #FF6E6E;
  --color-gray: #9e9e9e;
  --color-sky: #73ABFF;
  --color-life: #FF8126;

  --weather-icon-sunny: #4a7c59;
  --weather-icon-overcast: #90A4AE;
  --weather-icon-rain: #42A5F5;
  --weather-icon-storm: #AB47BC;
  --weather-icon-snow: #81D4FA;
  --weather-icon-fog: #B0BEC5;
  --weather-icon-haze: #BCAAA4;
  --weather-icon-hot: #EF5350;
  --weather-icon-cold: #4DD0E1;
  --weather-icon-wind: #81C784;
  --weather-icon-unknown: #BDBDBD;
  --weather-text-sunny: #4a7c59;
  --weather-text-overcast: #607D8B;
  --weather-text-rain: #1976D2;
  --weather-text-storm: #6A1B9A;
  --weather-text-snow: #0288D1;
  --weather-text-fog: #757575;
  --weather-text-haze: #6D4C41;
  --weather-text-hot: #D32F2F;
  --weather-text-cold: #0097A7;
  --weather-text-wind: #388E3C;
  --weather-text-unknown: #616161;
  --sunset-accent: #FF9800;
  --sunset-quality-burn: #D32F2F;
  --sunset-quality-light: #FF9800;
  --sunset-quality-slight: #FFC107;
}

html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* ============================================
   2. Base reset and shared primitives
   ============================================ */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  outline: none;
  -webkit-tap-highlight-color: transparent;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
    "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow: hidden;
  transition: background .3s ease, color .3s ease;
}

.glass-btn {
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  color: var(--text);
  backdrop-filter: blur(var(--hgu-blur-md));
  border-radius: var(--hgu-radius-md);
  padding: 6px 10px;
  font-size: 13px;
  cursor: pointer;
  box-shadow: var(--hgu-shadow-card);
  transition: transform .2s, background .3s, color .3s;
}

.glass-btn:active {
  transform: scale(0.95);
}

.map-brand-watermark {
  position: fixed;
  left: 18px;
  bottom: var(--hgu-chrome-bottom-watermark);
  z-index: 650;
  min-height: 34px;
  max-width: min(270px, calc(100vw - 36px));
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text);
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: inherit;
  cursor: pointer;
  transition: transform .32s ease, bottom .32s ease, opacity .2s ease;
}

body.home-panel-compact .map-brand-watermark.is-raised {
  bottom: calc(218px + var(--hgu-bottom-band-lift));
}

body:not(.home-panel-compact) .map-brand-watermark {
  bottom: var(--hgu-chrome-bottom-watermark);
}

.map-brand-watermark img {
  width: 20px;
  height: 20px;
  border-radius: var(--hgu-radius-sm);
  flex-shrink: 0;
  filter: drop-shadow(0 0 1px rgba(255,255,255,.9));
}

.map-brand-name {
  color: #666;
  font-size: 12px;
  font-weight: 800;
  max-width: 118px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-shadow: 0 1px 0 rgba(255,255,255,.85), 0 0 2px rgba(255,255,255,.75);
}

.map-brand-watermark i {
  color: var(--text);
  font-size: 17px;
  filter: drop-shadow(0 0 1px rgba(255,255,255,.9));
}

.map-brand-temp {
  color: #555;
  font-size: 12px;
  font-weight: 900;
  text-shadow: 0 1px 0 rgba(255,255,255,.85), 0 0 2px rgba(255,255,255,.75);
}

/* 紧凑形态（服务卡片）的内容层：容器高度收缩到卡片高度时显示这一层。
   铺满容器宽度、顶部让开共用的拖拽把手；自身高度由内容决定（≈ 卡片高度）。
   容器长高变矮时它不重排，只做淡出 —— 所以卡片和抽屉确实是同一个容器。 */
.home-compact-layer {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 3;
  /* = .drawer-drag-handle 的高度，让开共用的拖拽把手 */
  padding-top: 48px;
  /* 卡片内容一律不许画到卡片之外（内含 white-space:nowrap 的提示文字、
     以及不收缩的按钮，窄屏下会横向溢出） */
  overflow: hidden;
  transition: opacity .3s ease;
}

.home-compact-content {
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  padding: 6px 14px 76px;
}

.home-compact-loading,
.home-recommend-card {
  display: flex;
  align-items: center;
  gap: 12px;
}

.home-compact-loading {
  color: var(--subtext);
  min-height: 82px;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
}

.home-recommend-card {
  width: 100%;
  min-height: 78px;
  border: 0;
  border-radius: var(--hgu-radius-3xl);
  background: transparent;
  color: var(--text);
  padding: 8px 4px;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.home-recommend-card > .fas:last-child {
  color: var(--subtext);
  font-size: 14px;
  flex-shrink: 0;
}

.home-recommend-icon {
  width: 44px;
  height: 44px;
  border-radius: var(--hgu-radius-2xl);
  background: var(--text);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  flex-shrink: 0;
}

.home-recommend-copy {
  min-width: 0;
  flex: 1;
  text-align: left;
}

.home-recommend-kicker {
  display: block;
  color: var(--subtext);
  font-size: 12px;
  font-weight: 700;
  margin-bottom: 2px;
}

.home-recommend-title {
  display: block;
  color: var(--text);
  font-size: 16px;
  font-weight: 900;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.home-recommend-subtitle {
  display: block;
  color: var(--subtext);
  font-size: 12px;
  line-height: 1.45;
  margin-top: 4px;
}

.home-course-reminder {
  --course-reminder-accent: #ff8126;
  width: 100%;
  min-height: 88px;
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  border: 0;
  border-radius: var(--hgu-radius-3xl);
  background: transparent;
  color: var(--course-reminder-accent);
  padding: 8px 4px;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.home-course-reminder.is-ongoing {
  --course-reminder-accent: #2f80ed;
}

.home-course-reminder-icon {
  width: 48px;
  height: 48px;
  border-radius: 17px;
  background: rgba(255, 129, 38, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}

.home-course-reminder.is-ongoing .home-course-reminder-icon {
  background: rgba(47, 128, 237, 0.12);
}

.home-course-reminder-icon img {
  width: 32px;
  height: 32px;
  object-fit: contain;
}

.home-course-reminder-copy {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: left;
}

.home-course-reminder-kicker {
  color: var(--course-reminder-accent);
  font-size: 12px;
  line-height: 1.25;
  font-weight: 900;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.home-course-reminder-title {
  color: var(--course-reminder-accent);
  font-size: 20px;
  line-height: 1.15;
  font-weight: 950;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.home-course-reminder-distance {
  color: var(--subtext);
  font-size: 11px;
  line-height: 1.28;
  font-weight: 700;
  opacity: 0.78;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.home-course-cancel-btn {
  min-width: 52px;
  height: 34px;
  border: 1px solid rgba(255, 129, 38, 0.32);
  border-radius: var(--hgu-radius-pill);
  background: rgba(255, 129, 38, 0.1);
  color: var(--course-reminder-accent);
  font: inherit;
  font-size: 13px;
  font-weight: 900;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  flex-shrink: 0;
}

.home-course-reminder.is-ongoing .home-course-cancel-btn {
  border-color: rgba(47, 128, 237, 0.32);
  background: rgba(47, 128, 237, 0.1);
}

.home-course-cancel-btn:active {
  transform: scale(0.96);
}

/* ===== 冲突课程提醒：多门课程同时在提醒窗口内时按行展示，并可切换聚焦课程 ===== */
.home-course-reminder.is-conflict {
  padding-top: 10px;
  padding-bottom: 10px;
}

/* 每门课程一行（课程名 / 教室与倒计时 / 距离），非聚焦行淡化，聚焦行高亮 */
.home-course-reminder-course {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: left;
}

.home-course-reminder.is-conflict .home-course-reminder-copy {
  gap: 10px;
}

.home-course-reminder.is-conflict .home-course-reminder-course {
  opacity: 0.55;
  transition: opacity 0.18s ease;
}

.home-course-reminder.is-conflict .home-course-reminder-course.is-active {
  opacity: 1;
}

.home-course-reminder.is-conflict .home-course-reminder-title {
  font-size: 16px;
  line-height: 1.2;
}

.home-course-reminder.is-conflict .home-course-reminder-distance {
  font-size: 10px;
}

/* 右侧列：切换按钮占用原取消按钮位置，取消按钮固定到右下角 */
.home-course-reminder-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  flex-shrink: 0;
}

.home-course-reminder.is-conflict .home-course-reminder-actions {
  align-self: stretch;
  justify-content: space-between;
}

.home-course-switch-btn {
  min-width: 52px;
  height: 30px;
  border: 1px solid rgba(255, 129, 38, 0.32);
  border-radius: var(--hgu-radius-pill);
  background: rgba(255, 129, 38, 0.1);
  color: var(--course-reminder-accent);
  font: inherit;
  font-size: 12px;
  font-weight: 900;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  flex-shrink: 0;
}

.home-course-switch-btn:active {
  transform: scale(0.96);
}

.home-course-switch-btn.is-active {
  background: var(--course-reminder-accent);
  border-color: var(--course-reminder-accent);
  color: #fff;
}

.home-course-reminder.is-ongoing .home-course-switch-btn {
  border-color: rgba(47, 128, 237, 0.32);
  background: rgba(47, 128, 237, 0.1);
}

.home-course-reminder.is-ongoing .home-course-switch-btn.is-active {
  background: var(--course-reminder-accent);
  border-color: var(--course-reminder-accent);
  color: #fff;
}

.home-rain-reminder {
  --rain-reminder-accent: #2f80ed;
  width: 100%;
  min-height: 88px;
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  border: 0;
  border-radius: var(--hgu-radius-3xl);
  background: transparent;
  color: var(--rain-reminder-accent);
  padding: 8px 4px;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.home-rain-reminder .home-recommend-icon {
  background: rgba(47, 128, 237, 0.12);
  color: var(--rain-reminder-accent);
}

.home-rain-reminder .home-recommend-kicker {
  color: var(--rain-reminder-accent);
  font-weight: 900;
}

.home-rain-reminder .home-recommend-title {
  color: var(--rain-reminder-accent);
  font-size: 17px;
  font-weight: 950;
  white-space: normal;
}

.home-rain-reminder .home-recommend-subtitle {
  font-weight: 700;
}

.home-rain-reminder .home-course-cancel-btn {
  border-color: rgba(47, 128, 237, 0.32);
  background: rgba(47, 128, 237, 0.1);
  color: var(--rain-reminder-accent);
}

/* 火烧云提醒：橙红主题色（与"火烧云"视觉一致） */
.home-sunset-reminder {
  --sunset-reminder-accent: #ff4d1f;
  width: 100%;
  min-height: 88px;
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  border: 0;
  border-radius: var(--hgu-radius-3xl);
  background: transparent;
  color: var(--sunset-reminder-accent);
  padding: 8px 4px;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.home-sunset-reminder .home-recommend-icon {
  background: rgba(255, 77, 31, 0.12);
  color: var(--sunset-reminder-accent);
}

.home-sunset-reminder .home-recommend-kicker {
  color: var(--sunset-reminder-accent);
  font-weight: 900;
}

.home-sunset-reminder .home-recommend-title {
  color: var(--sunset-reminder-accent);
  font-size: 17px;
  font-weight: 950;
  white-space: normal;
}

.home-sunset-reminder .home-recommend-subtitle {
  font-weight: 700;
}

.home-sunset-reminder .home-course-cancel-btn {
  border-color: rgba(255, 77, 31, 0.32);
  background: rgba(255, 77, 31, 0.1);
  color: var(--sunset-reminder-accent);
}

/* 社团活动提醒：跟随「社团与活动」页主题色（紫 #7f4dae / 品红 #c54fae） */
.home-activities-reminder {
  --activities-reminder-accent: #7f4dae;
  --activities-reminder-icon: #c54fae;
  width: 100%;
  min-height: 88px;
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  border: 0;
  border-radius: var(--hgu-radius-3xl);
  background: transparent;
  color: var(--activities-reminder-accent);
  padding: 8px 4px;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.home-activities-reminder .home-recommend-icon {
  background: rgba(127, 77, 174, 0.12);
  color: var(--activities-reminder-icon);
}

.home-activities-reminder .home-recommend-kicker {
  color: var(--activities-reminder-accent);
  font-weight: 900;
}

.home-activities-reminder .home-recommend-title {
  color: var(--activities-reminder-accent);
  font-size: 17px;
  font-weight: 950;
  white-space: normal;
}

.home-activities-reminder .home-recommend-subtitle {
  font-weight: 700;
}

.home-activities-reminder .home-course-cancel-btn {
  border-color: rgba(127, 77, 174, 0.32);
  background: rgba(127, 77, 174, 0.1);
  color: var(--activities-reminder-accent);
}

html[data-theme="dark"] .home-activities-reminder {
  --activities-reminder-accent: #d7b8ff;
  --activities-reminder-icon: #ffaddf;
}

html[data-theme="dark"] .home-activities-reminder .home-recommend-icon {
  background: rgba(255, 173, 223, 0.16);
}

html[data-theme="dark"] .home-activities-reminder .home-course-cancel-btn {
  border-color: rgba(215, 184, 255, 0.34);
  background: rgba(215, 184, 255, 0.12);
}

.home-location-card {
  min-height: 92px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto auto auto auto auto;
  gap: 4px 12px;
  padding: 7px 4px 4px;
  color: var(--text);
}

.home-location-title {
  min-width: 0;
  font-size: 21px;
  line-height: 1.2;
  font-weight: 950;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.home-location-cancel {
  align-self: start;
  min-width: 52px;
  height: 32px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-pill);
  background: rgba(127, 127, 127, 0.08);
  color: var(--text);
  font: inherit;
  font-size: 13px;
  font-weight: 850;
  cursor: pointer;
}

.home-location-divider {
  grid-column: 1 / -1;
  height: 1px;
  background: var(--hgu-border-soft, rgba(127, 127, 127, 0.18));
  margin: 3px 0 2px;
}

.home-location-meta {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  min-width: 0;
}

.home-location-distance {
  color: var(--subtext);
  font-size: 11px;
  line-height: 1.28;
  font-weight: 700;
}

.home-location-status-row {
  grid-column: 1 / -1;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.home-location-status {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 800;
  line-height: 1.2;
  color: #fff;
  background: #2f80ed; /* 营业中：蓝色 */
}

.home-location-status.status-soon {
  background: #f5a623; /* 即将营业 / 即将关门：橙黄色 */
}

.home-location-status.status-closed {
  background: #9e9e9e; /* 已关门：灰色 */
}

.home-location-hours {
  flex-shrink: 0;
  color: var(--subtext);
  font-size: 11px;
  line-height: 1.2;
  font-weight: 700;
}

.home-location-actions {
  grid-column: 1 / -1;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.home-location-action {
  height: 34px;
  padding: 0 15px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 0;
  border-radius: var(--hgu-radius-pill);
  background: rgba(127, 127, 127, 0.11);
  color: var(--text);
  font: inherit;
  font-size: 13px;
  font-weight: 850;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.home-location-action.is-share {
  background: var(--text);
  color: var(--bg, #fff);
}

.home-location-cancel:active,
.home-location-action:active {
  transform: scale(0.96);
}

/* 活动服务卡片：跟随「社团与活动」页主题色（紫 #7f4dae / 品红 #c54fae），
   仅通过 .is-activity 变体生效，不影响店铺/驿站卡片外观 */
.home-location-card.is-activity {
  --activity-card-accent: #7f4dae;
  --activity-card-accent-2: #c54fae;
  --activity-card-accent-soft: rgba(127, 77, 174, 0.12);
  --activity-card-accent-border: rgba(127, 77, 174, 0.32);
  --activity-card-accent2-soft: rgba(197, 79, 174, 0.12);
  --activity-card-accent2-border: rgba(197, 79, 174, 0.32);
}

.home-location-card.is-activity .home-location-title {
  color: var(--activity-card-accent);
}

.home-location-card.is-activity .home-location-cancel {
  border-color: var(--activity-card-accent-border);
  background: var(--activity-card-accent-soft);
  color: var(--activity-card-accent);
}

.home-location-card.is-activity .home-location-divider {
  background: var(--activity-card-accent-border);
}

/* 活动信息行（组织方/时间/地点）改为纵向排列，取代店铺/驿站的单行直线距离 */
.home-location-card.is-activity .home-location-meta {
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
}

.home-location-card.is-activity .home-location-info {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  color: var(--activity-card-accent);
  font-size: 12px;
  line-height: 1.35;
  font-weight: 700;
}

.home-location-card.is-activity .home-location-info i {
  flex-shrink: 0;
  color: var(--activity-card-accent-2);
  font-size: 11px;
}

.home-location-card.is-activity .home-location-action {
  border: 1px solid var(--activity-card-accent-border);
  background: var(--activity-card-accent-soft);
  color: var(--activity-card-accent);
}

.home-location-card.is-activity .home-location-action[data-location-activity-all] {
  border-color: var(--activity-card-accent2-border);
  background: var(--activity-card-accent2-soft);
  color: var(--activity-card-accent-2);
}

html[data-theme="dark"] .home-location-card.is-activity {
  --activity-card-accent: #d7b8ff;
  --activity-card-accent-2: #ffaddf;
  --activity-card-accent-soft: rgba(215, 184, 255, 0.12);
  --activity-card-accent-border: rgba(215, 184, 255, 0.34);
  --activity-card-accent2-soft: rgba(255, 173, 223, 0.14);
  --activity-card-accent2-border: rgba(255, 173, 223, 0.34);
}

/* 新同学联系提醒卡片（橙红 #FF4D2E 主题）：发布者收到他人联系方式时的服务卡片
 * 结构仿 .home-location-card：标题=帖子物品名 / 取消 / 分隔线 / 正文 / 右下角操作 */
.home-lf-contact-card {
  min-height: 92px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto auto auto auto auto;
  gap: 4px 12px;
  padding: 7px 4px 4px;
  color: var(--text);
  --lf-contact-accent: #ff4d2e;
  --lf-contact-accent-soft: rgba(255, 77, 46, 0.12);
  --lf-contact-accent-border: rgba(255, 77, 46, 0.32);
}

.home-lf-contact-title {
  min-width: 0;
  font-size: 21px;
  line-height: 1.2;
  font-weight: 950;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--lf-contact-accent);
}

.home-lf-contact-cancel {
  align-self: start;
  min-width: 52px;
  height: 32px;
  border: 1px solid var(--lf-contact-accent-border);
  border-radius: var(--hgu-radius-pill);
  background: var(--lf-contact-accent-soft);
  color: var(--lf-contact-accent);
  font: inherit;
  font-size: 13px;
  font-weight: 850;
  cursor: pointer;
}

.home-lf-contact-divider {
  grid-column: 1 / -1;
  height: 1px;
  background: var(--lf-contact-accent-border);
  margin: 3px 0 2px;
}

.home-lf-contact-body {
  grid-column: 1 / -1;
  min-width: 0;
  color: var(--subtext);
  font-size: 12px;
  line-height: 1.35;
  font-weight: 700;
}

.home-lf-contact-actions {
  grid-column: 1 / -1;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.home-lf-contact-action {
  height: 34px;
  padding: 0 15px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 0;
  border-radius: var(--hgu-radius-pill);
  background: rgba(127, 127, 127, 0.11);
  color: var(--text);
  font: inherit;
  font-size: 13px;
  font-weight: 850;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.home-lf-contact-action.is-primary {
  background: var(--lf-contact-accent);
  color: #fff;
}

.home-lf-contact-action:active {
  transform: scale(0.97);
}

html[data-theme="dark"] .home-lf-contact-card {
  --lf-contact-accent: #ff7a5c;
  --lf-contact-accent-soft: rgba(255, 122, 92, 0.14);
  --lf-contact-accent-border: rgba(255, 122, 92, 0.36);
}

.home-default-panel {
  position: relative;
  min-height: 108px;
  padding: 4px 0 0;
}

.home-default-title {
  color: var(--subtext);
  font-size: 15px;
  font-weight: 800;
  line-height: 1.35;
  padding: 0 4px;
  max-width: 52%;
}

.home-default-actions {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}

.home-default-action {
  height: 76px;
  border: 0;
  border-radius: var(--hgu-radius-3xl);
  background: linear-gradient(180deg, rgba(255,255,255,.38), rgba(255,255,255,.18));
  color: var(--text);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28), 0 10px 20px rgba(0,0,0,.1);
  font: inherit;
  font-size: 12px;
  font-weight: 900;
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  text-align: left;
  padding: 10px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  overflow: hidden;
}

.home-default-action img {
  position: absolute;
  right: 6px;
  bottom: 5px;
  width: 42px;
  height: 42px;
  object-fit: contain;
  filter: drop-shadow(0 8px 10px rgba(0,0,0,.18));
}

.home-default-action span {
  color: var(--subtext);
  line-height: 1;
  position: relative;
  z-index: 1;
}

  html[data-theme="dark"] .map-brand-watermark {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
  }

  html[data-theme="dark"] .map-brand-name,
  html[data-theme="dark"] .map-brand-temp {
    color: rgba(255,255,255,0.74);
    text-shadow: 0 1px 1px rgba(0,0,0,.8), 0 0 2px rgba(255,255,255,.22);
  }

  html[data-theme="dark"] .map-brand-watermark img,
  html[data-theme="dark"] .map-brand-watermark i {
    filter: drop-shadow(0 0 1px rgba(255,255,255,.65));
  }

  /* 深色模式：面板自身就是卡片表面（单一容器），不需要再给某一层单独上底色 */
  html[data-theme="dark"] #tools-page {
    background: var(--drawer-surface);
    border-color: rgba(255, 255, 255, 0.14);
    box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.42);
  }

  html[data-theme="dark"] .home-default-action {
    background: linear-gradient(180deg, rgba(255,255,255,.12), rgba(255,255,255,.06));
    box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 10px 20px rgba(0,0,0,.22);
  }

body.home-panel-compact .bottom-nav {
  background: var(--hgu-surface-glass);
  border-color: var(--hgu-border-soft);
  box-shadow: none;
  backdrop-filter: blur(var(--hgu-blur-dock));
  -webkit-backdrop-filter: blur(var(--hgu-blur-dock));
}

/* 搴曢儴瀵艰埅鏍?*/
/* 底部悬浮栏：外层 dock 负责整体居中，内部两个栏（今天吃什么 / 总悬浮栏）
   始终「一个折叠、一个展开」；折叠 = 只保留激活项，其余项宽度归零。
   用非线性 cubic-bezier（带一点回弹）做展开/收起，收起时带轻微位移。 */
.bottom-dock {
  position: fixed;
  left: 50%;
  bottom: var(--hgu-bottom-dock-bottom);
  transform: translateX(-50%);  display: flex;
  align-items: center;
  width: max-content;
  max-width: calc(100vw - 16px);
  z-index: 999;
  pointer-events: none;   /* 只有两个栏本身吃点击，缝隙不吃 */
}
.bottom-dock .bottom-nav {
  pointer-events: auto;
}
/* dock 里的两个栏：不再自己 fixed 居中，宽度交给内容决定
   （基线 .bottom-nav 有固定 width:300px，这里必须一起覆盖，否则折叠时不会收缩） */
.bottom-dock > .bottom-nav {
  position: static;
  left: auto;
  bottom: auto;
  transform: none;
  width: max-content;
  min-width: 0;
  flex: 0 0 auto;
  animation: none !important;
}
.bottom-dock .bottom-nav-item {
  flex: 0 0 auto;
  width: clamp(42px, calc((100vw - 70px) / 5), 64px);
  min-width: 0;
  box-sizing: border-box;
}
/* 今天吃什么栏：总悬浮栏的样式 + 橙黄色主题，默认「已飞出」。
   DOM 里排在总悬浮栏之后（保证 querySelector('.bottom-nav') 拿到的是总悬浮栏），
   视觉上用 order 提到左边。 */
.eatwhat-dock-bar {
  order: -1;
  margin-right: 8px;
  border-color: var(--ew-theme-border, rgba(246, 168, 33, 0.5));
  transform-origin: left bottom;
}
.eatwhat-dock-bar .bottom-nav-item {
  color: var(--subtext);
}
.eatwhat-dock-bar .bottom-nav-item.active {
  background: var(--ew-theme-soft, rgba(246, 168, 33, 0.16));
  color: var(--ew-theme-strong, #e08500);
}
/* 未进入今天吃什么：整体向左下飞出（宽度收干，不占位、不挡点击） */
.eatwhat-dock-bar.is-out {
  width: 0;
  min-width: 0;
  margin-right: 0;
  padding-left: 0;
  padding-right: 0;
  border-width: 0;
  opacity: 0;
  transform: translate(-28px, 18px) scale(.86);
  pointer-events: none;
  overflow: hidden;
}
.eatwhat-dock-bar.is-out .bottom-nav-item {
  width: 0;
  opacity: 0;
}
/* 折叠态：只留激活项（宽度归零，动画由子项过渡带出） */
.bottom-dock .bottom-nav.is-collapsed .bottom-nav-item:not(.active) {
  width: 0;
  min-width: 0;
  padding-left: 0;
  padding-right: 0;
  margin-left: 0;
  margin-right: 0;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
/* 两个栏共用同一套展开/收起过渡 */
.bottom-dock .bottom-nav,
.bottom-dock .bottom-nav-item {
  transition: width .46s cubic-bezier(.22, 1.35, .36, 1),
              opacity .26s ease,
              padding .46s cubic-bezier(.22, 1.35, .36, 1),
              margin .46s cubic-bezier(.22, 1.35, .36, 1),
              border-width .3s ease,
              transform .46s cubic-bezier(.22, 1.35, .36, 1),
              background .3s, border-color .3s, color .18s;
}
.bottom-dock .bottom-nav-item {
  overflow: hidden !important;
}

.bottom-nav {
  position: fixed;
  bottom: var(--hgu-bottom-dock-bottom);
  left: 50%;
  transform: translateX(-50%);
  width: 300px;
  --bottom-nav-count: 4;
  height: 45px;
  box-sizing: border-box;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-5xl);
  box-shadow: var(--hgu-shadow-card);
  /* 底部双栏（总悬浮栏 + 今天吃什么栏）：模糊度用 --hgu-blur-dock，比全站默认更糊一点 */
  backdrop-filter: blur(var(--hgu-blur-dock));
  -webkit-backdrop-filter: blur(var(--hgu-blur-dock));
  display: flex;
  align-items: center;
  justify-content: space-around;
  padding: 4px;
  overflow: hidden;
  z-index: 999;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  cursor: pointer;
  transition: background 0.3s, border-color 0.3s;
}

.bottom-nav-slider {
  display: none;
}

.bottom-nav-item {
  position: relative;
  flex: 1;
  height: 100%;
  min-height: 0;
  border-radius: var(--hgu-radius-4xl);
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--subtext);
  font-size: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  transition: color 0.18s ease, background 0.18s ease;
  z-index: 1;
  pointer-events: auto;
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}

.bottom-nav-item.active {
  color: var(--text);
  background: var(--text-light);
}

/* 抽屉页收起时（服务卡片态 / 完全隐藏）没有任何页面打开，悬浮栏不再高亮 */
body.home-panel-compact .bottom-nav-item.active,
body.home-panel-hidden .bottom-nav-item.active {
  background: transparent;
  color: var(--subtext);
}

.bottom-nav-item i {
  font-size: 15px;
  line-height: 1;
}

/* 妤煎眰鏍?*/
#floorBar {
  position: absolute;
  left: 20px;
  bottom: calc(130px + var(--hgu-bottom-band-lift));
  display: none;
  flex-direction: column;
  border: 1px solid var(--hgu-border-soft);
  gap: 6px;
  z-index: 5;
  background: var(--hgu-surface-glass);
  border-radius: var(--hgu-radius-5xl);
  padding: 6px;
  box-shadow: var(--hgu-shadow-card);
  backdrop-filter: blur(var(--hgu-blur-md));
  width: 48px;
  align-items: center;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
  cursor: pointer;
  transition: transform 0.2s ease, bottom .32s ease;
  will-change: transform;
}

body.home-panel-compact #floorBar {
  bottom: calc(264px + var(--hgu-bottom-band-lift));
}

#floorBar:active {
  transform: scale(0.98);
}

.floor-btn {
  width: 36px;
  height: 36px;
  border: none;
  background: transparent;
  color: var(--subtext);
  font-size: 12px;
  cursor: pointer;
  border-radius: var(--hgu-radius-round);
  transition: color 0.2s, transform 0.2s;
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 500;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}

.floor-btn.active {
  color: var(--text);
  font-weight: 600;
}

.floor-btn:active {
  transform: scale(0.9);
}

.floor-slider {
  position: absolute;
  left: 6px;
  right: 6px;
  width: 36px;
  height: 36px;
  background: var(--text-light);
  border-radius: var(--hgu-radius-round);
  transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  z-index: 1;
  will-change: transform;
  transform-origin: center center;
  pointer-events: none;
}

/* ============================================
   瀹ゅ唴鍦板浘鍥句緥鍗＄墖
   ============================================ */
#indoorLegend {
  position: absolute;
  right: 16px;
  bottom: var(--hgu-chrome-bottom-legend);
  z-index: 10;
  display: none;
  flex-direction: column;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-3xl);
  padding: 10px 12px;
  box-shadow: var(--hgu-shadow-card);
  backdrop-filter: blur(var(--hgu-blur-2xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-2xl));
  min-width: 90px;
  max-width: 140px;
  transition: bottom .32s ease;
}

body.home-panel-compact #indoorLegend {
  bottom: calc(278px + var(--hgu-bottom-band-lift));
}

.legend-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--hgu-border-soft);
}

.legend-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

.legend-toggle {
  width: 34px;
  height: 18px;
  border-radius: 9px;
  background: var(--subtext);
  border: none;
  position: relative;
  cursor: pointer;
  transition: background 0.3s;
  padding: 0;
}

.legend-toggle.active {
  background: var(--text);
}

.legend-toggle-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  border-radius: var(--hgu-radius-round);
  background: #fff;
  transition: transform 0.3s;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}

.legend-toggle.active .legend-toggle-thumb {
  transform: translateX(16px);
}

.legend-items {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.legend-item-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.legend-icon-box {
  width: 24px;
  height: 24px;
  min-width: 24px;
  border-radius: var(--hgu-radius-round);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}

.legend-icon {
  font-size: 11px;
  font-weight: 900;
  color: #fff;
}

.legend-label {
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 鏆楄壊妯″紡閫傞厤 */

  html[data-theme="dark"] #indoorLegend {
    border-color: rgba(255, 255, 255, 0.12);
  }
  
  html[data-theme="dark"] .legend-title {
    border-color: rgba(255, 255, 255, 0.1);
  }
  
  html[data-theme="dark"] .legend-icon-box {
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
  }

/* 瀹氫綅鎸夐挳 */
.location-btn {
  position: fixed;
  bottom: var(--hgu-chrome-bottom-location);
  right: 20px;
  width: 45px;
  height: 45px;
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  /* 与右上角三个按钮同色：主文本色 */
  color: var(--hgu-idle-chrome);
  backdrop-filter: blur(var(--hgu-blur-md));
  -webkit-backdrop-filter: blur(var(--hgu-blur-md));
  box-shadow: var(--hgu-shadow-card);
  cursor: pointer;
  z-index: 996;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  transition: transform 0.2s, background 0.3s, bottom .32s ease;
}

.location-btn.is-raised {
  bottom: calc(232px + var(--hgu-bottom-band-lift));
}

body:not(.home-panel-compact) .location-btn {
  bottom: var(--hgu-chrome-bottom-location);
}

.location-btn:active {
  transform: scale(0.9);
}

.location-btn * {
  pointer-events: none;
}

/* ============================================
   4. 鍦板浘鐩稿叧缁勪欢
   ============================================ */
#mapCanvas {
  position: absolute;
  top: 0;
  left: 0;
  cursor: grab;
  user-select: none;
  touch-action: none;
}

#mapCanvas:active {
  cursor: grabbing;
}

.toggle-switch {
  -webkit-appearance: none;
  appearance: none;
  width: 40px;
  height: 22px;
  background: #ccc;
  border-radius: 11px;
  position: relative;
  cursor: pointer;
  transition: background .3s;
}

.toggle-switch::after {
  content: '';
  position: absolute;
  left: 2px;
  top: 2px;
  width: 18px;
  height: 18px;
  background: #fff;
  border-radius: var(--hgu-radius-round);
  transition: transform .3s;
}

.toggle-switch:checked::after {
  transform: translateX(18px);
}

/* ============================================
   5. 椤甸潰瑕嗙洊灞傚熀纭€
   ============================================ */
.page-overlay {
  position: fixed;
  inset: 0;
  background: var(--drawer-surface);
  backdrop-filter: blur(var(--hgu-blur-lg));
  display: none;
  flex-direction: column;
  align-items: center;
  padding: 60px 20px 80px;
  overflow-y: auto;
  z-index: 998;
}

.page-overlay.active {
  display: flex;
}

.page-title {
  font-size: 20px;
  font-weight: bold;
  margin-bottom: 24px;
}

.back-btn {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 4px;
}

/* ============================================
   6. 閫氱敤鍗＄墖缁勪欢
   ============================================ */
.card {
  width: 100%;
  max-width: 360px;
  background: var(--hgu-surface-glass);
  border-radius: var(--hgu-radius-xl);
  padding: 12px;
  margin-bottom: 12px;
  box-shadow: var(--hgu-shadow-card);
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  transition: transform .2s;
}

.card:active {
  transform: scale(0.9);
}

.card img {
  width: 28px;
  height: 28px;
  border-radius: var(--hgu-radius-md);
  margin-left: 16px;
}

.card-title {
  font-size: 16px;
  font-weight: 600;
}

.card.blue { border: 1px solid var(--color-blue); color: var(--color-blue); }
.card.green { border: 1px solid var(--text); color: var(--text); }
.card.orange { border: 1px solid var(--color-orange); color: var(--color-orange); }
.card.brown { border: 1px solid var(--color-brown); color: var(--color-brown); }
.card.red { border: 1px solid var(--color-red); color: var(--color-red); }
.card.lightred { border: 1px solid var(--color-lightred); color: var(--color-lightred); }
.card.gray { border: 1px solid var(--color-gray); color: var(--color-gray); }
.card.red { border: 1px solid var(--color-red); color: var(--color-red); }

.tool-btn.qq-channel-row-btn {
  flex-direction: row;
  aspect-ratio: auto;
  height: auto;
  padding: 8px 10px;
  gap: 8px;
  justify-content: center;
  width: 100%;
  border-radius: var(--hgu-radius-2xl);
  border: 1px solid #6BA3FF;
}

.tool-btn.qq-channel-row-btn img {
  width: 40px;
  height: 40px;
  border-radius: var(--hgu-radius-md);
  object-fit: contain;
  pointer-events: none;
  margin-left: 0;
}

.tool-btn.qq-channel-row-btn span {
  font-size: 15px;
  font-weight: 600;
  color: #6BA3FF;
  pointer-events: none;
}

/* APP下载底部按钮容器（网页版：已从学习页移到首页顶部） */
.tools-app-section {
  width: 100%;
  max-width: 400px;
  margin-top: 0;
  margin-bottom: 16px;
}

/* 网页版「下载APP」提示按钮：与首页其它卡片按钮同一套玻璃背景
   （背景 + 毛玻璃 + 卡片投影），边框用主文本色 */
.tool-btn.qq-channel-row-btn.download {
  border-color: var(--text);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  backdrop-filter: blur(var(--hgu-blur-xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-xl));
}

/* ================== 棰戦亾鐑鍗＄墖 ================== */
.channel-hot-card {
  width: 100%;
  max-width: 400px;
  background: var(--hgu-surface-glass);
  border: 1px solid #6BA3FF;
  border-radius: var(--hgu-radius-2xl);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-shadow: var(--hgu-shadow-card);
  position: relative;
  overflow: hidden;
}

.channel-hot-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.channel-hot-title-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
}

.channel-hot-title-wrap img {
  width: 40px;
  height: 40px;
  border-radius: var(--hgu-radius-sm);
  object-fit: contain;
}

.channel-hot-title-wrap span {
  font-size: 15px;
  font-weight: 600;
  color: #6BA3FF;
}

.channel-hot-join-btn {
  padding: 8px 16px;
  border: 1px solid #6BA3FF;
  background: transparent;
  color: #6BA3FF;
  border-radius: var(--hgu-radius-xl);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
  white-space: nowrap;
}

.channel-hot-join-btn:hover {
  background: rgba(107, 163, 255, 0.1);
}

.channel-hot-join-btn:active {
  transform: scale(0.95);
}

.channel-hot-divider {
  width: 100%;
  height: 1px;
  background: var(--border);
  opacity: 0.6;
}

/* Tab 鍒囨崲鏍?*/
.channel-hot-tabs {
  position: relative;
  display: flex;
  gap: 4px;
  margin-bottom: 4px;
}

.channel-hot-tab {
  background: transparent;
  border: none;
  color: var(--subtext);
  font-size: 14px;
  font-weight: 500;
  padding: 6px 12px;
  cursor: pointer;
  transition: color 0.2s;
  font-family: inherit;
  position: relative;
  z-index: 2;
}

.channel-hot-tab.active {
  color: #6BA3FF;
  font-weight: 600;
}

.channel-tab-indicator {
  position: absolute;
  bottom: 0;
  height: 2px;
  background: #6BA3FF;
  border-radius: 1px;
  transition: all 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
  z-index: 1;
}

.channel-hot-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.channel-hot-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
  cursor: pointer;
  transition: opacity 0.2s;
  text-decoration: none;
}

.channel-hot-item:active {
  opacity: 0.6;
}

.channel-hot-index {
  font-size: 16px;
  font-weight: 700;
  color: #6BA3FF;
  width: 22px;
  text-align: center;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

.channel-hot-avatar {
  width: 32px;
  height: 32px;
  border-radius: var(--hgu-radius-round);
  object-fit: cover;
  flex-shrink: 0;
  background: var(--text-light);
}

.channel-hot-content {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--subtext);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.4;
}

.channel-hot-loading {
  text-align: center;
  font-size: 13px;
  color: var(--subtext);
  padding: 12px 0;
}

/* 鏆楄壊妯″紡閫傞厤 */

  html[data-theme="dark"] .channel-hot-card {
    border-color: #6BA3FF;
  }
  html[data-theme="dark"] .channel-hot-title-wrap span {
    color: #8BB8FF;
  }
  html[data-theme="dark"] .channel-hot-join-btn {
    border-color: #8BB8FF;
    color: #8BB8FF;
  }
  html[data-theme="dark"] .channel-hot-join-btn:hover {
    background: rgba(139, 184, 255, 0.12);
  }
  html[data-theme="dark"] .channel-hot-tab.active {
    color: #8BB8FF;
  }
  html[data-theme="dark"] .channel-tab-indicator {
    background: #8BB8FF;
  }
  html[data-theme="dark"] .channel-geo-toggle-btn.active {
    background: #8BB8FF;
  }

/* ============================================
   7. 工具页面（抽屉式）
   ============================================ */
/* 【移除】不再对地图施加毛玻璃模糊层 .drawer-backdrop-blur（用户确认：只去 blur）。
   面板自身保持半透明背景，地图在抽屉展开时清晰可见。

   【单一容器】服务卡片与抽屉就是同一个元素 #tools-page：
   它贴屏幕底边、宽度恒定，三态之间只改高度（--drawer-height）与容器内的内容：
     hidden   = 高度 0 + 淡出
     compact  = 卡片高度（--home-card-height，由 JS 按卡片内容量出）
     expanded = 整屏高
   两层内容（.home-compact-layer 卡片内容 / .tools-content-container 抽屉内容）
   都绝对定位、高度恒定，所以容器长高变矮时它们不重排，只是被容器裁切。 */

#tools-page {
  --expand-progress: 0;
  --drawer-height: 0px;
  position: fixed;
  top: auto; /* 覆盖 .page-overlay 的 inset:0，避免卡片态被顶到页面顶部 */
  bottom: 0;
  /* 覆盖 .page-overlay 的 display:none（面板内部全是绝对定位的子层，
     高度完全由 --drawer-height 决定，所以用 block 即可）。
     padding 必须清零：.page-overlay 自带 60px/80px 上下内边距，在
     box-sizing: border-box 下会把"高度 0"撑成 141px，隐藏态就藏不干净。
     原来的 52px/80px 内边距已经搬到 .tools-content-container 上。 */
  display: block;
  padding: 0;
  /* 水平居中只用 CSS（left:50% + translateX(-50%)），与 .bottom-nav 一致。
     【修复】这里原先用 left: var(--hgu-visual-center, 50vw)（由 navigation.js 依据
     visualViewport 写入的 px 值）。该值一旦与当前布局视口不一致——旋转屏幕后
     visualViewport 尚未更新、捏合缩放到小于 1 倍、部分 WebView 报错值——
     服务卡片就会整体右移，右半部分跑到页面右侧外面。
     --hgu-visual-* 由 JS 继续维护，但不再参与本元素的几何计算。 */
  left: 50%;
  right: auto;
  transform: translateX(-50%);
  /* 宽度用百分比，不用 100vw：百分比与上面的 left: 50% 取自同一个包含块（视口），
     两者永远一致；而 vw 在 APP 动态改「显示大小」、WebView 布局宽度跟着变的瞬间
     可能还停在旧视口上，于是抽屉比屏幕窄、两侧留空，退出重进（网页重新加载）才恢复。
     上限仍是 580px：宽视口下保持「居中面板」的观感不变。 */
  width: 100%;
  max-width: 580px;
  height: var(--drawer-height);
  /* 抽屉先提供一层自己的背景与地图模糊，页面内容位于其上方，
     标题栏再在页面内容之上取样。这样标题栏不会把底图地图直接透出来。 */
  -webkit-backdrop-filter: blur(var(--hgu-blur-lg));
  backdrop-filter: blur(var(--hgu-blur-lg));
  background: var(--drawer-surface);
  /* 保留顶部圆角 */
  border-radius: var(--hgu-radius-drawer);
  border: 1px solid var(--hgu-border-soft);
  border-bottom: none;
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.2);
  z-index: 997;
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
  /* 展开 / 收起只动高度：宽度、位移一概不变 */
  transition: height 0.58s cubic-bezier(0.32, 0.72, 0, 1),
              opacity 0.3s ease,
              visibility 0s 0s;
  will-change: height;
  /* 容器只负责裁切，滚动交给内部各自的内容区（高度动画时内部不重排） */
  overflow: hidden;
  touch-action: pan-y;
  overscroll-behavior: contain;
}

/* 展开态：整屏高。
   高度值由 JS 写进 --drawer-expanded-height（window.innerHeight 的像素值，
   与服务卡片高度同一套基准）；JS 未就绪时退回 100vh。
   【严禁写成 dvh】自定义属性不做单位校验，dvh 在不支持的内核（安卓 System WebView
   < 108）里不会被解析期丢弃，代入 height: var(...) 会变成计算期非法 → height:auto，
   整个面板塌成 1px，表现就是"点悬浮栏抽屉完全打不开"。 */
:root {
  --drawer-expanded-height: 100vh;
}

#tools-page[data-home-state="expanded"] {
  --drawer-height: var(--drawer-expanded-height);
}

/* 软键盘弹起时（安卓 WebView 会把键盘高度加成容器底边距 → 布局视口变矮）：
   面板是 position:fixed + bottom:0 + 满屏高，视口一矮整块就被抬起来，
   页面上半部分的输入框被挤出屏幕。键盘期间改成贴顶：位置与高度都不变，
   只有下半部分落到键盘后面；输入框本身仍在可视区，浏览器不需要再整体平移。
   （高度由 core.js 的 hguIsKeyboardOpen() 判定，不会跟着键盘重算，避免跳动。）

   --hgu-kbd-lift：贴顶之后位置偏下的输入框（写评价页的正文框 #editorText）仍会被
   键盘压住，而面板是 fixed 且内部页面高度已满，scrollIntoView 无处可滚 → 只能整体上滑。
   上滑多少由 core.js 按「聚焦框底部 - 键盘上沿 + 16px」实时算，且只对评价正文框生效：
   其它输入框（今天吃什么顶部的搜索框等）保持 0px，页面一点都不会动，不会整页乱跳。 */
body.hgu-keyboard-open #tools-page[data-home-state="expanded"] {
  top: 0;
  bottom: auto;
  transform: translateX(-50%) translateY(calc(-1 * var(--hgu-kbd-lift, 0px)));
}

/* 卡片态：高度收缩为服务卡片高度 —— 看上去就是抽屉被拉开了一截 */
#tools-page[data-home-state="compact"] {
  --drawer-height: var(--home-card-height, 196px);
}

/* 隐藏态：高度归零 + 淡出（点掉卡片直接收起时不会闪现抽屉内容） */
#tools-page[data-home-state="hidden"] {
  --drawer-height: 0px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: height 0.58s cubic-bezier(0.32, 0.72, 0, 1),
              opacity 0.3s ease,
              visibility 0s 0.58s;
}

/* ---------- 容器内的两层内容交叉淡入淡出 ---------- */
/* 卡片内容：仅紧凑态可见 */
#tools-page[data-home-state="expanded"] .home-compact-layer {
  opacity: 0;
  pointer-events: none;
}

/* 抽屉内容与装饰层：仅展开态可见 */
#tools-page[data-home-state="compact"] .tools-content-container,
#tools-page[data-home-state="hidden"] .tools-content-container,
#tools-page[data-home-state="compact"] .page-deco-layer,
#tools-page[data-home-state="hidden"] .page-deco-layer,
#tools-page[data-home-state="compact"] .about-bg-layer,
#tools-page[data-home-state="hidden"] .about-bg-layer {
  opacity: 0;
  pointer-events: none;
}

/* 拖拽展开中间态：卡片内容随 --expand-progress 淡出、抽屉内容淡入；
   高度由 JS 逐帧跟手写入 */
#tools-page[data-home-state="expanded"][data-dragging="true"] .home-compact-layer {
  opacity: calc(1 - min(1, var(--expand-progress, 0)));
  pointer-events: none;
  transition: none; /* 拖拽逐帧控制淡出，禁用过渡避免跟手滞后 */
}

#tools-page[data-home-state="expanded"][data-dragging="true"] .tools-content-container {
  opacity: var(--expand-progress, 0);
  pointer-events: none;
  transition: none; /* 拖拽逐帧设置 opacity，禁用过渡避免跟手滞后 */
}

#tools-page[data-dragging="true"] .drawer-drag-handle {
  opacity: 0;
}

/* 抽屉下拉收起中间态：高度逐帧插值，抽屉内容随进度渐隐
   （不设 pointer-events，避免手势中途的命中测试变化干扰内容原生滚动）。
   两种情况都要淡出抽屉内容：收回服务卡片（data-collapse-card）和直接收起隐藏。 */
#tools-page[data-home-state="expanded"][data-collapsing="true"] .tools-content-container {
  opacity: var(--expand-progress, 0);
  transition: none; /* 下拉收起逐帧插值，禁用过渡避免跟手滞后 */
}

/* 只有"收回服务卡片"时才让卡片内容同步渐显：
   没有卡片内容时容器会一路缩到 0（收起隐藏），此时闪出一层空卡片很难看 */
#tools-page[data-home-state="expanded"][data-collapsing="true"][data-collapse-card="true"] .home-compact-layer {
  opacity: calc(1 - min(1, var(--expand-progress, 0)));
  pointer-events: none;
  transition: none; /* 下拉收起逐帧插值，禁用过渡避免跟手滞后 */
}

#tools-page[data-collapsing="true"] .drawer-drag-handle {
  opacity: 0;
}

html.app-route-instant #tools-page,
html.app-route-instant .tools-sub-page,
html.app-route-instant .secondary-drawer-overlay,
html.app-route-instant .secondary-drawer,
html.app-route-instant .bottom-nav-slider {
  animation: none !important;
  transition: none !important;
}

.drawer-drag-handle {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 48px;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding-top: 10px;
  background: transparent;
  pointer-events: none;
  touch-action: none;
  transition: opacity .2s ease;
}

.drawer-hint-bar {
  width: 40px;
  height: 5px;
  background: var(--subtext);
  opacity: 0.3;
  border-radius: 3px;
  margin-bottom: 6px;
  transition: opacity 0.2s, transform 0.2s;
}

/* 抽屉关闭提示：抽屉打开时（一级页面与二级页面都算），
   浮在主悬浮栏正上方一点的位置。文案跟随悬浮栏高亮的按钮（见 core.js），
   右侧「不再提示」写入本地存储后不再出现。
   站位与右下角固定按钮同口径：bottom 取悬浮栏避让高度 --hgu-nav-clearance
   （= 栏高 + 栏底距 + 16px 余量，由 navigation.js 按悬浮栏实测写入）；
   这条高度带上还有别的固定控件时（写评价按钮 / 课表周次切换 / 随机视图底部按钮），
   core.js 会把 --drawer-close-hint-lift 写成正值，提示整条抬到它们上面，避免叠在一起。
   外观：不要再有底色/边框/投影（那就是原来那个"背景文本框"），
   只是一行跟随位置的小灰字浮在内容之上，所以给一点文字投影保可读。
   层级：抽屉面板(997) 之上、悬浮栏(999) 之下。 */
.drawer-close-hint {
  position: fixed;
  left: 50%;
  bottom: calc(var(--hgu-nav-clearance, 106px) + var(--drawer-close-hint-lift, 0px));
  transform: translateX(-50%);
  z-index: 998;
  display: none;
  align-items: center;
  gap: 6px;
  max-width: calc(100vw - 24px);
  box-sizing: border-box;
  padding: 0;
  border: none;
  background: none;
  color: var(--color-gray);
  font-size: 12px;
  line-height: 1.3;
  white-space: nowrap;
  text-shadow: 0 1px 3px rgba(255, 255, 255, 0.75);
  /* 没有底色框了：整行只透传点击，只有右侧「不再提示」自己吃点击，
     否则这条看不见的横带会挡住它下面的内容 */
  pointer-events: none;
}

.drawer-close-hint.is-visible {
  display: inline-flex;
  animation: drawerCloseHintIn 0.26s var(--ease-standard) both;
}

/* 提示文本左侧的下箭头图标 */
.drawer-close-hint-icon {
  flex: 0 0 auto;
  font-size: 11px;
  opacity: 0.85;
}

.drawer-close-hint-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.drawer-close-hint-dismiss {
  flex: 0 0 auto;
  border: none;
  padding: 3px 9px;
  border-radius: var(--hgu-radius-pill);
  background: rgba(158, 158, 158, 0.18);
  color: var(--color-gray);
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.3;
  cursor: pointer;
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}

.drawer-close-hint-dismiss:active {
  transform: scale(0.96);
}

/* 深色模式：--color-gray 是给浅底用的中灰，深底上要提亮一档才看得清 */
html[data-theme="dark"] .drawer-close-hint {
  color: #b4b8be;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}

html[data-theme="dark"] .drawer-close-hint-dismiss {
  background: rgba(255, 255, 255, 0.12);
  color: #b4b8be;
}

@keyframes drawerCloseHintIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* 抽屉内容层：高度锁死为"完全展开时的高度"，#tools-page 做高度动画时这里不重排，
   只是被容器裁切 —— 展开就是露出更多内容，收起就是被裁掉。 */
.tools-content-container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  margin: 0 auto;
  width: 100%;
  max-width: 480px;
  /* 与 #tools-page 的展开态高度共用同一个值（JS 写入的 px），
     保证"容器高度 == 面板高度"，不会因为两条高度来源不一致而错位/被裁 */
  height: var(--drawer-expanded-height, 100vh);
  /* 底部不再留固定空白：原来这里还有 80px，和页面自己的悬浮栏避让叠在一起，
     滚到底时悬浮栏上方会空出很大一块。避让统一交给 --hgu-nav-clearance。 */
  /* 标题栏改为脱离文档流的固定层，页面内容从抽屉最上方开始，
     这样拖拽把手下方的 52px 区域也能采样到页面内容。 */
  padding: 0 var(--drawer-inline-pad, 20px) 0;
  box-sizing: border-box;
  background: transparent;
  overflow: visible;
  display: flex;
  flex-direction: column;
  touch-action: pan-y;  /* 抽屉内容与卡片内容交叉淡入淡出，避免状态切换时内容闪变 */
  transition: opacity .3s ease;
  /* 保持普通 DOM 合成，让页面级玻璃层能够读取滚动内容。 */
  will-change: auto;
}

/* ================== 抽屉顶部的渐进毛玻璃 ==================
 * 玻璃放在滚动页面之外（抽屉根层），WebView 才能把页面里的文字、图标、
 * 边框和图片一起当作背景采样；标题栏位于这层之上，所以标题文字不会被糊掉。
 *
 * 用「多段固定半径」叠出真正的渐进模糊，而不是「一层强模糊 + 长渐变淡出」：
 *   · 渐变 mask 是把那一层强模糊按 alpha 混回原图 ——
 *     得到的是「原图 + 强模糊」的柔光叠加，看起来发灰发雾、没有高斯感
 *     （就是反馈里的"柔光 / 低硬化度"）。底色 rgba(128,128,128,.018)
 *     与 saturate() 还会进一步抬高亮度、加剧发灰。
 *   · 现在每段一个**固定**半径，从下往上递增（2.5 / 5 / 8px），
 *     每段只覆盖自己那段高度，用**多段式** mask 淡入：
 *     底边几乎不糊，往上逐步加强。
 *   · 段与段重叠，过渡连续、不会出现硬边。
 *   · 最高只到 8px（= --hgu-blur-lg）—— 与抽屉弹窗打开时背景遮罩
 *     （.page-overlay 的 backdrop-filter）同一档，不再往上加。
 *   · 不刷底色、不加 saturate：观感只来自模糊本身。
 *
 * 高度参照（层高 **96px = 抽屉顶部留空(0~52) + 标题栏(52~96)**）：
 *   · 0 ~ 48px   上半部 —— 恒定最高模糊
 *   · 48 ~ 96px  下半部 —— **渐变**（这一段正好覆盖标题栏那一行）
 *
 * 这些段由 core.js 注入（一个元素只有一个 ::before，必须有真实元素才能叠多段）。
 * ⚠️ 2026-10-04 回退注记：不要停用这条带子。当天曾把它停用（display:none）、
 *    只留 .tools-fixed-header-layer 里那条，结果竖屏真机（PC + 安卓平板）上
 *    标题栏玻璃整条不渲染（文字完全清晰、毫无模糊）——说明真机上一直是这条
 *    在出图。停用即竖屏玻璃全灭，已回退。
 *    （分栏下这条 mask 会丢 / 采样退化的问题见分栏一节注记，与此无关。） */
.tools-top-glass-layer {
  position: absolute;
  top: 0;
  left: -20px;
  right: -20px;
  height: 96px;
  z-index: 40;
  pointer-events: none;
}

.tools-top-glass-pane,
.tools-fixed-header-glass {
  position: absolute;
  left: 0;
  right: 0;
  pointer-events: none;
  background: transparent;
  -webkit-backdrop-filter: blur(var(--glass-blur, 20px));
  backdrop-filter: blur(var(--glass-blur, 20px));
  -webkit-mask-image: var(--glass-mask);
  mask-image: var(--glass-mask);
  z-index: 0;
}

/* 顶部毛玻璃：**单层** backdrop-filter + 遮罩渐变。
 * ★ 只有一段，.is-band-1。不要再加 .is-band-2/3/4 ——
 *   多层 backdrop-filter 会递推展开出 F²(B)、F³(B)：
 *   叠加发生在"取样源"上，不在权重上，
 *   所以无论怎么归一化 alpha 都消不掉标题栏比页面背景更亮/更暗的问题。
 *   推导与数值模拟见 _diag/explain-brightness.js。
 *   （另外实测：把 96px 切成 6 段固定半径做"分段渐变"这条路走不通 ——
 *     多层 backdrop-filter 会让合成器降级，连竖屏原本正常的模糊一起丢掉，
 *     而且分档在视觉上就是台阶，不是渐变。别再试这条路。）
 * ★ 单层的绘制结果恰好是  D = a·F(B) + (1-a)·B ：
 *   a=1 处是纯模糊，a=0 处是原图，中间是凸组合 —— 不会有叠加色差。
 * ★ 半径取 --hgu-blur-lg(8px)：与抽屉弹窗打开时背景遮罩（.page-overlay）同一档。
 * ★ 遮罩写的是 `to bottom`：0% = 层顶（抽屉顶边）、100% = 层底（96px）。
 *   0~50%（0~48px）保持满 alpha，以上是恒定满强度；
 *   50%~100% 依次降到 0，就是"下半部分逐渐增强"的那段渐变。
 *   底部 alpha 收到 0 = 完全不模糊，所以层底不会有分界线。
 * 坐标换算（层高 96px）：50% = 48px（渐变起点）、54.2% = 52px（标题栏上沿）、
 *   77.1% = 74px（中部）、100% = 96px（下沿）。 */

/* 唯一的一段（8px = --hgu-blur-lg，与抽屉遮罩同一档） */
.tools-top-glass-pane.is-band-1,
.tools-fixed-header-glass.is-band-1 {
  --glass-blur: 8px;
  top: 0;
  height: 100%;
  /* 50% 之前满 alpha（恒定 8px）；之后平滑降到 0（底部完全不模糊）。
     用多停靠点把曲线做平，避免在底部出现可见的折线。 */
  --glass-mask: linear-gradient(to bottom,
    #000 0%, #000 50%, rgba(0, 0, 0, .96) 53%, rgba(0, 0, 0, .91) 56%,
    rgba(0, 0, 0, .85) 59%, rgba(0, 0, 0, .78) 62%, rgba(0, 0, 0, .70) 65%,
    rgba(0, 0, 0, .61) 68%, rgba(0, 0, 0, .52) 71%, rgba(0, 0, 0, .43) 74%,
    rgba(0, 0, 0, .34) 77%, rgba(0, 0, 0, .26) 80%, rgba(0, 0, 0, .18) 83%,
    rgba(0, 0, 0, .11) 86%, rgba(0, 0, 0, .06) 89%, rgba(0, 0, 0, .02) 93%,
    transparent 97%, transparent 100%);
}

/* 旧实现（一层 + 长渐变 + 灰底）已停用 */
.tools-content-container::before,
.drawer-top-glass {
  display: none;
}

/* 页面内部不再建立玻璃层：滚动页面的 backdrop 在 Android WebView 中只能
   稳定采样图片纹理，且会漏掉文字、图标和边框。玻璃统一由容器伪元素提供。 */
.tools-sub-page::before,
.tools-home-content::before {
  display: none;
}

/* 鍏ㄥ眬椤甸潰瑁呴グ鍥撅紙鍙充笅瑙掞紝涓嶈窡闅忓唴瀹规粴鍔級 */
.page-deco-layer {
  position: absolute;
  /* 抬到悬浮栏上方：原来贴的是抽屉底边（bottom: -6px），而底部悬浮栏浮在同一块
     区域上，装饰人物卡片的下半截会被栏压住。--hgu-nav-clearance 是 JS 按悬浮栏
     真实占用算出的避让高度（栏高 + 底距 + 余量），页面内容用的是同一套基准，
     显示大小、横竖屏变化都会自动跟着变。
     这里只改平面位置（垂直方向让开），不动 z-index —— 装饰图仍在内容之下。 */
  bottom: var(--hgu-nav-clearance, 81px);
  right: -6px;
  width: 240px;
  max-width: 50%;
  height: auto;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
  opacity: 0.35;
  /* 卡片↔抽屉状态切换时淡入淡出，避免装饰图瞬间闪现 */
  transition: opacity .3s ease;
}

.page-deco-img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--hgu-radius-xl);
}

.tools-home-content {
  width: 100%;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: transform 0.3s ease, opacity 0.3s ease;
  overflow-y: auto;
  overflow-x: hidden;
  flex: 1;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
  /* 首页 / 学习页原本各靠一点 padding-top 来"假装"有标题栏；
     现在两个视图都有自己的 .sub-page-header 了，这份补偿去掉。 */
  padding-top: 0;
  padding-bottom: var(--hgu-nav-clearance, 64px);
  scrollbar-width: none;
  -ms-overflow-style: none;
  will-change: transform, opacity;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  opacity: 1;
}

/* backdrop-filter 无法读取同一合成层中的后代内容。首页滚动层只在视图切换
   动画期间需要 transform，稳定显示时解除合成层，保证玻璃层能采样完整 DOM。 */
.tools-home-content:not(.hidden) {
  transform: none !important;
  will-change: auto;
  backface-visibility: visible;
  -webkit-backface-visibility: visible;
  /* 可见态 = 新页面：等旧页面淡完（out）再花 in 淡入；visibility 立刻生效 */
  transition: opacity var(--page-switch-in) var(--ease-standard) var(--page-switch-out),
              visibility 0s linear 0s;
}

/* 首页 ↔ 学习两个视图之间的切换：容器原地闪一下。
   两个视图是同一个页面里靠 display 切换的，做不了交叉淡入淡出，
   所以让它们共用的容器先快速淡出、换完视图再快速淡入（时间与页面切换一致）。
   .is-view-out 负责淡出，紧接着换成 .is-view-in 淡入（两者都在容器可见时生效，
   不会和 .hidden 那条可见/隐藏规则打架）。 */
.tools-home-content.is-view-out {
  opacity: 0;
  transition: opacity var(--page-switch-out) var(--ease-standard);
}

.tools-home-content.is-view-out.is-view-in {
  opacity: 1;
  transition: opacity var(--page-switch-in) var(--ease-standard);
}

.home-content-view {
  width: 100%;
  display: flex;
  flex-direction: column;
  /* 用 stretch 而不是 center：标题栏靠左右负边距铺满面板，
     而 align-items: center 是按**外边距盒**居中的，会把标题栏又推窄 40px。
     内容本身的居中仍在（下面每一块都有自己的 max-width）。 */
  align-items: stretch;
}

.tools-home-grid {
  width: 100%;
  max-width: 400px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

#studyView {
  --color-blue: var(--study-cyan);
  color: var(--study-cyan);
  /* 原来这里补了 16px 顶部留白，是为了让学习页与首页的"没有标题栏"状态对齐；
     现在两页都有真标题栏了，这份补偿改由标题栏下面的间距统一负责。 */
  padding-top: 0;
}

#score-page,
#search-page,
#classroom-page,
#training-plan-page,
#calendar-page,
#elective-page,
#classroom-schedule-page {
  --color-blue: var(--study-cyan);
  --study-blue: var(--study-cyan);
  --study-blue-soft: rgba(var(--study-cyan-rgb), 0.12);
  --study-blue-border: rgba(var(--study-cyan-rgb), 0.68);
}

#score-page,
#search-page,
#classroom-page,
#training-plan-page,
#elective-page,
#classroom-schedule-page {
  --text: var(--study-cyan);
}

#classroom-schedule-page,
#classroom-page {
  --text-light: rgba(var(--study-cyan-rgb), 0.14);
}

#studyView .tools-home-grid {
  gap: 12px;
}

.study-dashboard {
  --study-blue: var(--color-blue);
  --study-blue-soft: rgba(var(--study-cyan-rgb), 0.12);
  --study-blue-border: rgba(var(--study-cyan-rgb), 0.68);
}

.study-top-grid {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

/* 【不要给这三张卡加 backdrop-filter】学习页的卡片直接坐在抽屉面板（#tools-page）上：
   面板自身有 backdrop-filter + background: var(--drawer-surface)，它就是这些卡片的
   背景根(backdrop root)，卡片的玻璃取样到的是"面板底色（半透明白）"而不是真正的
   页面背景 —— 结果卡面被整块抬亮（暗色模式压暗），看起来就是多出一层遮罩
   （见 _diag/backdrop-root-audit.js 的结论）。抽屉展开/收起动画期间
   .tools-content-container 的 opacity < 1，它自己成了背景根，卡片反而正常，
   所以这个遮罩只在页面停稳之后才出现。
   卡面观感由 background: var(--hgu-surface-glass) 单独负责，与全站其它卡片一致。 */
.study-feature-panel,
.study-simple-card,
.study-schedule-card {
  border: 1.5px solid var(--study-blue-border);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
}

.study-feature-panel {
  min-height: 148px;
  border-radius: var(--hgu-radius-polished);
  padding: 12px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 7px;
}

.study-feature-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 52px;
}

.study-feature-title {
  color: var(--study-blue);
  font-size: 16px;
  line-height: 1.25;
  font-weight: 800;
  flex: 1;
  text-align: center;
}

.study-feature-img {
  width: 48px;
  height: 48px;
  object-fit: contain;
  flex-shrink: 0;
}

.study-feature-actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
}

.study-feature-action,
.study-tool-button {
  appearance: none;
  -webkit-appearance: none;
  border: none;
  background: transparent;
  color: var(--study-blue);
  font-family: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.study-feature-action {
  min-width: 0;
  min-height: 50px;
  border-radius: var(--hgu-radius-xl);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.study-feature-action:active,
.study-tool-button:active {
  transform: scale(0.97);
  background: var(--study-blue-soft);
}

.study-feature-action i {
  font-size: 18px;
}

.study-feature-action span {
  max-width: 100%;
  font-size: 9px;
  line-height: 1.2;
  color: var(--subtext);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.study-simple-card {
  grid-column: 1 / -1;
  border-radius: var(--hgu-radius-polished);
  padding: 10px;
}

.study-tool-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 88px));
  gap: 8px;
  justify-content: flex-start;
}

.study-tool-button {
  width: 88px;
  min-height: 76px;
  border-radius: var(--hgu-radius-default);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 6px;
}

.study-tool-button img {
  width: 34px;
  height: 34px;
  object-fit: contain;
}

.study-tool-button > i {
  font-size: 28px;
  line-height: 34px;
}

.study-tool-button span {
  color: var(--study-blue);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
}

.study-schedule-card {
  grid-column: 1 / -1;
  border-radius: var(--hgu-radius-polished);
  padding: 12px;
  position: relative;
  z-index: 0;
}

.study-official-links-wrap {
  grid-column: 1 / -1;
  margin-top: 6px;
}

/* 学习页底部「官方页面跳转」卡片：边框与内部文本统一使用学习页青蓝色（--study-cyan） */
.study-official-links-wrap .official-links-card {
  border-color: rgba(var(--study-cyan-rgb), 0.5);
}
.study-official-links-wrap .official-links-title {
  color: var(--study-cyan);
}
.study-official-links-wrap .official-link-row {
  color: var(--study-cyan);
}
.study-official-links-wrap .official-link-button {
  border-color: rgba(var(--study-cyan-rgb), 0.42);
  background: rgba(var(--study-cyan-rgb), 0.1);
  color: var(--study-cyan);
}

.study-schedule-tabs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: center;
  gap: 0;
  margin: -2px 0 12px;
  padding-bottom: 7px;
  position: relative;
}

.study-schedule-tab {
  appearance: none;
  -webkit-appearance: none;
  min-width: 0;
  min-height: 34px;
  padding: 0 4px;
  border: none;
  border-radius: 0;
  background: transparent;
  color: var(--subtext);
  font-size: 13px;
  font-weight: 800;
  font-family: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  position: relative;
  z-index: 1;
  white-space: nowrap;
  opacity: 0.58;
  transition: color 0.2s, opacity 0.2s, transform 0.2s;
}

.study-schedule-tab:active {
  transform: scale(0.97);
}

.study-schedule-tab span {
  display: inline-block;
  line-height: 1.2;
}

.study-schedule-tab i {
  flex-shrink: 0;
  font-size: 12px;
  line-height: 1;
}

.study-schedule-tab.active {
  color: var(--study-blue);
  opacity: 1;
}

.study-schedule-tab-indicator {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 33.333%;
  height: 3px;
  transform: translateX(calc(var(--active-tab-index, 0) * 100%));
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}

.study-schedule-tab-indicator::after {
  content: '';
  display: block;
  width: 48px;
  max-width: 66%;
  height: 100%;
  margin: 0 auto;
  border-radius: var(--hgu-radius-pill);
  background: var(--study-blue);
  box-shadow: 0 2px 8px rgba(var(--study-cyan-rgb), 0.28);
}

.study-schedule-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.study-card-loading,
.study-card-empty {
  padding: 18px 8px;
  text-align: center;
  color: var(--subtext);
  font-size: 13px;
}

.study-calendar-semester {
  color: var(--subtext);
  font-size: 12px;
  font-weight: 700;
  margin-bottom: 8px;
}

.study-calendar-preview-list,
.study-exam-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: none;
  width: 100%;
  margin-bottom: 0;
}

.study-exam-row {
  position: relative;
  border: 1px solid var(--exam-accent-border, rgba(var(--study-cyan-rgb), 0.24));
  border-radius: var(--hgu-radius-2xl);
  background: linear-gradient(var(--exam-accent-soft, rgba(var(--study-cyan-rgb), 0.12)), var(--exam-accent-soft, rgba(var(--study-cyan-rgb), 0.12))), var(--glass);
  padding: 12px;
  overflow: hidden;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.12) inset;
}

/* 校历图片现在排在日程列表下面（与列表互换过位置）：
   与列表之间只保留 .study-schedule-body 的 gap，自身不再多加外边距；
   带上 .study-schedule-body 是为了提高优先级，否则会被后面
   .calendar-img-wrap 的 margin-bottom: 20px 覆盖，末尾多出一块空白。 */
.study-schedule-body .study-calendar-image-wrap {
  margin-top: 0;
  margin-bottom: 0;
}

.study-calendar-image {
  width: 100%;
  display: block;
}

.study-exam-name {
  color: var(--exam-accent, var(--text));
  font-size: 14px;
  font-weight: 700;
  line-height: 1.35;
}

.study-exam-row-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}

.study-exam-actions {
  display: flex;
  align-items: center;
  gap: 6px;
}

.study-exam-icon-btn,
.study-exam-add-btn {
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid var(--exam-accent-border, rgba(var(--study-cyan-rgb), 0.24));
  background: var(--exam-accent-soft, rgba(255, 255, 255, 0.38));
  color: var(--exam-accent, var(--study-blue));
  font-family: inherit;
  cursor: pointer;
}

.study-exam-icon-btn {
  width: 30px;
  height: 30px;
  border-radius: var(--hgu-radius-lg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.study-exam-meta {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.study-exam-meta span,
.study-exam-meta-empty {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 10px;
  border-radius: var(--hgu-radius-pill);
  background: rgba(255, 255, 255, 0.28);
  color: var(--subtext);
  font-size: 12px;
  font-weight: 600;
}

.study-exam-row.is-unset {
  background: var(--hgu-surface-glass);
  border-style: dashed;
}

.study-exam-row.is-past {
  opacity: 0.72;
}

.study-exam-remain {
  position: absolute;
  right: 12px;
  bottom: 12px;
  font-size: 12px;
  font-weight: 700;
  color: var(--exam-accent, var(--study-blue));
}

.study-exam-add-btn {
  min-height: 46px;
  border-radius: var(--hgu-radius-default);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  --exam-accent: var(--study-blue);
  --exam-accent-soft: var(--study-blue-soft);
  --exam-accent-border: var(--study-blue-border);
}

.secondary-drawer.study-exam-editor {
  max-width: 480px;
  --text: var(--study-cyan);
  border: 1.5px solid rgba(var(--study-cyan-rgb), 0.55);
}

.study-exam-editor .secondary-drawer-handle,
.study-info-drawer .secondary-drawer-handle {
  background: var(--study-cyan);
}

.study-exam-editor-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.study-exam-field {
  width: 100%;
  min-height: 42px;
  border: 1px solid rgba(var(--study-cyan-rgb), 0.2);
  border-radius: var(--hgu-radius-xl);
  background: rgba(255, 255, 255, 0.2);
  color: var(--text);
  padding: 0 12px;
  font-size: 14px;
  font-family: inherit;
  outline: none;
}

.study-exam-room-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 240px;
  overflow-y: auto;
  padding-right: 2px;
}

.study-exam-room-option {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  min-height: 40px;
  border: 1px solid rgba(var(--study-cyan-rgb), 0.18);
  border-radius: var(--hgu-radius-xl);
  background: rgba(255, 255, 255, 0.18);
  color: var(--text);
  padding: 0 12px;
  font-size: 13px;
  text-align: left;
  font-family: inherit;
  cursor: pointer;
}

.study-exam-room-option.active {
  border-color: var(--study-blue-border);
  background: var(--study-blue-soft);
  color: var(--study-blue);
}

.study-exam-room-empty,
.study-exam-selected {
  font-size: 12px;
  color: var(--subtext);
}

.study-exam-selected {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 30px;
}

.study-exam-selected button {
  appearance: none;
  -webkit-appearance: none;
  border: none;
  background: transparent;
  color: var(--study-blue);
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  flex-shrink: 0;
}

.study-exam-editor-actions {
  display: flex;
  gap: 10px;
  margin-top: 4px;
}

.life-dashboard {
  --life-orange: var(--color-life);
  --life-orange-soft: rgba(255, 129, 38, 0.12);
  --life-orange-border: rgba(255, 129, 38, 0.6);
  --life-blue: #2F7CFF;
  --life-blue-soft: rgba(47, 124, 255, 0.12);
  --life-blue-border: rgba(47, 124, 255, 0.58);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* 首页这一组卡片同样不再自带 backdrop-filter（原因见 .study-feature-panel 上方那段：
   面板就是它们的背景根，卡片玻璃只会把面板底色再糊一层 → 卡面泛白/暗色泛黑）。
   卡面 = background: var(--hgu-surface-glass)，与全站其它卡片同一套。 */
.life-freshman-card,
.life-tool-card,
.life-balance-card,
.life-package-card {
  border: 1.5px solid var(--life-orange-border);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
}

.life-freshman-card {
  grid-column: 1 / -1;
  border-radius: var(--hgu-radius-polished);
  padding: 12px;
}

.life-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.life-card-title {
  color: var(--life-orange);
  font-size: 16px;
  font-weight: 800;
}

.life-card-toggle {
  appearance: none;
  -webkit-appearance: none;
  min-height: 30px;
  padding: 0 10px;
  border: 1px solid var(--life-orange-border);
  border-radius: var(--hgu-radius-lg);
  background: var(--life-orange-soft);
  color: var(--life-orange);
  font-size: 12px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
}

.life-tool-grid {
  grid-template-columns: repeat(3, minmax(0, 88px));
}

.life-tool-card .life-tool-grid {
  grid-template-columns: minmax(0, 1fr);
}

.life-tool-card {
  border-color: var(--text);
}

.life-tool-card .study-tool-button {
  width: 100%;
}

.life-tool-card .study-tool-button span {
  color: var(--text);
}

.life-freshman-card .study-tool-button span {
  color: var(--life-orange);
}

.life-freshman-card .life-tool-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}

.life-freshman-card.life-tool-card .life-tool-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 6px;
}

.life-freshman-card .study-tool-button {
  width: 100%;
  min-width: 0;
  min-height: 72px;
  padding-inline: 3px;
}

.life-freshman-card .study-tool-button span {
  width: 100%;
  overflow-wrap: anywhere;
}

.life-freshman-card.life-tool-card .study-tool-button span {
  color: var(--text);
}
/* 生活区两列：左列「一卡通 + 宿舍电费」，右列「快递」（与改版前一致） */
.life-service-grid {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  align-items: stretch;
}

.life-balance-stack {
  display: grid;
  grid-template-rows: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.life-balance-card {
  position: relative;
  min-height: 92px;
  border-color: var(--life-blue-border);
  border-radius: var(--hgu-radius-2xl);
  padding: 12px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  color: var(--life-blue);
  font-family: inherit;
  cursor: pointer;
}

.life-card-enter-hint {
  position: absolute;
  top: 9px;
  right: 10px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--life-blue);
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
}

.life-card-enter-hint i {
  font-size: 11px;
}

/* 卡片标题行右侧的引导箭头（样式与「假期食堂营业安排」右侧箭头一致）：
   与标题同高（15px），垂直居中；颜色由各卡片自己给。 */
.life-head-arrow {
  flex: 0 0 auto;
  align-self: center;
  font-size: 15px;
  line-height: 1;
  opacity: 0.85;
}

.life-canteen-card .life-head-arrow {
  color: var(--canteen-accent);
}

.life-activities-card .life-head-arrow {
  color: #C55DB5;
}

/* 一卡通 / 宿舍电费：图标与标题同一行，余额另起一行居左，箭头在卡片右侧垂直居中 */
.life-balance-icon {
  width: 22px;
  height: 22px;
  object-fit: contain;
  flex-shrink: 0;
}

.life-balance-copy {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.life-balance-head {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.life-balance-title {
  color: var(--subtext);
  font-size: 14px;
  font-weight: 700;
}

.life-balance-value {
  max-width: 100%;
  color: var(--life-blue);
  font-size: 22px;
  line-height: 1.15;
  font-weight: 900;
  text-align: left;
  word-break: break-word;
}

.life-balance-arrow {
  flex: 0 0 auto;
  align-self: center;
  color: var(--life-blue);
  font-size: 15px;
  line-height: 1;
  opacity: 0.85;
}

/* 一卡通 / 宿舍电费卡片背景折线（.life-balance-spark）已按需求整体移除：
   样式与 JS 渲染一起去掉，卡片只剩纯色背景。 */

.life-balance-card .life-balance-copy,
.life-balance-card .life-balance-arrow {
  position: relative;
  z-index: 1;
}

/* 余额不足（低于 5 元）：卡片边框、余额文本、背景折线统一转成偏红的橙红。
   颜色在卡片上覆盖 --life-blue：边框用它，折线的 currentColor 也就是它。
   取的是比纯橙红更深一点的红，折线只有 2px、边框只有 1.5px，太浅会看不清。 */
.life-balance-card.is-low-warning {
  --life-blue: #E23B2E;
  --life-blue-soft: rgba(226, 59, 46, 0.12);
  --life-blue-border: rgba(226, 59, 46, 0.80);
}

html[data-theme="dark"] .life-balance-card.is-low-warning {
  --life-blue: #FF7A5C;
  --life-blue-soft: rgba(255, 122, 92, 0.14);
  --life-blue-border: rgba(255, 122, 92, 0.85);
}

/* 余额不足时右上角的红色感叹号气泡（由 refreshLifeBalanceWarnings 动态补进卡片）：
   位置避开右侧垂直居中的箭头，也盖在背景折线之上。 */
.life-balance-badge {
  position: absolute;
  top: 7px;
  right: 8px;
  z-index: 2;
  width: 20px;
  height: 20px;
  border-radius: var(--hgu-radius-round);
  background: #E5342A;
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  line-height: 1;
  box-shadow: 0 1px 4px rgba(229, 52, 42, 0.45);
  pointer-events: none;
  animation: lifeBalanceBadgePulse 1.9s var(--ease-standard) infinite;
}

.life-balance-badge i {
  font-size: 11px;
  line-height: 1;
}

@keyframes lifeBalanceBadgePulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(0.86); opacity: 0.88; }
}

/* 关了动效就只留一个静态气泡 */
@media (prefers-reduced-motion: reduce) {
  .life-balance-badge { animation: none; }
}

.life-package-card {
  appearance: none;
  -webkit-appearance: none;
  min-height: 194px;
  border-color: var(--life-blue-border);
  border-radius: var(--hgu-radius-2xl);
  padding: 16px 12px;
  color: var(--life-blue);
  font-family: inherit;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.life-package-icon {
  width: 52px;
  height: 52px;
  object-fit: contain;
  margin-top: 4px;
}

.life-package-title {
  color: var(--life-blue);
  font-size: 18px;
  font-weight: 900;
  line-height: 1.2;
}

.life-package-subtitle {
  color: var(--subtext);
  font-size: 12px;
  font-weight: 700;
}

.life-package-action {
  width: 100%;
  min-height: 32px;
  border-radius: var(--hgu-radius-pill);
  background: var(--life-blue-soft);
  border: 1px solid var(--life-blue-border);
  color: var(--life-blue);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 800;
}

.life-canteen-card {
  grid-column: 1 / -1;
  width: 100%;
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  /* 不带 backdrop-filter：抽屉面板就是它的背景根，卡面会被面板底色整块
     抬亮（暗色压暗），停稳后就是那层"多出来的遮罩"——原因见
     .study-feature-panel 上方那段说明。 */
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  box-sizing: border-box;
}

.life-canteen-card {
  --canteen-accent: #ff9800;
  --canteen-accent-soft: rgba(255, 152, 0, 0.12);
  --canteen-accent-border: rgba(255, 152, 0, 0.58);
  /* 图标外框进度环的轨道色（浅色下与卡片橙边框呼应） */
  --canteen-accent-track: rgba(255, 152, 0, 0.26);
  position: relative;
  padding: 12px;
  border: 1.5px solid var(--canteen-accent-border);
  color: var(--canteen-accent);
  cursor: pointer;
}

/* 卡片空白处也可进入今天吃什么，提示色跟随本卡片的橙色主题 */
.life-canteen-card .life-card-click-hint {
  color: var(--canteen-accent);
}

.life-section-card-head,
.life-activities-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.life-section-card-head > span,
.life-activities-title {
  color: var(--life-orange);
  font-size: 15px;
  font-weight: 800;
}

.life-section-card-head > span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.life-canteen-card .life-section-card-head > span {
  color: var(--canteen-accent);
}

.life-section-card-head img,
.life-activities-title img {
  width: 28px;
  height: 28px;
  object-fit: contain;
}

.life-section-card-head small,
.life-card-click-hint {
  color: var(--subtext);
  font-size: 11px;
  font-weight: 700;
}

.life-canteen-list {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 2px;
  margin-top: 10px;
}

/* 单个食堂：图标（圆角矩形进度环）→ 食堂名 → 距离 */
.life-canteen-item {
  appearance: none;
  -webkit-appearance: none;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 4px 1px 2px;
  border: 0;
  border-radius: var(--hgu-radius-md);
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--motion-fast) var(--ease-standard),
              background-color var(--motion-base) ease;
}

.life-canteen-item:active {
  transform: scale(0.95);
  background: rgba(255, 152, 0, 0.08);
}

/* 环形进度：SVG 圆角矩形描边，宽度跟随列宽自动放大（上限 56px），高度按 viewBox 比例 */
.life-canteen-ring {
  position: relative;
  display: block;
  width: 100%;
  max-width: 56px;
  margin: 0 auto;
}

.life-canteen-ring-svg {
  display: block;
  width: 100%;
  height: auto;
}

.life-canteen-ring-track,
.life-canteen-ring-fill {
  fill: none;
  stroke-width: 4;
}

.life-canteen-ring-track {
  stroke: var(--canteen-accent-track);
}

/* 进度从圆角矩形左上角起顺时针生长；dasharray/dashoffset 由脚本按距离写入 */
.life-canteen-ring-fill {
  stroke: var(--canteen-accent);
  stroke-linecap: round;
  transition: stroke-dashoffset 0.45s var(--ease-standard);
}

.life-canteen-icon {
  position: absolute;
  top: 12%;
  right: 12%;
  bottom: 12%;
  left: 12%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: 24%;
  background: var(--canteen-accent-soft);
}

.life-canteen-icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.life-canteen-icon i {
  color: var(--canteen-accent);
  font-size: 18px;
}

.life-canteen-name {
  max-width: 100%;
  color: var(--subtext);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.15;
  text-align: center;
  overflow-wrap: anywhere;
}

.life-canteen-distance-text {
  max-width: 100%;
  color: var(--subtext);
  font-size: 10px;
  font-weight: 600;
  line-height: 1.1;
  text-align: center;
  white-space: nowrap;
}

/* 只有最近的食堂高亮为橙色加粗，其余保持普通深色文本 */
.life-canteen-item.is-nearest .life-canteen-name,
.life-canteen-item.is-nearest .life-canteen-distance-text {
  color: var(--canteen-accent);
  font-weight: 900;
}

  html[data-theme="dark"] .life-canteen-card {
    --canteen-accent: #ffb74d;
    --canteen-accent-soft: rgba(255, 183, 77, 0.12);
    --canteen-accent-border: rgba(255, 183, 77, 0.58);
    --canteen-accent-track: rgba(255, 183, 77, 0.30);
  }

/* 「社团与活动」：排在「今天吃什么」下面，只占右半边（宽度是原来的一半），
   左半边由同行的一张占位卡补上 —— 生活区网格是两列，
   占位卡落在第 1 列、活动卡自然落到第 2 列，两者都不需要写 grid-column。
   占位卡不参与卡片入场动画的错峰（避免比邻居晚半拍出现）。 */
.life-dashboard-spacer {
  min-width: 0;
  animation: none;
}

/* ---- 「还没想好加啥」占位卡 ----
   自己画边框，不走 .life-freshman-card 那组橙色主题边框：需求要的是灰色边框。
   同行的「社团与活动」是 1.5px 品红边框 + --hgu-radius-2xl + 12px 内边距，
   这里除了把描边换成灰色，其余保持一致，两张卡才像一对。
   灰色取两层：外层描边用半透明中性色（浅色/暗色都能透出背景，不用各写一套），
   加载图标用 --subtext，跟随主题。 */
.life-placeholder-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  box-sizing: border-box;
  padding: 12px;
  border: 1.5px solid rgba(148, 163, 184, 0.55);
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  /* 见 .study-feature-panel 上方那段：抽屉面板是这些卡片的背景根，
     卡片自带 backdrop-filter 只会把面板底色再糊一层 → 卡面多出白色遮罩。
     这里同样只保留玻璃底色。 */
  color: var(--text);
  animation: none;
}

/* 顶部标题：与 .life-activities-title 同一套字号字重，颜色跟着卡片走灰色 */
.life-placeholder-title {
  font-size: 15px;
  font-weight: 800;
  color: var(--subtext);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 中间：撑满剩余高度，把加载图标稳稳放在正中 */
.life-placeholder-body {
  flex: 1;
  min-height: 110px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.life-placeholder-spinner {
  font-size: 42px;
  color: var(--subtext);
  opacity: 0.55;
}

html[data-theme="dark"] .life-placeholder-card {
  border-color: rgba(148, 163, 184, 0.42);
}

html[data-theme="dark"] .life-placeholder-spinner {
  opacity: 0.65;
}

/* 系统开了「减弱动态效果」时别让它一直转（同项目其它动画的同一约定） */
@media (prefers-reduced-motion: reduce) {
  .life-placeholder-spinner {
    animation: none;
  }
}

/* ==================== 首页广告卡片 ====================
   由后台「广告管理」投放（admin.hgu.life/advertisement.html），
   数据来自 api/advertisement.php，渲染逻辑在 js/home.js 的 lifeAdRenderCard()。

   需求给定的取色：
     --life-ad-deep   #386232  订餐时间线段 / 卡片渐变边框起点
     --life-ad-light  #C5DBA4  送餐时间线段 / 卡片渐变边框终点
     --life-ad-brand  #C8C59F  广告名 / 订餐开放中 / 点击订餐（深色模式原值）
     --life-ad-brand-text      亮色模式下的略暗版本，保证浅色玻璃底上的可读性
  版式：标题行 → 状态行（左"订餐开放中/送餐中"、右"点击订餐"）→ 底部时间轴 → 时间点标签。

   背景：与其它卡片一致的玻璃底（--hgu-surface-glass），**不额外加渐变**；
   渐变只出现在边框那一圈（padding-box 盖住 border-box 的写法见下）。

   几个必须记住的坑（都踩过或有明确代价）：
     1) 渐变边框必须同时具备【等宽的真实透明边框】与【不透明的内边衬】，
        否则 border-box 那层渐变会盖住整张卡片（实测上半张卡泛粉）；
     2) 「当前时间」图标所在位置要把时间轴**真的切开**：除了图标本身，
        还叠了一块与卡片同色的小方块（.life-ad-split），把图标下方那一段线抹掉；
        两者宽度共用 --life-ad-split（由 JS 按轨道实测宽度写入），保证严丝合缝；
     3) 图标用 translate 定位、rotation 属性做动画 —— 两者互不覆盖，
        动画只切换 rotation，不影响这个图标相对时间轴的上下居中。 */
.life-ad-slot {
  width: 100%;
  max-width: 400px;
  /* 与 .tools-home-grid 同一条左基线（后者也是 400px 上限、不加左右外边距），
     所以这里**不能**用 margin:0 auto —— 那会把卡片往右推 20px，与下面的服务卡片错开。 */
  margin: 0 0 10px;
}

.life-ad-slot[hidden] {
  display: none;
}

.life-ad-card {
  --life-ad-deep: #386232;
  --life-ad-light: #C5DBA4;
  --life-ad-brand: #C8C59F;
  /* 亮色模式用的略暗版本（同一色相压暗）：浅色玻璃底上 #C8C59F 太淡看不清 */
  --life-ad-brand-text: #7C7748;
  /* 边框宽度：给 2px —— 1.5px 会被部分浏览器取整成 1px，看着像"没边框"。
     实际显示：Chrome 里 1.5px→1px、2px→2px，所以直接给 2px 更稳。 */
  --life-ad-border: 2px;
  /* 边框颜色 = 广告名（"轻禾轻食"）**实际显示**的颜色。
     用 --life-ad-brand-text 而不是 --life-ad-brand：亮色模式下广告名会压暗成
     #7C7748 以保证可读性，边框必须跟着一起暗，否则两者颜色对不上。 */
  --life-ad-border-color: var(--life-ad-brand-text);
  /* 线段自己高 12px，与上/下标签各留 3px 间距 —— 这几个数必须与
     .life-ad-rail 的 padding-top 以及 .life-ad-now 的偏移配套：
       · 列内 padding-top = 12 + 3 = 15 → 线段顶边距列顶 15px
       · 图标 top = 21、margin-top = -12 → 中心正好落在线段中线上
     改这几个数要一起改，否则图标会整体偏移（靠自检的"图标中心 = 线段中心"抓）。 */
  --life-ad-track-gap: 4px;
  /* 上标签占的行高（12px 文字 + 3px 与线段的间距）。
     每一列都留出这一行，五段线才会落在同一条水平线上（只有第 2、4 段有上标签）。 */
  --life-ad-label-row: 15px;
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  box-sizing: border-box;
  /* 边框就用最直白的 border —— 之前用 mask 画"渐变圆环"，那套在部分内核上
     整层不画，表现就是"边框完全看不到"。1.5px 上下的误差肉眼看不出来，
     换来的是"一定画得出来"。 */
  border: var(--life-ad-border) solid var(--life-ad-border-color);
  padding: 11px 12px 9px;
  border-radius: var(--hgu-radius-2xl);
  box-shadow: var(--hgu-shadow-card);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  /* 卡面就是**和其它卡片完全一样的一层玻璃**：background: var(--hgu-surface-glass)。
     边框在 border 上，不经过 background，所以卡面不会被边框颜色染色。 */
  background: var(--hgu-surface-glass);
  /* 广告卡与其它首页卡一样**不自带 backdrop-filter**：抽屉面板
     （#tools-page）才是背景根，卡片玻璃只会把面板底色再糊一层，
     卡面就会多出一层偏白的遮罩（暗色模式偏黑）。原因见
     .study-feature-panel 上方那段说明。 */
  /* 右下角装饰图要"有一部分在卡片外不显示"，靠这里裁掉 */
  overflow: hidden;
  isolation: isolate;
}

/* 旧的 mask 渐变圆环：保留在 DOM 里（index.html 里那一层）但不显示，
   免得删了结构以后想回退又要改 HTML。 */
.life-ad-ring {
  display: none;
}

html[data-theme="dark"] .life-ad-card {
  /* 深色底上原色就够亮，不加亮也不压暗 */
  --life-ad-brand-text: #C8C59F;
}

.life-ad-card:active {
  transform: scale(0.985);
}

/* 右下角装饰图：倾斜 -45°、半透明、约有 1/3 被卡片裁掉（overflow:hidden）。
   display:block 必需 —— img 默认是 inline-replaced，绝对定位后
   width:auto + height:50% 会算不出尺寸（实测 getBoundingClientRect 全 NaN）。
   ⚠️ 这里是**独立于旋转动画**的 -45°（用户只要求把"当前时间"图标改成 -30°）。 */
.life-ad-deco {
  display: block;
  position: absolute;
  right: -18px;
  /* 往上抬：原来 bottom:0 是贴着卡片底边，视觉上偏下、和右下角挤在一起。
     现在底部留出一块空白，整张装饰图明显上移。 */
  bottom: 26px;
  width: auto;
  height: 50%;
  /* 半透明但要看得出：这张图本身极浅（近乎白的盘子），
     26% 叠在同样很浅的玻璃上几乎等于没有，试过 0.26 视觉上完全消失。 */
  opacity: 0.42;
  transform: rotate(-45deg);
  transform-origin: bottom right;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}

html[data-theme="dark"] .life-ad-deco {
  /* 深色玻璃上浅色图本来就更显眼，稍微压一点 */
  opacity: 0.34;
}

/* 顶部：左标题（logo + 几何地大 + 链接图标 + 展示图 + 广告名），右箭头上下居中 */
.life-ad-head {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 8px;
}

.life-ad-title {
  display: flex;
  align-items: center;
  /* 不换行：宽度不够时让广告名自己省略，而不是把展示图挤到下一行 */
  flex-wrap: nowrap;
  gap: 5px;
  min-width: 0;
  flex: 1;
}

.life-ad-logo {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  border-radius: 6px;
  object-fit: cover;
}

.life-ad-title-text {
  font-size: 14px;
  font-weight: 800;
  color: var(--text);
  white-space: nowrap;
}

.life-ad-link-icon {
  width: 13px;
  height: 13px;
  flex: 0 0 auto;
  color: var(--subtext);
  opacity: 0.62;
}

.life-ad-image {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  border-radius: 6px;
  object-fit: cover;
}

.life-ad-name {
  font-size: 14px;
  font-weight: 800;
  color: var(--life-ad-brand-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex: 0 1 auto;
}

.life-ad-arrow {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--subtext);
  opacity: 0.7;
}

/* 中间：左「订餐开放中 / 送餐中」，右「点击订餐」（两者同色）。
   flex:1 把时间轴顶到卡片底部；min-height 保证这一行本身是一块有高度的"中间带"。 */
.life-ad-status-row {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex: 1 1 auto;
  min-height: 28px;
  padding: 8px 1px 0;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--subtext);
}

.life-ad-status,
.life-ad-action {
  color: var(--life-ad-brand-text);
}

/* 时间轴：贴卡片底部。margin-top 给出与状态行之间的固定间距 ——
   用 padding 做不到：状态行是 flex:1 的弹性块，会把它自己的下内边距吃掉。 */
.life-ad-timeline {
  position: relative;
  z-index: 1;
  margin: 11px 1px 0;
  padding-bottom: 2px;
}

/* 时间段：五段，"当前时间"那一处被切开。
   ⚠️ 轨道是**行**方向排列的"每一段一列"：每段外面包一层 .life-ad-rail，
   列内自上而下是「上标签 → 线段 → 下标签」，所以标签天然落在该段的正上下方，
   不会像绝对定位那样在窄段上互相重叠。轨道高度交给内容撑开，
   .life-ad-seg 用固定高度而不是 height:100%（否则会被标签撑高）。 */
/* 轨道：一行五列，每列是「上标签 → 线段 → 下标签」。
   ⚠️ 「当前时间」的缺口与图标渲染在**线段所在的那一列**（.life-ad-rail）里，
   所以它们的垂直基准就是线段自己（top: 6px = 线段半高），不需要任何运行时测量，
   也不会因为上下标签的字号/有无而错位。 */
.life-ad-track {
  position: relative;      /* 「当前时间」缺口与图标的定位基准就是它（顶边 = 线段顶边） */
  display: flex;
  align-items: flex-start;
  gap: var(--life-ad-track-gap);
}

/* 一段的列容器：内容按列居中（上标签 / 线段 / 下标签） */
/* 一段的列容器。
   ⚠️ 关键：**所有列都留出上标签那一行**，线段才会落在同一条水平线上。
   只有第 2、4 段真有上标签，其余三列的标签是空占位 —— 不占位的话，
   那三列的线段会往上顶一行，五段线就"断成两截、高低不平"（用户反馈过）。
   因为基准固定，缺口/图标的垂直位置用 CSS 写死即可，不需要运行时测量。 */
.life-ad-rail {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 0;
  min-width: 0;
  padding-top: var(--life-ad-label-row);
}

/* 线段上方的时间范围文字（如 10:15-12:00）：浅金绿。
   负 margin 把它放回上面的 padding 区域里（那段是给线段让出的空间）。 */
.life-ad-above {
  display: block;
  flex: 0 0 auto;
  height: 12px;
  margin-top: calc(-1 * var(--life-ad-label-row));
  margin-bottom: 3px;      /* 与线段之间的间距 */
  font-size: 9.5px;
  font-weight: 700;
  line-height: 12px;
  white-space: nowrap;
  color: var(--life-ad-light);
  /* 没有文案的列也保留这一行（内容为空），结构统一 */
}

/* 线段下方的文案（如「截单」「午晚餐预定」）：深绿 */
.life-ad-below {
  display: block;
  flex: 0 0 auto;
  height: 12px;
  margin-top: 3px;         /* 与线段之间的间距 */
  font-size: 9.5px;
  font-weight: 700;
  line-height: 12px;
  white-space: nowrap;
  color: var(--life-ad-deep);
}

/* 每一段自己是**两端圆头**的胶囊（999px）。
   两条要求同时存在时只有这一种做法站得住：
     · 两端要圆 → 每段自己 999px；
     · 不同时间段之间要有距离 → 靠 flex 的 gap（--life-ad-track-gap = 4px）。
   如果只给轨道圆角，中间几段的切口就是直角；而把 gap 调到 0 时，
   相邻两段的圆头会正好接上，看起来又是一条线。 */
.life-ad-seg {
  display: block;
  width: 100%;
  height: 12px;
  min-width: 2px;
  border-radius: 999px;
}

.life-ad-seg.deep { background: var(--life-ad-deep); }
.life-ad-seg.light { background: var(--life-ad-light); }

/* 说明：图标背后那块"与卡面同色的遮罩"（原 .life-ad-split）已按需求去掉 ——
   它本来是用来把图标所在处的线段抹掉、做成一个缺口的。现在图标直接盖在线段上。 */

/* 「当前时间」小图：只负责位置，压在图标所在那一段的线段上，与线段上下居中。
   横向 left 由 JS 按**本段内比例**写入（见 js/home.js 的 lifeAdNowPosition）。
   定位与旋转分两层：这一层管位置，内层 .life-ad-now-img 只管旋转动画 ——
   动画里的 rotate 会替换掉同层的 translate/margin 效果（踩过一次，图标会偏半高）。 */
.life-ad-now {
  position: absolute;
  left: 0;
  /* 这一列里线段顶边距列顶 15px，再上移自身半高 12px → 中心落在线段中线上。
     （top/负 margin 这几个数与 --life-ad-label-row 配套，改要一起改） */
  top: 21px;
  margin-top: -12px;      /* 自身高 24px 的一半 */
  width: 26px;
  height: 24px;
  pointer-events: none;
  z-index: 2;
}

/* 每秒切换两次：不倾斜 ↔ 倾斜 -30°（steps 是"直接改变"，不是渐变动画） */
.life-ad-now-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.28));
  animation: lifeAdNowTilt 1s steps(2, jump-none) infinite;
  transform-origin: center;
}

@keyframes lifeAdNowTilt {
  0%   { rotate: 0deg; }
  50%  { rotate: -30deg; }
  100% { rotate: 0deg; }
}

/* 用户开了"减弱动态效果"时不要一直闪：停在不倾斜的状态 */
@media (prefers-reduced-motion: reduce) {
  .life-ad-now-img { animation: none; }
}

/* 线段下方的时间点标签（除 00:00 外每个时间点都有；当前时间也在其中）
   统一使用 --life-ad-deep 实色，不再做渐变。 */
.life-ad-times {
  position: relative;
  height: 17px;
  margin: 0 1px;
}

.life-ad-time {
  position: absolute;
  top: 3px;
  transform: translateX(-50%);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  color: var(--life-ad-deep);
}

/* 深色主题下时间轴底色/文字对比度补偿 */
html[data-theme="dark"] .life-ad-time {
  color: var(--life-ad-light);
}

/* ==================== 轻禾轻食 · 菜品弹窗 ====================
   点击首页广告卡片打开（js/ad-modal.js）。视觉与动画参考根目录 轻食demo.html：
   同一套缓动、漂浮食材、以屏幕底部为圆心的弧线位移、跟手拖拽。
   幻灯片是**循环**的传送带，DOM 由 ad-modal.js 生成，所以这里只有外壳样式。

   结构（自下而上）：
     .life-adm-blur    背景模糊层（下半最强、越往上越弱）
     .life-adm-deco    底部背景图（垫在文本下面，允许与文字重叠）
     .life-adm-track   滑动容器（铺满 inner，接管拖拽）
     .life-adm-slide   一张菜品：上方食材舞台 / 中间大图 / 下方菜名+介绍
     .life-adm-close   关闭 */
.life-adm {
  position: fixed;
  inset: 0;
  /* 要盖住底部悬浮栏（z-index 999）与其它浮层，所以取 10001；
     仍低于协议页 / 引导层（100000），免得把该挡的也挡住。 */
  z-index: 10001;
  display: grid;
  place-items: center;
  /* 只加模糊遮罩，**不加黑遮罩**（需求）：底色保持透明 */
  background: transparent;
  visibility: hidden;
  pointer-events: none;
}

/* 背景模糊层：**下半部分模糊最强，越往上越弱**（需求，同 demo 的分层模糊）。
   做法是 blur(18px) 再叠一层"从下往上递减"的 mask —— 等于给模糊本身加了渐变，
   比叠好几层不同 blur 更省、也不会在接缝处出现条纹。
   ⚠️ mask 要写 -webkit- 前缀，iOS Safari 只认它。 */
.life-adm-blur {
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0;
  transition: opacity .42s ease;
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  -webkit-mask-image: linear-gradient(to top, #000 0%, rgba(0, 0, 0, .82) 42%, rgba(0, 0, 0, .34) 74%, transparent 100%);
  mask-image: linear-gradient(to top, #000 0%, rgba(0, 0, 0, .82) 42%, rgba(0, 0, 0, .34) 74%, transparent 100%);
  pointer-events: none;
}

.life-adm.show { visibility: visible; pointer-events: auto; }
.life-adm.show .life-adm-blur { opacity: 1; }

/* 浏览器不支持背景模糊时：给一层很淡的压暗 + 均匀模糊度兜底，
   总比"弹窗浮在清清楚楚的页面上"要好认 */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .life-adm-blur {
    background: linear-gradient(to top, rgba(16, 24, 12, .26), rgba(16, 24, 12, 0) 72%);
    -webkit-mask-image: none;
    mask-image: none;
  }
}

.life-adm-inner {
  position: relative;
  width: min(520px, 94vw);
  height: min(760px, 92vh);
}

/* 自由漂浮的装饰圆形（切换菜品时保持不动，只是入场时错峰浮上来）。
   z-index 1 与 .life-adm-track 同级但写在前面，所以不会盖住幻灯片内容。 */
.life-adm-blobs { position: absolute; inset: -8% -6%; z-index: 1; pointer-events: none; }
.life-adm-blob { position: absolute; border-radius: 50%; opacity: 0; will-change: transform, opacity; }
.life-adm-b-a {
  width: 320px; height: 320px; right: -70px; top: 40%;
  background: radial-gradient(circle at 34% 30%,
    rgba(168, 208, 120, .34) 0%, rgba(168, 208, 120, .16) 46%,
    rgba(168, 208, 120, .04) 68%, rgba(168, 208, 120, 0) 76%);
}
.life-adm-b-b {
  width: 240px; height: 240px; left: -80px; bottom: -50px;
  background: radial-gradient(circle at 40% 38%,
    rgba(214, 236, 178, .58) 0%, rgba(214, 236, 178, .22) 48%,
    rgba(214, 236, 178, .05) 70%, rgba(214, 236, 178, 0) 78%);
}
.life-adm-b-c {
  width: 130px; height: 130px; left: 4%; top: 58%;
  background: radial-gradient(circle at 38% 34%,
    rgba(182, 217, 138, .42) 0%, rgba(182, 217, 138, .15) 52%, rgba(182, 217, 138, 0) 74%);
}
.life-adm-b-d {
  width: 92px; height: 92px; right: 10%; top: 22%;
  background: radial-gradient(circle at 36% 32%,
    rgba(232, 243, 220, .9) 0%, rgba(214, 236, 178, .28) 52%, rgba(214, 236, 178, 0) 76%);
}

.life-adm.show .life-adm-blob { animation: lifeAdmBlobIn .95s cubic-bezier(.16, 1, .3, 1) both; }
.life-adm.show .life-adm-b-a { animation-delay: .08s; }
.life-adm.show .life-adm-b-b { animation-delay: .14s; }
.life-adm.show .life-adm-b-c { animation-delay: .20s; }
.life-adm.show .life-adm-b-d { animation-delay: .26s; }

@keyframes lifeAdmBlobIn {
  from { opacity: 0; transform: translateY(80px) scale(.72); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.life-adm.show.closing .life-adm-blob {
  animation: lifeAdmBlobOut .34s ease-in both;
  animation-delay: 0s;
}
@keyframes lifeAdmBlobOut {
  from { opacity: 1; transform: translateY(0) scale(1); }
  to   { opacity: 0; transform: translateY(60px) scale(.75); }
}

/* 滑动容器 */
.life-adm-track {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  border-radius: 26px;
  touch-action: none;
  cursor: grab;
  -webkit-tap-highlight-color: transparent;
}
.life-adm.dragging .life-adm-track { cursor: grabbing; }

/* 一张菜品（绝对定位铺满，位移由 JS 逐帧写 transform） */
.life-adm-slide {
  position: absolute;
  inset: 0;
  display: block;
  will-change: transform, opacity;
  backface-visibility: hidden;
}

/* ---------- 上方：随机食材 ----------
   槽位是按"舞台区域"的百分比算的，所以菜品图往下挪多少，这里就跟着挪多少
   （top 0 → 6%），食材才会整体跟着下移、与菜品图的相对距离不变。 */
.life-adm-stage {
  position: absolute;
  left: 0; right: 0; top: 6%;
  height: 46%;
  z-index: 1;
  pointer-events: none;
}
/* ⚠️ 食材/菜品图的 transform 由 ad-modal.js 逐帧写（横向滞后 + 上下浮动一起算），
   这里**不要**挂 CSS 动画 —— 会整个覆盖 JS 写的 transform，表现就是"滑动没反应"。 */
.life-adm-float {
  position: absolute;
  will-change: transform;
}
.life-adm-float-img {
  display: block;
  height: auto;
  filter: drop-shadow(0 6px 14px rgba(95, 145, 70, .18));
  user-select: none;
  -webkit-user-drag: none;
}

/* ---------- 中间：菜品图（贴近下方标题；食材舞台跟着一起下移） ---------- */
.life-adm-bowl {
  position: absolute;
  left: 0; right: 0;
  top: 30%;
  height: 32%;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
  pointer-events: none;
}
/* 菜品图的 transform 同样由 JS 逐帧写（层内滞后），不要再加 CSS 动画 */
.life-adm-bowl-img {
  display: block;
  max-width: 66%;
  max-height: 100%;
  height: auto;
  object-fit: contain;
  filter: drop-shadow(0 18px 30px rgba(70, 110, 50, .26));
  user-select: none;
  -webkit-user-drag: none;
}

/* ---------- 下方：品牌行 + 菜名 + 介绍 ----------
   品牌行紧跟菜品图（图底与这一块顶部只差 2%），所以 top 定在 64%、
   菜品图 top:30% + height:32% = 62% 结束。改图的位置要一起改这里。 */
.life-adm-text {
  position: absolute;
  left: 6%; right: 6%;
  top: 64%;
  max-height: 24%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-align: left;             /* 品牌行居左（需求）；菜名与介绍跟着左对齐更整齐 */
  z-index: 3;
  pointer-events: none;
}
/* 品牌行：居左的 logo + 名字，**字号与菜品名一样大** */
.life-adm-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
/* 品牌行的 logo：**与卡片标题左侧那个 .life-ad-logo 完全一致**
   （同一张 images/logo.png、同样的 22×22 圆角裁切），只是跟着品牌名一起对齐。 */
.life-adm-brand-logo {
  display: block;
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  border-radius: 6px;
  object-fit: cover;
}
.life-adm-brand-name {
  font-size: clamp(18px, 4.6vw, 23px);   /* 与 .life-adm-title 同一档 */
  font-weight: 800;
  letter-spacing: .04em;
  color: #3f6b3a;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .6);
  white-space: nowrap;
}
.life-adm-title {
  margin: 0;
  font-size: clamp(18px, 4.6vw, 23px);
  font-weight: 800;
  letter-spacing: .04em;
  color: #3f6b3a;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .6);
}
.life-adm-desc {
  margin: 0;
  font-size: clamp(12.5px, 3.4vw, 14px);
  line-height: 1.75;
  color: #47543f;
}

/* ---------- 底部背景图 ----------
   位置：原来"左右滑动切换菜品"提示所在的那一带（bottom: 84px），后来又往上抬了 26px。
   尺寸：菜品图的 1.5 倍（菜品图 max-width 66% / max-height 32%
         → 这里 66% × 1.5 = 99%、32% × 1.5 = 48%）。
   它只是**背景**：z-index 低于文本（3），允许与文字重叠、不挤占任何布局
   （position:absolute + pointer-events:none，不参与 flex 排版）。
   ⚠️ 与 .life-adm-bowl 一样：**不要**给它挂 CSS 动画，JS 会逐帧写 transform。 */
.life-adm-deco {
  position: absolute;
  left: 50%;
  bottom: 110px;
  transform: translate(-50%, 50%);
  width: 99%;                       /* .life-adm-bowl-img 的 66% × 1.5 */
  max-height: 48%;                  /* 32% × 1.5 */
  height: auto;
  object-fit: contain;
  /* ⚠️ 透明度与缩放由 ad-modal.js 的 render() 逐帧写（跟随入场/收起的进度），
     这里**不要**再写 opacity 或 transition —— 会和 JS 的逐帧赋值打架。 */
  z-index: 2;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
}

/* 说明：原来这里的「左右滑动切换菜品」提示（.life-adm-hint 及两个箭头
   .life-adm-arrow / @keyframes lifeAdmArrow）已按需求删除。 */

/* ---------- 关闭 ---------- */
.life-adm-close {
  position: absolute;
  top: 14px; right: 16px;
  width: 40px; height: 40px;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, .92);
  color: #5c8f4a;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 10px 24px -12px rgba(95, 145, 70, .75);
  transition: transform .25s ease, background .25s ease;
  z-index: 7;
}
.life-adm-close:hover { transform: rotate(90deg); background: #fff; }
.life-adm.show .life-adm-close { animation: lifeAdmCloseIn .6s cubic-bezier(.16, 1, .3, 1) .46s backwards; }
@keyframes lifeAdmCloseIn {
  from { opacity: 0; transform: translateY(30px) scale(.5); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.life-adm.show.closing .life-adm-close {
  animation: none;
  opacity: 0;
  transform: scale(.7);
  transition: opacity .22s ease, transform .22s ease;
}

/* 说明：原来这里的「打开 轻禾轻食 小程序」大按钮与「左右滑动切换菜品」提示
   都已按需求移除，那一带现在由 .life-adm-deco 背景图占着。 */

/* 窄屏：图片与文字区都收紧一点（比例与宽屏保持一致：图 30% / 文字 64%） */
@media (max-width: 560px) {
  .life-adm-inner { height: 94vh; }
  .life-adm-stage { top: 6%; height: 44%; }
  .life-adm-bowl { top: 29%; height: 30%; }
  .life-adm-bowl-img { max-width: 60%; }
  /* 背景图同步保持"菜品图 1.5 倍"：60% × 1.5 / 30% × 1.5，位置也一起抬 */
  .life-adm-deco { width: 90%; max-height: 45%; bottom: 96px; }
  .life-adm-text { top: 61%; max-height: 26%; }
}

/* 深色主题：文字与提示底色都提亮，避免在深色遮罩上发灰 */
html[data-theme="dark"] .life-adm-title,
html[data-theme="dark"] .life-adm-brand-name { color: #cfe8b8; text-shadow: none; }
html[data-theme="dark"] .life-adm-desc { color: #dfe9d6; }
html[data-theme="dark"] .life-adm-close { background: rgba(40, 52, 34, .9); color: #cfe8b8; }

.life-canteen-card {
  grid-column: 1 / -1;
  width: 100%;
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  /* 不带 backdrop-filter：抽屉面板就是它的背景根，卡面会被面板底色整块
     抬亮（暗色压暗），停稳后就是那层"多出来的遮罩"——原因见
     .study-feature-panel 上方那段说明。 */
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  box-sizing: border-box;
}

/* 「社团与活动」卡：同样去掉 backdrop-filter（面板底色会被再糊一层 → 泛白遮罩）。 */
.life-activities-card {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  width: 100%;
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  box-sizing: border-box;
  padding: 12px;
  border: 1.5px solid #C55DB5;
  color: var(--text);
}

.life-activities-title {
  justify-content: flex-start;
  color: #C55DB5;
}

/* 半宽卡片：标题字号与图标都收一点，避免换行 */
.life-activities-title strong {
  font-size: 14px;
  white-space: nowrap;
}

.life-activities-title img {
  width: 22px;
  height: 22px;
}

/* 箭头靠右，标题文本仍紧贴图标居左 */
.life-activities-card .life-head-arrow {
  margin-left: auto;
}

.life-card-click-hint {
  position: absolute;
  top: 13px;
  right: 12px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: #C55DB5;
}

/* 半宽卡片里统计图与计数上下居中 */
.life-activity-chart {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin-top: 6px;
}

/* 环 + 环心数字：定位容器就是半环的外接矩形 */
.life-activity-ring {
  position: relative;
  width: 100%;
  max-width: 140px;
  margin: 0 auto;
}

.life-activity-ring-plot {
  width: 100%;
}

/* 底轨与三段线条共用：不填充，只描边，两端圆头 —— 所以整张图是「三条圆头线段」而不是实心扇形 */
.life-activity-ring-track,
.life-activity-ring-arc {
  fill: none;
  stroke-width: 9;
  stroke-linecap: round;
}

.life-activity-ring-svg {
  display: block;
  width: 100%;
  height: auto;
}

.life-activity-ring-arc {
  transition: stroke 0.25s ease;
}

/* 图下计数：第一行「进行中xx / 规划中xx」，数字是标签的两倍大（标签 10px → 数字 20px） */
.life-activity-summary {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 100%;
  line-height: 1.15;
  text-align: center;
}

.life-activity-line {
  display: inline-flex;
  align-items: baseline;
  justify-content: center;
  gap: 6px;
  max-width: 100%;
  color: var(--subtext);
  font-size: 10px;
  font-weight: 600;
}

.life-activity-line-sep {
  color: var(--subtext);
  font-size: 10px;
  opacity: 0.6;
}

.life-activity-line-label {
  display: inline-flex;
  align-items: baseline;
  white-space: nowrap;
}

.life-activity-line strong {
  font-size: 20px;
  font-weight: 900;
  line-height: 1;
}

.life-activity-line strong[data-life-activity-count="ongoing"] { color: #7F4DAE; }
.life-activity-line strong[data-life-activity-count="planning"] { color: #C55DB5; }

/* 已结束单独一行，数字与标签同号（不放大），颜色最淡 */
.life-activity-line-ended strong[data-life-activity-count="ended"] {
  font-size: 10px;
  font-weight: 700;
  color: #FDBDBD;
}

.app-download-drawer {
  max-width: 420px;
  max-height: 86vh;
}

.app-download-drawer .modal-body {
  overflow-y: auto;
  max-height: calc(86vh - 76px);
  scrollbar-width: none;
}

.app-download-drawer .modal-body::-webkit-scrollbar {
  display: none;
}

.secondary-drawer.study-info-drawer {
  max-width: 480px;
  --text: var(--study-cyan);
  --color-blue: var(--study-cyan);
  border: 1.5px solid rgba(var(--study-cyan-rgb), 0.55);
}

.protocol-drawer-overlay { z-index: 10020; }
.protocol-drawer { max-height: min(82vh, 720px); padding-bottom: max(24px, env(safe-area-inset-bottom)); scrollbar-width: none; -ms-overflow-style: none; }
.protocol-drawer::-webkit-scrollbar { width: 0; height: 0; display: none; }
.protocol-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 0 0 10px; border-bottom: 1px solid var(--hgu-border-soft); }
.protocol-header > div { display: flex; flex-direction: column; gap: 3px; }
.protocol-header strong { color: var(--text); font-size: 18px; }
.protocol-header small { color: var(--subtext); font-size: 12px; }
.protocol-body { padding: 12px 0; color: var(--subtext); font-size: 14px; line-height: 1.7; }
.protocol-body p { margin: 0 0 10px; }
.protocol-body p:last-child { margin-bottom: 0; }
.protocol-body h2,.protocol-body h3,.protocol-body h4 { margin: 16px 0 8px; color: var(--text); line-height: 1.4; }
.protocol-body h2 { font-size: 17px; }.protocol-body h3 { font-size: 16px; }.protocol-body h4 { font-size: 15px; }
.protocol-body ul,.protocol-body ol { margin: 8px 0 12px; padding-left: 22px; }
.protocol-body li { margin: 5px 0; }
.protocol-body blockquote { margin: 10px 0; padding: 8px 12px; border-left: 3px solid var(--text); background: var(--text-light); color: var(--subtext); }
.protocol-body code { padding: 2px 5px; border-radius: var(--hgu-radius-xs); background: var(--text-light); font-family: monospace; }
.protocol-body strong { color: var(--text); }
.protocol-body a { color: var(--text); text-decoration: underline; }
.protocol-actions { position: sticky; bottom: -24px; padding: 12px 0 max(0px, env(safe-area-inset-bottom)); background: var(--hgu-surface-glass); }
.protocol-primary-btn,.protocol-secondary-btn { min-height: 44px; padding: 0 16px; border-radius: var(--hgu-radius-md); font-size: 14px; font-weight: 600; cursor: pointer; }
.protocol-primary-btn { width: 100%; border: 1px solid var(--text); background: var(--text); color: #fff; }
.protocol-secondary-btn { border: 1px solid var(--text); background: transparent; color: var(--text); }
.protocol-dual-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.protocol-dual-actions .protocol-primary-btn { width: auto; }

.study-info-drawer .official-links-card {
  border-color: rgba(var(--study-cyan-rgb), 0.55);
}

.study-info-drawer .official-links-title,
.study-info-drawer .official-link-row,
.study-info-drawer .official-link-button {
  color: var(--study-cyan);
}

.study-info-drawer .official-link-button {
  border-color: rgba(var(--study-cyan-rgb), 0.42);
  background: rgba(var(--study-cyan-rgb), 0.1);
}

.study-info-drawer-body {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.study-info-drawer-text {
  color: var(--text);
  font-size: 14px;
  line-height: 1.6;
  font-weight: 600;
}

.study-info-drawer-image {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-default);
}

.official-links-card {
  width: 100%;
  border: 1.5px solid rgba(0, 123, 255, 0.5);
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  overflow: hidden;
  backdrop-filter: blur(var(--hgu-blur-xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-xl));
}

.official-links-title {
  padding: 12px 14px;
  color: var(--color-blue);
  font-size: 14px;
  font-weight: 800;
  border-bottom: 1px solid var(--hgu-border-soft);
}

.official-link-row {
  min-height: 48px;
  padding: 8px 12px 8px 14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid var(--hgu-border-soft);
}

.official-link-row:last-child {
  border-bottom: none;
}

.official-link-button {
  min-height: 30px;
  padding: 0 10px;
  border: 1px solid rgba(0, 123, 255, 0.4);
  border-radius: var(--hgu-radius-lg);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--color-blue);
  background: rgba(0, 123, 255, 0.1);
  font-size: 12px;
  white-space: nowrap;
  flex-shrink: 0;
}

#score-page .official-links-card {
  margin-top: 16px;
}

:is(#score-page, #search-page, #training-plan-page, #calendar-page, #elective-page) .official-links-card {
  border-color: rgba(var(--study-cyan-rgb), 0.5);
}

:is(#score-page, #search-page, #training-plan-page, #calendar-page, #elective-page) .official-links-title,
:is(#score-page, #search-page, #training-plan-page, #calendar-page, #elective-page) .official-link-button {
  color: var(--study-cyan);
}

:is(#score-page, #search-page, #training-plan-page, #calendar-page, #elective-page) .official-link-button {
  border-color: rgba(var(--study-cyan-rgb), 0.4);
  background: rgba(var(--study-cyan-rgb), 0.1);
}

  html[data-theme="dark"] .study-exam-row {
    background: linear-gradient(var(--exam-accent-soft, rgba(var(--study-cyan-rgb), 0.18)), var(--exam-accent-soft, rgba(var(--study-cyan-rgb), 0.18))), rgba(0, 0, 0, 0.22);
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.08) inset;
  }

  html[data-theme="dark"] .study-exam-meta span,
  html[data-theme="dark"] .study-exam-meta-empty,
  html[data-theme="dark"] .study-exam-field,
  html[data-theme="dark"] .study-exam-room-option {
    background-color: rgba(0, 0, 0, 0.18);
  }

  html[data-theme="dark"] .study-schedule-tab-indicator::after {
    box-shadow: 0 2px 10px rgba(var(--study-cyan-rgb), 0.36);
  }

.tools-home-content::-webkit-scrollbar {
  display: none;
}

.tools-home-content.hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  position: absolute;
  /* ★ 宽度必须与「可见态」完全一致，否则切页第一帧就会横向跳变（旧 bug：
     这里写 width:100%，绝对定位按父级 padding box 计算 → 比流内的 content box
     宽出左右各一个 --drawer-inline-pad，手机上表现为"页面变宽了一下"）。
     用 left/right + width:auto 钉住同一对边距，宽度恒定。 */
  top: 0;
  left: var(--drawer-inline-pad, 20px);
  right: var(--drawer-inline-pad, 20px);
  bottom: 0;
  width: auto;
  height: auto;
  /* 上一版隐藏态没设高度，绝对定位后 flex:1 失效 → 高度从整屏掉到内容高，
     淡出时下半截会突然收掉。top/bottom:0 一起修掉。 */
  /* 隐藏态 = 旧页面：out 时长渐隐，visibility 用 0s + out 延迟收尾，
     这样淡出期间它还在画面上，淡完才真正不可见（也才彻底让出点击）。
     注意：这里**不能**用 display:none —— 那会让淡出根本没有画面。 */
  transition: opacity var(--page-switch-out) var(--ease-standard),
              visibility 0s linear var(--page-switch-out);
}

.tools-sub-page {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: transparent;
  overflow-y: auto;
  overflow-x: hidden;
  opacity: 0;
  transform: none;
  /* 基态 = 「旧页面」：out 时长渐隐 + visibility 延迟收尾。
     切页时 JS 只是摘掉 .active，元素就落到这条上，于是自动获得"淡出、
     淡完才隐藏"的行为；.active 那条则带 out 延迟，负责"等旧的淡完再淡入"。 */
  transition: opacity var(--page-switch-out) var(--ease-standard),
              visibility 0s linear var(--page-switch-out);
  visibility: hidden;
  pointer-events: none;
  /* 底部悬浮栏的避让空间：由 JS 按悬浮栏真实占用高度写入（栏高 + 底距，
     刘海屏会更大）。内容正好停在悬浮栏上沿，既不留空也不会被压住。 */
  padding-bottom: var(--hgu-nav-clearance, 64px);
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
  overscroll-behavior: contain;
  scrollbar-width: none;
  -ms-overflow-style: none;
  will-change: transform, opacity;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.tools-sub-page::-webkit-scrollbar {
  display: none;
}

.tools-sub-page.active {
  opacity: 1;
  /* 清除导航脚本写入的 translateX 合成层；否则 backdrop 只能看到图片纹理，
     无法读取同一页面层里的文字、图标和边框。 */
  transform: none !important;
  will-change: auto;
  backface-visibility: visible;
  -webkit-backface-visibility: visible;
  visibility: visible;
  pointer-events: auto;
  position: relative;
  height: auto;
  min-height: 100%;
  /* 新页面：opacity 0→1 的起点在 out 之后（延迟 = 旧页面淡出那一段），
     visibility 不延迟，这样它立刻参与布局与绘制（重活都在延迟里做完，
     用户看到的只是"旧页面淡完 → 新页面淡入"）。 */
  transition: opacity var(--page-switch-in) var(--ease-standard) var(--page-switch-out),
              visibility 0s linear 0s;
}

/* ★ 非激活态（= 旧页面 / 离场瞬间）的盒子必须与 .active 完全一致。
   基态的 left:0 + width:100% 是绝对定位，按父级 padding box 计算，比流内的
   content box 宽出左右各一个 --drawer-inline-pad —— 离开子页时它会"变宽"。
   这里用 left/right + width:auto 钉回同一对内边距。
   ⚠️ 必须带 :not(.active)：.active 是 position:relative，若把 left/right 写进基态，
   激活中的子页会被整体推走一个内边距。 */
.tools-sub-page:not(.active) {
  left: var(--drawer-inline-pad, 20px);
  right: var(--drawer-inline-pad, 20px);
  width: auto;
}

/* 离场/隐藏态不再提升为合成层：几何差已消除，但低端 WebView 上「先沿用旧纹理
   再重新栅格化」仍可能把 1~2px 的差异拉成一段"慢动作变宽"。可见态本来就
   will-change:auto，这里只影响看不见的页面。 */
.tools-home-content.hidden,
.tools-sub-page:not(.active) {
  will-change: auto;
  backface-visibility: visible;
  -webkit-backface-visibility: visible;
}

.sub-page-header {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  margin-bottom: 20px;
  margin-top: 16px;
  flex-shrink: 0;
}

/* ================== 抽屉内页的固定标题栏 ==================
 * .sub-page-header 是每个子页（.tools-sub-page）的第一个子元素；固定层脱离页面
 * 滚动流后，标题栏始终停在抽屉顶部内边距下方，不需要 JS 监听 scroll。
 *
 * 关键点：
 * 1. top: 52px 把标题栏放在抽屉顶部内边距下方；页面内容从 y=0 开始，
 *    因而拖拽把手区域也能透出页面内容并被上方玻璃层采样。
 * 2. 标题栏宽度与内容容器一致；分栏布局在后面按面板宽度重新对齐。
 * 3. z-index 只给到 50：必须高于本页滚上来的内容和课表粘性表头，
 *    但要低于抽屉的拖拽把手
 *    （把手是 #tools-page 里的 z-index:1000，层级更高）。
 *
 * 毛玻璃只用**一层** backdrop-filter，靠 mask 在底部淡出；
 * 不铺任何底色，也不做多层叠加 —— 原因见下一段注释。
 * ======================================================== */
.is-fixed-header {
  position: fixed !important;
  top: 52px !important;
  left: -20px;
  right: auto;
  z-index: 50;
  margin: 0 !important;
  /* 左右各吃 20px 抵消 .tools-content-container 的水平内边距，让毛玻璃铺满面板；
     再用同样的 20px 内边距把内容收回内容区 ——
     这样左右两端的按钮（返回键、刷新、管理…）不会被面板边缘切掉。
     （上一版只铺背景、不留内容内边距，靠 left/right: 8px 定位的按钮就顶到边上被遮挡了。） */
  width: calc(100% + 40px);
  transform: none;
  box-sizing: border-box;
  padding: 10px 20px;
  /* 实际玻璃背景放在 ::before；标题栏本体保持透明，避免在渐变底部
     额外叠出一条发白或发黑的色带。 */
  background: transparent;
  /* 子元素万一超宽（长标题、内联定位的按钮）时裁掉，而不是溢出到面板外 */
  overflow: hidden;
  /* 模糊放在伪元素里，避免 mask-image 把标题文字一起淡化。 */
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  -webkit-mask-image: none;
  mask-image: none;
}

/* 标题栏只模糊其背后的页面内容，标题文字和按钮保持清晰。 */
.is-fixed-header::before {
  /* 玻璃已移到 .tools-sub-page::before；这里不再建立 backdrop 层，
     避免标题栏内部的合成路径只模糊图片而漏掉文字和边框。 */
  content: none;
}

/* 课表页自身会向两侧扩展 20px 以铺满内容区，固定后沿用同样的宽度。 */
#schedule-page .is-fixed-header,
#classroom-schedule-page .is-fixed-header {
  left: 20px;
  width: calc(100% - 40px);
}

/* ================== 玻璃层的合成策略 ==================
 * 放弃"多层不同半径叠加"：那一套依赖 backdrop-filter 与 mask 的合成，
 *   在部分浏览器里两者不合成，结果是"要么整块生效、要么整块不生效"；
 *   实际表现就是用户报的「顶部发白（暗色发黑）」+「课表页完全不透」。
 *   一层 backdrop-filter 是最稳的写法。
 *
 * 伪元素只使用极低透明度的中性底色来触发 Android WebView 的完整图层合成，
 * 再由渐变遮罩控制模糊强度；标题栏本体保持透明，避免额外叠出发白 / 发黑的色带。
 * ============================================================ */

/* 标题栏里的注入层已经不需要了（保留选择器只为兼容已被旧版本注入过的 DOM：
   老版本会在页面里留下 .sub-page-header-blur / .sub-page-header-veil 节点）。 */
.sub-page-header-blur,
.sub-page-header-veil {
  display: none !important;
}

/* 标题栏里的实际内容都要压在毛玻璃之上 */
.is-fixed-header > * {
  position: relative;
  z-index: 1;
}

/* 空标题栏（首页 / 学习页 / 选项页）：需求要求"不放标题内容，标题栏留空"。
   留空也要占住高度 —— 它就是那条常驻的毛玻璃，同时承担页面顶部的呼吸感。
   高度对齐有标题的页面（返回键 44px 撑起来的那一行）。 */
.sub-page-header-empty {
  min-height: 44px;
}

/* 标题栏里的"那一行"：返回键 + 标题 + 右侧按钮。
   JS 会把原来的内容包进这一行（课表页靠它单独设内边距）。 */
.sub-page-header-row {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  width: 100%;
  min-height: 44px;
  flex-shrink: 0;
  overflow: hidden;
}

/* 课表页 / 教室课表页例外：这两个页面自己已经「向左右各吃 20px 再补回 20px」，
   页面盒子本身就是整块面板宽（见下面 #schedule-page, #classroom-schedule-page 那段），
   再套这层 -20px 会把标题栏推到面板外面。
   （ID 选择器的优先级高于 .is-fixed-header，不用 !important。） */
#schedule-page .is-fixed-header,
#classroom-schedule-page .is-fixed-header {
  left: 20px;
  width: calc(100% - 40px);
  margin-left: 0;
  margin-right: 0;
}

/* ================== 抽屉容器顶部的透明模糊带 ==================
 * 抽屉面板最上面那 52px（拖拽把手所在的一带）原本只是一块半透明底色，
 * 下面的内容透不出来，与各页标题栏的毛玻璃观感对不上。
 * 这一层给那段区域补上毛玻璃；实际玻璃放在容器伪元素上，
 * 只用极低透明度底色触发完整 DOM 合成，避免顶端出现发白 / 发黑的带。
 * 向下用渐变 mask 淡出，于是与下面第一条标题栏的毛玻璃连成一片。
 *
 * 旧版兄弟节点仍保留选择器以兼容历史 DOM，但当前不参与渲染。 */
.drawer-top-glass {
  /* 顶部玻璃已移到 .tools-content-container::before，避免旧兄弟层
     排在页面内容下面而无法采样滚动内容。 */
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  /* 略高于容器的 52px 顶部内边距，多出来的部分正好压在第一条标题栏上，避免接缝 */
  height: var(--drawer-top-glass-h, 64px);
  z-index: -1;
  border-radius: var(--hgu-radius-drawer) var(--hgu-radius-drawer) 0 0;
  pointer-events: none;
  background: transparent;
  -webkit-backdrop-filter: blur(var(--hgu-blur-lg));
  backdrop-filter: blur(var(--hgu-blur-lg));
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 42%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 42%, transparent 100%);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .drawer-top-glass {
    display: none;
  }
}

/* 不支持 backdrop-filter 的老 WebView：什么都补不了，也不该刷底色 ——
   刷了就会在顶端切出一条发白 / 发黑的带，这正是要避免的。
   这类环境整个抽屉本来也没有毛玻璃（.page-overlay 同样用了 backdrop-filter），
   因此标题栏就是完全透明的，内容照旧从下面透上来。 */

.sub-page-title {
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
}

/* 子页面返回箭头：只有图标本身，没有圆角矩形底、没有边框/阴影/毛玻璃、没有按下缩放。
   color 仍由各页面主题决定（见下方各页 #xxx-page 与 .tools-fixed-header-layer 的覆盖），
   .sub-page-back i 也照旧继承这个颜色；44×44 只作为点击区域保留，视觉上不可见。 */
.sub-page-back {
  position: absolute;
  left: 8px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  color: var(--text);
  font-size: 18px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
}

#tools-page .page-title {
  margin-bottom: 20px;
  margin-top: 16px;
  font-size: 22px;
}

.tools-grid-section {
  width: 100%;
  max-width: 400px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 0;
}

.tools-divider {
  width: 100%;
  max-width: 400px;
  height: 1px;
  background: var(--border);
  margin: 8px 0 16px 0;
  opacity: 0.6;
}

.tools-grid-section-secondary {
  width: 100%;
  max-width: 400px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-bottom: 0;
}

.tool-btn {
  aspect-ratio: 1;
  background: transparent;
  border: none;
  border-radius: var(--hgu-radius-2xl);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: pointer;
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1),
    background 0.3s;
  padding: 8px;
  text-decoration: none;
  position: relative;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}

.tool-btn:active {
  transform: scale(0.92);
  background: rgba(128, 128, 128, 0.1);
}

.tool-btn.pressing {
  transform: scale(0.92);
  background: rgba(128, 128, 128, 0.15);
  transition: transform 0.1s ease, background 0.1s ease;
}

.tool-btn img {
  width: 32px;
  height: 32px;
  border-radius: var(--hgu-radius-md);
  object-fit: contain;
  pointer-events: none;
}

.tool-btn span {
  font-size: 11px;
  font-weight: 500;
  text-align: center;
  line-height: 1.3;
  max-width: 100%;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  color: #000;
  pointer-events: none;
  word-break: break-all;
}

.tools-search-bar {
  width: 100%;
  max-width: 400px;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-4xl);
  padding: 12px 16px;
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  transition: all 0.2s ease;
  margin-bottom: 20px;
  margin-top: 16px;
}

.tools-search-bar:active {
  transform: scale(0.98);
  background: rgba(128, 128, 128, 0.15);
}

.tools-search-bar i {
  font-size: 16px;
  color: var(--subtext);
  opacity: 0.6;
}

.search-placeholder {
  font-size: 15px;
  color: var(--subtext);
  opacity: 0.7;
}

.page-transitioning #tools-page {
  pointer-events: none !important;
}

/* ============================================
   14. 鍔ㄧ敾涓庣壒鏁?   ============================================ */
@property --angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

@keyframes fa-spin {
  to { --angle: 360deg; }
}

@keyframes arrowBounce {
  0%, 100% { transform: translateY(0) rotate(-45deg); opacity: 1; }
  50% { transform: translateY(-10px) rotate(-45deg); opacity: 0.8; }
}

/* ============================================
   15. 鏆楄壊妯″紡锛堢粺涓€鏀惧湪鏈€鍚庯級
   ============================================ */
html[data-theme="dark"] {
  color-scheme: dark;
  --glass: rgba(0, 0, 0, .25);
  --bg: #30425A;
  --text: #a8e063;
  --text-light: rgba(168, 224, 99, .15);
  --subtext: #e5e7eb;
  --border: rgba(255, 255, 255, .15);
  --shadow: 0 2px 12px rgba(0, 0, 0, .25);
  --drawer-surface: rgba(36, 43, 50, 0.78);
  --study-cyan: #36c2d8;
  --study-cyan-rgb: 54, 194, 216;
  --weather-icon-sunny: #a8e063;
  --weather-icon-overcast: #B0BEC5;
  --weather-icon-rain: #64B5F6;
  --weather-icon-storm: #CE93D8;
  --weather-icon-snow: #B3E5FC;
  --weather-icon-fog: #CFD8DC;
  --weather-icon-haze: #D7CCC8;
  --weather-icon-hot: #E57373;
  --weather-icon-cold: #80DEEA;
  --weather-icon-wind: #A5D6A7;
  --weather-icon-unknown: #E0E0E0;
  --weather-text-sunny: #a8e063;
  --weather-text-overcast: #B0BEC5;
  --weather-text-rain: #64B5F6;
  --weather-text-storm: #CE93D8;
  --weather-text-snow: #B3E5FC;
  --weather-text-fog: #CFD8DC;
  --weather-text-haze: #D7CCC8;
  --weather-text-hot: #E57373;
  --weather-text-cold: #80DEEA;
  --weather-text-wind: #A5D6A7;
  --weather-text-unknown: #E0E0E0;
}
html[data-theme="light"] {
  color-scheme: light;
  --glass: rgba(255, 255, 255, .25);
  --bg: #E1ECF2;
  --text: #4a7c59;
  --text-light: rgba(76, 175, 80, .15);
  --subtext: #333;
  /* 底部悬浮栏「未选中」那一档的颜色：地图上的悬浮按钮（通知 / 反馈 / 分享 / 定位）
     统一取它。单独做一个 token 是因为 --text 会被抽屉内的页面主题覆盖
     （.tools-fixed-header-layer > [data-header-for=...] 等），直接用 --text 会变色。 */
  --hgu-idle-chrome: var(--text);
  --border: rgba(255, 255, 255, .4);
  --shadow: 0 2px 8px rgba(0, 0, 0, .1);
  --drawer-surface: rgba(255, 255, 255, 0.5);
  --study-cyan: #008fa8;
  --study-cyan-rgb: 0, 143, 168;
  --weather-icon-sunny: #4a7c59;
  --weather-icon-overcast: #90A4AE;
  --weather-icon-rain: #42A5F5;
  --weather-icon-storm: #AB47BC;
  --weather-icon-snow: #81D4FA;
  --weather-icon-fog: #B0BEC5;
  --weather-icon-haze: #BCAAA4;
  --weather-icon-hot: #EF5350;
  --weather-icon-cold: #4DD0E1;
  --weather-icon-wind: #81C784;
  --weather-icon-unknown: #BDBDBD;
  --weather-text-sunny: #4a7c59;
  --weather-text-overcast: #607D8B;
  --weather-text-rain: #1976D2;
  --weather-text-storm: #6A1B9A;
  --weather-text-snow: #0288D1;
  --weather-text-fog: #757575;
  --weather-text-haze: #6D4C41;
  --weather-text-hot: #D32F2F;
  --weather-text-cold: #0097A7;
  --weather-text-wind: #388E3C;
  --weather-text-unknown: #616161;
}

html[data-theme="dark"] .page-overlay {
  background: var(--drawer-surface);
  border-color: rgba(255, 255, 255, 0.15);
}

html[data-theme="dark"] #tools-page {
  -webkit-backdrop-filter: blur(var(--hgu-blur-lg));
  backdrop-filter: blur(var(--hgu-blur-lg));
  background: var(--drawer-surface);
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.42);
}

html[data-theme="dark"] .tools-sub-page.active {
  background: transparent;
}

html[data-theme="dark"] #schedule-page .sub-page-header,
html[data-theme="dark"] #classroom-schedule-page .sub-page-header {
  border-bottom-color: rgba(255, 255, 255, 0.12);
}

html[data-theme="dark"] #homeScheduleTable th:first-child,
html[data-theme="dark"] #homeScheduleTable td:first-child {
  background: rgba(255, 255, 255, 0.06);
}

html[data-theme="dark"] #homeScheduleTable td:not(:has(.course-cell)):not(:first-child) {
  background: rgba(255, 255, 255, 0.03);
}

html[data-theme="dark"] .course-cell-overlay {
  color: #fff;
  border-color: rgba(255,255,255,0.15);
}

html[data-theme="dark"] .course-cell-overlay .course-name,
html[data-theme="dark"] .course-cell-overlay .course-room,
html[data-theme="dark"] .course-cell-overlay .course-teacher {
  color: rgba(255,255,255,0.95);
}

html[data-theme="dark"] .room-name {
  color: #fff;
}

html[data-theme="dark"] #shareScheduleOverlay {
  background: rgba(30, 30, 30, 0.7);
}

html[data-theme="dark"] .modal-overlay {
  background: rgba(0, 0, 0, 0.6);
}

html[data-theme="dark"] .station-locate-btn {
  background: rgba(60, 60, 60, 0.6);
  color: var(--text);
}

html[data-theme="dark"] .station-locate-btn:hover {
  background: rgba(80, 80, 80, 0.8);
}

  html[data-theme="dark"] {
    color-scheme: dark;
    --glass: rgba(0, 0, 0, .25);
    --bg: #30425A;
    --text: #a8e063;
    --subtext: #e5e7eb;
    --border: rgba(255, 255, 255, .15);
    --shadow: 0 2px 12px rgba(0, 0, 0, .25);
    --study-cyan: #36c2d8;
    --study-cyan-rgb: 54, 194, 216;
  }

  html[data-theme="dark"] .page-overlay {
    background: var(--drawer-surface);
  }

  html[data-theme="dark"] #tools-page {
    -webkit-backdrop-filter: blur(var(--hgu-blur-lg));
    backdrop-filter: blur(var(--hgu-blur-lg));
    background: var(--drawer-surface);
    border-color: rgba(255, 255, 255, 0.15);
  }

  /* 【删除】原先这里有一条
       html[data-theme="dark"] #tools-page[data-home-state="expanded"] { height: 100vh; max-height: 100vh; }
     那是旧设计（面板恒为整屏高、靠 transform 位移）留下的补丁：它的优先级高于
     #tools-page { height: var(--drawer-height) }，会把展开态高度硬钉在 100vh，
     绕开现在的三态高度机制。在 APP 的 WebView 里 100vh 是"大视口"（含被应用自身
     顶栏/底栏盖住的区域），而面板是贴底定位的，于是整块被推到屏幕下沿之外 ——
     表现就是"点悬浮栏抽屉不出现/只露出一半"。深色主题下才触发，所以浏览器（浅色
     或 100vh 就等于可视高度）看起来一切正常。高度只允许由 --drawer-height 决定。 */

  html[data-theme="dark"] #tools-page .option-switch-title,
  html[data-theme="dark"] #tools-page .tool-btn span {
    color: #fff;
  }

  html[data-theme="dark"] #tools-page .option-switch-icon {
    filter: brightness(1.2);
  }

  html[data-theme="dark"] .tool-btn.qq-channel-row-btn span {
    color: #fff;
  }

  html[data-theme="dark"] .option-switch-title,
  html[data-theme="dark"] .tool-btn span {
    color: #fff;
  }

  html[data-theme="dark"] #homeScheduleTable th:first-child,
  html[data-theme="dark"] #homeScheduleTable td:first-child {
    background: rgba(255, 255, 255, 0.06);
  }

  html[data-theme="dark"] #homeScheduleTable td:not(:has(.course-cell)):not(:first-child) {
    background: rgba(255, 255, 255, 0.03);
  }

  html[data-theme="dark"] .course-cell-overlay {
    color: #fff;
    border-color: rgba(255,255,255,0.15);
  }

  html[data-theme="dark"] .course-cell-overlay .course-name,
  html[data-theme="dark"] .course-cell-overlay .course-room,
  html[data-theme="dark"] .course-cell-overlay .course-teacher {
    color: rgba(255,255,255,0.95);
  }

  html[data-theme="dark"] .room-name {
    color: #fff;
  }

  html[data-theme="dark"] .modal-overlay {
    background: rgba(0, 0, 0, 0.6);
  }

  html[data-theme="dark"] .station-locate-btn {
    background: rgba(60, 60, 60, 0.6);
    color: var(--text);
  }
  html[data-theme="dark"] .station-locate-btn:hover {
    background: rgba(80, 80, 80, 0.8);
  }

/* ============================================
   16. 鍝嶅簲寮忛€傞厤
   ============================================ */
@media (max-width: 380px) {
  #homeScheduleTable th:first-child,
  #homeScheduleTable td:first-child {
    width: 36px !important;
    min-width: 36px !important;
  }

  #homeScheduleTable th:not(:first-child),
  #homeScheduleTable td:not(:first-child) {
    width: calc((100% - 36px) / 7) !important;
  }
}

@supports (-webkit-touch-callout: none) {
  .tools-sub-page,
  .tools-home-content,
  #calendar-page,
  #search-page {
    -webkit-overflow-scrolling: touch;
  }

  .tools-sub-page,
  .tools-home-content {
    overscroll-behavior-y: contain;
  }
}

/* ============================================
   iOS 鐗堟湰鍒囨崲鎸夐挳
   ============================================ */
.ios-version-toggle {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}

.ios-toggle-btn {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid var(--hgu-border-soft);
  background: var(--hgu-surface-glass);
  border-radius: var(--hgu-radius-lg);
  font-size: 13px;
  font-weight: 600;
  color: var(--subtext);
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
}

.ios-toggle-btn.active {
  background: var(--text);
  color: #fff;
  border-color: var(--text);
}

.ios-toggle-btn:active {
  transform: scale(0.95);
}

.ios-guide-content strong {
  color: var(--text);
  font-weight: 700;
}

  html[data-theme="dark"] .ios-guide-content strong {
    color: var(--text);
  }

/* ============================================
   宸ュ叿椤垫澘鍧楀垎缁?   ============================================ */
.tools-section {
  width: 100%;
  max-width: 400px;
  border: 1.5px solid;
  border-radius: var(--hgu-radius-3xl);
  padding: 14px 10px 10px;
  margin-bottom: 16px;
  position: relative;
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
}

.tools-section-title {
  font-size: 15px;
  font-weight: 700;
  line-height: 1.2;
}

.study-section {
  border-color: var(--color-blue);
}
.study-section .tools-section-title {
  color: var(--color-blue);
}

.life-section {
  border-color: var(--text);
}
.life-section .tools-section-title {
  color: var(--text);
}
.welcome-section {
  border-color: var(--color-orange);
}
.welcome-section .tools-section-title {
  color: var(--color-orange);
}

.frequent-section {
  border-color: var(--color-sky);
}
.frequent-section .tools-section-title {
  color: var(--color-sky);
}

/* ============================================
   甯哥敤鍗＄墖涓庣紪杈戝姛鑳芥牱寮?   ============================================ */
.tools-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
  padding: 0 4px;
}

.tools-section-divider {
  width: 100%;
  height: 1px;
  background: var(--border);
  margin-bottom: 10px;
  opacity: 0.6;
}

.service-card-grid {
  width: 100%;
  max-width: 400px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  align-items: start;
}

.service-card {
  position: relative;
  min-width: 0;
}

.service-card--compact {
  grid-column: span 1;
}

.service-card--featured,
.service-card--wide {
  grid-column: 1 / -1;
}

.service-card-main {
  width: 100%;
  min-height: 132px;
  appearance: none;
  -webkit-appearance: none;
  border: 1.5px solid var(--text);
  background: rgba(255, 255, 255, 0.18);
  border-radius: var(--hgu-radius-2xl);
  padding: 14px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 14px;
  text-align: left;
  color: inherit;
  cursor: pointer;
  box-shadow: var(--hgu-shadow-card);
  backdrop-filter: blur(var(--hgu-blur-xl));
  transition: transform 0.18s ease, border-color 0.2s ease, background 0.2s ease;
  font-family: inherit;
}

.service-card--featured .service-card-main {
  min-height: 164px;
}

.service-card--compact .service-card-main {
  min-height: 96px;
}

.service-card-main:active {
  transform: scale(0.985);
}

.service-card-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-width: 0;
}

.service-card-icon {
  width: 46px;
  height: 46px;
  border-radius: var(--hgu-radius-default);
  background: rgba(255, 255, 255, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border: 1px solid rgba(255, 255, 255, 0.28);
}

.service-card-icon img {
  width: 28px;
  height: 28px;
  object-fit: contain;
  border-radius: var(--hgu-radius-md);
}

.service-card-icon i {
  font-size: 22px;
  color: var(--text);
}

.service-card-meta {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.service-card-preview {
  min-height: 68px;
  padding: 10px 12px;
  border-radius: var(--hgu-radius-default);
  background: rgba(255, 255, 255, 0.26);
  border: 1px solid rgba(255, 255, 255, 0.22);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
}

.service-card-preview.loading {
  opacity: 0.72;
}

.service-card-preview-stack,
.service-card-preview-lines {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.preview-line {
  font-size: 12px;
  line-height: 1.5;
  color: var(--text);
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.preview-line.muted {
  color: var(--subtext);
  opacity: 0.85;
}

.preview-kicker {
  font-size: 11px;
  font-weight: 700;
  color: var(--subtext);
  opacity: 0.8;
}

.preview-row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px;
  align-items: center;
}

.preview-date {
  font-size: 11px;
  font-weight: 700;
  color: var(--text);
}

.preview-text {
  min-width: 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--subtext);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.preview-metric {
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.preview-value {
  font-size: 24px;
  line-height: 1;
  font-weight: 800;
  color: var(--text);
}

.preview-unit {
  font-size: 12px;
  color: var(--subtext);
}

.preview-metric-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
}

.preview-chip-row,
.preview-mini-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.preview-pill {
  display: inline-flex;
  align-items: center;
  min-height: 22px;
  padding: 0 8px;
  border-radius: var(--hgu-radius-pill);
  background: rgba(255, 255, 255, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.24);
  color: var(--subtext);
  font-size: 11px;
  white-space: nowrap;
}

.preview-pill.is-open {
  color: #237a45;
}

.preview-pill.is-soon {
  color: #b26a00;
}

.preview-pill.is-closed {
  color: #8a4a4a;
}

.preview-mini-list span {
  font-size: 11px;
  color: var(--subtext);
  padding-right: 4px;
}

.service-card-preview-empty {
  font-size: 12px;
  line-height: 1.45;
  color: var(--subtext);
  opacity: 0.8;
}

.service-card-title {
  font-size: 16px;
  line-height: 1.25;
  font-weight: 700;
  color: var(--text);
}

.service-card-plain-entry {
  min-height: 42px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
}

.plain-entry-label {
  color: var(--subtext);
  font-weight: 500;
}

.tools-section-edit-btn {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border-radius: var(--hgu-radius-lg);
  border: 1px solid var(--hgu-border-soft);
  background: var(--hgu-surface-glass);
  color: var(--subtext);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
}

.tools-section-edit-btn:active {
  transform: scale(0.95);
}

.tools-section-edit-btn.editing {
  background: var(--text-light);
  color: var(--text);
  border-color: var(--text);
}

.tools-section-edit-btn i {
  font-size: 11px;
}

/* 鎸夐挳鍙充笂瑙掓坊鍔?绉婚櫎鏍囪 */
.tool-btn-action-badge {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 18px;
  height: 18px;
  border-radius: var(--hgu-radius-round);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  color: #fff;
  z-index: 2;
  cursor: pointer;
  border: 1.5px solid #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
  transition: transform 0.15s;
}

.tool-btn-action-badge.remove {
  background: #ff4757;
}

.tool-btn-action-badge.add {
  background: #2ed573;
}

.tool-btn-action-badge.disabled {
  background: #ccc;
  cursor: not-allowed;
}

.tool-btn-action-badge:active {
  transform: scale(0.85);
}

.tool-btn-action-badge i {
  font-size: 9px;
  pointer-events: none;
}

/* 甯哥敤鍗＄墖绌虹姸鎬?*/
.frequent-empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 20px 0;
  color: var(--subtext);
  font-size: 13px;
  opacity: 0.7;
}

/* 鏆楄壊妯″紡閫傞厤 */

  html[data-theme="dark"] .frequent-section {
    border-color: #73ABFF;
  }
  html[data-theme="dark"] .frequent-section .tools-section-title {
    color: #8BB8FF;
  }
  html[data-theme="dark"] .tool-btn-action-badge {
    border-color: rgba(255,255,255,0.8);
  }
  html[data-theme="dark"] .service-card-main {
    background: rgba(0, 0, 0, 0.18);
  }
  html[data-theme="dark"] .service-card-icon,
  html[data-theme="dark"] .service-card-preview,
  html[data-theme="dark"] .preview-pill {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.12);
  }

@media (max-width: 380px) {
  .service-card-grid {
    gap: 8px;
  }

  .service-card-main {
    min-height: 134px;
    padding: 12px;
  }

  .service-card--featured .service-card-main {
    min-height: 150px;
  }

  .service-card-title {
    font-size: 15px;
  }
}

/* 楂樼骇 Toast 宸茬Щ闄わ紝閫氱煡缁熶竴鐢盇PP绯荤粺閫氱煡娓犻亾绠＄悊 */

/* ================== VR琛楁櫙椤?================== */
.vr-hint-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 12px 0;
  padding: 12px 14px;
  background: rgba(255, 152, 0, 0.12);
  border: 1px solid rgba(255, 152, 0, 0.35);
  border-radius: var(--hgu-radius-xl);
  color: #ff9800;
  font-size: 13px;
  font-weight: 500;
}
.vrstreetview-map-toggle {
  margin-bottom: 12px;
}
.vrstreetview-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.vrstreetview-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-default);
  box-shadow: var(--hgu-shadow-card);
}
.vrstreetview-left {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  min-width: 0;
}
.vrstreetview-thumb {
  width: 80px;
  height: 60px;
  border-radius: var(--hgu-radius-lg);
  object-fit: cover;
  background: #eee;
  flex-shrink: 0;
}
.vrstreetview-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.vrstreetview-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}
.vrstreetview-sub {
  font-size: 12px;
  color: var(--subtext);
}
.vrstreetview-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  background: var(--text);
  color: #fff;
  border: none;
  border-radius: var(--hgu-radius-lg);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.2s;
  flex-shrink: 0;
}
.vrstreetview-btn:active { opacity: 0.85; }

/* ================== 店铺查询 ================== */
.store-list-content {
  width: 100%;
  max-width: 520px;
  margin-top: 8px;
}
.store-view-tabs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  width: 100%;
  min-height: 42px;
  padding: 3px;
  margin-bottom: 10px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-md);
  background: var(--hgu-surface-glass);
}
.store-view-tab {
  min-width: 0;
  border: 0;
  border-radius: var(--hgu-radius-sm);
  background: transparent;
  color: var(--subtext);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, box-shadow 0.2s;
}
.store-view-tab.active {
  color: var(--text);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
}
.store-map-toggle-card {
  margin-bottom: 10px;
}
.store-map-toggle-card.hidden {
  display: none;
}
.store-list {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.store-list-item {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 30px 17px 9px;
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-xl);
  background: var(--hgu-surface-glass);
  color: inherit;
  box-shadow: var(--hgu-shadow-card);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  position: relative;
}
.store-list-item:active {
  transform: scale(0.985);
}
.store-list-thumb {
  width: 50px;
  height: 50px;
  flex: 0 0 50px;
  overflow: hidden;
  border-radius: var(--hgu-radius-lg);
  background: var(--text-light);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.store-list-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.store-list-main {
  min-width: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.store-list-main strong {
  color: var(--text);
  font-size: 14px;
  line-height: 1.25;
}
.store-list-main small {
  color: var(--subtext);
  font-size: 11px;
  line-height: 1.28;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
}
.store-list-main small i {
  color: var(--text);
  opacity: 0.72;
  width: 14px;
  text-align: center;
}
.store-list-arrow {
  color: var(--text);
  opacity: 0.55;
  flex: 0 0 auto;
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
}
.store-distance-text {
  position: absolute;
  right: 30px;
  bottom: 5px;
  color: var(--subtext);
  font-size: 10.5px;
  line-height: 1;
  font-weight: 600;
}

/* ================== 公共厕所服务卡片 ================== */
.home-toilet-reminder {
  --toilet-reminder-accent: #2f80ed;
  width: 100%;
  min-height: 88px;
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  border: 0;
  border-radius: var(--hgu-radius-3xl);
  background: transparent;
  color: var(--toilet-reminder-accent);
  padding: 8px 4px;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.home-toilet-reminder .home-recommend-icon {
  background: rgba(47, 128, 237, 0.12);
  color: var(--toilet-reminder-accent);
}

.home-toilet-reminder .home-recommend-kicker {
  color: var(--toilet-reminder-accent);
  font-weight: 900;
}

.home-toilet-reminder .home-recommend-title {
  color: var(--toilet-reminder-accent);
  font-size: 17px;
  font-weight: 950;
  white-space: normal;
}

.home-toilet-reminder .home-recommend-subtitle {
  font-weight: 700;
}

.home-toilet-reminder .home-course-cancel-btn {
  border-color: rgba(47, 128, 237, 0.32);
  background: rgba(47, 128, 237, 0.1);
  color: var(--toilet-reminder-accent);
}
.store-remark-card {
  width: 100%;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-2xl);
  padding: 16px;
  box-shadow: var(--hgu-shadow-card);
}
.store-remark-label {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text);
  font-weight: 700;
  margin-bottom: 12px;
}
.store-markdown-body {
  color: var(--subtext);
  font-size: 14px;
  line-height: 1.75;
  overflow-wrap: anywhere;
}
.store-detail-plain {
  width: 100%;
  max-width: 520px;
  padding: 4px 2px 24px;
}
.store-remark-drawer {
  padding-bottom: calc(24px + env(safe-area-inset-bottom));
}
.store-markdown-body p,
.store-markdown-body ul,
.store-markdown-body ol,
.store-markdown-body blockquote {
  margin: 0 0 12px;
}
.store-markdown-body p:last-child,
.store-markdown-body ul:last-child,
.store-markdown-body ol:last-child,
.store-markdown-body blockquote:last-child {
  margin-bottom: 0;
}
.store-markdown-body h3,
.store-markdown-body h4,
.store-markdown-body h5 {
  color: var(--text);
  line-height: 1.4;
  margin: 16px 0 8px;
}
.store-markdown-body ul,
.store-markdown-body ol {
  padding-left: 22px;
}
.store-markdown-body blockquote {
  padding: 8px 12px;
  border-left: 3px solid var(--text);
  background: var(--text-light);
  border-radius: var(--hgu-radius-md);
}
.store-markdown-body code {
  padding: 2px 5px;
  border-radius: 5px;
  background: var(--text-light);
  color: var(--text);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.store-markdown-body a {
  color: var(--text);
  text-decoration: underline;
}
.store-markdown-image {
  display: block;
  max-width: 100%;
  max-height: 320px;
  object-fit: contain;
  margin: 10px 0;
  border-radius: var(--hgu-radius-xl);
  border: 1px solid var(--hgu-border-soft);
  background: rgba(128, 128, 128, 0.08);
  cursor: zoom-in;
}

/* ================== 琛楁櫙鍏ㄦ櫙 ================== */
#panoBox {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: #000;
  display: none;
}
#panoViewer {
  position: absolute;
  inset: 0;
  cursor: grab;
}
#panoViewer:active { cursor: grabbing; }
#panoBackBtn {
  position: absolute;
  /* 站位高度与地图右上角的通知 / 图层按钮对齐：那边是 .map-top-actions 的 top。
     这里只对齐纵向位置，按钮自身的高度 / 内边距保持原样。 */
  top: calc(env(safe-area-inset-top, 0px) + 14px);
  left: 16px;
  z-index: 10001;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-xl);
  color: var(--text);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  backdrop-filter: blur(var(--hgu-blur-2xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-2xl));
  box-shadow: var(--hgu-shadow-card);
}
#panoBackBtn:active { transform: scale(0.95); }
.pano-text-bottom {
  position: absolute;
  bottom: 20px;
  left: 16px;
  z-index: 10001;
  text-align: left;
  pointer-events: none;
  user-select: none;
}
.pano-line {
  /* 与第一行「河地大几何地图 / 几何地大」同一个颜色：三行水印字色保持一致，
     品牌名那一行不再单独写色，直接继承这里。 */
  color: rgba(255,255,255,0.85);
  font-size: 12px;
  line-height: 1.6;
  font-weight: 400;
  text-shadow: 0 1px 3px rgba(0,0,0,0.6);
}
/* 水印第一行：网页图标 + 站名，与地图页水印同一套图标与文案
   （地图页是浅色底 + 深色字，街景是照片底，所以这里改成白字 + 深色投影） */
.pano-brand {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 4px;
}
.pano-brand img {
  width: 20px;
  height: 20px;
  border-radius: var(--hgu-radius-sm);
  flex-shrink: 0;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6));
}
.pano-brand-name {
  /* 颜色继承 .pano-line：三行水印字色永远一致 */
  font-size: 12px;
  font-weight: 800;
}
.pano-controls {
  position: absolute;
  bottom: 20px;
  right: 16px;
  z-index: 10001;
}
.pano-place-list {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 10002;
  display: flex;
  gap: 12px;
  padding: 16px;
  overflow-x: auto;
  background: var(--hgu-surface-glass);
  border-top: 1px solid var(--hgu-border-soft);
  backdrop-filter: blur(var(--hgu-blur-2xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-2xl));
  transform: translateY(100%);
  transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1);
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.pano-place-list::-webkit-scrollbar {
  display: none;
}
.pano-thumb {
  flex-shrink: 0;
  width: 120px;
  cursor: pointer;
  text-align: center;
}
.pano-thumb img {
  width: 120px;
  height: 80px;
  object-fit: cover;
  border-radius: var(--hgu-radius-lg);
  background: #333;
  border: 2px solid #fff;
  transition: border-color 0.2s;
}
.pano-thumb:hover img { border-color: #fff; }
.pano-thumb span {
  display: block;
  margin-top: 6px;
  font-size: 12px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

  html[data-theme="dark"] .vrstreetview-thumb { background: #3a3a3c; }
  html[data-theme="dark"] .pano-thumb img { background: #2c2c2e; }

/* ============================================
   瀛︽湡鍒囨崲妯悜婊氬姩鍒楄〃
   ============================================ */
.semester-scroll-list {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding: 4px 12px;
  margin: 0 -12px;
  touch-action: pan-x;
  overscroll-behavior-x: contain;
  scroll-padding: 0 12px;
}

.semester-scroll-list::-webkit-scrollbar {
  display: none;
}

.semester-chip {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 8px 14px;
  border-radius: var(--hgu-radius-3xl);
  border: 1.5px solid var(--subtext);
  background: var(--hgu-surface-glass);
  color: var(--subtext);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
  white-space: nowrap;
  scroll-snap-align: center;
  scroll-snap-stop: always;
  min-width: 80px;
  text-align: center;
  user-select: none;
  -webkit-user-select: none;
}

.semester-chip.active {
  background: var(--text);
  color: #fff;
  border-color: var(--text);
}

.semester-chip.disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.semester-chip:active:not(.disabled) {
  transform: scale(0.95);
}

.semester-chip .semester-label {
  font-size: 10px;
  opacity: 0.85;
  font-weight: 600;
  margin-bottom: 2px;
}

  html[data-theme="dark"] .semester-chip {
    background: rgba(255, 255, 255, 0.05);
  }
  html[data-theme="dark"] .semester-chip.active {
    background: var(--text);
    border-color: var(--text);
  }

/* ============================================
   棣栨鍚姩寮曞
   ============================================ */
#onboardingOverlay {
  position: fixed;
  inset: 0;
  z-index: 100000;
  display: none;
  background: var(--bg);
  overflow: hidden;
}

#onboardingOverlay.active { display: block; }

/* 全屏页面卡片容器 */
.onboarding-card {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  animation: onboardingPageFade 0.35s ease;
}

@keyframes onboardingPageFade {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* 高斯模糊运动圆形背景层（与「关于」页一致） */
.onboarding-glow-layer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

.onboarding-glow {
  position: absolute;
  border-radius: var(--hgu-radius-round);
  filter: blur(80px);
  opacity: 0.45;
  pointer-events: none;
  z-index: 0;
  transition: opacity .3s;
}

.onboarding-glow.green {
  width: 320px;
  height: 320px;
  background: #7cb342;
  top: -80px;
  right: -20px;
  animation: aboutFloatGreen 7s ease-in-out infinite;
}

.onboarding-glow.yellow {
  width: 260px;
  height: 260px;
  background: #fff59d;
  top: 10px;
  right: 15%;
  animation: aboutFloatYellow 9s ease-in-out infinite;
  animation-delay: -3s;
}

.onboarding-glow.blue {
  width: 280px;
  height: 280px;
  background: #f99090;
  top: -40px;
  right: 35%;
  animation: aboutFloatBlue 6s ease-in-out infinite;
  animation-delay: -2s;
}

.onboarding-nav {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  height: 58px;
  display: grid;
  grid-template-columns: 44px 1fr 44px;
  align-items: center;
  gap: 10px;
  padding: max(10px, env(safe-area-inset-top)) 14px 2px;
  box-sizing: border-box;
}

.onboarding-nav.is-single {
  display: none;
}

.onboarding-nav-btn {
  width: 38px;
  height: 38px;
  border-radius: var(--hgu-radius-round);
  border: 1px solid var(--hgu-border-soft);
  background: var(--hgu-surface-glass);
  color: var(--text);
  box-shadow: var(--hgu-shadow-card);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  backdrop-filter: blur(var(--hgu-blur-2xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-2xl));
}

.onboarding-nav-btn.is-hidden {
  visibility: hidden;
  pointer-events: none;
}

.onboarding-nav-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.onboarding-page-pill {
  justify-self: center;
  min-width: 78px;
  height: 34px;
  padding: 0 18px;
  border-radius: var(--hgu-radius-pill);
  border: 1px solid var(--hgu-border-soft);
  background: var(--hgu-surface-glass);
  color: var(--text);
  box-shadow: var(--hgu-shadow-card);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 800;
  backdrop-filter: blur(var(--hgu-blur-2xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-2xl));
}

.onboarding-content {
  position: relative;
  z-index: 1;
  height: 100%;
  padding: 72px 24px max(24px, env(safe-area-inset-bottom));
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
}

.onboarding-step {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.onboarding-logo {
  width: 92px;
  height: 92px;
  border-radius: var(--hgu-radius-4xl);
  object-fit: cover;
  box-shadow: 0 10px 28px rgba(0,0,0,.18);
  margin: 26px 0 20px;
}

.onboarding-title {
  color: var(--text);
  font-size: 27px;
  line-height: 1.3;
  font-weight: 900;
  margin: 0 0 18px;
  white-space: pre-line;
}

.onboarding-doc-title {
  color: var(--text);
  font-size: 22px;
  font-weight: 900;
  margin: 6px 0 14px;
}

.onboarding-doc-body {
  width: 100%;
  flex: 1;
  min-height: 0;
  padding: 14px;
  box-sizing: border-box;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-2xl);
  background: rgba(255,255,255,0.08);
  color: var(--subtext);
  overflow-y: auto;
  text-align: left;
  line-height: 1.7;
  font-size: 13px;
  -webkit-overflow-scrolling: touch;
}

.onboarding-doc-body p { margin: 0 0 12px; }
.onboarding-doc-body strong,
.onboarding-doc-body b,
.onboarding-doc-body h2,
.onboarding-doc-body h3,
.onboarding-doc-body h4 {
  color: var(--text);
}

.onboarding-primary-btn,
.onboarding-secondary-btn {
  width: 100%;
  height: 48px;
  min-height: 48px;
  margin-top: 0;
  border-radius: var(--hgu-radius-default);
  font: inherit;
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
}

.onboarding-primary-btn {
  margin-top: 14px;
  border: 1px solid var(--text);
  background: var(--text);
  color: #fff;
}

.onboarding-login-actions .onboarding-primary-btn,
.onboarding-login-actions .onboarding-secondary-btn {
  margin-top: 0;
}

.onboarding-secondary-btn {
  border: 1px solid var(--text);
  background: transparent;
  color: var(--text);
}

/* 第二页：登录引导 */
.onboarding-login-body {
  width: 100%;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.onboarding-login-icons {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 22px;
}

.onboarding-login-webicon,
.onboarding-login-hgulogo {
  width: 72px;
  height: 72px;
  border-radius: var(--hgu-radius-4xl);
  object-fit: cover;
  box-shadow: 0 10px 28px rgba(0,0,0,.16);
}

.onboarding-login-link-icon {
  font-size: 44px;
  color: var(--text);
  opacity: 0.85;
}

.onboarding-login-actions {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

/* ===== 旧域名迁移提示页（?migrated=1，见 life.js 的 renderOnboardingMigratedStep） ===== */
/* 结构：上半区（图标 + 两行「小灰标题 / 大标题」对）垂直居中占满，按钮钉在底部 */
.onboarding-migrated .onboarding-migrated-body {
  flex: 1 1 auto;
  width: 100%;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.onboarding-migrated-icon {
  width: 82px;
  height: 82px;
  border-radius: 22px;
  object-fit: cover;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .18);
  margin: 0 0 22px;
}

.onboarding-migrated-title {
  margin: 0 0 28px;
  color: var(--text);
  font-size: 18px;
  font-weight: 900;
  line-height: 1.4;
}

/* 小字灰标题（在线地图 / APP下载） */
.onboarding-migrated-label {
  margin: 0 0 6px;
  color: var(--subtext);
  font-size: 13px;
  font-weight: 600;
}

/* 大字域名 */
.onboarding-migrated-value {
  margin: 0 0 22px;
  color: var(--text);
  font-size: 26px;
  font-weight: 900;
  letter-spacing: .4px;
  line-height: 1.25;
  word-break: break-all;
}

.onboarding-migrated-hint {
  margin: 2px 0 24px;
  color: var(--subtext);
  font-size: 13px;
}

.onboarding-migrated .onboarding-primary-btn {
  flex: 0 0 auto;
  max-width: 420px;
}

  html[data-theme="dark"] .onboarding-nav-btn,
  html[data-theme="dark"] .onboarding-page-pill {
    background: rgba(28, 28, 31, 0.62);
    border-color: rgba(255, 255, 255, 0.16);
  }

.study-feature-action.is-disabled,
.study-feature-action:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
  filter: grayscale(0.15);
}

/* ===== Source: calendar.css ===== */
.calendar-subtitle {
  font-size: 14px;
  color: var(--subtext);
  text-align: center;
  margin-bottom: 16px;
  opacity: 0.8;
}

#calendar-page .sub-page-back {
  color: var(--study-cyan);
  border-color: rgba(var(--study-cyan-rgb), 0.4);
}

#calendar-page .sub-page-title {
  color: var(--study-cyan);
}

/* --- 校历图片容器 --- */
.calendar-img-wrap {
  position: relative;
  width: 100%;
  max-width: 480px;
  border-radius: var(--hgu-radius-xl);
  overflow: hidden;
  border: 2px solid var(--study-cyan);
  background: var(--hgu-surface-glass);
  margin-bottom: 20px;
  cursor: zoom-in;
  transition: transform 0.2s ease;
}

.calendar-zoom-hint {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 2;
  min-height: 26px;
  padding: 0 8px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 1px solid rgba(var(--study-cyan-rgb), 0.42);
  border-radius: var(--hgu-radius-md);
  background: rgba(255, 255, 255, 0.88);
  color: var(--study-cyan);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  font-size: 10px;
  font-weight: 700;
  pointer-events: none;
}

.calendar-img-wrap:active {
  transform: scale(0.98);
}

#calendarImg {
  width: 100%;
  display: block;
  border-radius: var(--hgu-radius-xl);
  pointer-events: none;
}

/* --- 日程列表 --- */
.calendar-event-list {
  width: 100%;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 20px;
}

/* 大卡片容器 */
.cal-section-card {
  width: 100%;
  background: var(--hgu-surface-glass);
  border: 1.5px solid var(--study-cyan);
  border-radius: var(--hgu-radius-2xl);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  box-shadow: var(--hgu-shadow-card);
  position: relative;
  overflow: hidden;
}

/* 已完成卡片 */
.cal-section-card.done {
  opacity: 0.9;
  border: 1.5px solid var(--study-cyan);
}

/* 区域标题 */
.cal-section-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--study-cyan);
  margin: 0 0 2px 4px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.cal-section-title::before {
  content: '';
  display: inline-block;
  width: 4px;
  height: 14px;
  background: var(--study-cyan);
  border-radius: 2px;
}

.cal-section-title.done {
  color: var(--study-cyan);
  opacity: 0.8;
}

.cal-section-title.done::before {
  background: var(--study-cyan);
}

/* 内容区 */
.cal-section-content {
  display: flex;
  flex-direction: column;
  gap: 5px;
  position: relative;
  z-index: 1;
}

/* --- 事件卡片 --- */
.cal-event-card {
  position: relative;
  display: flex;
  align-items: stretch;
  background: rgba(255, 255, 255, 0.4);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-xl);
  overflow: hidden;
  transition: all 0.2s ease;
  cursor: default;
}

.cal-event-card.done {
  opacity: 0.5;
  filter: grayscale(0.6);
}

/* 左侧竖条 */
.cal-event-bar {
  position: absolute;
  left: 8px;
  top: 12.5%;
  width: 3px;
  height: 75%;
  border-radius: 2px;
  background: var(--event-color);
}

/* 主内容区 */
.cal-event-main {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 7px 10px 7px 19px;
  gap: 6px;
}

.cal-event-left {
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1;
  min-width: 0;
}

/* 左侧文本颜色跟随右侧标签颜色 */
.cal-event-date {
  font-size: 10px;
  color: var(--subtext);
  opacity: 0.85;
  font-weight: 500;
}

.cal-event-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--event-color);
  line-height: 1.25;
}

.cal-event-card.done .cal-event-date,
.cal-event-card.done .cal-event-title {
  opacity: 0.6;
}

/* 标签 */
.cal-event-tag {
  font-size: 10px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 7px;
  white-space: nowrap;
  flex-shrink: 0;
  margin-left: 6px;
}

/* --- 图片缩放遮罩 --- */
.cal-zoom-overlay {
  position: fixed;
  inset: 0;
  z-index: 100000;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
  touch-action: none;
}

.cal-zoom-overlay.active {
  opacity: 1;
  pointer-events: auto;
}

.cal-zoom-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.88);
  backdrop-filter: blur(var(--hgu-blur-panel));
  -webkit-backdrop-filter: blur(var(--hgu-blur-panel));
}

.cal-zoom-viewport {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.cal-zoom-img {
  position: absolute;
  left: 50%;
  top: 50%;
  max-width: 92vw;
  max-height: 85vh;
  object-fit: contain;
  border-radius: var(--hgu-radius-xs);
  user-select: none;
  -webkit-user-drag: none;
  transform: translate(-50%, -50%) translate(0px, 0px) scale(1);
  will-change: transform;
}

/* 大图上的标签层（线下招领处）：位置/宽高由 core.js 同步成图片的实际显示框，
   transform 与图片完全一致 —— 标签因此永远贴着图片上的同一个点；
   标签自身再按 var(--cal-zoom-inv) 反向缩放，所以放大/缩小图片时
   标签在屏幕上看起来大小不变（圆点同理）。 */
.cal-zoom-tags {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) translate(0px, 0px) scale(1);
  pointer-events: none;
  will-change: transform;
  z-index: 1;
  line-height: normal;
}

.cal-zoom-tag {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 60%;
  /* 锚点 = 圆点中心：origin 落在圆点中心，缩放时圆点不动；再平移一个半径把圆点对到坐标点 */
  transform-origin: 3.5px center;
  transform: translate(-3.5px, -50%) scale(var(--cal-zoom-inv, 1));
  will-change: transform;
}

/* 靠右的标签翻到圆点左侧（与前台卡片同一阈值 0.5），避免胶囊被图片右边缘裁掉 */
.cal-zoom-tag.is-flip {
  flex-direction: row-reverse;
  transform-origin: calc(100% - 3.5px) center;
  transform: translate(calc(-100% + 3.5px), -50%) scale(var(--cal-zoom-inv, 1));
}

/* 只有动画式缩放（双击 / 回弹）才给标签补过渡，捏合跟随手指时不要 */
.cal-zoom-tags.is-animating .cal-zoom-tag {
  transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

/* 视觉与前台卡片 .lf-loc-tag 保持一致：白圆点（在胶囊外面）+ 黑色半透明胶囊 + 白字 */
.cal-zoom-tag-dot {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 1.5px rgba(0, 0, 0, 0.55), 0 1px 3px rgba(0, 0, 0, 0.35);
}

.cal-zoom-tag-body {
  display: block;
  min-width: 0;
  max-width: 100%;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.62);
  color: #fff;
  font-size: 12px;
  line-height: 1.25;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.28);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.cal-zoom-hint {
  position: absolute;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  color: rgba(255, 255, 255, 0.6);
  font-size: 12px;
  z-index: 2;
  pointer-events: none;
  white-space: nowrap;
  background: rgba(0, 0, 0, 0.3);
  padding: 6px 14px;
  border-radius: var(--hgu-radius-3xl);
  backdrop-filter: blur(var(--hgu-blur-sm));
}

/* 暗色模式 */

  html[data-theme="dark"] .calendar-zoom-hint {
    background: rgba(22, 35, 40, 0.88);
  }

  html[data-theme="dark"] #calendar-page .sub-page-back {
    color: var(--study-cyan);
  }

  html[data-theme="dark"] #calendar-page .sub-page-title {
    color: var(--study-cyan);
  }

  html[data-theme="dark"] .cal-section-title,
  html[data-theme="dark"] .cal-section-title::before {
    color: var(--study-cyan);
  }

  html[data-theme="dark"] .cal-section-title.done,
  html[data-theme="dark"] .cal-section-title.done::before {
    color: var(--study-cyan);
  }

  html[data-theme="dark"] .calendar-img-wrap {
    border-color: var(--study-cyan);
  }

  html[data-theme="dark"] .cal-section-card {
    border-color: var(--study-cyan);
  }

  html[data-theme="dark"] .cal-section-card.done {
    border-color: var(--study-cyan);
  }

  html[data-theme="dark"] .cal-event-card {
    background: rgba(0, 0, 0, 0.2);
  }

  html[data-theme="dark"] .cal-event-card.done {
    opacity: 0.35;
  }

/* ===== Source: station.css ===== */
#packageStation-page {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
}

.package-station-content,
.station-drawer-body {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.package-station-content {
  max-width: 360px;
  margin: 0 auto;
  padding-bottom: 16px;
}

.station-drawer {
  max-width: 430px;
  border: 1.5px solid rgba(47, 124, 255, 0.48);
  border-bottom: none;
}

/* 顶部只留标题 + 关闭：取件/寄件切换与分割线都去掉了 */
.station-drawer-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 16px 6px;
}

.station-drawer-title {
  min-width: 0;
  color: #2F7CFF;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: 0.2px;
}

.station-drawer-close {
  appearance: none;
  -webkit-appearance: none;
  width: 34px;
  height: 34px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-lg);
  background: var(--hgu-surface-glass);
  color: #2F7CFF;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  cursor: pointer;
  flex-shrink: 0;
}

.station-drawer-tabs {
  display: flex;
  gap: 8px;
  flex: 1;
  min-width: 0;
}

.station-drawer-tabs button {
  appearance: none;
  -webkit-appearance: none;
  flex: 1;
  height: 34px;
  border: 1px solid rgba(47, 124, 255, 0.45);
  border-radius: var(--hgu-radius-lg);
  background: rgba(47, 124, 255, 0.06);
  color: #2F7CFF;
  font-size: 13px;
  font-weight: 800;
  font-family: inherit;
  cursor: pointer;
}

.station-drawer-tabs button.active {
  border-color: #1F5FD1;
  background: #2F7CFF;
  color: #fff;
  box-shadow: 0 4px 12px rgba(47, 124, 255, 0.28);
}

.station-drawer-body {
  padding: 12px 16px 28px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.station-container {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  width: 100%;
  max-width: 360px;
  min-height: 78px;
  border: 1.5px solid var(--station-color, #F08400);
  border-radius: var(--hgu-radius-default);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  color: inherit;
  padding: 12px 10px 10px;
  margin: 0 auto;
  display: block;
  text-align: left;
  font-family: inherit;
  cursor: pointer;
  backdrop-filter: blur(var(--hgu-blur-xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-xl));
}

.station-container.is-disabled {
  opacity: 0.58;
}

.station-header {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 52px;
}

/* 驿站图标：正方形 + 透明背景（原来是有底色的长方形） */
.station-icon-wrap {
  width: 44px;
  height: 44px;
  border-radius: var(--hgu-radius-lg);
  background: transparent;
  overflow: hidden;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

.station-icon-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: var(--hgu-radius-md);
  display: block;
}

.station-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.station-title-line {
  display: flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
  padding-right: 22px;
}

.station-name {
  min-width: 0;
  color: var(--station-color, #F08400);
  font-size: 14px;
  font-weight: 900;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.station-hours {
  color: var(--subtext);
  font-size: 11px;
  font-weight: 600;
  flex-shrink: 0;
  opacity: 0.82;
}

.station-status-badge {
  position: absolute;
  top: 0;
  left: 0;
  padding: 4px 10px;
  border-radius: var(--hgu-radius-corner-badge);
  background: var(--station-color, #F08400);
  color: #fff;
  font-size: 10px;
  font-weight: 800;
  line-height: 1.2;
  pointer-events: none;
}

.station-status-badge.status-soon {
  background: #bdbdbd !important;
}

.station-status-badge.status-closed {
  background: #9e9e9e !important;
}

/* 右上角原来是「点击跳转」文字 + 外链图标，改成上下居中的箭头
   （样式与「今天吃什么 / 社团与活动」卡片右侧箭头一致） */
.station-head-arrow {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--station-color, #F08400);
  font-size: 15px;
  line-height: 1;
  opacity: 0.85;
  pointer-events: none;
}

.station-express-section {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  width: 100%;
}

.station-express-icons {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.station-express-icon {
  width: 20px;
  height: 20px;
  border-radius: var(--hgu-radius-round);
  object-fit: cover;
  border: 2px solid var(--bg, #fff);
  box-shadow: 0 1px 3px rgba(0,0,0,0.16);
  flex-shrink: 0;
}

.station-express-icon:not(:first-child) {
  margin-left: -8px;
}

.station-express-text {
  min-width: 0;
  flex: 1;
  color: var(--station-color, #F08400);
  font-size: 12px;
  font-weight: 700;
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  word-break: break-word;
  line-height: 1.35;
}

.station-empty {
  width: 100%;
  padding: 34px 12px;
  text-align: center;
  color: var(--subtext);
  font-size: 13px;
}

#appJumpModal .modal-card {
  max-width: 320px;
  text-align: center;
  padding: 28px 24px;
}

#appJumpModal img {
  width: 140px;
  height: auto;
  margin: 0 auto 16px;
  display: block;
  border-radius: var(--hgu-radius-xl);
  pointer-events: none;
}

#appJumpModalText {
  font-size: 15px;
  color: var(--text);
  font-weight: 600;
  line-height: 1.6;
}

  html[data-theme="dark"] .station-status-badge.status-soon {
    background: rgba(255,255,255,0.4) !important;
  }

  html[data-theme="dark"] .station-status-badge.status-closed {
    background: rgba(255,255,255,0.25) !important;
  }

/* ===== Source: activities.css ===== */
/* 社团与活动页的品牌色。
   放在 :root 而不是 #activities-page 上：社团详情页（#club-detail-page）是它的**兄弟节点**，
   不是子节点，挂在 #activities-page 上的变量与暗色重定义在详情页里全都取不到
   （详情页会 fallback 成继承色，暗色下更淡，对比度不够）。 */
:root {
  --club-purple: #7f4dae;
  --club-magenta: #c54fae;
  --club-pink: #f8dbe9;
  --club-pink-strong: #efa9ca;
}

#activities-page {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
}

.activities-content {
  width: 100%;
  max-width: 600px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.activities-settings {
  margin: 0 auto;
}

#activities-page .activities-settings[hidden] {
  display: none !important;
}

/* 活动页标记设置卡片：跟随社团主题配色 */
#activities-page .activities-settings {
  max-width: 600px;
  border-color: rgba(197, 79, 174, 0.4);
  /* 与下方三个分类卡片同一种背景（原来是半透明白色，和下面的卡片不一致） */
  background: var(--hgu-surface-glass);
}

#activities-page .options-map-setting-label {
  color: var(--club-purple);
}

#activities-page .options-map-setting-label i {
  color: var(--club-magenta);
}

#activities-page .options-map-settings-card .store-map-toggle-btn.active,
#activities-page .options-notification-settings-card .store-map-toggle-btn.active {
  background: var(--club-magenta);
}

.community-view-tabs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  width: 100%;
  min-height: 42px;
  padding: 3px;
  border: 1px solid rgba(197, 79, 174, 0.25);
  border-radius: var(--hgu-radius-md);
  /* 与下方三个分类卡片同一种背景（原来是半透明白色，和下面的卡片不一致） */
  background: var(--hgu-surface-glass);
}

.community-view-tab {
  min-width: 0;
  border: 0;
  border-radius: var(--hgu-radius-sm);
  background: transparent;
  color: var(--subtext);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, box-shadow 0.2s;
}

.community-view-tab i { margin-right: 6px; }
.community-view-tab.active {
  background: rgba(127, 77, 174, 0.16);
  box-shadow: 0 1px 6px rgba(127, 77, 174, 0.14);
}
#activitiesTab.active { color: var(--club-purple); }
#clubsTab.active { color: var(--club-magenta); }

.community-view-panel[hidden] { display: none !important; }

/* ============================================================
   社团列表：双列不规则瀑布流图文贴（与食堂窗口列表同一套做法）
   两个独立列容器（.club-grid-col），life.js 把卡片按「先横行」轮流放进左右两列：
   1、2 并排，3、4 并排…… 不用 CSS 多列布局（先纵后横，序号会乱），也不用 grid
   （同一行等行高，矮卡片下面必然留大小不一的空档）。
   卡片形态按数据分三种：
     · 有宣传图        → 上面铺图（比例随图变，这是"不规则"的来源）
     · 只有文案        → 上面的图区整个让给文案
     · 图与文案都没有  → 只留一小块「图标 + 名称」，并排到最后
   ============================================================ */
.clubs-list { width: 100%; display: block; }
.club-grid {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
}
.club-grid-col {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* 加载中 / 空状态要占满整行，否则会被挤成半宽 */
.club-grid > .search-loading,
.club-grid > .search-empty-state {
  flex: 1 1 100%;
}

.club-card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  width: 100%;
  border: 1px solid rgba(239, 169, 202, 0.58);
  border-radius: var(--hgu-radius-xl);
  background: var(--hgu-surface-glass);
  box-shadow: 0 2px 9px rgba(127, 77, 174, 0.07);
  cursor: pointer;
  transition: transform 0.16s ease, box-shadow 0.18s ease, border-color 0.2s ease;
}
.club-card:active {
  transform: scale(0.975);
  box-shadow: var(--hgu-shadow-raised);
}
/* 有宣传内容的卡片边框更实一点，一眼能看出「有内容可看」 */
.club-card.is-promoted {
  border-color: rgba(197, 79, 174, 0.72);
  box-shadow: 0 4px 14px rgba(197, 79, 174, 0.17);
}

/* 上面的部分：有图铺图（保留原始比例），没图就放文案，两者都没有则整块不出现 */
.club-card-media {
  position: relative;
  width: 100%;
  overflow: hidden;
  background: rgba(248, 219, 233, 0.28);
}
.club-card-media img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
}
/* 没有宣传图时，上面的区域直接让给文案（多显示几行，充分利用这块空间） */
.club-card-media.is-text {
  padding: 11px 11px 2px;
}
.club-card-media.is-text .club-card-excerpt {
  -webkit-line-clamp: 8;
}
.club-card-excerpt {
  margin: 0;
  color: var(--subtext);
  font-size: 12.5px;
  line-height: 1.6;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* 图 + 文案都有：图下面紧跟一小段文案（压在图上会看不清，所以单独占一行并留白） */
.club-card-excerpt.is-under-image {
  padding: 8px 10px 0;
  -webkit-line-clamp: 2;
  font-size: 12px;
  line-height: 1.55;
}

.club-card-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 9px 10px 10px;
}
/* 图与文案都没有：只留一小块「图标 + 名称」 */
.club-card.is-minimal .club-card-body {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  padding: 9px 10px;
}
.club-card-footer {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.club-logo {
  width: 30px;
  height: 30px;
  flex: 0 0 30px;
  object-fit: cover;
  border: 1px solid rgba(239, 169, 202, 0.62);
  border-radius: var(--hgu-radius-round);
  background: rgba(248, 219, 233, 0.5);
}
.club-card.is-minimal .club-logo {
  width: 24px;
  height: 24px;
  flex-basis: 24px;
}
.club-name {
  flex: 1;
  min-width: 0;
  color: var(--club-purple);
  font-size: 13px;
  font-weight: 650;
  line-height: 1.35;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.club-card.is-promoted .club-name { color: var(--club-magenta); }
.club-card.is-minimal .club-name { -webkit-line-clamp: 1; font-size: 12.5px; }

/* 点赞：爱心 + 数字；未登录也能点（点了会提示登录） */
.club-like-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 26px;
  padding: 0 8px;
  border: 1px solid rgba(239, 169, 202, 0.62);
  border-radius: var(--hgu-radius-pill);
  background: rgba(248, 219, 233, 0.4);
  color: var(--club-magenta);
  font-family: inherit;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.14s ease, background 0.2s ease, color 0.2s ease;
}
.club-like-btn i { font-size: 12px; }
.club-like-btn:active { transform: scale(0.92); }
.club-like-btn.is-liked {
  background: var(--club-magenta);
  border-color: var(--club-magenta);
  color: #fff;
}
.club-like-btn.is-busy { opacity: 0.6; pointer-events: none; }

/* 详情子页：标题（图标 + 社团名）→ 文案 → 宣传图横滑 */
.club-detail-head {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.club-detail-head .club-logo {
  width: 40px;
  height: 40px;
  flex-basis: 40px;
}
.club-detail-name {
  color: var(--club-magenta);
  font-size: 17px;
  font-weight: 750;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
.club-detail-content {
  padding: 4px 0 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.club-detail-text {
  margin: 0;
  padding: 12px;
  border: 1px solid rgba(239, 169, 202, 0.44);
  border-radius: var(--hgu-radius-xl);
  background: var(--hgu-surface-glass);
  color: var(--subtext);
  font-size: 14px;
  line-height: 1.8;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
/* 宣传图横向排列、可左右滑动（多于一张时才需要滑） */
.club-detail-gallery {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 4px;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.club-detail-gallery::-webkit-scrollbar { display: none; }
.club-detail-gallery img {
  flex: 0 0 auto;
  width: min(72vw, 280px);
  height: auto;
  max-height: 380px;
  object-fit: cover;
  border: 1px solid rgba(239, 169, 202, 0.44);
  border-radius: var(--hgu-radius-xl);
  background: rgba(248, 219, 233, 0.28);
  cursor: zoom-in;
  scroll-snap-align: start;
}
/* 只有一张时铺满整行，不留下右侧空白 */
.club-detail-gallery.is-single img {
  width: 100%;
  max-height: none;
  object-fit: contain;
}
.club-detail-empty {
  padding: 26px 12px;
  text-align: center;
  color: var(--subtext);
  font-size: 13px;
}

.retry-loading { cursor: pointer; }

@media (max-width: 420px) {
  .club-logo { width: 28px; height: 28px; flex-basis: 28px; }
  .club-name { font-size: 12.5px; }
  .club-detail-gallery img { width: min(78vw, 240px); }
  .club-like-btn { padding: 0 6px; font-size: 10px; }
}

.activities-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 100%;
}

/* --- 活动列表：三块（进行中 / 规划中 / 已结束） ---
   每块一个标题，块内每个活动一张占满整行的卡片；
   三种状态的边框色由 JS 内联写进 style（沿用原来的紫 / 品红 / 粉配色）。 */
.activity-list-group {
  width: 100%;
  border: 1px solid;
  border-radius: var(--hgu-radius-2xl);
  padding: 14px;
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.activity-list-title {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 14px;
  font-weight: 700;
}

.activity-list-title i {
  font-size: 13px;
}

.activity-list-title span {
  margin-left: auto;
  font-size: 12px;
  font-weight: 600;
  opacity: 0.7;
}

.activity-list-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* 一张活动卡片：占满整行。
   注意：**卡片本身不加边框** —— 边框只加在三个分类（.activity-list-group）外层，
   用一条边框把"这一组"框起来，组内每张卡片靠背景色区分。 */
.activity-list-card {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  border: 0;
  border-radius: var(--hgu-radius-lg);
  background: var(--hgu-surface);
  transition: transform var(--motion-fast) var(--ease-standard),
              background-color var(--motion-base) ease,
              box-shadow var(--motion-base) ease;
}

.activity-list-card.is-clickable {
  cursor: pointer;
}

.activity-list-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

/* 活动名用状态色（三种颜色沿用原来的规则） */
.activity-list-card.is-ongoing .activity-list-name { color: #7F4DAE; }
.activity-list-card.is-upcoming .activity-list-name { color: #C55DB5; }
.activity-list-card.is-ended .activity-list-name { color: #FDBDBD; }

.activity-list-name {
  font-size: 14.5px;
  font-weight: 700;
  line-height: 1.35;
  overflow-wrap: anywhere;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}

/* 「可得学分x.xx」：跟在活动名后面，只在填了学分时出现 */
.activity-list-credit {
  flex-shrink: 0;
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(127, 77, 174, 0.12);
  color: #7F4DAE;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.6;
  white-space: nowrap;
}

.activity-list-card.is-upcoming .activity-list-credit {
  background: rgba(197, 93, 181, 0.12);
  color: #C55DB5;
}

.activity-list-card.is-ended .activity-list-credit {
  background: rgba(197, 93, 181, 0.08);
  color: #B4789F;
}

/* 组织方就是该社团负责人时：把通用图标换成社团的小圆形图标 */
.activity-list-organizer-logo {
  width: 15px;
  height: 15px;
  flex: 0 0 15px;
  border-radius: 50%;
  object-fit: cover;
  background: rgba(0, 0, 0, 0.05);
}

.activity-list-meta-item.is-club {
  gap: 5px;
}

.activity-list-time,
.activity-list-meta-item {
  color: var(--subtext);
}

/* 时间/地点前面的图标与文字之间要留一点空隙（图标紧贴文字会显得很挤） */
.activity-list-time i,
.activity-list-meta-item i {
  margin-right: 5px;
}

.activity-list-time {
  font-size: 12px;
  opacity: 0.9;
}

.activity-list-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 10px;
  font-size: 12px;
  opacity: 0.85;
}

.activity-list-meta-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
}

.activity-list-meta-item i {
  font-size: 11px;
  width: 13px;
  text-align: center;
  opacity: 0.8;
}

/* 右侧箭头：只有填了活动链接才出现 */
.activity-list-arrow {
  flex-shrink: 0;
  font-size: 13px;
  opacity: 0.55;
  color: var(--subtext);
}

.activity-list-card.is-clickable:active {
  transform: scale(0.99);
}

@media (hover: hover) and (pointer: fine) {
  .activity-list-card.is-clickable:hover {
    transform: translateY(-1px);
    box-shadow: var(--hgu-shadow-card);
  }
}

html[data-theme="dark"] .activity-list-card {
  background: rgba(255, 255, 255, 0.05);
}

html[data-theme="dark"] .activity-list-card.is-ongoing .activity-list-name { color: #d7b8ff; }
html[data-theme="dark"] .activity-list-card.is-upcoming .activity-list-name { color: #ffaddf; }
html[data-theme="dark"] .activity-list-card.is-ended .activity-list-name { color: #f0a9b8; }

/* --- 社团页顶部标题与返回按钮颜色覆盖 --- */
#activities-page .sub-page-title {
  color: #7F4DAE;
}
#activities-page .sub-page-back {
  color: #7F4DAE;
}

  html[data-theme="dark"] #activities-page {
    --club-purple: #d7b8ff;
    --club-magenta: #ffaddf;
    --club-pink: rgba(255, 173, 223, 0.14);
    --club-pink-strong: rgba(255, 173, 223, 0.34);
  }

  /* 注意：这里**不要**给 .community-view-tabs / .activities-settings 的 background 写暗色覆盖。
     两者的浅色背景是 var(--hgu-surface-glass) → var(--glass)，
     而 --glass 在暗色主题下已经被重定义为 rgba(0,0,0,.25)；
     再写死一个暗色值会让这三个卡片与下方 .activity-list-group（同样用 --glass）
     的背景对不上 —— 之前"深色模式没变化"就是这个原因。 */
  html[data-theme="dark"] #activities-page .community-view-tabs {
    border-color: rgba(255, 173, 223, 0.28);
  }

  html[data-theme="dark"] #activities-page .community-view-tab {
    color: rgba(255, 255, 255, 0.58);
  }

  html[data-theme="dark"] #activities-page .community-view-tab.active,
  html[data-theme="dark"] #activities-page .club-card,
  html[data-theme="dark"] #activities-page .club-card.is-promoted,
{
    background: rgba(22, 18, 30, 0.76);
  }

  html[data-theme="dark"] #activities-page .community-view-tab.active {
    box-shadow: 0 1px 8px rgba(215, 184, 255, 0.18);
  }

  html[data-theme="dark"] #activities-page #activitiesTab.active,
  html[data-theme="dark"] #activities-page #clubsTab.active {
    background: rgba(215, 184, 255, 0.18);
  }

  html[data-theme="dark"] #activities-page .club-logo {
    background: rgba(255, 255, 255, 0.08);
  }

  /* 同上：不覆盖 background，交给 --glass 自己按主题切换 */
  html[data-theme="dark"] #activities-page .activities-settings {
    border-color: rgba(255, 173, 223, 0.3);
  }

  html[data-theme="dark"] #activities-page .options-map-setting-label {
    color: var(--club-purple);
  }

  html[data-theme="dark"] #activities-page .options-map-setting-label i {
    color: var(--club-magenta);
  }

  html[data-theme="dark"] #activities-page .activities-settings .store-map-toggle-btn {
    background: rgba(255, 255, 255, 0.18);
  }

  html[data-theme="dark"] #activities-page .activities-settings .store-map-toggle-btn.active {
    background: var(--club-magenta);
  }

  html[data-theme="dark"] #activities-page .club-card-media {
    background: rgba(255, 173, 223, 0.12);
  }

  html[data-theme="dark"] #activities-page .club-card-excerpt {
    color: rgba(255, 255, 255, 0.72);
  }

  html[data-theme="dark"] #activities-page .club-like-btn {
    border-color: rgba(255, 173, 223, 0.42);
    background: rgba(197, 79, 174, 0.24);
    color: #ffd7ef;
  }

  html[data-theme="dark"] #activities-page .club-like-btn.is-liked {
    background: var(--club-magenta);
    border-color: var(--club-magenta);
    color: #2a1030;
  }

  html[data-theme="dark"] #activities-page .club-detail-text,
  html[data-theme="dark"] #activities-page .club-detail-gallery img {
    border-color: rgba(255, 173, 223, 0.26);
    background: rgba(255, 255, 255, 0.08);
  }

  html[data-theme="dark"] #activities-page .section-header {
    border-bottom-color: rgba(255, 255, 255, 0.12);
  }

/* 社团标签布局 */
.club-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.club-tags {
  margin-top: 6px;
}

/* ===== Source: score-query.css ===== */
.score-content {
  width: 100%;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* 顶部统计：3 列均分 */
.score-stats-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 4px;
}

/* 统计卡片统一样式 */
.score-stat-card {
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  padding: 14px 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--hgu-shadow-card);
}

.score-stat-card .stat-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.score-stat-card .stat-inner > i {
  font-size: 20px;
  color: var(--text);
  opacity: 0.75;
}

.score-stat-card .stat-info {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.score-stat-card .stat-label {
  font-size: 11px;
  color: var(--subtext);
  opacity: 0.9;
}

.score-stat-card .stat-value {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* 彻底隐藏顶部警告 */
.score-warning-banner {
  display: none !important;
}

.score-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.score-section-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
  padding-left: 4px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.score-section-title::before {
  content: '';
  display: inline-block;
  width: 4px;
  height: 14px;
  background: var(--text);
  border-radius: 2px;
}

/* 学期卡片：边框 + 间距 */
.score-semester-card {
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  overflow: hidden;
  box-shadow: var(--hgu-shadow-card);
  margin-bottom: 12px;
}

.score-semester-card:last-child {
  margin-bottom: 0;
}

.score-semester-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  cursor: pointer;
  transition: background 0.2s;
  gap: 12px;
}

.score-semester-header:active {
  background: rgba(128, 128, 128, 0.08);
}

.score-semester-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.3;
}

.score-semester-meta {
  font-size: 12px;
  color: var(--subtext);
  margin-top: 2px;
}

.score-semester-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

.score-semester-gpa {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  background: var(--text-light);
  padding: 4px 10px;
  border-radius: var(--hgu-radius-lg);
  white-space: nowrap;
}

.score-semester-arrow {
  font-size: 14px;
  color: var(--subtext);
  transition: transform 0.3s;
}

.score-semester-card.expanded .score-semester-arrow {
  transform: rotate(180deg);
}

.score-course-list {
  display: none;
  flex-direction: column;
  border-top: 1px solid var(--hgu-border-soft);
}

.score-semester-card.expanded .score-course-list {
  display: flex;
}

.score-course-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  gap: 12px;
  border-bottom: 1px solid var(--hgu-border-soft);
}

.score-course-item.has-detail { cursor: pointer; }
.score-course-item.has-detail:active { opacity: .72; }
.score-detail-chevron { color: var(--subtext); font-size: 12px; margin-left: 4px; flex: 0 0 auto; }
.score-detail-overlay .score-detail-drawer {
  --text: var(--study-cyan);
  --color-blue: var(--study-cyan);
  padding-bottom: max(24px, env(safe-area-inset-bottom));
  border: 1.5px solid rgba(var(--study-cyan-rgb), 0.55);
}
.score-detail-overlay .secondary-drawer-handle { background: var(--study-cyan); }
.score-detail-header > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.score-detail-header strong { color: var(--study-cyan); font-size: 17px; }
.score-detail-header small { color: var(--subtext); font-size: 12px; }
.score-detail-header .modal-close { color: var(--study-cyan); }
.score-detail-summary { display: flex; justify-content: space-between; gap: 12px; padding: 10px 12px; margin: 8px 0; border: 1px solid rgba(var(--study-cyan-rgb), 0.38); border-radius: var(--hgu-radius-md); background: rgba(var(--study-cyan-rgb), 0.08); color: var(--study-cyan); font-size: 12px; }
.score-detail-list { border-top: 1px solid rgba(var(--study-cyan-rgb), 0.25); }
.score-detail-row { min-height: 58px; padding: 10px 4px; border-bottom: 1px solid rgba(var(--study-cyan-rgb), 0.2); display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.score-detail-row > div { display: flex; flex-direction: column; gap: 3px; }
.score-detail-row > div:last-child { text-align: right; }
.score-detail-row strong { color: var(--study-cyan); font-size: 14px; }
.score-detail-row span { color: var(--subtext); font-size: 12px; }
.score-detail-loading { min-height: 150px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; color: var(--subtext); font-size: 14px; text-align: center; }
.score-detail-loading i { color: var(--study-cyan); font-size: 24px; }
.score-detail-loading.is-error i { color: #ff4757; }

.score-course-item:last-child {
  border-bottom: none;
}

.score-course-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* 课程名颜色与成绩数字相同 */
.score-course-name {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  word-break: break-word;
}

/* 曾不及格删除线 */
.score-course-name.strikethrough,
.score-score-value.strikethrough {
  text-decoration: line-through;
  opacity: 0.75;
}

.score-course-tags {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.score-tag {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: var(--hgu-radius-sm);
  font-weight: 500;
  line-height: 1.4;
}

.score-tag.required { background: rgba(74, 124, 89, 0.15); color: var(--text); }
.score-tag.elective { background: rgba(255, 152, 0, 0.15); color: #ff9800; }
.score-tag.optional { background: rgba(var(--study-cyan-rgb), 0.15); color: var(--study-cyan); }
.score-tag.makeup { background: rgba(255, 71, 87, 0.15); color: #ff4757; }
.score-tag.retake { background: rgba(158, 158, 158, 0.15); color: #9e9e9e; }

.score-course-score {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  flex-shrink: 0;
}

/* 成绩颜色分级：越高越绿，越低越黄和红 */
.score-score-value {
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

.score-score-value.score-excellent { color: #4caf50; }
.score-score-value.score-good { color: #8bc34a; }
.score-score-value.score-pass { color: #ffc107; }
.score-score-value.score-weak { color: #ff9800; }
.score-score-value.score-fail { color: #ff4757; }

/* 课程名与成绩同色 */
.score-course-name.score-excellent { color: #4caf50; }
.score-course-name.score-good { color: #8bc34a; }
.score-course-name.score-pass { color: #ffc107; }
.score-course-name.score-weak { color: #ff9800; }
.score-course-name.score-fail { color: #ff4757; }

.score-score-gp {
  font-size: 11px;
  color: var(--subtext);
  white-space: nowrap;
}

.score-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  text-align: center;
  color: var(--subtext);
}

.score-empty-state i {
  font-size: 48px;
  margin-bottom: 16px;
  opacity: 0.3;
}

/* 本学期成绩列表边框统一 */
#scoreThisTermList {
  border: 1px solid var(--text) !important;
}

/* 暗色模式微调 */

  html[data-theme="dark"] .score-score-value.score-excellent { color: #81c784; }
  html[data-theme="dark"] .score-score-value.score-good { color: #aed581; }
  html[data-theme="dark"] .score-score-value.score-pass { color: #ffd54f; }
  html[data-theme="dark"] .score-score-value.score-weak { color: #ffb74d; }
  html[data-theme="dark"] .score-score-value.score-fail { color: #ff5252; }

  html[data-theme="dark"] .score-course-name.score-excellent { color: #81c784; }
  html[data-theme="dark"] .score-course-name.score-good { color: #aed581; }
  html[data-theme="dark"] .score-course-name.score-pass { color: #ffd54f; }
  html[data-theme="dark"] .score-course-name.score-weak { color: #ffb74d; }
  html[data-theme="dark"] .score-course-name.score-fail { color: #ff5252; }

  html[data-theme="dark"] .score-tag.required { background: rgba(168, 224, 99, 0.15); color: var(--text); }
  
  html[data-theme="dark"] .score-stat-card,
  html[data-theme="dark"] .score-semester-card {
    border-color: var(--text);
  }
  
  html[data-theme="dark"] #scoreThisTermList {
    border-color: var(--text) !important;
  }

/* APP专属提示 */
.app-only-prompt {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 20px;
  text-align: center;
  gap: 20px;
}

.app-only-prompt i {
  font-size: 64px;
  color: var(--text);
  opacity: 0.3;
  margin-bottom: 8px;
}

.app-only-prompt p {
  font-size: 16px;
  color: var(--subtext);
  font-weight: 600;
  margin: 0;
}

.app-only-prompt .download-btn {
  margin-top: 8px;
  padding: 12px 24px;
  border: none;
  border-radius: var(--hgu-radius-xl);
  background: var(--text);
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
  box-shadow: var(--hgu-shadow-card);
}

.app-only-prompt .download-btn:active {
  transform: scale(0.96);
  opacity: 0.9;
}

/* ================== 教学评估提示卡片 ================== */
.score-eval-prompt-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    background: var(--hgu-surface-glass);
    border: 1px solid var(--text);
    border-radius: var(--hgu-radius-2xl);
    padding: 14px 16px;
    box-shadow: var(--hgu-shadow-card);
}

.score-eval-prompt-text {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
    line-height: 1.4;
    flex: 1;
    min-width: 0;
}

.score-eval-prompt-text i {
    font-size: 18px;
    color: #ff9800;
    flex-shrink: 0;
}

.score-eval-prompt-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    border-radius: var(--hgu-radius-xl);
    background: var(--text);
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    transition: all 0.2s ease;
    flex-shrink: 0;
    cursor: pointer;
    border: none;
    font-family: inherit;
}

.score-eval-prompt-btn i {
    font-size: 11px;
    opacity: 0.8;
}

.score-eval-prompt-btn:active {
    transform: scale(0.95);
    opacity: 0.9;
}

/* ================== 一键评估按钮 ================== */
.score-eval-prompt-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

.score-eval-auto-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    border-radius: var(--hgu-radius-xl);
    background: linear-gradient(135deg, #ff9800, #f57c00);
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    transition: all 0.2s ease;
    flex-shrink: 0;
    cursor: pointer;
    border: none;
    font-family: inherit;
    box-shadow: 0 2px 8px rgba(255, 152, 0, 0.3);
}

.score-eval-auto-btn i {
    font-size: 12px;
}

.score-eval-auto-btn:active {
    transform: scale(0.95);
    opacity: 0.9;
}

/* ================== 一键评估警告弹窗 ================== */
.score-eval-warning-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: var(--hgu-surface-glass);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10000;
    padding: 20px;
    backdrop-filter: blur(var(--hgu-blur-sm));
}

.score-eval-warning-dialog {
    background: var(--hgu-surface-glass);
    border: 1px solid var(--hgu-border-soft);
    border-radius: var(--hgu-radius-3xl);
    padding: 24px;
    max-width: 380px;
    width: 100%;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}

.score-eval-warning-header {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 16px;
    font-size: 17px;
    font-weight: 700;
    color: #ff9800;
}

.score-eval-warning-header i {
    font-size: 20px;
}

.score-eval-warning-body {
    margin-bottom: 20px;
}

.score-eval-warning-body p {
    font-size: 14px;
    line-height: 1.7;
    color: var(--text-secondary, #666);
}

.score-eval-warning-footer {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
}

.score-eval-warning-cancel {
    padding: 10px 20px;
    border-radius: var(--hgu-radius-xl);
    border: 1px solid var(--hgu-border-soft);
    background: transparent;
    color: var(--text-secondary, #666);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    transition: all 0.2s;
}

.score-eval-warning-cancel:active {
    opacity: 0.7;
    transform: scale(0.96);
}

.score-eval-warning-confirm {
    padding: 10px 20px;
    border-radius: var(--hgu-radius-xl);
    border: none;
    background: linear-gradient(135deg, #ff9800, #f57c00);
    color: #fff;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    transition: all 0.2s;
    box-shadow: 0 2px 8px rgba(255, 152, 0, 0.3);
}

.score-eval-warning-confirm:active {
    opacity: 0.9;
    transform: scale(0.96);
}

    html[data-theme="dark"] .score-eval-prompt-text i {
        color: #ffb74d;
    }

/* ===== Source: training-plan.css ===== */
.training-plan-content {
  --training-green: var(--study-cyan);
  --training-green-soft: rgba(var(--study-cyan-rgb), 0.1);
  --training-green-border: rgba(var(--study-cyan-rgb), 0.58);
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  color: var(--training-green);
}

#trainingPlanDynamicContent {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.training-plan-loading,
.training-plan-empty,
.training-plan-error {
  min-height: 180px;
  padding: 28px 18px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  color: var(--subtext);
  text-align: center;
}

.training-plan-loading i,
.training-plan-empty i,
.training-plan-error i {
  font-size: 28px;
  color: var(--training-green);
}

.training-plan-error i {
  color: #e05252;
}

.training-plan-empty p,
.training-plan-error p {
  margin: 0;
  font-size: 13px;
  line-height: 1.6;
}

.training-plan-retry {
  min-height: 38px;
  padding: 0 16px;
  border: 1px solid var(--training-green-border);
  border-radius: var(--hgu-radius-md);
  background: transparent;
  color: var(--training-green);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
}

.training-plan-summary {
  padding: 16px;
  border: 1.5px solid var(--training-green-border);
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
}

.training-plan-name {
  font-size: 16px;
  font-weight: 800;
  line-height: 1.45;
}

.training-plan-number {
  margin-top: 4px;
  color: var(--subtext);
  font-size: 11px;
}

.training-plan-credit-line {
  margin-top: 15px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.training-plan-credit-value {
  font-size: 26px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.training-plan-credit-value small {
  margin-left: 3px;
  color: var(--subtext);
  font-size: 12px;
  font-weight: 600;
}

.training-plan-percent {
  color: var(--training-green);
  font-size: 17px;
  font-weight: 800;
}

.training-plan-progress,
.training-module-progress {
  height: 7px;
  margin-top: 8px;
  overflow: hidden;
  border-radius: var(--hgu-radius-xs);
  background: var(--border);
}

.training-plan-progress > span,
.training-module-progress > span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--training-green);
}

.training-plan-metrics {
  margin-top: 14px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--hgu-border-soft);
}

.training-plan-metric {
  padding: 12px 6px 0;
  text-align: center;
}

.training-plan-metric + .training-plan-metric {
  border-left: 1px solid var(--hgu-border-soft);
}

.training-plan-metric strong {
  display: block;
  font-size: 17px;
  font-variant-numeric: tabular-nums;
}

.training-plan-metric span {
  display: block;
  margin-top: 2px;
  color: var(--subtext);
  font-size: 11px;
}

.training-plan-tabs {
  display: grid;
  gap: 4px;
  padding: 4px;
  border: 1.5px solid var(--training-green-border);
  border-radius: var(--hgu-radius-xl);
  background: var(--hgu-surface-glass);
}

.training-plan-tabs {
  grid-template-columns: repeat(2, 1fr);
}

.training-plan-tab {
  min-width: 0;
  min-height: 36px;
  padding: 0 6px;
  border: none;
  border-radius: var(--hgu-radius-md);
  background: transparent;
  color: var(--training-green);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.training-plan-tab.active {
  background: var(--training-green);
  color: #fff;
}

.training-plan-section-title {
  padding: 0 2px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 15px;
  font-weight: 800;
}

.training-plan-section-title small {
  color: var(--subtext);
  font-size: 11px;
  font-weight: 500;
}

.training-module-list,
.training-term-content {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.training-module,
.training-term-panel {
  overflow: hidden;
  border: 1.5px solid var(--training-green-border);
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
}

.training-module-summary {
  min-height: 64px;
  padding: 12px 14px;
  cursor: pointer;
  list-style: none;
}

.training-module-summary::-webkit-details-marker {
  display: none;
}

.training-module-summary-top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
}

.training-module-name {
  overflow-wrap: anywhere;
  font-size: 14px;
  font-weight: 750;
}

.training-module-credit {
  color: var(--subtext);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.training-fold-chevron {
  margin-left: 5px;
  color: var(--training-green);
  font-size: 10px;
  transition: transform 0.2s ease;
}

.training-module[open] .training-fold-chevron,
.training-term-panel[open] .training-fold-chevron {
  transform: rotate(90deg);
}

.training-module-meta {
  margin-top: 7px;
  display: flex;
  flex-wrap: wrap;
  gap: 5px 12px;
  color: var(--subtext);
  font-size: 11px;
}

.training-module-courses,
.training-term-courses {
  border-top: 1px solid var(--hgu-border-soft);
}

.training-subgroup { border-bottom: 1px solid var(--hgu-border-soft); }
.training-subgroup:last-child { border-bottom: 0; }
.training-subgroup-summary {
  min-height: 46px;
  padding: 10px 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  cursor: pointer;
  list-style: none;
  color: var(--study-cyan, var(--text));
  font-size: 14px;
  font-weight: 600;
}
.training-subgroup-summary::-webkit-details-marker { display: none; }
.training-subgroup-summary small { color: var(--subtext); font-size: 12px; font-weight: 500; text-align: right; }
.training-subgroup[open] > .training-subgroup-summary .training-fold-chevron { transform: rotate(90deg); }
.training-subgroup-courses { padding: 0 10px 10px; }

.training-course-row {
  min-height: 58px;
  padding: 10px 12px;
  display: grid;
  grid-template-columns: 9px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  border-bottom: 1px solid var(--hgu-border-soft);
}

.training-course-row:last-child {
  border-bottom: none;
}

.training-course-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--hgu-radius-round);
  background: #8b94a3;
}

.training-course-row.is-passed .training-course-dot {
  background: #2e9d62;
}

.training-course-row.is-attention .training-course-dot {
  background: #e05252;
}

.training-course-row.is-planned .training-course-dot {
  background: #8b94a3;
}

.training-course-main {
  min-width: 0;
}

.training-course-name {
  overflow-wrap: anywhere;
  font-size: 13px;
  font-weight: 650;
  line-height: 1.35;
}

.training-course-meta {
  margin-top: 4px;
  display: flex;
  flex-wrap: wrap;
  gap: 3px 8px;
  color: var(--subtext);
  font-size: 10px;
}

.training-course-score {
  min-width: 34px;
  color: var(--subtext);
  font-size: 13px;
  font-weight: 800;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.training-course-row.is-passed .training-course-score {
  color: #2e9d62;
}

.training-course-row.is-attention .training-course-score {
  color: #e05252;
}

.training-plan-no-results {
  padding: 28px 16px;
  color: var(--subtext);
  font-size: 13px;
  text-align: center;
}

.training-term-head {
  padding: 14px;
  cursor: pointer;
  list-style: none;
}

.training-term-head::-webkit-details-marker {
  display: none;
}

.training-term-panel[open] .training-term-head {
  border-bottom: 1px solid var(--hgu-border-soft);
}

.training-term-name {
  font-size: 15px;
  font-weight: 800;
}

.training-term-stats {
  margin-top: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.training-term-stat,
.training-course-tag {
  padding: 3px 7px;
  border-radius: var(--hgu-radius-xs);
  background: var(--training-green-soft);
  color: var(--training-green);
  font-size: 10px;
  font-weight: 650;
}

.training-term-subtitle {
  padding: 10px 12px;
  background: rgba(127, 127, 127, 0.07);
  color: var(--subtext);
  font-size: 11px;
  font-weight: 800;
}

.training-plan-official-links {
  margin-top: 16px;
  border-color: var(--training-green-border);
}

.training-plan-official-links .official-links-title,
.training-plan-official-links .official-link-row,
.training-plan-official-links .official-link-button {
  color: var(--training-green);
}

.training-plan-official-links .official-link-button {
  border-color: var(--training-green-border);
  background: var(--training-green-soft);
}

.training-plan-notice {
  padding: 13px 14px;
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  gap: 10px;
  border: 1.5px solid var(--training-green-border);
  border-radius: var(--hgu-radius-2xl);
  background: var(--training-green-soft);
  box-shadow: var(--hgu-shadow-card);
}

.training-plan-notice > i {
  margin-top: 2px;
  color: var(--training-green);
}

.training-plan-notice strong,
.training-plan-notice span {
  display: block;
}

.training-plan-notice strong {
  color: var(--training-green);
  font-size: 13px;
}

.training-plan-notice span {
  margin-top: 4px;
  color: var(--subtext);
  font-size: 11px;
  line-height: 1.6;
}

@media (max-width: 380px) {
  .training-plan-metrics {
    grid-template-columns: repeat(3, minmax(72px, 1fr));
    overflow-x: auto;
  }
}

  html[data-theme="dark"] .training-course-row.is-passed .training-course-dot {
    background: #55c987;
  }

  html[data-theme="dark"] .training-course-row.is-attention .training-course-dot {
    background: #ff7373;
  }

/* ===== Source: energy-query.css ===== */
#energy-page {
  --text: #2563eb;
  --text-light: rgba(37, 99, 235, 0.12);
}

/* 内容容器 */
.energy-content {
  width: 100%;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* 余额卡片 */
.energy-balance-card-v2 {
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  padding: 20px 16px 16px;
  box-shadow: var(--hgu-shadow-card);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin: 0;
}
.energy-balance-top {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 8px;
}
.energy-account-name {
  font-size: 13px;
  color: var(--subtext);
  font-weight: 500;
  line-height: 1.3;
  max-width: 60%;
  word-break: break-all;
}
.energy-recharge-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border-radius: var(--hgu-radius-3xl);
  background: var(--text);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  transition: transform 0.2s, opacity 0.2s;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
  border: none;
  cursor: pointer;
}
.energy-recharge-btn:active {
  transform: scale(0.95);
  opacity: 0.9;
}
.energy-balance-amount {
  font-size: 36px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  margin-top: 4px;
}
.energy-balance-amount.negative {
  color: #ff4757;
}
.energy-balance-amount.positive {
  color: var(--text);
}
.energy-balance-label {
  font-size: 12px;
  color: var(--subtext);
  opacity: 0.8;
  margin-top: 2px;
}

/* 图表卡片 */
.energy-chart-card {
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  padding: 14px 12px 12px;
  box-shadow: var(--hgu-shadow-card);
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
}
.energy-chart-wrap {
  width: 100%;
  height: 180px;
  position: relative;
}
#energyChartCanvas {
  width: 100%;
  height: 100%;
  display: block;
}
.energy-chart-legend {
  display: flex;
  justify-content: center;
  gap: 20px;
  flex-wrap: wrap;
}
.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--subtext);
  font-weight: 500;
}
.legend-item i {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: var(--hgu-radius-round);
}
.legend-item.elec i { background: #2563eb; }
.legend-item.ac i   { background: #93c5fd; }

/* 详情卡片 */
.energy-detail-card {
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  overflow: hidden;
  box-shadow: var(--hgu-shadow-card);
  display: flex;
  flex-direction: column;
  padding: 14px 16px 16px;
  margin: 0;
  position: relative;
}
.energy-detail-card .score-section-title {
  margin-bottom: 12px;
}

.energy-month-bar {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding-bottom: 4px;
  width: 100%;
}
.energy-month-bar::-webkit-scrollbar { display: none; }
.energy-month-bar-inside {
  margin-bottom: 12px;
}
.energy-month-btn {
  flex: 1;
  min-width: 48px;
  padding: 10px 0;
  border: 1px solid var(--hgu-border-soft);
  background: var(--hgu-surface-glass);
  border-radius: var(--hgu-radius-xl);
  font-size: 14px;
  font-weight: 500;
  color: var(--subtext);
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
  text-align: center;
}
.energy-month-btn.active {
  background: var(--text);
  color: #fff;
  border-color: var(--text);
  font-weight: 600;
}
.energy-month-btn:active {
  transform: scale(0.95);
}

.energy-detail-section {
  background: rgba(128, 128, 128, 0.04);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-xl);
  padding: 14px 16px;
  margin-bottom: 12px;
}
.energy-detail-section:last-child {
  margin-bottom: 0;
}
.energy-detail-section-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.energy-detail-section-title i {
  font-size: 16px;
  width: 20px;
  text-align: center;
}
.energy-detail-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--hgu-border-soft);
}
.energy-detail-row:last-child {
  border-bottom: none;
}
.energy-detail-label {
  font-size: 14px;
  color: var(--subtext);
}
.energy-detail-value {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* 暗色模式蓝色覆盖 */

  html[data-theme="dark"] #energy-page {
    --text: #60a5fa;
    --text-light: rgba(96, 165, 250, 0.15);
  }
  html[data-theme="dark"] .legend-item.elec i { background: #60a5fa; }
  html[data-theme="dark"] .legend-item.ac i   { background: #93c5fd; }

/* APP专属提示 */
.app-only-prompt {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 20px;
  text-align: center;
  gap: 20px;
}

.app-only-prompt i {
  font-size: 64px;
  color: var(--text);
  opacity: 0.3;
  margin-bottom: 8px;
}

.app-only-prompt p {
  font-size: 16px;
  color: var(--subtext);
  font-weight: 600;
  margin: 0;
}

.app-only-prompt .download-btn {
  margin-top: 8px;
  padding: 12px 24px;
  border: none;
  border-radius: var(--hgu-radius-xl);
  background: var(--text);
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
  box-shadow: var(--hgu-shadow-card);
}

.app-only-prompt .download-btn:active {
  transform: scale(0.96);
  opacity: 0.9;
}

/* ===== Source: campus-card.css ===== */
#campus-card-page {
  --text: #2563eb;
  --text-light: rgba(37, 99, 235, 0.12);
}

#campus-card-page .campus-card-content {
  width: 100%;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.campus-card-balance-card,
.campus-card-section,
.campus-card-summary-item {
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  box-shadow: var(--hgu-shadow-card);
}

.campus-card-balance-card {
  padding: 20px 16px 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin: 0;
}

.campus-card-top {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  margin-bottom: 8px;
  gap: 12px;
}

.campus-card-recharge-btn,
.campus-card-scan-water-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border-radius: var(--hgu-radius-4xl);
  background: var(--text);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  transition: transform 0.2s, opacity 0.2s;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
  border: none;
  cursor: pointer;
  flex: 0 0 auto;
}

.campus-card-recharge-btn:active,
.campus-card-scan-water-btn:active {
  transform: scale(0.95);
  opacity: 0.9;
}

.campus-card-balance {
  font-size: 36px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  margin-top: 4px;
}

.campus-card-balance::before {
  content: "\00A5";
  font-size: 20px;
  font-weight: 700;
  margin-right: 2px;
}

.campus-card-balance.is-empty::before {
  content: "";
}

.campus-card-balance-label {
  font-size: 12px;
  color: var(--subtext);
  opacity: 0.8;
  margin-top: 2px;
}

.campus-card-summary-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.campus-card-summary-item {
  min-height: 76px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
}

.campus-card-summary-item span {
  font-size: 12px;
  color: var(--subtext);
}

.campus-card-summary-item strong {
  font-size: 20px;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.campus-card-section {
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: 14px 16px 16px;
  margin: 0;
  position: relative;
  gap: 12px;
}

.campus-card-section-title {
  display: flex;
  align-items: center;
  gap: 7px;
  color: var(--text);
  font-size: 15px;
  font-weight: 750;
}

.campus-card-chart-status {
  padding: 28px 8px;
  color: var(--subtext);
  font-size: 12px;
  text-align: center;
}

/* ===== 消费日历：标题右侧显示当月支出，格子按支出多少加深主题蓝 ===== */
.campus-card-calendar-title {
  justify-content: space-between;
}

.campus-card-calendar-title > span {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.campus-card-calendar-total {
  color: var(--text);
  font-size: 14px;
  font-weight: 800;
}

.campus-card-calendar {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 5px;
}

.campus-card-cal-head {
  padding: 2px 0;
  color: var(--subtext);
  font-size: 11px;
  text-align: center;
}

.campus-card-cal-day {
  min-height: 46px;
  padding: 3px 2px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-md);
  background: var(--hgu-surface-glass);
}

/* 补位空格子：不画边框、不填底色 */
.campus-card-cal-day.is-empty {
  border-color: transparent;
  background: transparent;
}

.campus-card-cal-day.is-today {
  border-color: var(--text);
}

/* 那天没有上传记录 → 灰色虚线，说明当天用量没能正常算出来 */
.campus-card-cal-day.is-missing {
  border-style: dashed;
  border-color: rgba(128, 128, 128, 0.55);
}

.campus-card-cal-date {
  color: var(--subtext);
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
}

.campus-card-cal-cost {
  color: var(--subtext);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
}

/* 支出较多的格子（背景够深）改用白字，保证可读 */
.campus-card-cal-day.is-deep .campus-card-cal-date,
.campus-card-cal-day.is-deep .campus-card-cal-cost {
  color: #fff;
}

/* ===== 宿舍电费：用电日历（复用消费日历的格子样式） ===== */
.energy-calendar-head {
  display: flex;
  align-items: center;
  /* 不用 space-between：.score-section-title 的 ::before 竖条也算一个 flex 子项，
     三项目平分会把标题挤到中间；标题靠左 + 开关 margin-left:auto 顶右即可 */
  justify-content: flex-start;
  gap: 8px;
}

.energy-calendar-head .energy-calendar-switch {
  margin-left: auto;
}

.energy-calendar-switch {
  display: inline-flex;
  gap: 4px;
  padding: 3px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-pill);
  background: rgba(128, 128, 128, 0.06);
}

.energy-calendar-tab {
  appearance: none;
  -webkit-appearance: none;
  min-width: 52px;
  padding: 5px 12px;
  border: 0;
  border-radius: var(--hgu-radius-pill);
  background: transparent;
  color: var(--subtext);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.energy-calendar-tab.active {
  background: var(--text);
  color: #fff;
}

/* 灰字说明：用电日历的数据说明 / 一卡通消费日历的微信支付宝说明 */
.energy-calendar-hint,
.campus-card-calendar-hint {
  color: var(--subtext);
  font-size: 11px;
  line-height: 1.5;
  opacity: 0.9;
}

.campus-card-tab-switch {
  display: flex;
  justify-content: center;
  gap: 6px;
  padding: 4px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-default);
  background: rgba(128, 128, 128, 0.06);
  width: fit-content;
  margin: 0 auto;
}

.campus-card-tab {
  min-width: 88px;
  padding: 8px 18px;
  border: 0;
  border-radius: var(--hgu-radius-lg);
  background: transparent;
  color: var(--subtext);
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
}

.campus-card-tab.active {
  background: var(--text);
  color: #fff;
}

/* 月份切换容器：单独一条，放在卡片上方，控制它下面的卡片月份。
   蓝色边框 + 蓝色文字（电费页本身是绿色主题，这里统一成蓝色）。 */
.life-period-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 8px 12px;
  /* 边框色与文字色都走变量：一卡通账单是蓝色主题，活动页会把它覆盖成品红 */
  border: 1.5px solid var(--period-border, rgba(37, 99, 235, 0.55));
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  --text: #2563eb;
}

.campus-card-period-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
}

.campus-card-period-btn {
  width: 34px;
  height: 34px;
  border-radius: var(--hgu-radius-round);
  border: 1px solid var(--period-button-border, var(--hgu-border-soft));
  background: var(--hgu-surface-glass);
  color: var(--text);
  display: grid;
  place-items: center;
  cursor: pointer;
  font-size: 13px;
}

/* 活动页的月份选择器：整体改成品红主题（边框、按钮边框、文字），
   并且占满整行、圆角加满。一卡通账单那边不受影响（变量只在这里被赋值）。 */
.activity-period-bar {
  width: 100%;
  min-width: 0;
  align-self: stretch;
  padding: 8px 14px;
  border-radius: 999px;
  --period-border: #C55DB5;
  --period-button-border: rgba(197, 93, 181, 0.55);
  --text: #C55DB5;
}

.activity-period-bar[hidden] {
  display: none;
}

html[data-theme="dark"] .activity-period-bar {
  --period-border: #ffaddf;
  --period-button-border: rgba(255, 173, 223, 0.55);
  --text: #ffaddf;
}

.campus-card-period-btn:disabled {
  opacity: 0.35;
}

.campus-card-period-label {
  min-width: 112px;
  text-align: center;
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.campus-card-date-group {
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-xl);
  overflow: hidden;
  background: rgba(128, 128, 128, 0.04);
  margin-bottom: 12px;
}

/* 账单明细：按日一层卡片，天内每条流水用分割线分隔（比之前每条一个卡片更密） */
#campusCardRecordsList {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.campus-card-day-card {
  padding: 8px 10px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-xl);
  background: rgba(128, 128, 128, 0.04);
}

.campus-card-day-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding-bottom: 5px;
}

.campus-card-day-label {
  color: var(--text);
  font-size: 11.5px;
  font-weight: 700;
}

.campus-card-day-count {
  color: var(--subtext);
  font-size: 10.5px;
  opacity: 0.85;
}

#campusCardRecordsList .campus-card-record-row {
  padding: 7px 0;
  border: 0;
  border-top: 1px solid var(--hgu-border-soft);
  border-radius: 0;
  background: transparent;
}

/* 日期头是第 1 个子元素，所以这天第一条流水（第 2 个）不要上分割线。
   选择器要带上 #campusCardRecordsList，否则压不过上面那条 id 规则。 */
#campusCardRecordsList .campus-card-day-card .campus-card-record-row:nth-child(2) {
  border-top: 0;
  padding-top: 2px;
}

.campus-card-date-title {
  padding: 10px 12px;
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  border-bottom: 1px solid var(--hgu-border-soft);
}

.campus-card-record-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px;
  border-bottom: 1px solid var(--hgu-border-soft);
}

.campus-card-record-row:last-child {
  border-bottom: 0;
}

.campus-card-record-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.campus-card-record-title {
  font-size: 12.5px;
  font-weight: 650;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.campus-card-record-meta {
  font-size: 10.5px;
  color: var(--subtext);
  opacity: 0.9;
}

/* 右侧金额统一灰色（收/支靠 +- 号区分，不再用红绿色） */
.campus-card-record-money {
  flex: 0 0 auto;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--subtext);
  font-variant-numeric: tabular-nums;
}

.campus-card-chart-wrap {
  width: 100%;
  height: 220px;
  position: relative;
}

#campusCardStatsCanvas {
  width: 100%;
  height: 100%;
  display: block;
}

.secondary-drawer.campus-water-drawer {
  max-width: 480px;
  padding: 10px 14px max(18px, env(safe-area-inset-bottom));
  --text: #2563eb;
  border: 1.5px solid rgba(37, 99, 235, 0.48);
}

.campus-water-drawer .secondary-drawer-handle {
  background: var(--text);
}

.campus-water-toolbar {
  min-height: 42px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 14px;
}

.campus-water-toolbar > strong {
  flex: 0 0 auto;
  color: var(--text);
  font-size: 16px;
}

.campus-water-toolbar-actions {
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 5px;
}

.campus-water-toolbar-actions button {
  min-height: 32px;
  padding: 0 7px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border: 1px solid rgba(37, 99, 235, 0.35);
  border-radius: var(--hgu-radius-md);
  background: rgba(37, 99, 235, 0.08);
  color: var(--text);
  font: inherit;
  font-size: 10px;
  font-weight: 700;
  white-space: nowrap;
}

.campus-water-toolbar-actions button:disabled {
  opacity: 0.42;
}

.campus-water-toolbar-actions .campus-water-refresh-btn,
.campus-water-toolbar-actions .campus-water-close-btn {
  width: 32px;
  padding: 0;
  flex: 0 0 32px;
  font-size: 13px;
}

/* 更换 / 禁用：小胶囊，居中 */
.campus-water-code-actions {
  width: 100%;
  margin-top: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
}

.campus-water-code-actions button {
  min-height: 30px;
  padding: 0 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  border: 1px solid rgba(37, 99, 235, 0.35);
  border-radius: var(--hgu-radius-pill);
  background: rgba(37, 99, 235, 0.08);
  color: var(--text);
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}

.campus-water-code-actions button:disabled {
  opacity: 0.42;
}

.campus-water-code-actions button:active:not(:disabled) {
  transform: scale(0.97);
}

/* 用水码容器：只包「用水码 + 更换/禁用」，充值/账单/扫码用水留在外面。
   边框跟着一卡通的蓝色主色（和抽屉本身的蓝框同色系）。 */
.campus-water-code-card {
  width: 100%;
  margin-top: 14px;
  padding: 14px 14px 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  border: 1.5px solid rgba(37, 99, 235, 0.55);
  border-radius: var(--hgu-radius-3xl);
  background: var(--hgu-surface-glass);
}

.campus-water-code-card .campus-water-code {
  margin-top: 8px;
}

.campus-water-code-card .campus-water-code-actions {
  margin-top: 12px;
}

.campus-water-code-label {
  color: var(--subtext);
  font-size: 12px;
}

.campus-water-code {
  width: 100%;
  margin-top: 12px;
  color: var(--text);
  font-size: 42px;
  font-weight: 800;
  line-height: 1.15;
  text-align: center;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.campus-water-code.is-disabled {
  color: var(--subtext);
  text-decoration: line-through;
}

.campus-water-code-status {
  min-height: 18px;
  margin-top: 8px;
  color: var(--subtext);
  font-size: 11px;
  text-align: center;
}

.campus-water-primary-actions {
  width: 100%;
  margin-top: 18px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

/* 充值 / 账单：透明底 + 描边（选择器要压过下面那条 .campus-water-drawer 规则） */
.campus-water-drawer .campus-water-primary-actions button:nth-child(-n + 2) {
  border: 1.5px solid var(--text);
  background: transparent;
  color: var(--text);
}

/* 三个按钮同一行；充值 / 账单为透明描边，扫码用水为实心主操作。
   圆角与上面「用水码」卡片一致（都是 20px 的圆角矩形，不再用胶囊）。
   选择器带 .campus-water-drawer：文件后面还有一条
   `.campus-water-primary-actions button { border-radius: var(--hgu-radius-2xl) }`
   的共用圆角规则（同特异性、位置在后），不加一层会被它盖成 16px。 */
.campus-water-drawer .campus-water-primary-actions button {
  min-width: 0;
  min-height: 56px;
  padding: 8px 10px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: none;
  border-radius: var(--hgu-radius-3xl);
  background: var(--text);
  color: #fff;
  font: inherit;
  font-size: 13px;
  font-weight: 750;
}

.campus-water-primary-actions button i {
  font-size: 17px;
}

.campus-water-toolbar-actions button:active:not(:disabled),
.campus-water-primary-actions button:active {
  transform: scale(0.97);
}

  html[data-theme="dark"] #campus-card-page {
    --text: #60a5fa;
    --text-light: rgba(96, 165, 250, 0.15);
  }

  html[data-theme="dark"] .secondary-drawer.campus-water-drawer {
    --text: #60a5fa;
    border-color: rgba(96, 165, 250, 0.48);
  }

  html[data-theme="dark"] .campus-water-toolbar-actions button {
    border-color: rgba(96, 165, 250, 0.38);
    background: rgba(96, 165, 250, 0.1);
  }

  html[data-theme="dark"] .campus-water-code-card {
    border-color: rgba(96, 165, 250, 0.55);
  }

  html[data-theme="dark"] .life-period-bar {
    border-color: rgba(96, 165, 250, 0.55);
    --text: #60a5fa;
  }

@media (max-width: 420px) {
  .campus-card-balance {
    font-size: 34px;
  }

  .campus-water-toolbar-actions button {
    padding: 0 5px;
    font-size: 9px;
  }

  .campus-water-code {
    font-size: 38px;
  }
}

/* ===== Source: eat-what.css ===== */
#eatwhat-page, #window-detail-page, #eatwhat-random-page {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
}

/* 顶部标题栏 */
#eatwhat-page .sub-page-back,
#window-detail-page .sub-page-back,
#eatwhat-random-page .sub-page-back {
  color: #ff9800;
}

#eatwhat-page .sub-page-title,
#window-detail-page .sub-page-title,
#eatwhat-random-page .sub-page-title {
  color: #ff9800;
}

/* 喝什么主题 - 随机推荐页标题和返回按钮蓝色 */
#eatwhat-random-page.theme-drink .sub-page-back {
  color: #4facfe;
}

#eatwhat-random-page.theme-drink .sub-page-title {
  color: #4facfe;
}

/* 内容区 */
.eatwhat-content {
  width: 100%;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* 搜索栏 - 橙色边框 */
.eatwhat-search-bar {
  position: relative;
  width: 100%;
  margin-bottom: 4px;
  border: 1.5px solid #ff9800;
  border-radius: var(--hgu-radius-4xl);
  background: var(--hgu-surface-glass);
  display: flex;
  align-items: center;
  padding: 2px 4px;
}

.eatwhat-search-bar i.fa-magnifying-glass {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--subtext);
  font-size: 16px;
}

.eatwhat-search-bar input {
  width: 100%;
  padding: 10px 40px 10px 42px;
  border: none;
  background: transparent;
  font-size: 15px;
  outline: none;
  color: #f07b18;
  -webkit-text-fill-color: #f07b18;
  caret-color: #f07b18;
}

.eatwhat-search-bar input::placeholder {
  color: #f4a261;
  opacity: 0.85;
}

.eatwhat-search-bar .clear-btn {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  color: var(--subtext);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  opacity: 0.7;
  transition: opacity 0.2s;
  padding: 0 4px;
}

.eatwhat-search-bar .clear-btn:hover {
  opacity: 1;
  color: #ff9800;
}

/* 紧凑点餐式菜品列表：左侧分类，右侧高密度文本行 */
.dish-menu-layout {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr);
  gap: 10px;
  align-items: start;
}

.dish-menu-sidebar {
  position: sticky;
  top: 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px 0;
  border-right: 1px solid var(--hgu-border-soft);
}

.dish-menu-primary {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 8px 6px 2px 4px;
  color: var(--subtext);
  font-size: 10px;
  font-weight: 700;
}

.dish-menu-primary.dish,
.dish-menu-category.dish,
.dish-menu-group.dish,
.dish-menu-row.dish {
  --dish-accent: #ff6b35;
  --dish-accent-bg: rgba(255, 107, 53, .12);
}

.dish-menu-primary.drink,
.dish-menu-category.drink,
.dish-menu-group.drink,
.dish-menu-row.drink {
  --dish-accent: #4facfe;
  --dish-accent-bg: rgba(79, 172, 254, .12);
}

.dish-menu-primary.condiment,
.dish-menu-category.condiment,
.dish-menu-group.condiment,
.dish-menu-row.condiment {
  --dish-accent: #9c27b0;
  --dish-accent-bg: rgba(156, 39, 176, .12);
}

.dish-menu-primary { color: var(--dish-accent, var(--subtext)); }

.dish-menu-category {
  width: calc(100% - 8px);
  min-height: 34px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  padding: 6px 7px;
  border: 0;
  border-radius: 7px 0 0 7px;
  background: transparent;
  color: var(--subtext);
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}

.dish-menu-category { color: var(--dish-accent, var(--subtext)); }
.dish-menu-category small { color: inherit; font-size: 10px; opacity: .8; }
.dish-menu-category.active { background: var(--dish-accent-bg, rgba(255, 152, 0, .15)); color: var(--dish-accent, #e87516); font-weight: 700; }
.dish-menu-category.active small { color: inherit; }

.dish-menu-results { min-width: 0; }
.dish-menu-group { margin-bottom: 8px; scroll-margin-top: 72px; }
.dish-menu-group-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 5px 4px;
  color: var(--subtext);
  font-size: 11px;
  font-weight: 700;
  border-bottom: 1px solid var(--hgu-border-soft);
}
.dish-menu-group-title small { font-size: 10px; font-weight: 500; }
.dish-menu-group .dish-menu-group-title { color: var(--dish-accent, var(--subtext)); }
.dish-menu-row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  padding: 5px 7px;
  border-bottom: 1px solid var(--hgu-border-soft);
}
.dish-menu-row:last-child { border-bottom: 0; }
.dish-menu-type-icon {
  width: 25px;
  height: 25px;
  display: grid;
  place-items: center;
  flex: 0 0 25px;
  border-radius: 7px;
  color: var(--dish-accent, #e87516);
  background: var(--dish-accent-bg, rgba(255, 152, 0, .12));
  font-size: 11px;
}
.dish-menu-info { min-width: 0; flex: 1; }
.dish-menu-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; font-weight: 600; color: var(--dish-accent, var(--text)); }
.dish-menu-price { flex: 0 0 auto; color: var(--dish-accent, #e87516); font-size: 13px; font-weight: 700; }

#detailDishList .dish-image { display: none; }

@media (max-width: 380px) {
  .dish-menu-layout { grid-template-columns: 82px minmax(0, 1fr); gap: 7px; }
  .dish-menu-category { font-size: 11px; }
  .dish-menu-row { gap: 6px; padding-inline: 4px; }
}

/* 菜品图片已停用：随机推荐保留纯图标占位，不加载图片资源。 */

/* 食堂切换按钮 */
.eatwhat-canteen-tabs {
  display: flex;
  gap: 20px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
  margin-bottom: 6px;
  padding: 0 4px;
  position: relative;
}

/* 「今天吃什么」首页的食堂切换：上下各留一点间距，别贴着搜索栏和瀑布流 */
#eatwhatCanteenTabs {
  margin: 6px 0 12px;
}

.eatwhat-canteen-tabs::-webkit-scrollbar {
  display: none;
}

/* 食堂切换按钮：仿考试安排/校历日程的"文字高亮 + 可移动底部横线"样式 */
.canteen-tab {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  appearance: none;
  -webkit-appearance: none;
  padding: 8px 2px 10px;
  border: none;
  border-radius: 0;
  background: transparent;
  font-size: 14px;
  font-weight: 800;
  font-family: inherit;
  color: var(--subtext);
  opacity: 0.6;
  cursor: pointer;
  white-space: nowrap;
  position: relative;
  transition: color 0.2s, opacity 0.2s, transform 0.2s;
}
.canteen-tab i { font-size: 13px; }

.canteen-tab:active {
  transform: scale(0.97);
}

.canteen-tab.active {
  color: #ff9800;
  opacity: 1;
  font-weight: 900;
}

/* 可移动高亮横线：由 JS 定位到当前选中的食堂下方 */
.canteen-tab-indicator {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0;
  height: 3px;
  border-radius: var(--hgu-radius-pill);
  background: #ff9800;
  box-shadow: 0 2px 6px rgba(255, 152, 0, 0.35);
  transition: left 0.28s cubic-bezier(0.22, 1, 0.36, 1), width 0.28s cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}

/* ============ 窗口详情页：右下角固定的写评价 / 修改评价按钮 ============
   和课表页的周次切换按钮一样固定在右下角，且要抬到悬浮栏上方
   （--hgu-nav-clearance 由 JS 按悬浮栏真实占用写入）。
   外观：玻璃背景 + 橙黄描边（原来是实心橙黄底 + 白字，压在地图/封面上太重）。 */
.window-rate-fab {
  position: fixed;
  right: 16px;
  bottom: var(--hgu-nav-clearance, 74px);
  /* 按钮挂在 body 上，必须压过抽屉面板（#tools-page 是 z-index 997 的层叠上下文），
     但仍在悬浮栏（999）之下 —— 与课表页周次切换按钮的层级效果一致。 */
  z-index: 998;
  display: none;
  align-items: center;
  gap: 6px;
  padding: 11px 16px;
  border: 1.5px solid var(--ew-theme, #f6a821);
  border-radius: var(--hgu-radius-pill);
  background: var(--hgu-surface-glass);
  -webkit-backdrop-filter: blur(var(--hgu-blur-xl)) saturate(1.5);
  backdrop-filter: blur(var(--hgu-blur-xl)) saturate(1.5);
  color: var(--ew-theme-strong, #e08500);
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.16), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

.window-rate-fab i { font-size: 13px; }
.window-rate-fab:active { transform: scale(0.96); }
/* 按钮挂在 body 上（见 life.js initWindowRateFab）：用 body 的类控制显隐。
   今天吃什么页（窗口/随机/评价三个视图）与窗口详情页都显示，
   评价编辑页、我的食评页不显示 */
body.window-rate-fab-open .window-rate-fab { display: inline-flex; }

/* ============ 在线点单（窗口详情 · 在线点单页） ============
   图片宽度始终占满页面宽度；点一下可放大查看（复用窗口封面那套缩放）。 */
.ew-order-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ew-order-image {
  width: 100%;
  display: block;
  border-radius: var(--hgu-radius-xl);
  overflow: hidden;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  cursor: zoom-in;
}

.ew-order-image img {
  width: 100%;
  height: auto;
  display: block;
}

.ew-order-tip {
  color: var(--subtext);
  font-size: 11.5px;
  line-height: 1.6;
  opacity: 0.9;
}

/* 窗口卡片上的「可在线点单」标签 */
.ew-tag-order {
  background: rgba(255, 152, 0, 0.12);
  color: #e87516;
}

html[data-theme="dark"] .ew-tag-order {
  background: rgba(255, 183, 77, 0.16);
  color: #ffb74d;
}

/* ============ 食品问题投诉：页头小按钮 + 弹窗 ============ */
.food-complaint-btn {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 9px;
  border: 1px solid rgba(255, 152, 0, 0.5);
  border-radius: var(--hgu-radius-pill);
  background: rgba(255, 152, 0, 0.1);
  color: #e87516;
  font-family: inherit;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
}

.food-complaint-btn i {
  font-size: 11px;
}

.food-complaint-btn:active {
  transform: translateY(-50%) scale(0.96);
}

html[data-theme="dark"] .food-complaint-btn {
  border-color: rgba(255, 183, 77, 0.5);
  background: rgba(255, 183, 77, 0.12);
  color: #ffb74d;
}

/* 抽屉形态：只把原来取「主文本色」(--text) 的那几处改成橙黄
   —— 抽屉标题、加粗那句、电话号、复制按钮；
   说明文字 / 负责人名 / 底部小字 / 关闭按钮 / 把手仍用次要文本色。 */
.food-complaint-drawer {
  max-width: 480px;
  --food-complaint-accent: #ff8f00;
  /* 抽屉本体 + 两条联系方式都要一圈橙黄边框（透明度不动，只加边框） */
  border: 1.5px solid rgba(255, 152, 0, 0.55);
  border-bottom: none;
}

html[data-theme="dark"] .food-complaint-drawer {
  --food-complaint-accent: #ffb74d;
  border-color: rgba(255, 183, 77, 0.55);
}

.food-complaint-drawer .modal-header span,
.food-complaint-em,
.food-complaint-phone,
.food-complaint-copy {
  color: var(--food-complaint-accent, #ff8f00);
}

.food-complaint-text {
  margin: 0 0 10px;
  color: var(--subtext);
  font-size: 12.5px;
  line-height: 1.65;
}

.food-complaint-em {
  margin: 0 0 14px;
  font-size: 13px;
  font-weight: 800;
  line-height: 1.5;
}

.food-complaint-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 10px;
}

.food-complaint-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 8px;
  padding: 8px 10px;
  border: 1.5px solid rgba(255, 152, 0, 0.45);
  border-radius: var(--hgu-radius-lg);
  background: rgba(128, 128, 128, 0.06);
}

html[data-theme="dark"] .food-complaint-row {
  border-color: rgba(255, 183, 77, 0.45);
}

.food-complaint-who {
  flex: 1 1 100%;
  min-width: 0;
  color: var(--subtext);
  font-size: 12px;
}

.food-complaint-phone {
  font-size: 13px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.3px;
}

.food-complaint-copy {
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 9px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-pill);
  background: transparent;
  font-family: inherit;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
}

.food-complaint-copy:active {
  transform: scale(0.95);
}

.food-complaint-note {
  margin: 0;
  color: var(--subtext);
  font-size: 11px;
  opacity: 0.8;
}

/* 食品问题投诉维权流程 */
.food-complaint-flow {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 10px;
}

.food-complaint-step {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border: 1.5px solid rgba(255, 152, 0, 0.35);
  border-radius: var(--hgu-radius-lg);
  background: rgba(128, 128, 128, 0.04);
}

.food-complaint-step.is-final {
  border-color: rgba(255, 152, 0, 0.55);
  background: rgba(255, 152, 0, 0.08);
}

html[data-theme="dark"] .food-complaint-step {
  border-color: rgba(255, 183, 77, 0.35);
  background: rgba(255, 183, 77, 0.06);
}

html[data-theme="dark"] .food-complaint-step.is-final {
  border-color: rgba(255, 183, 77, 0.55);
  background: rgba(255, 183, 77, 0.12);
}

.food-complaint-step-num {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--food-complaint-accent, #ff8f00);
  color: #fff;
  font-size: 12px;
  font-weight: 800;
  line-height: 1;
}

.food-complaint-step-num i {
  color: #fff;
  font-size: 11px;
}

.food-complaint-step-body {
  flex: 1;
  min-width: 0;
}

.food-complaint-step-title {
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.5;
}

.food-complaint-step-title.is-plain {
  color: #1f2937;
}

html[data-theme="dark"] .food-complaint-step-title.is-plain {
  color: #f3f4f6;
}

.food-complaint-step-title b {
  color: var(--food-complaint-accent, #ff8f00);
}

.food-complaint-step-note {
  margin-top: 4px;
  color: var(--subtext);
  font-size: 11px;
  line-height: 1.55;
  opacity: 0.85;
}

.food-complaint-arrow {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 18px;
  color: var(--food-complaint-accent, #ff8f00);
  font-size: 11px;
  opacity: 0.7;
}

/* 随机推荐按钮 - 透明背景+边框样式 */
.eatwhat-action-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  margin-bottom: 4px;
}

.eatwhat-action-btn {
  padding: 14px;
  border: 1.5px solid;
  border-radius: var(--hgu-radius-2xl);
  font-size: 15px;
  font-weight: 600;
  background: var(--hgu-surface-glass);
  backdrop-filter: blur(var(--hgu-blur-md));
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: all 0.2s;
  font-family: inherit;
}

.eatwhat-action-btn:active {
  transform: scale(0.95);
  background: rgba(128, 128, 128, 0.1);
}

/* 随机推荐按钮 - 与下方窗口列表卡片一致的背景效果（玻璃拟态+卡片阴影） */
.eatwhat-action-btn.random-btn {
  background: var(--hgu-surface-glass);
  border-color: #ff9800;
  color: #ff9800;
  box-shadow: var(--hgu-shadow-card);
}

/* 楼层分组卡片 */
.eatwhat-windows-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-bottom: 40px;
}

.floor-group-card {
  border: 1.5px solid #ff9800;
  border-radius: var(--hgu-radius-2xl);
  padding: 14px;
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
}

.floor-group-title {
  font-size: 16px;
  font-weight: 700;
  color: #ff9800;
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(255, 152, 0, 0.25);
  display: flex;
  align-items: center;
  gap: 6px;
}

.floor-group-title i {
  font-size: 14px;
}

.floor-group-content {
  display: flex;
  flex-direction: column;
}

.eatwhat-window-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 4px;
  cursor: pointer;
  transition: all 0.2s;
  border-radius: var(--hgu-radius-lg);
}

.eatwhat-window-item:active {
  transform: scale(0.98);
  background: rgba(255, 152, 0, 0.06);
}

.eatwhat-window-preview {
  width: 56px;
  height: 56px;
  border-radius: var(--hgu-radius-lg);
  overflow: hidden;
  flex-shrink: 0;
  background: var(--bg);
  border: 1px solid rgba(255, 152, 0, 0.15);
}

.eatwhat-window-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.eatwhat-window-info {
  flex: 1;
  min-width: 0;
}

.eatwhat-window-name {
  font-size: 15px;
  font-weight: 600;
  color: #ff9800;
  margin-bottom: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.eatwhat-window-tags {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

/* 窗口卡片下方的标签：字号/内边距都收小一点 */
.eatwhat-window-tags .ew-tag {
  padding: 2px 8px;
  font-size: 10.5px;
  border-radius: var(--hgu-radius-md);
}

.eatwhat-window-tags .ew-tag i {
  font-size: 9px;
}

.ew-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: var(--hgu-radius-lg);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.4;
  background: rgba(100, 100, 100, 0.08);
  color: var(--subtext);
}

.ew-tag i {
  font-size: 11px;
}

.ew-tag-hours.unknown {
  background: rgba(255, 152, 0, 0.1);
  color: #ff9800;
}

.window-divider {
  height: 1px;
  background: var(--border);
  margin: 2px 0;
  opacity: 0.6;
}

/* 窗口详情页 */
.window-detail-content {
  width: 100%;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 0 4px;
}

.window-info-card {
  background: var(--hgu-surface-glass);
  border: 1.5px solid rgba(255, 152, 0, 0.3);
  border-radius: var(--hgu-radius-2xl);
  overflow: hidden;
  box-shadow: var(--hgu-shadow-card);
}

.window-cover {
  width: 100%;
  height: 160px;
  overflow: hidden;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 1px solid rgba(255, 152, 0, 0.15);
  cursor: zoom-in;
  transition: transform 0.2s ease;
}

.window-cover:active {
  transform: scale(0.98);
}

.window-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.window-header-info {
  padding: 14px;
}

.window-header-info h2 {
  font-size: 18px;
  font-weight: 700;
  color: #ff9800;
  margin-bottom: 8px;
}

.window-meta {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}

/* 菜品列表 */
.dish-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-bottom: 40px;
}

.dish-category-section {
  margin-bottom: 4px;
}

.dish-category-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 15px;
  font-weight: 600;
  margin-bottom: 10px;
  padding-bottom: 6px;
  border-bottom: 2px solid;
}

.dish-category-title.dish { color: #ff6b35; border-color: rgba(255, 107, 53, 0.3); }
.dish-category-title.drink { color: #4facfe; border-color: rgba(79, 172, 254, 0.3); }
.dish-category-title.condiment { color: #9c27b0; border-color: rgba(156, 39, 176, 0.3); }

.dish-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-xl);
  cursor: pointer;
  transition: all 0.2s;
}

.dish-item:active {
  transform: scale(0.98);
}

.dish-image {
  width: 56px;
  height: 56px;
  border-radius: var(--hgu-radius-md);
  overflow: hidden;
  flex-shrink: 0;
  background: var(--bg);
  border: 1px solid rgba(255, 152, 0, 0.15);
}

.dish-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.dish-info {
  flex: 1;
  min-width: 0;
}

.dish-name {
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dish-price {
  font-size: 13px;
  color: var(--subtext);
  font-weight: 600;
}

.dish-item.ew-dish { border-color: rgba(255, 107, 53, 0.25); }
.dish-item.ew-drink { border-color: rgba(79, 172, 254, 0.25); }
.dish-item.ew-condiment { border-color: rgba(156, 39, 176, 0.25); }

.dish-name.ew-name-dish { color: #ff6b35; }
.dish-name.ew-name-drink { color: #4facfe; }
.dish-name.ew-name-condiment { color: #9c27b0; }

/* 随机推荐页 */

.random-refresh-btn {
  width: 100%;
  padding: 14px;
  border: 1.5px solid;
  border-radius: var(--hgu-radius-2xl);
  font-size: 15px;
  font-weight: 600;
  background: var(--hgu-surface-glass);
  backdrop-filter: blur(var(--hgu-blur-md));
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: all 0.2s;
  font-family: inherit;
}

.random-refresh-btn:active {
  transform: scale(0.95);
  background: rgba(128, 128, 128, 0.1);
}

#eatwhat-random-page.theme-dish .random-refresh-btn {
  border-color: #ff9800;
  color: #ff9800;
}

#eatwhat-random-page.theme-drink .random-refresh-btn {
  border-color: #4facfe;
  color: #4facfe;
}

/* 搜索结果 */
.eatwhat-search-results {
  display: flex;
  flex-direction: column;
  gap: 10px;
  animation: fadeInUp 0.3s ease;
}

.ew-search-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  background: var(--hgu-surface-glass);
  border: 1px solid rgba(255, 152, 0, 0.2);
  border-radius: var(--hgu-radius-default);
  cursor: pointer;
  transition: all 0.2s;
}

.ew-search-item:active {
  transform: scale(0.98);
  background: rgba(255, 152, 0, 0.08);
}

.ew-search-main {
  flex: 1;
  min-width: 0;
}

.ew-search-name {
  font-size: 15px;
  font-weight: 600;
  color: #ff9800;
  margin-bottom: 6px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ew-search-meta {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}

.ew-search-tag {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  background: rgba(255, 152, 0, 0.12);
  color: var(--subtext);
  border-radius: var(--hgu-radius-md);
  font-size: 11px;
  font-weight: 500;
}

.ew-search-price {
  font-size: 14px;
  font-weight: 700;
  color: #ff9800;
}

.ew-search-goto {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px 14px;
  border: 1px solid #ff9800;
  background: transparent;
  color: #ff9800;
  border-radius: var(--hgu-radius-default);
  font-size: 12px;
  cursor: pointer;
  transition: all 0.2s;
  white-space: nowrap;
  flex-shrink: 0;
  font-family: inherit;
}

.ew-search-goto:hover {
  background: #ff9800;
  color: #fff;
}

/* 菜品搜索结果与随机推荐统一使用菜品列表的分类配色 */
.ew-search-item.dish {
  border-color: rgba(255, 107, 53, 0.3);
}

.ew-search-item.drink {
  border-color: rgba(79, 172, 254, 0.3);
}

.ew-search-item.condiment {
  border-color: rgba(156, 39, 176, 0.3);
}

.ew-search-item.dish:active {
  background: rgba(255, 107, 53, 0.08);
}

.ew-search-item.drink:active {
  background: rgba(79, 172, 254, 0.08);
}

.ew-search-item.condiment:active {
  background: rgba(156, 39, 176, 0.08);
}

.ew-search-item.dish .ew-search-name,
.ew-search-item.dish .ew-search-price {
  color: #ff6b35;
}

.ew-search-item.drink .ew-search-name,
.ew-search-item.drink .ew-search-price {
  color: #4facfe;
}

.ew-search-item.condiment .ew-search-name,
.ew-search-item.condiment .ew-search-price {
  color: #9c27b0;
}

.ew-search-item.dish .ew-search-tag {
  background: rgba(255, 107, 53, 0.12);
}

.ew-search-item.drink .ew-search-tag {
  background: rgba(79, 172, 254, 0.12);
}

.ew-search-item.condiment .ew-search-tag {
  background: rgba(156, 39, 176, 0.12);
}

.ew-search-item.dish .ew-search-goto {
  border-color: #ff6b35;
  color: #ff6b35;
}

.ew-search-item.dish .ew-search-goto:hover {
  background: #ff6b35;
}

.ew-search-item.drink .ew-search-goto {
  border-color: #4facfe;
  color: #4facfe;
}

.ew-search-item.drink .ew-search-goto:hover {
  background: #4facfe;
}

.ew-search-item.condiment .ew-search-goto {
  border-color: #9c27b0;
  color: #9c27b0;
}

.ew-search-item.condiment .ew-search-goto:hover {
  background: #9c27b0;
}

/* 通用动画 */
@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

/* 加载与空状态 */
.search-loading {
  text-align: center;
  font-size: 13px;
  color: var(--subtext);
  padding: 20px 0;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  text-align: center;
  color: var(--subtext);
  opacity: 0.7;
}

.empty-state i {
  font-size: 40px;
  margin-bottom: 12px;
  opacity: 0.4;
}

/* 暗色模式 */

  html[data-theme="dark"] #eatwhat-page .sub-page-back,
  html[data-theme="dark"] #window-detail-page .sub-page-back,
  html[data-theme="dark"] #eatwhat-random-page .sub-page-back {
    color: #ffb74d;
  }

  html[data-theme="dark"] #eatwhat-page .sub-page-title,
  html[data-theme="dark"] #window-detail-page .sub-page-title,
  html[data-theme="dark"] #eatwhat-random-page .sub-page-title {
    color: #ffb74d;
  }

  html[data-theme="dark"] /* 喝什么暗色 - 蓝色系 */
  #eatwhat-random-page.theme-drink .sub-page-back {
    color: #66b3ff;
  }

  html[data-theme="dark"] #eatwhat-random-page.theme-drink .sub-page-title {
    color: #66b3ff;
  }

  html[data-theme="dark"] .eatwhat-search-bar {
    border-color: #ffb74d;
  }

  html[data-theme="dark"] .eatwhat-search-bar .clear-btn:hover {
    color: #ffb74d;
  }

  html[data-theme="dark"] .canteen-tab.active {
    color: #ffb74d;
  }

  html[data-theme="dark"] .canteen-tab-indicator {
    background: #ffb74d;
    box-shadow: 0 2px 6px rgba(255, 183, 77, 0.35);
  }

  html[data-theme="dark"] .eatwhat-action-btn.dish-btn {
    border-color: #ffb74d;
    color: #ffb74d;
  }

  html[data-theme="dark"] .eatwhat-action-btn.drink-btn {
    border-color: #66b3ff;
    color: #66b3ff;
  }

  html[data-theme="dark"] .floor-group-card {
    border-color: #ffb74d;
  }

  html[data-theme="dark"] .floor-group-title {
    color: #ffb74d;
    border-color: rgba(255, 183, 77, 0.25);
  }

  html[data-theme="dark"] .eatwhat-window-name {
    color: #ffb74d;
  }

  html[data-theme="dark"] .eatwhat-window-preview,
  html[data-theme="dark"] .window-cover,
  html[data-theme="dark"] .dish-image {
    border-color: rgba(255, 183, 77, 0.15);
  }

  html[data-theme="dark"] .window-info-card {
    border-color: rgba(255, 183, 77, 0.3);
  }

  html[data-theme="dark"] .window-header-info h2 {
    color: #ffb74d;
  }

  html[data-theme="dark"] .dish-category-title.dish { color: #ff8a65; border-color: rgba(255, 138, 101, 0.3); }
  html[data-theme="dark"] .dish-category-title.drink { color: #66b3ff; border-color: rgba(102, 179, 255, 0.3); }
  html[data-theme="dark"] .dish-category-title.condiment { color: #ce93d8; border-color: rgba(206, 147, 216, 0.3); }

  html[data-theme="dark"] .dish-menu-primary.dish,
  html[data-theme="dark"] .dish-menu-category.dish,
  html[data-theme="dark"] .dish-menu-group.dish,
  html[data-theme="dark"] .dish-menu-row.dish {
    --dish-accent: #ff8a65;
    --dish-accent-bg: rgba(255, 138, 101, .15);
  }

  html[data-theme="dark"] .dish-menu-primary.drink,
  html[data-theme="dark"] .dish-menu-category.drink,
  html[data-theme="dark"] .dish-menu-group.drink,
  html[data-theme="dark"] .dish-menu-row.drink {
    --dish-accent: #66b3ff;
    --dish-accent-bg: rgba(102, 179, 255, .15);
  }

  html[data-theme="dark"] .dish-menu-primary.condiment,
  html[data-theme="dark"] .dish-menu-category.condiment,
  html[data-theme="dark"] .dish-menu-group.condiment,
  html[data-theme="dark"] .dish-menu-row.condiment {
    --dish-accent: #ce93d8;
    --dish-accent-bg: rgba(206, 147, 216, .15);
  }

  html[data-theme="dark"] .dish-name.ew-name-dish { color: #ff8a65; }
  html[data-theme="dark"] .dish-name.ew-name-drink { color: #66b3ff; }
  html[data-theme="dark"] .dish-name.ew-name-condiment { color: #ce93d8; }

  html[data-theme="dark"] .dish-price {
    color: var(--subtext);
  }

  html[data-theme="dark"] .ew-tag-hours.unknown {
    background: rgba(255, 183, 77, 0.15);
    color: #ffb74d;
  }

  html[data-theme="dark"] .ew-search-name,
  html[data-theme="dark"] .ew-search-price {
    color: #ffb74d;
  }

  html[data-theme="dark"] .ew-search-tag {
    background: rgba(255, 183, 77, 0.15);
    color: #aaa;
  }

  html[data-theme="dark"] .ew-search-goto {
    border-color: #ffb74d;
    color: #ffb74d;
  }

  html[data-theme="dark"] .ew-search-goto:hover {
    background: #ffb74d;
    color: #1e1e1e;
  }

  

  

  

  

  

  

  

  

  html[data-theme="dark"] #eatwhat-random-page.theme-dish .random-refresh-btn {
    border-color: #ffb74d;
    color: #ffb74d;
  }

  html[data-theme="dark"] #eatwhat-random-page.theme-drink .random-refresh-btn {
    border-color: #66b3ff;
    color: #66b3ff;
  }

/* ==================== 随机推荐页面样式 ====================
   这一块的小票样式刻意「1:1 照搬」小票机.html 的观感：
   同一套配色变量（--ink / --ink-2 / --line / --paper）、同一种等宽字体、
   同样的虚线分隔与三列商品行。唯一不同的是小票里允许少量文字保留
   菜品橙 / 饮品蓝（食堂名、窗口名、菜品名、前往按钮），其余一律走小票配色。 */
#eatwhatPanelRandom {
  --rcpt-ink: #2b3244;
  --rcpt-ink-2: #8a93a6;
  --rcpt-line: #c8d0dc;
  --rcpt-paper: #ffffff;
  --rcpt-paper-edge: rgba(43, 50, 68, .10);
  --rcpt-divider: #d8dee8;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* 给底部固定的按钮留出空间，最后一张小票不会被挡住 */
  padding-bottom: 96px;
}

/* ---- 打印机 + 纸带的舞台 ----
   overflow: hidden 是这套动画的关键：新票插入时整张票被负 margin-top 顶到
   出纸口上方，如果没有这一层裁剪，就会看到小票从打印机**顶部**冒出来。
   裁掉之后才是「从机器内部滑出来」。 */
.ew-printer-stage {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow: hidden;
}

/* ---- 打印机：页面宽度的 3/4（高度不变） ----
   内容区宽 = 480 − 两侧各 20 = 440，取 3/4 即 330。 */
.ew-printer {
  position: relative;
  z-index: 5;
  width: 75%;
  max-width: 330px;
  height: 128px;
  flex-shrink: 0;
  background: var(--rcpt-ink);
  border-radius: 24px 24px 10px 10px;
  box-shadow: 0 26px 44px -26px rgba(43, 50, 68, .55);
}

.ew-printer-lid {
  position: absolute;
  top: 16px;
  left: 20px;
  right: 20px;
  height: 42px;
  background: #39415a;
  border-radius: 13px;
}

.ew-printer-slot {
  position: absolute;
  left: 50%;
  bottom: 11px;
  transform: translateX(-50%);
  width: 72%;
  max-width: 285px;
  height: 11px;
  background: #12161f;
  border-radius: 6px;
}

.ew-printer-leds {
  position: absolute;
  right: 22px;
  bottom: 26px;
  display: flex;
  gap: 7px;
}

.ew-printer-leds i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #4a5470;
  transition: background .25s ease;
}

.ew-printer-leds i.on { background: #3ddc97; }

.ew-printer-leds i.busy {
  background: #ffb020;
  animation: ewPrinterBlink .3s linear infinite;
}

@keyframes ewPrinterBlink {
  0%, 100% { opacity: 1; }
  50% { opacity: .15; }
}

/* ---- 纸带 ---- */
.ew-tape {
  width: 240px;
  max-width: 100%;
  margin-top: -8px;          /* 让第一张票从出纸口里"钻"出来，而不是浮在下面 */
  display: flex;
  flex-direction: column;
}

/* ---- 单张小票 ----
   新票插入时通过 margin-top 负值把整张票藏在出纸口上方，再动画到 0 ——
   视觉上就是「整张票从机器里向下滑出来」（与参考实现同一手法）。 */
.ew-receipt {
  width: 240px;
  max-width: 100%;
  transition: margin-top .68s cubic-bezier(.25, .8, .3, 1);
  will-change: margin-top;
}

.ew-receipt-inner {
  width: 240px;
  max-width: 100%;
  background: var(--rcpt-paper);
  padding: 18px 16px 0;
  color: var(--rcpt-ink);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, "PingFang SC", monospace;
  font-size: 12px;
  line-height: 1.6;
}

/* 两张小票之间的长虚线（模仿撕纸线） */
.ew-tear-line {
  height: 2px;
  margin-top: 18px;
  background-image: repeating-linear-gradient(
    to right,
    var(--rcpt-line) 0 16px,
    transparent 16px 26px
  );
}

/* 最底部那张不显示撕纸线（保留占位，避免高度跳动） */
.ew-receipt:last-child .ew-tear-line { visibility: hidden; }

/* ---- 小票内容 ---- */
.ew-r-shop {
  text-align: center;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 2px;
  margin-bottom: 4px;
  overflow-wrap: anywhere;
}

.ew-r-divider {
  border-top: 1px dashed var(--rcpt-divider);
  margin: 11px 0;
}

.ew-r-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 11px;
  color: var(--rcpt-ink-2);
  line-height: 1.85;
}

.ew-r-row > span:last-child {
  color: var(--rcpt-ink);
  text-align: right;
  overflow-wrap: anywhere;
}

/* 随机的菜品 / 饮品：菜名与数量、价格三列（与参考的 .r-good 一致） */
.ew-r-good {
  display: grid;
  grid-template-columns: 1fr 30px 56px;
  gap: 6px;
  font-size: 12px;
  line-height: 1.9;
}

.ew-r-good .g-price { text-align: right; }

/* 唯一保留彩色的四处：食堂名、窗口名、菜品名、前往按钮。
   浅色纸上的橙 / 蓝压得深一点，保证在小票的浅灰底上够清楚。 */
.ew-r-accent-dish { color: #c05f0c; }
.ew-r-accent-drink { color: #1f76bb; }

/* 评分那一行：星星 + 平均分 + (人数) */
.ew-r-rating {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-size: 11px;
  color: var(--rcpt-ink-2);
}

.ew-r-rating .stars {
  display: inline-flex;
  gap: 1px;
  color: #f5a623;
  font-size: 11px;
}

.ew-r-rating .stars .is-off { opacity: .28; }

.ew-r-rating .score {
  color: var(--rcpt-ink);
  font-weight: 700;
}

/* 小票底部的「前往」按钮 */
.ew-r-goto {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  margin: 2px 0 16px;
  padding: 10px 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 3px;
  text-indent: 3px;
  cursor: pointer;
  transition: transform .14s ease, background .2s ease;
}

.ew-r-goto:active { transform: scale(.95); }

.ew-r-goto.is-dish {
  color: #ff9800;
  border: 1.5px solid #ff9800;
}

.ew-r-goto.is-drink {
  color: #4facfe;
  border: 1.5px solid #4facfe;
}

/* 纸张用尽的提示（没有可推荐的菜品 / 饮品时） */
.ew-tape-empty {
  width: 240px;
  max-width: 100%;
  padding: 22px 16px;
  background: var(--rcpt-paper);
  color: var(--rcpt-ink-2);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, "PingFang SC", monospace;
  font-size: 12px;
  text-align: center;
}

/* ---- 底部按钮：居中放「推荐菜品」「推荐饮品」 ----
   挂在 body 上（见 life.js 的 initRandomDock）——
   抽屉里那一层带 transform，会成为 position:fixed 的包含块，
   按钮就会跟着页面一起上下滚；挂到 body 才是真正相对视口固定。 */
.ew-random-dock {
  position: fixed;
  left: 0;
  right: 0;
  bottom: var(--hgu-nav-clearance, 74px);
  display: flex;
  justify-content: center;
  gap: 12px;
  padding: 10px 16px;
  /* 只让按钮本身可点，中间的空隙不挡住小票上的「前往」 */
  pointer-events: none;
  z-index: 998;
}

/* [hidden] 必须能压住 display:flex —— 否则非随机视图下按钮也会一直挂在那儿 */
.ew-random-dock[hidden] { display: none !important; }

.ew-random-dock .random-type-btn {
  pointer-events: auto;
  min-width: 132px;
  padding: 11px 18px;
  /* 胶囊型：圆角加满，不跟 --hgu-radius-default 的方角 */
  border-radius: var(--hgu-radius-pill, 999px);
}

/* ---- 深色模式：小票换成「深灰纸 + 浅灰字」 ----
   纸在暗色下仍然是"纸"，只是深色纸；所有走 --rcpt-* 的文字、分隔线、
   撕纸线都会跟着换，不需要逐条覆盖。橙 / 蓝两处强调色相应提亮，
   否则原来的 #c05f0c / #1f76bb 在深灰底上几乎看不见。 */
html[data-theme="dark"] #eatwhatPanelRandom {
  --rcpt-ink: #e8ebf2;
  --rcpt-ink-2: #9aa3b5;
  --rcpt-line: #4a5266;
  --rcpt-paper: #2a2f3a;
  --rcpt-paper-edge: rgba(0, 0, 0, .4);
  --rcpt-divider: #454d60;
}

html[data-theme="dark"] .ew-printer {
  background: #1e2430;
  box-shadow: 0 26px 44px -26px rgba(0, 0, 0, .7);
}

html[data-theme="dark"] .ew-printer-lid {
  background: #2b3242;
}

html[data-theme="dark"] .ew-printer-slot {
  background: #0c0f16;
}

html[data-theme="dark"] .ew-printer-leds i {
  background: #3c4557;
}

html[data-theme="dark"] .ew-r-accent-dish { color: #ffab4d; }

html[data-theme="dark"] .ew-r-accent-drink { color: #63b8f5; }

html[data-theme="dark"] .ew-r-goto.is-dish {
  color: #ffab4d;
  border-color: #ffab4d;
}

html[data-theme="dark"] .ew-r-goto.is-drink {
  color: #63b8f5;
  border-color: #63b8f5;
}

html[data-theme="dark"] .ew-r-rating .stars { color: #ffc857; }

html[data-theme="dark"] .ew-tape-empty { color: var(--rcpt-ink-2); }

/* ==================== 推荐类型切换按钮 ==================== */
.random-type-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 16px;
}

.random-type-btn {
  padding: 12px;
  border: 1.5px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-default);
  font-size: 14px;
  font-weight: 600;
  background: var(--hgu-surface-glass);
  backdrop-filter: blur(var(--hgu-blur-md));
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: all 0.2s;
  font-family: inherit;
  color: var(--subtext);
}

.random-type-btn:active {
  transform: scale(0.95);
}

/* 菜品按钮 - 橙色主题 */
.random-type-btn[data-type="dish"] {
  border-color: #ff9800;
  color: #ff9800;
}

/* 饮品按钮 - 蓝色主题 */
.random-type-btn[data-type="drink"] {
  border-color: #4facfe;
  color: #4facfe;
}

/* ==================== 无图片时的 FontAwesome 占位图标 ==================== */
.img-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--subtext);
  opacity: 0.35;
}

/* 窗口预览图 */
.eatwhat-window-preview .img-placeholder {
  font-size: 22px;
}

/* 菜品小图 */
.dish-image .img-placeholder {
  font-size: 20px;
}

/* 随机推荐图 */

/* 窗口详情封面大图 */
.window-cover .img-placeholder {
  font-size: 48px;
  opacity: 0.2;
}

/* 暗色模式 */

  html[data-theme="dark"] .img-placeholder {
    opacity: 0.25;
  }

/* 菜品图片已停用：随机推荐保留纯图标占位，不加载图片资源。 */

/* ===== Source: room-search.css ===== */
#search-page {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
}

/* ============================================
   课节选择栏
   ============================================ */

/* 课节选择标签 */
.period-filter-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  flex-shrink: 0;
}
.period-filter-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 24px;
  width: 100%;
  max-width: 400px;
  user-select: none;
  -webkit-user-select: none;
  padding: 0 12px;
  box-sizing: border-box;
  touch-action: manipulation;
}

.period-filter-label {
  min-width: 0;
  white-space: normal;
  line-height: 1.35;
}

.period-select-btn {
  appearance: none;
  -webkit-appearance: none;
  min-height: 36px;
  padding: 0 13px;
  border: 1px solid rgba(var(--study-cyan-rgb), 0.4);
  border-radius: var(--hgu-radius-xl);
  background: rgba(var(--study-cyan-rgb), 0.1);
  color: var(--color-blue);
  font-size: 13px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
}

.secondary-drawer.period-selector-drawer {
  max-width: 480px;
  --text: var(--study-cyan);
  --color-blue: var(--study-cyan);
  border: 1.5px solid rgba(var(--study-cyan-rgb), 0.55);
}

.period-selector-drawer .secondary-drawer-handle {
  background: var(--study-cyan);
}

.period-selector-drawer .modal-header,
.period-selector-drawer .modal-close {
  color: var(--study-cyan);
}

.period-selector-body {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.period-selector-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 9px;
}

.period-selector-item {
  appearance: none;
  -webkit-appearance: none;
  min-width: 0;
  min-height: 68px;
  padding: 8px 4px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-xl);
  background: var(--hgu-surface-glass);
  color: var(--text);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  font-family: inherit;
  cursor: pointer;
}

.period-selector-item strong {
  font-size: 20px;
  line-height: 1;
}

.period-selector-item span {
  color: var(--subtext);
  font-size: 10px;
  line-height: 1.2;
  white-space: nowrap;
}

.period-selector-item.active {
  border-color: var(--color-blue);
  background: rgba(var(--study-cyan-rgb), 0.14);
  color: var(--color-blue);
}

.period-selector-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.search-official-links {
  width: 100%;
  max-width: 400px;
  margin: 18px auto 0;
}

.period-range-wrapper {
  flex: 1;
  position: relative;
  height: 44px;
  display: flex;
  align-items: center;
  padding: 0 4px;
}

.period-range-track {
  position: relative;
  width: 100%;
  height: 6px;
  background: var(--border);
  border-radius: 3px;
  touch-action: none;
  cursor: pointer;
  margin: 0 10px;
}

.period-range-highlight {
  position: absolute;
  top: 0;
  height: 100%;
  background: var(--text);
  border-radius: 3px;
  pointer-events: none;
  opacity: 0.5;
}

.period-range-thumb {
  position: absolute;
  top: 50%;
  width: 20px;
  height: 20px;
  background: var(--text);
  border: 2px solid #fff;
  border-radius: var(--hgu-radius-round);
  transform: translate(-50%, -50%);
  cursor: grab;
  box-shadow: 0 2px 6px rgba(0,0,0,0.2);
  z-index: 2;
  touch-action: none;
  transition: transform 0.1s, opacity 0.2s;
  opacity: 0.5;
}

.period-range-thumb.dragging {
  transform: translate(-50%, -50%) scale(1.25);
  cursor: grabbing;
  opacity: 1;
}

.period-range-thumb.active {
  opacity: 1;
}

.period-range-labels {
  position: absolute;
  top: 22px;
  left: 0;
  right: 0;
  height: 16px;
  pointer-events: none;
}

.period-range-labels span {
  position: absolute;
  font-size: 11px;
  color: var(--subtext);
  width: 16px;
  text-align: center;
}

.period-clear-btn {
  flex-shrink: 0;
  padding: 6px 14px;
  border: 1px solid var(--hgu-border-soft);
  background: var(--hgu-surface-glass);
  border-radius: var(--hgu-radius-xl);
  font-size: 13px;
  color: var(--subtext);
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
}

.period-clear-btn:active {
  transform: scale(0.95);
}

/* ============================================
   教学楼筛选栏（横向滑动）
   ============================================ */
.building-filter-bar {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
  margin-top: 8px;
  margin-bottom: 16px;
  padding-bottom: 4px;
  width: 100%;
  max-width: 400px;
}

.building-filter-bar::-webkit-scrollbar {
  display: none;
}

.building-filter-btn {
  flex-shrink: 0;
  padding: 6px 14px;
  border: 1px solid var(--hgu-border-soft);
  background: var(--hgu-surface-glass);
  border-radius: var(--hgu-radius-2xl);
  font-size: 13px;
  color: var(--subtext);
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
  white-space: nowrap;
}

.building-filter-btn.active {
  background: var(--text);
  color: #fff;
  border-color: var(--text);
  font-weight: 600;
}

.building-filter-btn:active {
  transform: scale(0.95);
}

/* ============================================
   分类标题
   ============================================ */
.room-category-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  margin: 16px 0 8px;
  padding-left: 4px;
}

/* ============================================
   标签列表
   ============================================ */
.room-tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  width: 100%;
}

/* ============================================
   教室标签
   ============================================ */
.room-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-xl);
  cursor: pointer;
  transition: all 0.2s;
}

.room-tag:active {
  transform: scale(0.95);
  background: rgba(128, 128, 128, 0.15);
}

.room-tag-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}

.room-tag-notes {
  font-size: 12px;
  color: var(--subtext);
  opacity: 0.7;
  font-weight: 400;
}

.room-tag-status {
  font-size: 12px;
  font-weight: 500;
}

.room-tag-status.status-busy {
  color: #ff4757;
}

.room-tag-status.status-soon {
  color: #ff9800;
}

.room-tag-status.status-free {
  color: #999;
}

.room-tag-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: 4px;
}

.room-tag-btn {
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  border-radius: var(--hgu-radius-round);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
  padding: 0;
  font-size: 14px;
}

.room-tag-btn:hover {
  background: var(--text-light);
}

.room-tag-btn:active {
  transform: scale(0.9);
}

/* ============================================
   空状态与加载
   ============================================ */
.search-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 20px;
  text-align: center;
}

.search-empty-state i {
  font-size: 48px;
  margin-bottom: 16px;
  opacity: 0.3;
  color: var(--subtext);
}

.search-empty-state p {
  font-size: 15px;
  color: var(--subtext);
  margin: 0;
}

.search-loading {
  text-align: center;
  font-size: 13px;
  color: var(--subtext);
  padding: 12px 0;
}

.no-result {
  text-align: center;
  color: var(--subtext);
  padding: 40px 20px;
  opacity: 0.5;
}

/* ============================================
   新版空教室筛选卡片
   ============================================ */
.room-filter-card {
  width: 100%;
  max-width: 430px;
  margin: 0 auto 14px;
  padding: 12px;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-2xl);
  box-shadow: var(--hgu-shadow-card);
  box-sizing: border-box;
}

.room-filter-section + .room-filter-section {
  margin-top: 10px;
}

.room-filter-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 7px;
}

.room-date-filter-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px;
}

.room-date-btn,
.room-filter-card .period-filter-btn {
  appearance: none;
  -webkit-appearance: none;
  min-width: 0;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-lg);
  background: rgba(255, 255, 255, 0.42);
  color: var(--subtext);
  font-family: inherit;
  cursor: pointer;
  transition: transform 0.16s, background 0.16s, border-color 0.16s, color 0.16s;
}

.room-date-btn {
  min-height: 42px;
  padding: 5px 1px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
}

.room-date-btn span {
  font-size: 11px;
  line-height: 1.1;
  font-weight: 700;
  white-space: nowrap;
}

.room-date-btn small {
  font-size: 10px;
  line-height: 1;
  opacity: 0.75;
  white-space: nowrap;
}

.room-filter-card .period-filter-bar {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 5px;
  margin: 0;
  width: 100%;
  max-width: none;
  padding: 0;
}

.room-filter-card .period-filter-btn {
  min-height: 30px;
  padding: 4px 0;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.1;
}

.room-date-btn.active,
.room-filter-card .period-filter-btn.active {
  border-color: var(--study-cyan);
  background: rgba(var(--study-cyan-rgb), 0.16);
  color: var(--study-cyan);
}

.room-date-btn:active,
.room-filter-card .period-filter-btn:active,
.room-filter-clear-btn:active,
.room-floor-room-btn:active {
  transform: scale(0.96);
}

.room-filter-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
}

.room-filter-clear-btn {
  appearance: none;
  -webkit-appearance: none;
  min-height: 28px;
  padding: 0 10px;
  border: 1px solid rgba(var(--study-cyan-rgb), 0.36);
  border-radius: var(--hgu-radius-pill);
  background: transparent;
  color: var(--study-cyan);
  font-size: 12px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  transition: transform 0.16s, background 0.16s;
}

/* ============================================
   楼层折叠卡片
   ============================================ */
.room-search-list {
  width: 100%;
  max-width: 430px;
  margin: 0 auto;
}

.room-floor-card {
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-2xl);
  overflow: hidden;
  box-shadow: var(--hgu-shadow-card);
  margin-bottom: 12px;
}

.room-floor-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  cursor: pointer;
  transition: background 0.2s;
}

.room-floor-header:active {
  background: rgba(128, 128, 128, 0.08);
}

.room-floor-title-wrap {
  min-width: 0;
  flex: 1;
}

.room-floor-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.25;
}

.room-floor-meta {
  margin-top: 3px;
  font-size: 12px;
  color: var(--subtext);
}

.room-floor-progress {
  display: flex;
  height: 6px;
  margin-top: 9px;
  overflow: hidden;
  border-radius: var(--hgu-radius-pill);
  background: rgba(128, 128, 128, 0.16);
}

.room-floor-progress-free {
  height: 100%;
  background: var(--study-cyan);
}

.room-floor-progress-busy {
  height: 100%;
  background: rgba(255, 71, 87, 0.72);
}

.room-floor-arrow {
  flex-shrink: 0;
  color: var(--subtext);
  font-size: 13px;
  transition: transform 0.2s;
}

.room-floor-card.expanded .room-floor-arrow {
  transform: rotate(180deg);
}

.room-floor-body {
  display: none;
  border-top: 1px solid var(--hgu-border-soft);
  padding: 10px;
}

.room-floor-card.expanded .room-floor-body {
  display: block;
}

.room-floor-room-grid {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.room-floor-room-btn {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  box-sizing: border-box;
  min-height: 0;
  padding: 10px 12px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-xl);
  background: rgba(255, 255, 255, 0.38);
  color: var(--text);
  display: block;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: transform 0.16s, border-color 0.16s, background 0.16s;
}

.room-floor-room-btn.free {
  border-color: rgba(var(--study-cyan-rgb), 0.34);
}

.room-floor-room-btn.busy {
  opacity: 0.76;
}

.room-floor-room-main {
  display: flex;
  flex-direction: column;
  gap: 7px;
  width: 100%;
}

.room-floor-room-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.room-floor-room-id {
  min-width: 0;
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}

.room-floor-room-id strong {
  font-size: 15px;
  line-height: 1.1;
  color: var(--study-cyan);
  font-weight: 900;
}

.room-floor-room-id em {
  font-style: normal;
  font-size: 11px;
  line-height: 1.1;
  color: var(--subtext);
  font-weight: 600;
  white-space: nowrap;
}

.room-floor-room-schedule-hint {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--subtext);
  font-size: 11px;
  font-weight: 600;
}

.room-floor-room-schedule-hint i {
  color: var(--study-cyan);
  font-size: 12px;
}

.room-floor-room-note {
  font-size: 10px;
  line-height: 1.2;
  color: var(--subtext);
  font-style: normal;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 12 课时占用进度条 */
.room-period-track {
  display: flex;
  gap: 3px;
  width: 100%;
}

.room-period-cell {
  flex: 1 1 0;
  min-width: 0;
  height: 10px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.62);
  border: 1px solid rgba(127, 127, 127, 0.22);
  box-sizing: border-box;
}

.room-period-cell.busy {
  background: #e5484d;
  border-color: rgba(229, 72, 77, 0.4);
}

/* 选中课节（上方筛选条件）：格子边框黑色，区别于未选中的浅灰 */
.room-period-cell.selected {
  border-color: #000;
  border-width: 1.5px;
}

/* 课时数字：灰色字体；选中课节数字改为黑色 */
.room-period-labels {
  display: flex;
  gap: 3px;
  width: 100%;
  color: var(--subtext);
  font-size: 9px;
  font-weight: 600;
  line-height: 1.1;
}

.room-period-labels span {
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
}

.room-period-labels span.selected {
  color: #000;
  font-weight: 800;
}

/* 暗色模式适配 */

  html[data-theme="dark"] .room-date-btn,
  html[data-theme="dark"] .room-filter-card .period-filter-btn,
  html[data-theme="dark"] .room-floor-room-btn {
    background: rgba(255, 255, 255, 0.06);
  }
  html[data-theme="dark"] .room-tag-name {
    color: #fff;
  }
  html[data-theme="dark"] .room-tag-status.status-free {
    color: #888;
  }
  html[data-theme="dark"] .period-range-thumb {
    border-color: var(--bg);
  }
  html[data-theme="dark"] .room-floor-room-id strong {
    color: var(--study-cyan);
  }
  html[data-theme="dark"] .room-period-cell {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.14);
  }
  html[data-theme="dark"] .room-period-cell.busy {
    background: #e5484d;
    border-color: rgba(229, 72, 77, 0.4);
  }
  /* 暗色下黑色不可见，选中课节反色为白色 */
  html[data-theme="dark"] .room-period-cell.selected {
    border-color: #fff;
  }
  html[data-theme="dark"] .room-period-labels {
    color: rgba(255, 255, 255, 0.45);
  }
  html[data-theme="dark"] .room-period-labels span.selected {
    color: #fff;
  }

/* ===== Source: classroom-schedule.css ===== */
#classroom-schedule-page {
  padding: 0 !important;
  display: flex;
  flex-direction: column;
  overflow-y: hidden !important;
}

#classroom-schedule-page .schedule-header {
  justify-content: center !important;
  position: relative;
  flex-wrap: nowrap;
  gap: 8px;
}

#classroom-schedule-page .sub-page-back {
  position: absolute;
  left: 8px;
  top: 50%;
  transform: translateY(-50%);
}

#classroom-schedule-page .sub-page-title {
  text-align: center;
}

#classroom-schedule-page .schedule-page-content {
  max-width: 100%;
  padding: 0;
  align-items: stretch;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

#classroom-schedule-page .course-section {
  max-width: 100%;
  margin: 0;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

#classroom-schedule-page #classroomManageSection {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  position: relative;
}

#classroom-schedule-page:not(.active) .schedule-float-nav {
  display: none;
}

/* 教室课表课程块：统一单色背景 */
.classroom-course {
  background: rgba(var(--study-cyan-rgb), 0.14) !important;
  border-color: rgba(var(--study-cyan-rgb), 0.36) !important;
}

  html[data-theme="dark"] .classroom-course {
    background: rgba(var(--study-cyan-rgb), 0.15) !important;
    border-color: rgba(var(--study-cyan-rgb), 0.36) !important;
  }

/* ================== 课表/座位切换按钮 ================== */
.schedule-seat-toggle {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  background: var(--card-bg, rgba(0,0,0,0.06));
  border-radius: var(--hgu-radius-3xl);
  padding: 2px;
  gap: 0;
}

.schedule-seat-toggle .toggle-btn {
  border: none;
  background: transparent;
  color: var(--subtext, #999);
  font-size: 11px;
  padding: 4px 10px;
  border-radius: var(--hgu-radius-polished);
  cursor: pointer;
  transition: all 0.25s ease;
  display: flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}

.schedule-seat-toggle .toggle-btn.active {
  background: var(--study-cyan);
  color: #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,0.15);
}

.schedule-seat-toggle .toggle-btn:not(.active):hover {
  color: var(--text, #333);
}

/* ================== 座位排布视图 ================== */
.seat-layout-section {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  padding: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.seat-layout-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 1;
  min-height: 0;
}

.seat-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--subtext, #999);
  font-size: 14px;
  padding: 40px 0;
}

.seat-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  color: var(--subtext, #999);
  font-size: 14px;
  padding: 60px 0;
}

.seat-empty i {
  font-size: 40px;
  opacity: 0.3;
}

/* 座位图例 */
.seat-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  margin-bottom: 16px;
  padding: 10px 14px;
  background: var(--card-bg, rgba(0,0,0,0.04));
  border-radius: var(--hgu-radius-lg);
  width: 100%;
}

.seat-legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--subtext, #666);
}

.seat-legend-icon {
  width: 20px;
  height: 16px;
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 9px;
}

/* Canvas 座位图 */
.seat-canvas {
  border-radius: var(--hgu-radius-md);
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}

.seat-canvas-wrapper {
  cursor: default;
}

.seat-canvas-wrapper:active {
  cursor: grabbing;
}

/* 隐藏座位区域的滚动条 */
.seat-layout-section {
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* IE/Edge */
}

.seat-layout-section::-webkit-scrollbar {
  display: none;
}

  html[data-theme="dark"] .seat-legend {
    background: rgba(255,255,255,0.04);
  }

html[data-theme="dark"] .classroom-course {
  background: rgba(var(--study-cyan-rgb), 0.15) !important;
  border-color: rgba(var(--study-cyan-rgb), 0.36) !important;
}

html[data-theme="dark"] .seat-legend {
  background: rgba(255,255,255,0.04);
}

/* ===== Source: course-schedule.css ===== */
/* 课表页 */
#schedule-page {
  display: flex;
  flex-direction: column;
  overflow-y: hidden !important;
}

#schedule-page .sub-page-header {
  margin: 0;
  padding: 0;
  flex-shrink: 0;
}

#schedule-page .schedule-page-content {
  max-width: 100%;
  padding: 0;
  align-items: stretch;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  position: relative;
}

#schedule-page .course-section {
  max-width: 100%;
  margin: 0;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

#schedule-page #courseManageSection {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  position: relative;
}

/* 课表页标题栏：不再"完全透明"（那套会把毛玻璃关掉，下面滚上来的内容看不见）。
   这里只保留它自己的疏密与左右分布，底色与毛玻璃统一交给 .is-fixed-header。
   注意内边距：这两个页面自己已经铺满面板宽，内容靠 .sub-page-header-row 的
   10px 16px 定位 —— 位置与改造前一致。 */
.schedule-header {
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 0;
  padding: 0;
  justify-content: space-between;
}

.schedule-header-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

/* ================== 课表页固定标题栏：撤销"完全透明"那套 ==================
 * .schedule-header 上面写了 background: transparent !important 与
 * backdrop-filter: none !important —— 那是"标题栏完全透明"时代的产物，
 * 会把新的毛玻璃整套关掉，所以在这里覆盖回来。
 * （必须排在那条规则之后：两者优先级相同时后者生效。）
 *
 * 同时把上下内边距从 .schedule-header 挪到 .sub-page-header-row 上：
 * 标题栏本体只负责铺背景（毛玻璃 + 顶端纯色带），
 * 里面那一行仍旧是 10px 16px 的呼吸感，所以返回键/标题/管理按钮位置不变。 */
.schedule-header.is-fixed-header {
  /* 注意：**不要**在这里写 backdrop-filter: none ——
     那会把 .is-fixed-header 上那层毛玻璃整套关掉（上一版就是这么写的，
     结果这两个页面的标题栏完全不透明、下面滚上来的内容看不见）。
     也不要写 background: transparent !important —— 毛玻璃的透明度靠 blur，
     刷任何底色都会在顶端切出一条发白 / 发黑的带。 */
  border-bottom: 0;
  padding: 0 !important;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start !important;
}

.sub-page-header-row.schedule-header-row {
  justify-content: space-between !important;
  padding: 10px 16px;
}

/* 课表内容从标题栏下方开始显示，但滚动视口要延伸到标题栏后面，
   这样周次表格向上滚动时才能真正经过标题栏并被其毛玻璃采样。 */
#schedule-page .schedule-page-content,
#classroom-schedule-page .schedule-page-content {
  margin-top: -44px;
  padding-top: 0;
  box-sizing: border-box;
}

#schedule-page .schedule-slide,
#classroom-schedule-page .schedule-slide {
  /* 见文件后面那条同样选择器的规则（那里有完整的三步推导）。
     这里保留同样的值，避免两处不一致。 */
  padding-top: 44px;
  box-sizing: border-box;
}

/* 课表页的星期栏：**不算标题栏的一部分**（需求），但仍旧固定 ——
   它本来就在 .schedule-slide / .schedule-home-table-wrapper 这些滚动容器里
   写着 sticky top:0，那本身就已经是"固定"的了；
   之前我把它改成 top: var(--page-header-height) 想让它停在标题栏下面，
   那反而把它算成了标题栏的延伸。这里改回 top:0，让它按自己的方式固定：
   滚上去时吸在滚动容器顶部（与标题栏各自独立）。
   —— 注意它会被标题栏盖住一部分，那是正常的层叠：标题栏是"浮在内容上的毛玻璃"，
   星期栏属于被它盖住的内容。 */
#schedule-page .schedule-table thead th,
#classroom-schedule-page .schedule-table thead th {
  top: 0;
}

.schedule-header-btn {
  width: 36px;
  height: 36px;
  border-radius: var(--hgu-radius-round);
  border: 1px solid var(--text);
  background: transparent;
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 16px;
  transition: all 0.2s;
  padding: 0;
}

.schedule-header-btn:active {
  transform: scale(0.9);
}

.schedule-header-btn.danger {
  border-color: #ff4757;
  color: #ff4757;
}

/* 课表页标题栏「刷新」按钮：高度与管理按钮(pill)一致，图标用主文本色。
   .schedule-header-btn 默认是 36×36 圆形图标按钮，这里只改刷新按钮这一颗。
   注意：initFixedPageHeaders()（core.js）会把整个课表头部 appendChild 到
   .tools-fixed-header-layer，运行时 #scheduleRefreshBtn 已不在 #schedule-page 内，
   所以选择器【不能】限定 #schedule-page 祖先，否则匹配不到、退回圆形基础样式。
   直接按 id 命中即可（ID 特异性仍胜过 .schedule-header-btn 的 class）。 */
#scheduleRefreshBtn {
  width: auto;
  height: auto;
  box-sizing: border-box;
  white-space: nowrap;
  padding: 6px 13px;
  border-radius: var(--hgu-radius-3xl);
  /* 用「主文本色」token 而非裸 var(--text)：课表头部被移进 .tools-fixed-header-layer
     后，该层对 schedule-page 把 --text 覆盖成了 --study-cyan（青蓝，见 app.css:20391），
     裸 var(--text) 会跟着变青蓝。--hgu-idle-chrome 是项目专设的「主文本色」token
     （app.css:19，在 :root 顶层锁定 var(--text)），不随页面主题漂移，正好命中需求。 */
  border: 1px solid var(--hgu-idle-chrome);
  background: transparent;
  color: var(--hgu-idle-chrome);
  font-size: 14px;
}

/* 课表调休显示 选项后的「帮助」圆圈问号按钮（选项页 + 课表管理弹窗共用） */
.reschedule-help-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  margin-left: 6px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--subtext);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  vertical-align: middle;
  transition: color .15s;
}
.reschedule-help-btn:hover { color: var(--text); }
.reschedule-help-btn i { pointer-events: none; }

/* 调休说明悬浮提示框：点击位置右上角弹出，点击/滑动任意区域自动关闭 */
.reschedule-help-tip {
  position: fixed;
  /* ⛔ 必须高于所有二级抽屉遮罩 —— 课表管理弹窗是 .secondary-drawer-overlay
     （z-index 10002），而本提示框是挂在 <body> 上的固定层，两者同在根层叠上下文里，
     z-index 写小了会被弹窗整个盖住（表现：点了问号，文本框弹在弹窗"后面"看不见）。
     取值 10070 = 高过所有抽屉/弹窗（最高 10060），又低于 toast（100000）。 */
  z-index: 10070;
  max-width: 260px;
  padding: 10px 12px;
  background: #2b2f33;
  color: #fff;
  font-size: 13px;
  line-height: 1.5;
  border-radius: 10px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .25);
  pointer-events: auto;
}
.reschedule-help-tip[hidden] { display: none; }

/* 课表滑动容器：JS 控制，禁用原生惯性滚动 */
.schedule-slider {
  display: flex;
  width: 100%;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  position: relative;
  touch-action: pan-y;
}

.schedule-slide {
  flex: 0 0 100%;
  width: 100%;
  min-width: 100%;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  position: relative;
  /* 课表是按 slide 高度铺满的（.schedule-table 高度 100%），页面底部的固定留白
     去掉后最后两节课会落到悬浮栏下面：这里按悬浮栏避让高度留白，整张课表被抬到
     悬浮栏上方；行高由浏览器重新分配，不够时 slide 自身可以滚动。 */
  padding-bottom: var(--hgu-nav-clearance, 78px);
  box-sizing: border-box;
}

/* 电脑端隐藏课表页右侧滚动条 */
@media (min-width: 768px) {
  #schedule-page .schedule-slide,
  #classroom-schedule-page .schedule-slide {
    scrollbar-width: none;
    -ms-overflow-style: none;
  }

  #schedule-page .schedule-slide::-webkit-scrollbar,
  #classroom-schedule-page .schedule-slide::-webkit-scrollbar {
    display: none;
  }
}

/* 课表表格：表头与侧边栏完全透明 */
.schedule-table,
#homeScheduleTable {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  font-size: 11px;
  margin: 0;
}

.schedule-table {
  height: 100%;
}

.schedule-table th {
  position: sticky;
  top: 0;
  z-index: 30;
  background: transparent !important;
}

.schedule-table th:first-child,
#homeScheduleTable th:first-child,
.schedule-table td:first-child,
#homeScheduleTable td:first-child {
  width: 40px !important;
  min-width: 40px !important;
  max-width: 40px !important;
  text-align: center;
  vertical-align: middle;
}

.schedule-table th:first-child {
  padding: 8px 2px;
  z-index: 40;
  left: 0;
}

.schedule-table td:first-child {
  padding: 4px 1px;
  position: sticky;
  left: 0;
  z-index: 20;
  background: transparent !important;
}

#homeScheduleTable th:first-child,
#homeScheduleTable td:first-child {
  padding: 4px 1px;
  background: rgba(128, 128, 128, 0.06);
  border-right: 1px solid rgba(0,0,0,0.08);
  border-bottom: 1px solid rgba(0,0,0,0.08);
  position: sticky;
  left: 0;
  z-index: 20;
}

.schedule-table th:not(:first-child),
.schedule-table td:not(:first-child),
#homeScheduleTable th:not(:first-child),
#homeScheduleTable td:not(:first-child) {
  padding: 0;
  border-right: 1px solid rgba(0,0,0,0.08);
  border-bottom: 1px solid rgba(0,0,0,0.06);
}

#homeScheduleTable th:not(:first-child),
#homeScheduleTable td:not(:first-child) {
  width: calc((100% - 40px) / 7) !important;
}

.schedule-table th:not(:first-child),
#homeScheduleTable th:not(:first-child) {
  padding: 6px 2px;
  font-weight: 600;
  font-size: 11px;
  line-height: 1.2;
}

.schedule-table tbody tr,
#homeScheduleTable tbody tr {
  height: 60px !important;
  max-height: 60px;
}

.schedule-table tbody td,
#homeScheduleTable tbody td {
  height: 60px !important;
  max-height: 60px;
  box-sizing: border-box;
}

.schedule-table th:last-child,
.schedule-table td:last-child,
#homeScheduleTable th:last-child,
#homeScheduleTable td:last-child {
  border-right: 1px solid rgba(0,0,0,0.08) !important;
}

/* 右下角悬浮周次切换按钮 */
.schedule-float-nav {
  position: fixed;
  /* 这个按钮的包含块是 .tools-sub-page（带 transform），bottom 是相对页面底边算的。
     页面底边的留白去掉后它会落到悬浮栏下面，所以这里按悬浮栏避让高度抬起来
     （--hgu-nav-clearance 由 JS 按悬浮栏真实占用写入）。 */
  bottom: var(--hgu-nav-clearance, 74px);
  right: 16px;
  display: flex;
  flex-direction: row;
  gap: 10px;
  z-index: 60;
  pointer-events: none;
}

#schedule-page:not(.active) .schedule-float-nav {
  display: none;
}

.schedule-float-btn {
  width: 44px;
  height: 44px;
  border-radius: var(--hgu-radius-xl);
  border: 1px solid var(--hgu-border-soft);
  background: var(--hgu-surface-glass);
  backdrop-filter: blur(var(--hgu-blur-xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-xl));
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 18px;
  pointer-events: auto;
  box-shadow: var(--hgu-shadow-card);
  transition: all 0.2s;
  padding: 0;
}

.schedule-float-btn:active {
  transform: scale(0.92);
}

/* 课程导入按钮 */
.course-import-btn-wide {
  width: 100%;
  padding: 16px 24px;
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-xl);
  background: var(--text-light);
  color: var(--text);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s ease;
  font-family: inherit;
}

.course-import-btn-wide:hover {
  background: var(--text);
  color: #fff;
}

.course-import-btn-wide:active {
  transform: scale(0.98);
}

.freshman-schedule-entry {
  margin-top: 10px;
  background: rgba(var(--study-cyan-rgb), 0.08);
  border-color: rgba(var(--study-cyan-rgb), 0.58);
  color: var(--study-cyan);
}

/* 课程块样式 */
.course-cell-overlay {
  position: absolute;
  border-radius: var(--hgu-radius-sm);
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  padding: 4px;
  box-sizing: border-box;
  overflow: visible;
  cursor: pointer;
  font-size: 10px;
  color: #000;
  border: 1px solid rgba(0,0,0,0.1);
  backdrop-filter: blur(var(--hgu-blur-xs));
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  line-height: 1.2;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.course-cell-overlay:active {
  transform: scale(0.92);
  transition: transform 0.08s ease;
}

.course-cell-overlay .course-name {
  font-weight: 600;
  font-size: 8px;
  line-height: 1.2;
  text-align: left;
  width: 100%;
  word-break: break-word;
  overflow-wrap: break-word;
  white-space: normal;
  margin-bottom: 2px;
}

.course-cell-overlay .course-room {
  font-size: 7px;
  opacity: 0.85;
  text-align: left;
  width: 100%;
  line-height: 1.2;
  word-break: break-word;
  overflow-wrap: break-word;
  white-space: normal;
  margin-bottom: 1px;
}

.course-cell-overlay .course-teacher {
  font-size: 6px;
  opacity: 0.7;
  text-align: left;
  width: 100%;
  line-height: 1.2;
  word-break: break-word;
  overflow-wrap: break-word;
  white-space: normal;
  margin-top: auto;
}

/* 课表分享全屏页 */
#shareScheduleOverlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(255, 255, 255, 0.5);
  backdrop-filter: blur(var(--hgu-blur-lg));
  -webkit-backdrop-filter: blur(var(--hgu-blur-lg));
  display: none;
  flex-direction: column;
  align-items: center;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
  overscroll-behavior: contain;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

#shareScheduleOverlay::-webkit-scrollbar {
  display: none;
}

#shareScheduleOverlay.active {
  display: flex;
}

.share-back-btn {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 1001;
  width: 36px;
  height: 36px;
  border-radius: var(--hgu-radius-round);
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  cursor: pointer;
  backdrop-filter: blur(var(--hgu-blur-md));
  -webkit-backdrop-filter: blur(var(--hgu-blur-md));
  box-shadow: var(--hgu-shadow-card);
  transition: all 0.2s;
  padding: 0;
}

.share-back-btn:active {
  transform: scale(0.95);
}

.share-scroll-content {
  width: 100%;
  max-width: 420px;
  padding: 44px 14px 40px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.share-content {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
}

.share-title-row {
  text-align: center;
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 4px;
  padding: 0 4px;
  line-height: 1.3;
}

.share-title-input {
  display: inline-block;
  min-width: 32px;
  max-width: 160px;
  border-bottom: 2px solid var(--text);
  padding: 0 2px 1px;
  outline: none;
  color: var(--text);
  font-weight: 700;
  font-size: 16px;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  line-height: 1.2;
  transition: border-color 0.2s;
}

.share-title-input:focus {
  border-bottom-color: var(--color-blue);
}

.share-title-suffix {
  color: var(--text);
  font-weight: 700;
  font-size: 16px;
  white-space: nowrap;
}

.share-tags-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  padding: 0 2px;
  margin-bottom: 2px;
}

.share-tag {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--hgu-radius-2xl);
  font-size: 11px;
  font-weight: 600;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,0.15);
  letter-spacing: 0.2px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}

.share-weeks-grid {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
}

.share-weeks-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
}

.share-week-mini {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}

.share-week-cells {
  position: relative;
  width: 100%;
  padding-bottom: 155%;
  background: rgba(128,128,128,0.05);
  border-radius: var(--hgu-radius-sm);
  overflow: hidden;
  border: 1px solid rgba(0,0,0,0.05);
}

.share-week-cell {
  position: absolute;
  border-radius: 1px;
  opacity: 0.95;
  transform: scale(0.88);
  transform-origin: center;
}

.share-week-label {
  font-size: 9px;
  color: var(--subtext);
  font-weight: 500;
  line-height: 1.1;
}

/* ================== 课表总览：视图切换 + 课程列表 ================== */
/* 「热图 / 列表」切换：直接复用食堂切换按钮类名
   （.eatwhat-canteen-tabs / .canteen-tab / .canteen-tab-indicator），此处仅微调留白 */
#scheduleOverviewViewTabs {
  margin: 2px 0 0;
  padding: 0 2px;
}

/* 「列表」视图：课程明细卡片 */
.schedule-overview-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0 2px;
}

.schedule-overview-course {
  background: var(--glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-xl);
  padding: 10px 12px;
}

.schedule-overview-course-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}

.schedule-overview-course-name {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.35;
  word-break: break-word;
}

.schedule-overview-course-credit {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  background: #ff9800;
  border-radius: var(--hgu-radius-2xl);
  padding: 1px 8px;
  white-space: nowrap;
}

.schedule-overview-course-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 3px 12px;
  font-size: 12px;
  color: var(--subtext);
  line-height: 1.8;
}

.schedule-overview-course-meta i {
  width: 13px;
  text-align: center;
  margin-right: 2px;
  opacity: 0.75;
}

.schedule-overview-course-note {
  margin-top: 3px;
  font-size: 11px;
  color: var(--subtext);
  opacity: 0.65;
  line-height: 1.5;
  word-break: break-all;
}

.share-footer {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--hgu-border-soft);
  margin-top: 2px;
  width: 100%;
}

.share-footer-logo {
  width: 32px;
  height: 32px;
  border-radius: var(--hgu-radius-sm);
  object-fit: cover;
  flex-shrink: 0;
  background: var(--hgu-surface-glass);
}

.share-footer-info {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.share-footer-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.3;
}

.share-footer-link {
  font-size: 10px;
  color: var(--subtext);
  opacity: 0.7;
  line-height: 1.3;
  word-break: break-all;
}

/* ============================================
   8. 课表弹窗与课程表
   ============================================ */
.overlay {
  position: fixed;
  inset: 0;
  background: var(--hgu-surface-glass);
  backdrop-filter: blur(var(--hgu-blur-lg));
  z-index: 10001;
  display: none;
}

.course-section {
  width: 100%;
  max-width: 400px;
  margin-bottom: 16px;
  touch-action: pan-y;
  -webkit-overflow-scrolling: touch;
}

.course-schedule-home {
  width: 100%;
  max-width: 480px;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-2xl);
  overflow: hidden;
  margin-bottom: 12px;
  touch-action: pan-y;
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

.schedule-home-header {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--hgu-border-soft);
  background: var(--text-light);
  position: sticky;
  top: 0;
  z-index: 5;
}

.schedule-home-header button {
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
  border-radius: var(--hgu-radius-round);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}

.schedule-home-header button:hover {
  background: var(--text);
  color: #fff;
}

.schedule-home-header span {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  min-width: 70px;
  text-align: center;
}

.schedule-home-table-wrapper {
  width: 100%;
  overflow-x: auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
  flex: 1;
  min-height: 0;
}

.day-course-container {
  position: relative;
  width: 100%;
  height: 720px;
  overflow: visible;
}

.course-action-btns-wide {
  display: flex;
  gap: 10px;
  width: 100%;
  margin-top: 8px;
}

.course-action-btn {
  flex: 1;
  padding: 12px 16px;
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-lg);
  background: transparent;
  color: var(--text);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  font-family: inherit;
}

.course-action-btn:hover {
  background: var(--text-light);
}

.course-action-btn:active {
  transform: scale(0.98);
}

.course-action-btn.danger {
  border-color: #ff4757;
  color: #ff4757;
}

.course-action-btn.danger:hover {
  background: rgba(255, 71, 87, 0.1);
}

.modal-overlay {
  position: fixed;
  inset: 0;
  background: var(--hgu-surface-glass);
  backdrop-filter: blur(var(--hgu-blur-xl));
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  padding: 20px;
}

.modal-card {
  width: 100%;
  max-width: 360px;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-3xl);
  padding: 24px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
  animation: modalSlideUp 0.3s ease;
}

.modal-card.wide { max-width: 400px; }
.modal-card.scrollable { max-height: 85vh; overflow-y: auto; }
.modal-card.small { max-width: 320px; width: 90%; }

@keyframes modalSlideUp {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}

.modal-header span {
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
}

.modal-close {
  width: 32px;
  height: 32px;
  border: none;
  background: transparent;
  color: var(--subtext);
  font-size: 24px;
  cursor: pointer;
  border-radius: var(--hgu-radius-round);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}

.modal-close:hover {
  background: rgba(128, 128, 128, 0.1);
}

.modal-desc {
  font-size: 14px;
  color: var(--subtext);
  line-height: 1.6;
  margin-bottom: 20px;
}

.modal-btn {
  width: 100%;
  padding: 14px;
  border: none;
  border-radius: var(--hgu-radius-xl);
  font-size: 15px;
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
}

.modal-btn.primary {
  background: var(--text);
  color: #fff;
}

.modal-btn:hover {
  transform: translateY(-1px);
}

.modal-btn:active {
  transform: scale(0.98);
}

.reminder-cancel-btn {
  background: rgba(255, 71, 87, 0.15);
  border: 1px solid #ff4757;
  color: #ff4757;
  padding: 8px 16px;
  border-radius: var(--hgu-radius-3xl);
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  transition: all 0.2s ease;
}

.reminder-cancel-btn:hover {
  background: rgba(255, 71, 87, 0.25);
  transform: scale(1.05);
}

.reminder-countdown {
  font-size: 20px;
  font-weight: 700;
  color: #ff6b35;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.5px;
}

.schedule-page-content {
  width: 100%;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  align-items: center;
  animation: fadeInUp 0.3s ease;
}

@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ================== 课表管理胶囊按钮 ================== */
.schedule-manage-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border-radius: var(--hgu-radius-3xl);
  border: 1px solid var(--text);
  background: var(--text-light);
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
}

.schedule-manage-btn:active {
  transform: scale(0.95);
}

/* ================== 课表管理弹窗按钮（透明背景+边框） ================== */
#scheduleManageModal .modal-btn {
  background: transparent;
  border: 1.5px solid var(--text);
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

#scheduleManageModal .modal-btn.danger {
  border-color: #ff4757;
  color: #ff4757;
}

#scheduleManageModal .modal-btn:hover {
  background: var(--text-light);
  transform: translateY(-1px);
}

#scheduleManageModal .modal-btn.danger:hover {
  background: rgba(255, 71, 87, 0.1);
}

#scheduleManageModal .modal-btn:active {
  transform: scale(0.98);
}

#scheduleManageModal .modal-header,
#scheduleManageModal .modal-close {
  color: var(--text);
}

/* ================== 新生课表 ================== */
.freshman-schedule-content {
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  padding: 12px 12px 100px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 12px;
  --freshman-accent: var(--study-cyan, #008fa8);
  --freshman-accent-rgb: var(--study-cyan-rgb, 0, 143, 168);
}

.freshman-schedule-state {
  min-height: 180px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  color: var(--subtext);
  font-size: 13px;
  text-align: center;
}

.freshman-schedule-state i { color: var(--freshman-accent); font-size: 22px; }
.freshman-schedule-state.is-error i { color: #d94841; }

.freshman-catalog-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.freshman-catalog-toolbar > div {
  display: flex;
  align-items: baseline;
  gap: 5px;
  color: var(--subtext);
  font-size: 12px;
  white-space: nowrap;
}

.freshman-catalog-toolbar > div strong { color: var(--freshman-accent); font-size: 20px; }

.freshman-search {
  min-width: 0;
  flex: 0 1 230px;
  min-height: 38px;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 10px;
  border: 1px solid rgba(var(--freshman-accent-rgb), 0.35);
  border-radius: 9px;
  background: var(--hgu-surface-glass);
  color: var(--freshman-accent);
}

.freshman-search input {
  min-width: 0;
  flex: 1;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 12px;
}

.freshman-semester-label {
  color: var(--subtext);
  font-size: 11px;
  text-align: center;
}

.freshman-major-list { display: flex; flex-direction: column; gap: 8px; }

.freshman-major {
  border: 1px solid rgba(var(--freshman-accent-rgb), 0.38);
  border-radius: var(--hgu-radius-lg);
  overflow: hidden;
  background: var(--hgu-surface-glass);
}

.freshman-major-head,
.freshman-class-row,
.freshman-back-catalog {
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  font-family: inherit;
  cursor: pointer;
}

.freshman-major-head {
  width: 100%;
  min-height: 58px;
  padding: 10px 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: transparent;
  color: var(--text);
  text-align: left;
}

.freshman-major-head > span:first-child,
.freshman-class-row > span {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.freshman-major-head strong,
.freshman-class-row strong { color: var(--freshman-accent); font-size: 14px; }

.freshman-major-head small,
.freshman-class-row small { color: var(--subtext); font-size: 11px; }

.freshman-major-count {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--subtext);
  font-size: 11px;
}

.freshman-major-count i { transition: transform .2s; }
.freshman-major.is-open .freshman-major-count i { transform: rotate(180deg); }

.freshman-class-list {
  display: none;
  border-top: 1px solid rgba(var(--freshman-accent-rgb), 0.2);
}

.freshman-major.is-open .freshman-class-list { display: block; }

.freshman-class-row {
  width: 100%;
  min-height: 52px;
  padding: 9px 12px 9px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border-bottom: 1px solid rgba(var(--freshman-accent-rgb), 0.14);
  background: transparent;
  text-align: left;
}

.freshman-class-row:last-child { border-bottom: 0; }
.freshman-class-row > i { color: rgba(var(--freshman-accent-rgb), .6); font-size: 10px; }

.freshman-back-catalog {
  min-height: 36px;
  padding: 0 10px;
  border: 1px solid rgba(var(--freshman-accent-rgb), 0.38);
  border-radius: 9px;
  background: rgba(var(--freshman-accent-rgb), 0.08);
  color: var(--freshman-accent);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 700;
}

@media (max-width: 520px) {
  .freshman-catalog-toolbar { align-items: stretch; flex-direction: column; }
  .freshman-search { flex-basis: auto; width: 100%; box-sizing: border-box; }
}

/* ================== 二级抽屉弹窗（课程详情/课表管理） ================== */
.secondary-drawer-overlay {
  position: fixed;
  inset: 0;
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(var(--hgu-blur-sm));
  -webkit-backdrop-filter: blur(var(--hgu-blur-sm));
  z-index: 10002;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}

.secondary-drawer-overlay.active {
  opacity: 1;
  visibility: visible;
}

.secondary-drawer {
  width: 100%;
  background: var(--hgu-surface-glass);
  backdrop-filter: blur(var(--hgu-blur-3xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-3xl));
  border: 1px solid var(--hgu-border-soft);
  border-bottom: none;
  border-radius: 24px 24px 0 0;
  padding: 12px 20px 24px;
  box-shadow: 0 -8px 32px rgba(0,0,0,0.12);
  transform: translateY(100%);
  transition: transform 0.35s cubic-bezier(0.32, 0.72, 0, 1);
  max-height: 80vh;
  overflow-y: auto;
  position: relative;
}

.secondary-drawer-overlay.active .secondary-drawer {
  transform: translateY(0);
}

.secondary-drawer-handle {
  width: 36px;
  height: 4px;
  background: var(--subtext);
  opacity: 0.25;
  border-radius: 2px;
  margin: 0 auto 12px;
}

.study-course-detail-overlay .secondary-drawer {
  --text: var(--study-cyan);
  border: 1.5px solid rgba(var(--study-cyan-rgb), 0.55);
}

.study-course-detail-overlay .secondary-drawer-handle {
  background: var(--study-cyan);
}

.study-course-detail-overlay .modal-header,
.study-course-detail-overlay .modal-close {
  color: var(--study-cyan);
}

/* 宽屏下与一级抽屉宽度严格对齐 */
@media (min-width: 480px) {
  .secondary-drawer {
    width: 580px;
    max-width: 580px;
  }
}

/* ================== 右下角周次切换按钮（合并样式） ================== */
#scheduleFloatNav,
#classroomFloatNav {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  overflow: hidden;
  gap: 0;
  display: flex;
  flex-direction: row;
}

/* 统一左、中、右三个子元素的背景质感 */
#scheduleFloatNav .schedule-float-btn,
#classroomFloatNav .schedule-float-btn,
#scheduleFloatNav .schedule-float-text,
#classroomFloatNav .schedule-float-text {
  background: var(--hgu-surface-glass);
  backdrop-filter: blur(var(--hgu-blur-xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-xl));
  border: 1px solid var(--hgu-border-soft);
  color: var(--text);
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
  box-shadow: var(--hgu-shadow-card);
}

/* 左侧按钮：只有左半边圆角 */
#scheduleFloatNav .schedule-float-btn:first-child,
#classroomFloatNav .schedule-float-btn:first-child {
  width: 44px;
  border-radius: 12px 0 0 12px;
  border-right: none;
  cursor: pointer;
  font-size: 18px;
  padding: 0;
}

/* 中间周次文本：可点击回到本周（不再穿透，否则点不到） */
#scheduleFloatNav .schedule-float-text,
#classroomFloatNav .schedule-float-text {
  min-width: 60px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  pointer-events: auto;
  cursor: pointer;
  padding: 0 6px;
  user-select: none;
  border-radius: 0;
  border-left: none;
  border-right: none;
}

#scheduleFloatNav .schedule-float-text:active,
#classroomFloatNav .schedule-float-text:active {
  opacity: 0.6;
}

/* 右侧按钮：只有右半边圆角 */
#scheduleFloatNav .schedule-float-btn:last-child,
#classroomFloatNav .schedule-float-btn:last-child {
  width: 44px;
  border-radius: 0 12px 12px 0;
  border-left: none;
  cursor: pointer;
  font-size: 18px;
  padding: 0;
}

/* 点击反馈 */
#scheduleFloatNav .schedule-float-btn:active,
#classroomFloatNav .schedule-float-btn:active {
  background: rgba(128, 128, 128, 0.15);
  transform: scale(0.95);
}

/* 暗色模式 */

  html[data-theme="dark"] .schedule-table th,
  html[data-theme="dark"] .schedule-table td:first-child {
    background: transparent !important;
  }

  html[data-theme="dark"] .schedule-table td:not(:has(.course-cell)):not(:first-child) {
    background: rgba(255, 255, 255, 0.03);
  }

  html[data-theme="dark"] .course-cell-overlay {
    color: #fff;
    border-color: rgba(255,255,255,0.15);
  }

  html[data-theme="dark"] .course-cell-overlay .course-name,
  html[data-theme="dark"] .course-cell-overlay .course-room,
  html[data-theme="dark"] .course-cell-overlay .course-teacher {
    color: rgba(255,255,255,0.95);
  }

  html[data-theme="dark"] #shareScheduleOverlay {
    background: rgba(30, 30, 30, 0.7);
  }

  html[data-theme="dark"] .share-title-input {
    border-bottom-color: var(--text);
  }

  html[data-theme="dark"] .share-week-cells {
    background: rgba(255,255,255,0.04);
    border-color: rgba(255,255,255,0.06);
  }

  html[data-theme="dark"] .secondary-drawer-overlay {
    background: rgba(0, 0, 0, 0.15);
  }

#schedule-page {
  padding: 0 !important;
  display: flex;
  flex-direction: column;
  overflow-y: hidden !important;
  height: 100%;          /* 新增：打通内部 flex:1 高度链条 */
}

/* ================== 课表页 / 教室课表页：课表本体横向铺满 ==================
   抽屉容器（.tools-content-container）统一给了 20px 左右内边距，让内容与面板边缘
   保持距离；但课表是横向最挤的页面，这两侧的 20px 挤掉的正是最宝贵的列宽。
   这里只让**课表本体**铺满到面板边缘 —— 标题栏、导入按钮、官方链接卡片、座位视图
   等一律保持原有留白与位置。

   两步走，都只作用于这两页：
   1) 整页向外吃掉容器那 20px，再用等同的内边距还回去：页面自身的盒子变成整块面板
      宽，而页内元素的位置与改动前一致。两处 padding 必须带 !important ——
      这两页上面有 `padding: 0 !important`（用于取消 .tools-sub-page 的底部避让内边距），
      同优先级下本规则排在其后，逐条属性生效。
   2) 课表容器再抵消掉这份内边距，于是它铺满面板两边。
   可安全溢出的边界是"页面的 padding box"（第 1 步之后 = 整块面板），
   所以第 2 步向两侧各多出的 20px 不会被 .tools-sub-page 的 overflow-x:hidden 裁掉。 */
#schedule-page,
#classroom-schedule-page {
  width: calc(100% + 40px);   /* 100% = 容器内容宽（面板宽 - 40），加回 40 即铺满 */
  margin-left: -20px;
  margin-right: -20px;
  padding-left: 20px !important;
  padding-right: 20px !important;
}

/* 课表滑块容器：再向外抵消 20px，铺满到面板两边（标题栏等不受影响） */
#schedule-page #courseManageSection,
#classroom-schedule-page #classroomManageSection {
  width: calc(100% + 40px);
  margin-left: -20px;
  margin-right: -20px;
}

/* 解除 tbody 行高锁定，浏览器会自动均匀分配多余空间 */
.schedule-table tbody tr {
  height: 60px;         /* 保留建议高度，但移除 !important 与 max-height 限制 */
  /* 删除 max-height: 60px; */
  /* 删除 height: 60px !important; */
}

.schedule-table tbody td {
  height: 60px;
  /* 删除 max-height: 60px; */
  /* 删除 height: 60px !important; */
  box-sizing: border-box;
}

/* 解除 rowspan 单元格的 720px 硬编码，使其随行高自动拉伸 */
.schedule-table td[rowspan="12"] {
  height: 100%;         /* 占满 12 行的总高度 */
  /* 删除 height: 720px !important; */
  /* 删除 max-height: 720px; */
  vertical-align: top;
  position: relative;
}

/* 课程容器跟随单元格高度，而不是固定 720px */
.day-course-container {
  position: relative;
  width: 100%;
  height: 100%;         /* 占满 td 高度 */
  /* 删除 height: 720px; */
  overflow: visible;
}
html[data-theme="dark"] .schedule-table th,
html[data-theme="dark"] .schedule-table td:first-child {
  background: transparent !important;
}

html[data-theme="dark"] .schedule-table td:not(:has(.course-cell)):not(:first-child) {
  background: rgba(255, 255, 255, 0.03);
}

html[data-theme="dark"] .course-cell-overlay {
  color: #fff;
  border-color: rgba(255,255,255,0.15);
}

html[data-theme="dark"] .course-cell-overlay .course-name,
html[data-theme="dark"] .course-cell-overlay .course-room,
html[data-theme="dark"] .course-cell-overlay .course-teacher {
  color: rgba(255,255,255,0.95);
}

html[data-theme="dark"] #shareScheduleOverlay {
  background: rgba(30, 30, 30, 0.7);
}

html[data-theme="dark"] .share-title-input {
  border-bottom-color: var(--text);
}

html[data-theme="dark"] .share-week-cells {
  background: rgba(255,255,255,0.04);
  border-color: rgba(255,255,255,0.06);
}

html[data-theme="dark"] .secondary-drawer-overlay {
  background: rgba(0, 0, 0, 0.15);
}

/* ===== Source: elective.css ===== */
#elective-page {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
}

.elective-content {
  width: 100%;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.elective-view-switch {
  width: 100%;
  padding: 4px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px;
  border: 1.5px solid rgba(var(--study-cyan-rgb), 0.55);
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
}

.elective-view-tab {
  min-width: 0;
  min-height: 38px;
  padding: 0 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: none;
  border-radius: 11px;
  background: transparent;
  color: var(--study-cyan);
  font: inherit;
  font-size: 12px;
  font-weight: 750;
}

.elective-view-tab.active {
  background: var(--study-cyan);
  color: #fff;
}

.elective-view-panel {
  width: 100%;
}

#electiveProgressView {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

#electiveCatalogView {
  flex-direction: column;
  gap: 16px;
}

.elective-select-entry {
  width: 100%;
  min-height: 68px;
  padding: 11px 12px;
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  border: 1.5px solid rgba(var(--study-cyan-rgb), 0.58);
  border-radius: var(--hgu-radius-2xl);
  background: rgba(var(--study-cyan-rgb), 0.1);
  color: var(--study-cyan);
  box-shadow: var(--hgu-shadow-card);
  text-decoration: none;
}

.elective-select-entry-icon {
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--hgu-radius-lg);
  background: var(--study-cyan);
  color: #fff;
  font-size: 16px;
}

.elective-select-entry-copy {
  min-width: 0;
}

.elective-select-entry-copy strong,
.elective-select-entry-copy small {
  display: block;
}

.elective-select-entry-copy strong {
  font-size: 14px;
}

.elective-select-entry-copy small {
  margin-top: 3px;
  color: var(--subtext);
  font-size: 11px;
}

.elective-select-entry-action {
  min-height: 30px;
  padding: 0 9px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 1px solid rgba(var(--study-cyan-rgb), 0.42);
  border-radius: var(--hgu-radius-md);
  background: var(--hgu-surface-glass);
  color: var(--study-cyan);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}

.elective-progress-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.elective-plan-notice,
.elective-plan-summary,
.elective-rule-panel,
.elective-module-panel,
.elective-recommend-panel {
  border: 1.5px solid rgba(var(--study-cyan-rgb), 0.5);
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  overflow: hidden;
}

.elective-plan-notice {
  padding: 11px 13px;
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  gap: 9px;
  color: var(--subtext);
  font-size: 11px;
  line-height: 1.55;
}

.elective-plan-notice > i {
  margin-top: 2px;
  color: var(--study-cyan);
}

.elective-plan-summary {
  padding: 14px;
}

.elective-plan-summary-head,
.elective-panel-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.elective-plan-summary-head strong,
.elective-panel-title strong {
  color: var(--study-cyan);
  font-size: 14px;
}

.elective-settings-btn {
  min-height: 32px;
  padding: 0 10px;
  border: 1px solid rgba(var(--study-cyan-rgb), 0.42);
  border-radius: var(--hgu-radius-md);
  background: rgba(var(--study-cyan-rgb), 0.08);
  color: var(--study-cyan);
  font: inherit;
  font-size: 11px;
  font-weight: 700;
}

.elective-plan-source {
  margin-top: 4px;
  color: var(--subtext);
  font-size: 10px;
}

.elective-plan-metrics {
  margin-top: 13px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--hgu-border-soft);
}

.elective-plan-metric {
  padding: 11px 5px 0;
  text-align: center;
}

.elective-plan-metric + .elective-plan-metric {
  border-left: 1px solid var(--hgu-border-soft);
}

.elective-plan-metric strong {
  display: block;
  color: var(--study-cyan);
  font-size: 17px;
  font-variant-numeric: tabular-nums;
}

.elective-plan-metric span {
  display: block;
  margin-top: 2px;
  color: var(--subtext);
  font-size: 10px;
}

.elective-rule-panel,
.elective-module-panel,
.elective-recommend-panel {
  padding: 13px;
}

.elective-panel-title {
  margin-bottom: 9px;
}

.elective-panel-title small {
  color: var(--subtext);
  font-size: 10px;
}

.elective-rule-list,
.elective-module-list,
.elective-recommend-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.elective-rule-row {
  min-height: 46px;
  padding: 8px 9px;
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-lg);
}

.elective-rule-icon {
  color: var(--subtext);
  text-align: center;
}

.elective-rule-row.is-complete .elective-rule-icon,
.elective-rule-row.is-complete .elective-rule-status {
  color: #2e9d62;
}

.elective-rule-row.is-incomplete .elective-rule-icon,
.elective-rule-row.is-incomplete .elective-rule-status {
  color: #e05252;
}

.elective-rule-row.is-pending .elective-rule-icon,
.elective-rule-row.is-pending .elective-rule-status {
  color: #d58a16;
}

.elective-rule-row.is-warning .elective-rule-icon,
.elective-rule-row.is-warning .elective-rule-status {
  color: #d58a16;
}

.elective-rule-copy strong,
.elective-rule-copy span {
  display: block;
}

.elective-rule-copy strong {
  color: var(--study-cyan);
  font-size: 12px;
}

.elective-rule-copy span {
  margin-top: 2px;
  color: var(--subtext);
  font-size: 10px;
  line-height: 1.4;
}

.elective-rule-status {
  font-size: 10px;
  font-weight: 800;
  white-space: nowrap;
}

.elective-module-row {
  min-height: 42px;
  padding: 8px 9px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 9px;
  border-bottom: 1px solid var(--hgu-border-soft);
}

.elective-module-row:last-child {
  border-bottom: none;
}

.elective-module-name {
  color: var(--study-cyan);
  font-size: 12px;
  font-weight: 700;
}

.elective-module-meta {
  margin-top: 3px;
  color: var(--subtext);
  font-size: 10px;
}

.elective-module-credit {
  color: var(--study-cyan);
  font-size: 12px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.elective-module-row.is-capped .elective-module-credit {
  color: #d58a16;
}

.elective-recommend-row {
  padding: 9px 10px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-lg);
}

.elective-recommend-name {
  color: var(--study-cyan);
  font-size: 12px;
  font-weight: 700;
}

.elective-recommend-reason {
  margin-top: 3px;
  color: var(--subtext);
  font-size: 10px;
  line-height: 1.4;
}

.elective-recommend-credit {
  color: var(--study-cyan);
  font-size: 11px;
  font-weight: 800;
  white-space: nowrap;
}

.elective-recommend-empty {
  padding: 16px 8px;
  color: var(--subtext);
  font-size: 11px;
  line-height: 1.5;
  text-align: center;
}

.elective-catalog-heading strong,
.elective-catalog-heading span {
  display: block;
}

.elective-catalog-heading strong {
  color: var(--study-cyan);
  font-size: 15px;
}

.elective-catalog-heading span {
  margin-top: 3px;
  color: var(--subtext);
  font-size: 10px;
}

.elective-recommended-badge,
.elective-completed-badge,
.elective-capped-badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 8px;
  border-radius: var(--hgu-radius-md);
  font-size: 10px;
  font-weight: 700;
}

.elective-recommended-badge {
  color: var(--study-cyan);
  background: rgba(var(--study-cyan-rgb), 0.12);
}

.elective-completed-badge {
  color: #2e9d62;
  background: rgba(46, 157, 98, 0.12);
}

.elective-capped-badge {
  color: #d58a16;
  background: rgba(213, 138, 22, 0.12);
}

.secondary-drawer.elective-requirement-drawer {
  max-width: 480px;
  --text: var(--study-cyan);
  border: 1.5px solid rgba(var(--study-cyan-rgb), 0.55);
}

.elective-requirement-drawer .secondary-drawer-handle {
  background: var(--study-cyan);
}

.elective-requirement-intro {
  margin: 0 0 12px;
  color: var(--subtext);
  font-size: 11px;
  line-height: 1.55;
}

.elective-requirement-options {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.elective-requirement-option,
.elective-art-option {
  min-height: 42px;
  padding: 8px 10px;
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-lg);
  color: var(--study-cyan);
  font-size: 11px;
  font-weight: 650;
}

.elective-requirement-option input,
.elective-art-option input {
  accent-color: var(--study-cyan);
}

.elective-art-option {
  margin-top: 12px;
}

.elective-requirement-actions {
  margin-top: 14px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px;
}

/* ============================================
   搜索框（修复）
   ============================================ */
.search-input-wrapper {
  width: 100%;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-4xl);
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  transition: all 0.2s ease;
}

.search-input-wrapper > i:first-child {
  font-size: 16px;
  color: var(--subtext);
  opacity: 0.6;
  flex-shrink: 0;
}

.search-input-wrapper input {
  flex: 1;
  border: none;
  background: transparent;
  color: var(--text);
  font-size: 14px;
  outline: none;
  font-family: inherit;
  min-width: 0;
}

.search-input-wrapper input::placeholder {
  color: var(--subtext);
  opacity: 0.6;
}

.elective-search-bar {
  position: relative;
}

.elective-search-bar .clear-btn {
  background: none;
  border: none;
  color: var(--subtext);
  cursor: pointer;
  padding: 0 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  opacity: 0.7;
  transition: opacity 0.2s;
}

.elective-search-bar .clear-btn:hover {
  opacity: 1;
  color: var(--text);
}

/* 分类筛选栏 */
.elective-filter-bar {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
  margin-bottom: 4px;
  padding-bottom: 4px;
  width: 100%;
}

.elective-filter-bar::-webkit-scrollbar {
  display: none;
}

.elective-filter-btn {
  flex-shrink: 0;
  padding: 6px 14px;
  border: 1px solid var(--hgu-border-soft);
  background: var(--hgu-surface-glass);
  border-radius: var(--hgu-radius-2xl);
  font-size: 13px;
  color: var(--subtext);
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
  white-space: nowrap;
}

.elective-filter-btn.active {
  background: var(--text);
  color: #fff;
  border-color: var(--text);
  font-weight: 600;
}

.elective-filter-btn:active {
  transform: scale(0.95);
}

/* 课程列表 */
.elective-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-bottom: 40px;
}

.elective-card {
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-2xl);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-shadow: var(--hgu-shadow-card);
  transition: all 0.2s ease;
}

.elective-card:active {
  transform: scale(0.98);
}

.elective-card-header {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.elective-card-title-wrap {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.elective-card-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.4;
}

.elective-card-id {
  font-size: 12px;
  color: var(--subtext);
  opacity: 0.7;
}

.elective-card-tags {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.elective-tag {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--hgu-radius-lg);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.3;
}

.elective-tag.category {
  background: var(--text-light);
  color: var(--text);
}

.elective-tag.mooc {
  background: rgba(255, 107, 53, 0.12);
  color: #ff6b35;
}

.elective-platform {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--hgu-radius-lg);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.3;
}

.elective-platform.chaoxing {
  background: rgba(255, 152, 0, 0.12);
  color: #ff9800;
}

.elective-platform.zhihuishu {
  background: rgba(76, 175, 80, 0.12);
  color: #4caf50;
}

.elective-card-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.elective-info-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.elective-info-item {
  font-size: 13px;
  color: var(--subtext);
  display: flex;
  align-items: center;
  gap: 4px;
}

.elective-info-item i {
  font-size: 12px;
  color: var(--text);
  opacity: 0.6;
}

.elective-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 20px;
  text-align: center;
  color: var(--subtext);
}

.elective-empty i {
  font-size: 48px;
  margin-bottom: 16px;
  opacity: 0.3;
}

.elective-empty p {
  font-size: 15px;
  margin: 0;
}

/* 暗色模式 */

  html[data-theme="dark"] .elective-tag.mooc {
    background: rgba(255, 138, 101, 0.15);
    color: #ff8a65;
  }
  html[data-theme="dark"] .elective-platform.chaoxing {
    background: rgba(255, 183, 77, 0.15);
    color: #ffb74d;
  }
  html[data-theme="dark"] .elective-platform.zhihuishu {
    background: rgba(129, 199, 132, 0.15);
    color: #81c784;
  }

/* ===== Source: options-page.css ===== */
/* ============================================
   选项页基础布局
   ============================================ */
/* 选项页没有顶部标题行（不像其它子页有 .sub-page-header），内容会直接顶到
   抽屉把手下沿。这里留出一行标题文本的高度，并再补 16px 对齐首页的实际留白
   （首页那个空壳 .tools-app-section 自带 16px 下边距，见 #studyView 的注释）。 */
#options-page {
  /* 原来靠 padding-top: 40px 代替标题栏（"没有标题行，让出一行标题的高度"）。
     现在真有了标题栏，这份补偿要去掉，否则内容会被顶下去一大截。 */
  padding-top: 0;
}

.options-page-content {
  width: 100%;
  max-width: 480px;  /* 对齐聚焦页内容区 .tools-home-content */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.theme-mode-switch {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}
.theme-mode-switch button {
  min-height: 48px;
  padding: 6px 4px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-md);
  background: transparent;
  color: var(--subtext);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.theme-mode-switch button.active {
  border-color: var(--text);
  background: var(--text);
  color: #fff;
}
.account-info-card {
  width: 100%;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  padding: 16px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  box-shadow: var(--hgu-shadow-card);
  transition: transform 0.2s ease, background 0.3s;
}

.account-info-card.hidden {
  display: none;
}

.account-info-left {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  min-width: 0;
}

.account-info-icon {
  width: 44px;
  height: 44px;
  border-radius: var(--hgu-radius-round);
  background: var(--text-light);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.account-info-icon i {
  font-size: 20px;
  color: var(--text);
}

.account-info-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.account-info-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.account-info-subtitle {
  font-size: 13px;
  color: var(--subtext);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.account-info-subtitle.logged-in {
  color: #4CAF50;
}

.account-info-subtitle.expired {
  color: #ff4757;
}

.account-info-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.account-info-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--hgu-radius-round);
  background: var(--text-light);
  border: 1px solid var(--hgu-border-soft);
  color: var(--text);
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 14px;
}

.account-info-btn:hover {
  background: var(--hgu-surface-glass);
  transform: scale(1.05);
}

.account-info-btn:active {
  transform: scale(0.95);
}

.account-info-btn.login-btn {
  width: auto;
  padding: 0 16px;
  border-radius: var(--hgu-radius-polished);
  font-size: 14px;
  font-weight: 500;
  gap: 6px;
}

/* 版本更新卡片（仅APP环境显示） */
.version-update-card {
  width: 100%;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  box-shadow: var(--hgu-shadow-card);
  transition: all 0.3s ease;
  cursor: pointer;
}

.version-update-card.hidden {
  display: none;
}

.version-update-card.has-update {
  border-color: #6BA3FF;
  background: linear-gradient(135deg, rgba(107, 163, 255, 0.1) 0%, var(--glass) 100%);
}

.version-update-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.version-update-left {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  min-width: 0;
}

.version-update-left i {
  font-size: 20px;
  color: var(--text);
  width: 24px;
  text-align: center;
}

.version-update-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.version-update-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.version-update-title.has-update {
  color: #6BA3FF;
}

.version-update-subtitle {
  font-size: 12px;
  color: var(--subtext);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.version-update-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.version-update-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--hgu-radius-round);
  background: var(--text-light);
  border: 1px solid var(--hgu-border-soft);
  color: var(--text);
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 13px;
}

.version-update-btn:hover {
  background: var(--hgu-surface-glass);
  transform: scale(1.05);
}

.version-update-btn:active {
  transform: scale(0.95);
}

.version-update-btn.download-btn {
  background: #6BA3FF;
  border-color: #6BA3FF;
  color: white;
}

.version-update-btn.download-btn:hover {
  background: #5a90e8;
}

.version-update-changelog {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease, padding 0.3s ease;
  padding: 0 12px;
}

.version-update-changelog.expanded {
  max-height: 300px;
  padding: 12px;
  background: rgba(0, 0, 0, 0.03);
  border-radius: var(--hgu-radius-xl);
}

.version-update-changelog-content {
  font-size: 13px;
  color: var(--subtext);
  line-height: 1.6;
  white-space: pre-wrap;
}

.version-update-changelog-content h1,
.version-update-changelog-content h2,
.version-update-changelog-content h3 {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  margin: 8px 0 4px 0;
}

.version-update-changelog-content ul,
.version-update-changelog-content ol {
  margin: 4px 0;
  padding-left: 16px;
}

.version-update-changelog-content li {
  margin: 2px 0;
}

/* 地图显示设置卡片（标记设置） */
.options-map-settings-card {
  width: 100%;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-shadow: var(--hgu-shadow-card);
}

/* 点进二级抽屉的设置行（如「显示大小设置」）：整行都是热区，点标签 / 点空白 / 点箭头都一样 */
.options-map-setting-item-link {
  cursor: pointer;
  border-radius: var(--hgu-radius-default);
  transition: background 0.2s ease;
}

.options-map-setting-item-link:active {
  background: rgba(128, 128, 128, 0.1);
}

/* 行尾箭头：纯装饰（行本身在响应点击），按下反馈也挂在行上，按哪儿都有反应 */
.options-map-setting-arrow {
  width: 28px;
  height: 28px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--hgu-radius-round);
  color: var(--subtext);
  font-size: 14px;
  opacity: 0.7;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.options-map-setting-item-link:active .options-map-setting-arrow {
  opacity: 1;
  transform: scale(0.92);
}

/* ============================================
   显示大小（APP 端显示大小 / 字体大小，五档）
   选项页那一行的右侧直接摆五个档位按钮，点一下即生效，没有二级抽屉。
   ============================================ */
.options-map-setting-item-display-size {
  gap: 10px;
  padding: 8px 4px;
  min-height: 44px;
}

/* 去掉分组底色/边框的紧凑胶囊：整行高度只比普通设置行高一点 */
.options-map-setting-item-display-size .display-size-levels {
  flex: 0 1 auto;
  min-width: 0;
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  background: none;
  border: none;
  border-radius: var(--hgu-radius-xl);
}

.display-size-level {
  flex: 0 0 auto;
  width: clamp(26px, 7.4vw, 34px);
  min-height: 28px;
  padding: 3px 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: var(--hgu-radius-lg);
  background: rgba(128, 128, 128, 0.10);
  color: var(--subtext);
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.1;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}

.display-size-level.active {
  background: var(--text);
  color: #fff;
  font-weight: 600;
}

/* 原生不支持时退化成提示：容器不占五档宽度，直接靠右显示一行小字 */
.options-map-setting-item-display-size .display-size-levels.is-unsupported {
  flex: 0 1 auto;
}

.display-size-unsupported-inline {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--subtext);
  font-size: 12px;
  line-height: 1.3;
  text-align: right;
}

.display-size-unsupported-inline i {
  flex: none;
  color: var(--text);
  opacity: 0.8;
}

.options-map-settings-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.options-map-setting-item {
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 4px;
}

.options-map-setting-label {
  font-size: 14px;
  color: var(--subtext);
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
}

.options-map-setting-label i {
  font-size: 14px;
  width: 18px;
  text-align: center;
  color: var(--text);
  opacity: 0.8;
}

/* ============================================
   标记设置 & 通知设置 开关按钮样式（修复）
   ============================================ */

.options-home-service-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 12px;
  min-height: 58px;
  padding: 10px 4px;
}
.options-home-service-item + .options-home-service-item {
  border-top: 1px solid var(--hgu-border-soft);
}
.options-home-service-copy {
  min-width: 0;
  display: grid;
  gap: 4px;
}
.options-home-service-copy > span:last-child {
  color: var(--subtext);
  font-size: 11px;
  line-height: 1.35;
  opacity: .72;
  overflow-wrap: anywhere;
}
.options-home-service-actions {
  display: grid;
  grid-template-columns: 44px;
  align-items: center;
  gap: 8px;
}
.options-map-settings-card .store-map-toggle-btn,
.options-notification-settings-card .store-map-toggle-btn {
  width: 44px;
  height: 24px;
  background: #ccc;
  border-radius: var(--hgu-radius-xl);
  border: none;
  position: relative;
  cursor: pointer;
  transition: background 0.3s;
  padding: 0;
  flex-shrink: 0;
  outline: none;
  -webkit-tap-highlight-color: transparent;
}

.options-map-settings-card .store-map-toggle-btn.active,
.options-notification-settings-card .store-map-toggle-btn.active {
  background: var(--text);
}

.options-map-settings-card .store-map-toggle-btn .toggle-thumb,
.options-notification-settings-card .store-map-toggle-btn .toggle-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  background: #fff;
  border-radius: var(--hgu-radius-round);
  transition: transform 0.3s;
  display: block;
  pointer-events: none;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}

.options-map-settings-card .store-map-toggle-btn.active .toggle-thumb,
.options-notification-settings-card .store-map-toggle-btn.active .toggle-thumb {
  transform: translateX(20px);
}

/* 课表管理弹窗里的「课表调休显示」：整块是一个带边框的卡片（原来只有内联样式，
   现在固定在样式表里，框线用卡片同款 --hgu-border-soft 之外还叠一层 --border，
   保证在明暗两种主题下都看得见）。开关外观与选项页其它开关同款。 */
.schedule-manage-reschedule-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 14px;
  border: 1.5px solid var(--border);
  border-radius: var(--hgu-radius-xl);
  background: var(--glass);
}

.schedule-manage-reschedule-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}

.schedule-manage-reschedule-label i {
  color: var(--text);
  opacity: 0.8;
}

.schedule-manage-reschedule-toggle .store-map-toggle-btn {
  width: 44px;
  height: 24px;
  background: #ccc;
  border-radius: var(--hgu-radius-xl);
  border: none;
  position: relative;
  cursor: pointer;
  transition: background 0.3s;
  padding: 0;
  flex-shrink: 0;
  outline: none;
  -webkit-tap-highlight-color: transparent;
}

.schedule-manage-reschedule-toggle .store-map-toggle-btn.active {
  background: var(--text);
}

.schedule-manage-reschedule-toggle .store-map-toggle-btn .toggle-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  background: #fff;
  border-radius: var(--hgu-radius-round);
  transition: transform 0.3s;
  display: block;
  pointer-events: none;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}

.schedule-manage-reschedule-toggle .store-map-toggle-btn.active .toggle-thumb {
  transform: translateX(20px);
}

.options-notification-settings-card.hidden {
  display: none;
}

/* 快捷操作卡片 */
.options-actions-card {
  width: 100%;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  display: flex;
  flex-direction: column;
  box-shadow: var(--hgu-shadow-card);
  overflow: hidden;
}

.options-action-item {
  display: flex;
  align-items: center;
  gap: 12px;
  /* 左右内边距与上面的 .options-map-settings-card（14px 16px）对齐：
     两张卡片挨在一起，图标左边缘必须落在同一条竖线上，
     否则下面这张的图标会看着比上面那张更靠右。 */
  padding: 16px 16px;
  cursor: pointer;
  transition: transform 0.2s, background 0.2s ease;
}

.options-action-item:active {
  background: rgba(128, 128, 128, 0.08);
}

/* 行之间的分隔线：**每一行都有**（含最后一行 —— 它下面还接着
   .options-save-map-expand 展开面板，那条线正好把两者分开）。
   ⚠️ 不要再给保存为图片那一行加 border-bottom: 0：
      那样"三行中间都有分隔线"就不成立了（最后一行与展开面板之间会没线）。 */
.options-action-item {
  border-bottom: 1px solid var(--hgu-border-soft);
}

.options-action-item i {
  font-size: 18px;
  color: var(--text);
  width: 24px;
  text-align: center;
  flex: 0 0 24px;
  /* 上面那张设置卡片的图标是 18px 字号居中在 24px 盒子里（左右各 3px 余量），
     这里补同样的 3px，两张卡片的图标左边缘才会落在同一条竖线上。 */
  margin-left: 3px;
}

.options-action-text {
  font-size: 15px;
  font-weight: 500;
  color: var(--text);
  flex: 1;
  min-width: 0;
}

/* 行尾箭头：只作用于最后那颗箭头（.options-action-arrow），
   不要写成 .options-action-item i —— 那会把左侧的功能图标也一起改了。
   展开时旋转 90° 变成朝下。 */
.options-action-arrow {
  font-size: 14px;
  color: var(--subtext);
  opacity: 0.6;
  flex: 0 0 auto;
  transition: transform 0.25s ease;
}

.options-action-item-save-map.is-expanded .options-action-arrow {
  transform: rotate(90deg);
}

/* 分享展开区域 */
.options-share-expand {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease, padding 0.3s ease;
  display: flex;
  flex-direction: column;   /* 纵向排列：文本在上，二维码在下 */
  justify-content: center;
  align-items: center;
  gap: 10px;
}

.options-share-expand.expanded {
  max-height: 280px;        /* 适当增高以容纳文本 */
  padding: 16px;
  border-top: 1px solid var(--hgu-border-soft);
}

/* 新增：分享文本样式 */
.options-share-text {
  text-align: center;
  font-size: 14px;
  color: var(--text);
  line-height: 1.6;
}

.options-share-text p {
  margin: 0;
}

.options-share-text strong {
  font-size: 20px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: 1px;
}

.options-share-qrcode {
  width: 150px;
  height: 150px;
  border-radius: var(--hgu-radius-xl);
  object-fit: contain;
}

/* 意见反馈展开区域 */
.options-feedback-expand {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease, padding 0.3s ease;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.options-feedback-expand.expanded {
  max-height: 200px;
  padding: 16px;
  border-top: 1px solid var(--hgu-border-soft);
}

/* 保存地图图片展开区域 */
.options-save-map-expand {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease, padding 0.3s ease;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.options-save-map-expand.expanded {
  max-height: 420px;
  padding: 16px;
  border-top: 1px solid var(--hgu-border-soft);
}

.save-map-expand-notice {
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-size: 12px;
  color: var(--subtext);
  line-height: 1.6;
}

.save-map-expand-notice p {
  margin: 0;
}

.save-map-expand-notice strong {
  color: var(--text);
}

.save-map-expand-btn {
  width: 100%;
  padding: 12px;
  border-radius: var(--hgu-radius-xl);
  border: 1px solid var(--text);
  background: transparent;
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  transition: all 0.2s;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.save-map-expand-btn:hover {
  background: var(--text-light);
}

.save-map-expand-btn:active {
  transform: scale(0.98);
}

.feedback-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.feedback-label {
  font-size: 14px;
  color: var(--text);
  font-weight: 600;
  min-width: 48px;
  flex-shrink: 0;
}

.feedback-value {
  font-size: 14px;
  color: var(--subtext);
  flex: 1;
  text-align: left;
  word-break: break-all;
}

.feedback-copy-btn {
  padding: 6px 12px;
  border-radius: var(--hgu-radius-md);
  border: 1px solid var(--text);
  background: transparent;
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
  flex-shrink: 0;
}

.feedback-copy-btn:hover {
  background: var(--text-light);
}

.feedback-copy-btn:active {
  transform: scale(0.95);
}

/* #about-page / #notifications-page 是 #tools-page 的直接子元素
   （其余子页面都在 .tools-content-container 里面）。
   它们原来靠 #tools-page 的 padding 拿到内边距、靠 #tools-page 的 overflow-y:auto
   滚动；而面板现在必须保持 overflow:hidden 才能做"只变高度"的展开/收起动画，
   .tools-content-container 的 padding 又管不到这两个面板级子页。
   所以把内边距和滚动下放给它们自己：高度撑满面板，内部滚动。 */
#tools-page > .tools-sub-page.active {
  height: 100%;
  /* 页面内容从抽屉顶部开始，标题栏固定在 52px 处；底部按悬浮栏避让。 */
  padding: 0 20px var(--hgu-nav-clearance, 78px);
  box-sizing: border-box;
  overflow-x: hidden;
  overflow-y: auto;
}

/* 关于页面样式 - 复用选项页内容样式 */
#about-page .options-page-content {
  width: 100%;
  /* 关于页是 #tools-page 的直接子元素，不像其它子页那样被
     .tools-content-container 的 max-width:480 + padding:20 收窄，
     所以这里自己对齐到同一内容宽度（480 - 2×20 = 440），
     否则两侧会比别的页面各多出约 30px 留白。 */
  max-width: 440px;
  margin: 0 auto;    /* 内容居中 */
  position: relative;
  z-index: 1;
}

/* 关于页：面板宽度放开即可，overflow 保持默认的 hidden（原因见下方
   "#tools-page > .tools-sub-page.active" 规则） */
#tools-page.about-mode .tools-content-container {
  max-width: none;
  overflow: visible;
  z-index: 1;
}

#tools-page.about-mode #about-page.active {
  overflow-x: hidden;
  overflow-y: auto;
  z-index: 1;
}

#tools-page.about-mode .page-deco-layer {
  display: none;
}

#tools-page.about-mode::before {
  display: none;
}

#about-page .sub-page-header {
  margin-bottom: 0;
  min-height: 44px;
  z-index: 2;
}

.about-bg-layer {
  display: none;
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

#tools-page.about-mode > .about-bg-layer {
  display: block;
}

.about-bg-deco {
  position: absolute;
  border-radius: var(--hgu-radius-round);
  filter: blur(80px);
  opacity: 0.45;
  pointer-events: none;
  z-index: 0;
  transition: opacity .3s;
}

.about-bg-deco-green {
  width: 320px;
  height: 320px;
  background: #7cb342;
  top: -80px;
  right: -20px;
  animation: aboutFloatGreen 7s ease-in-out infinite;
}

.about-bg-deco-yellow {
  width: 260px;
  height: 260px;
  background: #fff59d;
  top: 10px;
  right: 15%;
  animation: aboutFloatYellow 9s ease-in-out infinite;
  animation-delay: -3s;
}

.about-bg-deco-blue {
  width: 280px;
  height: 280px;
  background: #f99090;
  top: -40px;
  right: 35%;
  animation: aboutFloatBlue 6s ease-in-out infinite;
  animation-delay: -2s;
}

@keyframes aboutFloatGreen {
  0%, 100% { transform: translate(0, 0) scale(1); }
  25% { transform: translate(120px, 160px) scale(1.12); }
  50% { transform: translate(-60px, 220px) scale(0.88); }
  75% { transform: translate(80px, 100px) scale(1.06); }
}

@keyframes aboutFloatYellow {
  0%, 100% { transform: translate(0, 0) scale(1); }
  20% { transform: translate(-100px, 140px) scale(0.9); }
  50% { transform: translate(140px, 200px) scale(1.15); }
  80% { transform: translate(-40px, 80px) scale(0.95); }
}

@keyframes aboutFloatBlue {
  0%, 100% { transform: translate(0, 0) scale(1); }
  33% { transform: translate(160px, 120px) scale(1.1); }
  66% { transform: translate(-80px, 240px) scale(0.85); }
}

.about-hero {
  width: 100%;
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 18px 20px 8px;
  text-align: center;
}

.about-hero-icon {
  width: 110px;
  height: 110px;
  border-radius: 26px;
  background: var(--hgu-surface-glass);
  backdrop-filter: blur(var(--hgu-blur-3xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-3xl));
  border: 1px solid var(--hgu-border-soft);
  box-shadow: 0 8px 32px rgba(0, 0, 0, .12);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 24px;
  position: relative;
  overflow: hidden;
  transition: transform .3s ease;
}

.about-hero-icon:active {
  transform: scale(0.95);
}

.about-hero-icon img {
  width: 80px;
  height: 80px;
  border-radius: var(--hgu-radius-polished);
  object-fit: cover;
  display: block;
}

.about-hero-icon::before {
  content: '';
  position: absolute;
  inset: -50%;
  background: linear-gradient(135deg, transparent 40%, rgba(255, 255, 255, 0.25) 50%, transparent 60%);
  animation: aboutHeroShimmer 3s infinite;
}

@keyframes aboutHeroShimmer {
  0% { transform: translateX(-100%) rotate(0deg); }
  100% { transform: translateX(100%) rotate(0deg); }
}

.about-hero-title {
  font-size: 32px;
  font-weight: 800;
  color: var(--text);
  margin: 0 0 10px;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.about-hero-tags {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: center;
}

.about-hero-tag {
  font-size: 12px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 100px;
  background: var(--text-light);
  color: var(--text);
  border: 1px solid var(--hgu-border-soft);
  backdrop-filter: blur(var(--hgu-blur-md));
  -webkit-backdrop-filter: blur(var(--hgu-blur-md));
}

.about-hero-subtitle {
  font-size: 14px;
  color: var(--subtext);
  line-height: 1.6;
  max-width: 320px;
  opacity: 0.85;
  margin: 20px 0 0;
}

/* 今日用户量那一行：数字走主文本色 + 加大加粗，两侧文案与上方副标题同字号同灰。
   ⛔ 不能用父级 opacity 压灰度 —— 那会把里面的数字一起压掉，数字就不再是主文本色。 */
.about-hero-usage {
  margin: 6px 0 0;
  font-size: 14px;
  font-weight: 400;
  color: rgba(51, 51, 51, 0.85);
  line-height: 1.6;
  max-width: 320px;
}

.about-hero-usage strong {
  margin-right: 0.22em;
  font-size: 20px;
  font-weight: 800;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.about-actions-row {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.about-qq-group-btn,
.about-disclaimer-btn {
  width: 100%;
  min-height: 48px;
  border-radius: var(--hgu-radius-2xl);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 700;
  transition: transform .2s ease, box-shadow .2s ease;
}

.about-qq-group-btn {
  background: var(--text);
  color: #fff;
  box-shadow: 0 4px 16px rgba(74, 124, 89, 0.3);
  text-decoration: none;
}

.about-disclaimer-btn {
  border: 1px solid var(--text);
  background: var(--hgu-surface-glass);
  color: var(--text);
  box-shadow: var(--hgu-shadow-card);
  cursor: pointer;
}

.about-qq-group-btn:active,
.about-disclaimer-btn:active {
  transform: scale(0.96);
}

/* 作者卡片 */
.about-author-card {
  width: 100%;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  padding: 16px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  box-shadow: var(--hgu-shadow-card);
}

.about-protocol-card { width: 100%; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.about-protocol-card button { width: 100%; min-height: 44px; padding: 9px 12px; border: 1px solid var(--text); border-radius: var(--hgu-radius-2xl); background: var(--hgu-surface-glass); color: var(--text); display: flex; flex-direction: row; align-items: center; justify-content: flex-start; gap: 8px; text-align: left; cursor: pointer; box-shadow: var(--hgu-shadow-card); }
.about-protocol-card button:active { background: var(--hover-bg); }
.about-protocol-card button > i:first-child { width: 20px; color: var(--text); text-align: center; font-size: 16px; flex-shrink: 0; }
.about-protocol-card button > i:last-child { display: none; }
.about-protocol-card button span { display: block; line-height: 1.2; }
.about-protocol-card button strong { font-size: 14px; }
@media (max-width: 360px) { .about-actions-row, .about-protocol-card { grid-template-columns: 1fr; } }

.about-author-avatar {
  width: 44px;
  height: 44px;
  border-radius: var(--hgu-radius-round);
  overflow: hidden;
  flex-shrink: 0;
  background: var(--text-light);
  display: flex;
  align-items: center;
  justify-content: center;
}

.about-author-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.about-author-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.about-author-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.3;
}

.about-author-desc {
  font-size: 13px;
  color: var(--subtext);
  line-height: 1.5;
  word-break: break-word;
}

/* 鸣谢卡片 */
.about-thanks-card {
  width: 100%;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  padding: 16px 18px;
  box-shadow: var(--hgu-shadow-card);
  display: flex;
  flex-direction: column;
}

.about-thanks-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}

.about-thanks-header i {
  font-size: 18px;
  color: var(--text);
}

.about-thanks-title {
  font-size: 17px;
  font-weight: 600;
  color: var(--text);
}

.about-thanks-sub {
  font-size: 11px;
  color: var(--subtext);
  opacity: 0.7;
  font-weight: 400;
  margin-left: 4px;
}

.about-thanks-divider {
  width: 100%;
  height: 1px;
  background: var(--border);
  margin-bottom: 12px;
  opacity: 0.6;
}

.about-thanks-empty {
  width: 100%;
  padding: 24px 0;
  text-align: center;
  color: var(--subtext);
  font-size: 13px;
}

.about-thanks-group {
  width: 100%;
  margin-bottom: 20px;
}

.about-thanks-group:last-child {
  margin-bottom: 0;
}

.about-thanks-group-title {
  width: 100%;
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 10px;
}

.about-thanks-avatar-viewport {
  width: 100%;
  overflow: hidden;
  padding: 4px 0 8px;
}

.about-thanks-avatar-track {
  display: flex;
  align-items: center;
  width: max-content;
  will-change: transform;
}

.about-thanks-avatar {
  position: relative;
  width: 36px;
  height: 36px;
  margin-left: -12px;
  border-radius: var(--hgu-radius-round);
  border: 2px solid var(--glass);
  background: var(--text-light);
  overflow: hidden;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.about-thanks-avatar:first-child {
  margin-left: 0;
}

.about-thanks-avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.about-thanks-avatar-fallback {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--subtext);
  font-size: 14px;
}

.about-thanks-names {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  row-gap: 4px;
  margin-top: 4px;
  font-size: 13px;
  color: var(--text);
  line-height: 1.5;
  text-align: center;
}

.about-thanks-name {
  white-space: nowrap;
}

.about-thanks-sep {
  color: var(--subtext);
  margin: 0 4px;
  flex-shrink: 0;
}
/* 备案信息 */
.options-beian {
  width: 100%;
  text-align: center;
  font-size: 12px;
  line-height: 1.6;
  margin-top: 8px;
}

.options-beian a {
  color: var(--subtext);
  text-decoration: none;
  display: block;
}

/* 关于页里的备案信息：从选项页移过来，放在「加入QQ群」上方，改为下方留白 */
.about-beian {
  margin-top: 0;
  margin-bottom: 12px;
}

/* 暗色模式适配 */

  html[data-theme="dark"] .account-info-icon {
    background: rgba(168, 224, 99, 0.15);
  }

  html[data-theme="dark"] .account-info-btn {
    background: rgba(168, 224, 99, 0.15);
    border-color: rgba(255, 255, 255, 0.15);
  }

  html[data-theme="dark"] .version-update-card.has-update {
    background: linear-gradient(135deg, rgba(107, 163, 255, 0.15) 0%, rgba(60, 60, 60, 0.4) 100%);
  }

  html[data-theme="dark"] .version-update-changelog.expanded {
    background: rgba(255, 255, 255, 0.05);
  }

  html[data-theme="dark"] .options-shortcut-preview {
    background: rgba(168, 224, 99, 0.15);
    border-color: rgba(255, 255, 255, 0.15);
  }

  html[data-theme="dark"] .about-hero-icon {
    box-shadow: 0 8px 32px rgba(0, 0, 0, .35);
  }

  html[data-theme="dark"] .about-qq-group-btn {
    color: #1a1a1a;
    box-shadow: 0 4px 16px rgba(168, 224, 99, 0.25);
  }

/* 通知设置卡片 */
.options-notification-settings-card {
  width: 100%;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-shadow: var(--hgu-shadow-card);
}

.options-notification-settings-header {
  display: flex;
  align-items: center;
  gap: 8px;
}

.options-notification-settings-header i {
  font-size: 18px;
  width: 24px;
  text-align: center;
}

.options-notification-title-wrap {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.options-notification-title-wrap > span:first-child {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}

.options-notification-subtitle {
  font-size: 11px;
  color: var(--subtext);
  opacity: 0.7;
  font-weight: 400;
}

/* 暗色模式适配 */

  html[data-theme="dark"] .options-notification-subtitle {
    opacity: 0.6;
  }

/* 响应式适配 */
@media (max-width: 380px) {
  .account-info-card,
  .version-update-card,
  .options-map-settings-card,
  .about-author-card,
  .about-thanks-card {
    padding: 12px 14px;
  }

  /* ⚠️ .options-actions-card 是个"行列表"卡片（关于 / 桌面小组件 / 保存为图片），
     行自己带 16px 内边距、需要顶到卡片边缘（分隔线才会通到边）。
     跟着上面一起加卡片内边距的话，窄视口下行会往里缩 15px，
     表现为卡片里多出一圈留空（用户反馈：只有大显示大小才出现）。
     所以它**不能**参与这条规则，将来也别把它加回去。 */
  .options-actions-card {
    padding: 0;
  }
}

/* 功能使用统计 */
.about-feature-stats-card {
  width: 100%;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  box-shadow: var(--hgu-shadow-card);
}

.about-feature-stats-header {
  display: flex;
  align-items: center;
  gap: 8px;
}

.about-feature-stats-header i {
  font-size: 18px;
  color: var(--text);
}

.about-feature-stats-title-wrap {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.about-feature-stats-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}

.about-feature-stats-sub {
  font-size: 11px;
  color: var(--subtext);
  opacity: 0.7;
  font-weight: 400;
}

.about-feature-stats-divider {
  width: 100%;
  height: 1px;
  background: var(--border);
  opacity: 0.6;
}

.about-feature-stats-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.about-feature-stat-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.about-feature-stat-info {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  min-width: 0;
}

.about-feature-stat-name {
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.about-feature-stat-bar-wrap {
  flex: 1;
  height: 6px;
  background: var(--border);
  border-radius: 3px;
  overflow: hidden;
  max-width: 120px;
}

.about-feature-stat-bar {
  height: 100%;
  background: var(--text);
  border-radius: 3px;
  transition: width 0.5s ease;
  opacity: 0.8;
}

.about-feature-stat-count {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  min-width: 36px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ---- 分组（首页 / 课表 / 学习 / 选项，另附「其他」） ----
   分组只显示名称与次数（不画进度条），子功能行沿用原来的窄条样式 ——
   两者是各自独立的计数口径，画在同一套比例尺上反而容易误读为包含关系 */
.about-feature-stat-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.about-feature-stat-group + .about-feature-stat-group {
  margin-top: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.about-feature-stat-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.about-feature-stat-group-name {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
}

.about-feature-stat-group-name i {
  font-size: 13px;
  opacity: 0.75;
}

.about-feature-stat-group-total {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.about-feature-stat-sublist {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-left: 3px;
  padding-left: 10px;
  border-left: 2px solid var(--border);
}

.about-feature-stat-item.is-child .about-feature-stat-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--subtext);
}

.about-feature-stat-item.is-child .about-feature-stat-count {
  font-size: 12px;
  font-weight: 600;
  color: var(--subtext);
}

.about-feature-stat-item.is-child .about-feature-stat-bar {
  opacity: 0.45;
}

  html[data-theme="dark"] .about-feature-stat-bar {
    opacity: 0.9;
  }

/* ===== Source: weather.css ===== */
/* 图标颜色 */
.wi-sunny,
.wi-cloudy  { color: var(--weather-icon-sunny); }
.wi-overcast{ color: var(--weather-icon-overcast); }
.wi-rain    { color: var(--weather-icon-rain); }
.wi-storm   { color: var(--weather-icon-storm); }
.wi-snow    { color: var(--weather-icon-snow); }
.wi-fog     { color: var(--weather-icon-fog); }
.wi-haze    { color: var(--weather-icon-haze); }
.wi-hot     { color: var(--weather-icon-hot); }
.wi-cold    { color: var(--weather-icon-cold); }
.wi-wind    { color: var(--weather-icon-wind); }
.wi-unknown { color: var(--weather-icon-unknown); }

/* 文本颜色 */
.wt-sunny,
.wt-cloudy  { color: var(--weather-text-sunny); }
.wt-overcast{ color: var(--weather-text-overcast); }
.wt-rain    { color: var(--weather-text-rain); }
.wt-storm   { color: var(--weather-text-storm); }
.wt-snow    { color: var(--weather-text-snow); }
.wt-fog     { color: var(--weather-text-fog); }
.wt-haze    { color: var(--weather-text-haze); }
.wt-hot     { color: var(--weather-text-hot); }
.wt-cold    { color: var(--weather-text-cold); }
.wt-wind    { color: var(--weather-text-wind); }
.wt-unknown { color: var(--weather-text-unknown); }

/* ============================================
   今日火烧云卡片
   ============================================ */
.weather-sunset-card {
  width: 100%;
  max-width: 400px;
  background: var(--hgu-surface-glass);
  border: 1.5px solid var(--sunset-accent);
  border-radius: var(--hgu-radius-3xl);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  box-shadow: var(--hgu-shadow-card);
  transition: border-color 0.5s ease;
}

.secondary-drawer.sunset-forecast-drawer {
  max-width: 480px;
  padding-bottom: max(22px, env(safe-area-inset-bottom));
  border: 1.5px solid rgba(255, 129, 38, 0.58);
}

.sunset-forecast-drawer .secondary-drawer-handle {
  background: var(--color-life);
}

.sunset-forecast-drawer .modal-header span {
  color: var(--color-life);
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.sunset-forecast-header-actions {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.sunset-forecast-header-actions .weather-sunset-link {
  color: var(--color-life);
  opacity: 0.82;
}

.sunset-forecast-drawer > .weather-sunset-body {
  margin-top: 12px;
}

.sunset-forecast-drawer .weather-sunset-card {
  width: auto;
  max-width: none;
  margin-top: 12px;
  border-radius: var(--hgu-radius-lg);
  box-shadow: none;
}

.weather-sunset-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 4px;
}

.weather-sunset-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--sunset-accent);
  display: flex;
  align-items: center;
  gap: 6px;
}

.weather-sunset-title i {
  color: var(--sunset-accent);
}

.weather-sunset-link {
  font-size: 12px;
  color: var(--subtext);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 4px;
  opacity: 0.7;
  transition: opacity 0.2s ease;
  white-space: nowrap;
}

.weather-sunset-link:hover {
  opacity: 1;
  color: var(--sunset-accent);
}

.weather-sunset-link i {
  font-size: 10px;
}

.weather-sunset-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* 今日/明日分卡片 */
.sunset-day-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.sunset-day-card.tomorrow {
  margin-top: 4px;
  padding-top: 10px;
  border-top: 1px dashed var(--border);
}

.sunset-day-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--sunset-accent);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 4px;
}

.sunset-day-title i {
  color: var(--sunset-accent);
  font-size: 14px;
}

/* 朝霞/晚霞子卡片 */
.sunset-event-item {
  background: rgba(255, 255, 255, 0.15);
  border-radius: var(--hgu-radius-default);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

  html[data-theme="dark"] .sunset-event-item {
    background: rgba(255, 255, 255, 0.08);
  }

.sunset-event-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.sunset-event-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--sunset-accent);
  display: flex;
  align-items: center;
  gap: 6px;
}

.sunset-event-name i {
  font-size: 16px;
}

.sunset-event-name .sunrise-icon {
  color: var(--sunset-accent);
}

.sunset-event-name .sunset-icon {
  color: var(--sunset-accent);
}

.sunset-event-time {
  font-size: 13px;
  font-weight: 500;
  color: var(--subtext);
}

/* 事件详情（鲜艳度 + 气溶胶） */
.sunset-event-details {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.sunset-detail-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sunset-detail-label {
  font-size: 11px;
  color: var(--subtext);
  opacity: 0.7;
}

.sunset-detail-value {
  font-size: 13px;
  font-weight: 600;
  color: var(--sunset-accent);
}

/* 鲜艳度等级颜色 */
.sunset-quality-burn   { color: var(--sunset-quality-burn); }
.sunset-quality-light  { color: var(--sunset-quality-light); }
.sunset-quality-slight { color: var(--sunset-quality-slight); }
.sunset-quality-none   { color: var(--subtext); }

/* 加载状态 */
.sunset-loading {
  text-align: center;
  padding: 16px 0;
  font-size: 14px;
  color: var(--subtext);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.sunset-error {
  text-align: center;
  padding: 12px 0;
  font-size: 13px;
  color: var(--subtext);
  opacity: 0.7;
}

/* ============================================
   预测解释折叠卡片
   ============================================ */
.sunset-explain-card {
  background: rgba(255, 255, 255, 0.08);
  border-radius: var(--hgu-radius-default);
  overflow: hidden;
  margin-top: 4px;
}

  html[data-theme="light"] .sunset-explain-card {
    background: rgba(0, 0, 0, 0.03);
  }

.sunset-explain-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  cursor: pointer;
  user-select: none;
  transition: background 0.2s ease;
}

.sunset-explain-header:hover {
  background: rgba(255, 255, 255, 0.05);
}

  html[data-theme="light"] .sunset-explain-header:hover {
    background: rgba(0, 0, 0, 0.03);
  }

.sunset-explain-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--sunset-accent);
  display: flex;
  align-items: center;
  gap: 6px;
}

.sunset-explain-title i {
  color: var(--sunset-accent);
  font-size: 14px;
}

.sunset-explain-icon {
  font-size: 12px;
  color: var(--sunset-accent);
  transition: transform 0.3s ease;
}

.sunset-explain-body {
  padding: 0 14px 14px;
  animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}

.explain-section {
  margin-bottom: 16px;
}

.explain-section:last-child {
  margin-bottom: 0;
}

.explain-text {
  font-size: 13px;
  color: var(--subtext);
  line-height: 1.7;
  margin: 0 0 10px 0;
}

.explain-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.explain-table td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--hgu-border-soft);
  color: var(--sunset-accent);
  line-height: 1.5;
}

.explain-table tr:last-child td {
  border-bottom: none;
}

.explain-range {
  white-space: nowrap;
  width: 1px;
  font-weight: 600;
  color: var(--sunset-accent);
}

/* 数据来源 */
.weather-data-source {
  width: 100%;
  max-width: 400px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 4px 0 8px;
}

.weather-data-source span {
  font-size: 11px;
  color: var(--subtext);
  opacity: 0.5;
}

/* ===== Source: hometown-groups.css ===== */
.hometown-groups-content {
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  padding: 12px 12px 100px;
  box-sizing: border-box;
  --hometown-accent: var(--color-life, #f07f20);
  --hometown-accent-soft: rgba(240, 127, 32, 0.12);
  --hometown-accent-border: rgba(240, 127, 32, 0.48);
}

#hometown-groups-page .sub-page-title {
  color: var(--hometown-page-accent, var(--color-life, #f07f20));
}

#hometown-groups-page .sub-page-back,
#hometown-groups-page .schedule-header-btn {
  border-color: rgba(240, 127, 32, 0.48);
  background: rgba(240, 127, 32, 0.12);
  color: var(--color-life, #f07f20);
}

/* 返回箭头不要底色：上面那条与 .schedule-header-btn 共享，橙色底只留给后者 */
#hometown-groups-page .sub-page-back {
  background: none;
}

.freshman-chat-card {
  min-height: 88px;
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  padding: 14px 12px 14px 14px;
  border: 1px solid var(--hometown-accent-border);
  border-radius: var(--hgu-radius-lg);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  backdrop-filter: blur(var(--hgu-blur-xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-xl));
  box-sizing: border-box;
}

.freshman-chat-copy {
  min-width: 0;
  flex: 1;
}

.freshman-chat-title {
  color: var(--hometown-accent);
  font-size: 15px;
  font-weight: 800;
}

.freshman-chat-subtitle {
  margin-top: 5px;
  color: var(--subtext);
  font-size: 12px;
  line-height: 1.55;
}

.freshman-chat-link {
  min-width: 64px;
  min-height: 38px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 10px;
  border: 1px solid var(--hometown-accent-border);
  border-radius: var(--hgu-radius-md);
  background: var(--hometown-accent-soft);
  color: var(--hometown-accent);
  font-size: 12px;
  font-weight: 800;
  text-decoration: none;
  box-sizing: border-box;
}

.freshman-chat-link i {
  font-size: 10px;
}

.hometown-tabs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--hometown-accent-border);
  border-radius: var(--hgu-radius-lg);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
}

.hometown-tab {
  min-height: 38px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--subtext);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}

.hometown-tab.active {
  background: var(--hometown-accent-soft);
  color: var(--hometown-accent);
}

.hometown-summary {
  margin: 12px 2px 8px;
  color: var(--subtext);
  font-size: 12px;
}

.hometown-group-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
}

.hometown-group-item {
  min-width: 0;
  min-height: 76px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 10px 10px 12px;
  border: 1px solid var(--hometown-accent-border);
  border-radius: var(--hgu-radius-lg);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  backdrop-filter: blur(var(--hgu-blur-xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-xl));
  box-sizing: border-box;
}

.hometown-region-icon {
  width: 48px;
  height: 48px;
  flex: 0 0 48px;
  object-fit: contain;
}

.hometown-group-main {
  min-width: 0;
  flex: 1;
}

.hometown-group-name {
  overflow: hidden;
  color: var(--hometown-accent);
  font-size: 14px;
  font-weight: 800;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hometown-group-number {
  margin-top: 4px;
  color: var(--subtext);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.hometown-copy-btn {
  width: 36px;
  height: 36px;
  flex: 0 0 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--hometown-accent-border);
  border-radius: var(--hgu-radius-md);
  background: var(--hometown-accent-soft);
  color: var(--hometown-accent);
  cursor: pointer;
}

.hometown-groups-state {
  grid-column: 1 / -1;
  min-height: 180px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--subtext);
  font-size: 13px;
  text-align: center;
}

@media (max-width: 380px) {
  .hometown-region-icon {
    width: 42px;
    height: 42px;
    flex-basis: 42px;
  }

  .freshman-chat-card {
    align-items: flex-start;
  }
}

/* ===== Source: phonebook.css ===== */
#phonebook-page {
  --phonebook-accent: var(--text);
  --phonebook-soft: var(--text-light);
  --phonebook-border: var(--text);
  --phonebook-active-text: #fff;
  --phonebook-number-bg: rgba(74, 124, 89, 0.08);
  --phonebook-number-border: rgba(74, 124, 89, 0.18);
}

#phonebook-page .sub-page-title {
  color: var(--phonebook-accent);
}

#phonebook-page .sub-page-back,
#phonebook-page .schedule-header-btn {
  border-color: var(--phonebook-accent);
  background: transparent;
  color: var(--phonebook-accent);
}

.phonebook-content {
  width: 100%;
  max-width: 100%;
  margin: 0 auto;
  padding: 12px 0 100px;
  box-sizing: border-box;
}

.phonebook-tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
  padding-bottom: 4px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.phonebook-tabs::-webkit-scrollbar {
  display: none;
}

.phonebook-tab {
  flex: 0 0 auto;
  padding: 8px 18px;
  border: 1.5px solid var(--phonebook-accent);
  border-radius: var(--hgu-radius-default);
  background: var(--hgu-surface-glass);
  color: var(--subtext);
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: all 0.2s;
  backdrop-filter: blur(var(--hgu-blur-md));
  -webkit-backdrop-filter: blur(var(--hgu-blur-md));
}

.phonebook-tab.active {
  background: var(--phonebook-accent);
  color: var(--phonebook-active-text);
  border-color: var(--phonebook-accent);
  font-weight: 600;
  box-shadow: 0 2px 8px rgba(74, 124, 89, 0.25);
}

.phonebook-tab:active {
  transform: scale(0.95);
}

.phonebook-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.phonebook-official-links {
  margin-top: 16px;
  border-color: rgba(74, 124, 89, 0.5);
}

.phonebook-official-links .official-links-title,
.phonebook-official-links .official-link-row,
.phonebook-official-links .official-link-button {
  color: var(--phonebook-accent);
}

.phonebook-official-links .official-link-button {
  border-color: rgba(74, 124, 89, 0.4);
  background: var(--phonebook-soft);
}

.phonebook-contact {
  padding: 14px;
  border: 1.5px solid var(--phonebook-accent);
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  backdrop-filter: blur(var(--hgu-blur-xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-xl));
}

.phonebook-contact-title {
  color: var(--phonebook-accent);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.4;
}

.phonebook-contact-location {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 100%;
  margin-top: 5px;
  color: var(--subtext);
  font-size: 12px;
  line-height: 1.45;
}

.phonebook-contact-location i {
  flex: 0 0 auto;
  color: var(--phonebook-accent);
  font-size: 11px;
}

.phonebook-contact-location span {
  min-width: 0;
  overflow-wrap: anywhere;
}

.phonebook-phone-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(74, 124, 89, 0.2);
}

.phonebook-phone-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 38px 38px;
  align-items: center;
  gap: 7px;
}

.phonebook-phone-number {
  min-width: 0;
  padding: 8px 10px;
  border-radius: var(--hgu-radius-md);
  border: 1px solid var(--phonebook-number-border);
  background: var(--phonebook-number-bg);
  color: var(--subtext);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.phonebook-action-btn {
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--phonebook-accent);
  border-radius: var(--hgu-radius-md);
  background: transparent;
  color: var(--phonebook-accent);
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.2s, background 0.2s;
}

.phonebook-action-btn:active {
  transform: scale(0.95);
  background: var(--phonebook-soft);
}

.phonebook-state {
  min-height: 180px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--subtext);
  font-size: 13px;
  text-align: center;
}

@media (max-width: 380px) {
  .phonebook-contact {
    padding: 12px;
  }

  .phonebook-phone-row {
    grid-template-columns: minmax(0, 1fr) 36px 36px;
  }

  .phonebook-action-btn {
    width: 36px;
    height: 36px;
  }
}

  html[data-theme="dark"] #phonebook-page {
    --phonebook-active-text: #263347;
    --phonebook-number-bg: rgba(0, 0, 0, 0.18);
    --phonebook-number-border: rgba(255, 255, 255, 0.1);
  }

  html[data-theme="dark"] .phonebook-phone-actions {
    border-top-color: rgba(168, 224, 99, 0.22);
  }

  html[data-theme="dark"] .phonebook-official-links {
    border-color: rgba(168, 224, 99, 0.5);
  }

  html[data-theme="dark"] .phonebook-official-links .official-link-button {
    border-color: rgba(168, 224, 99, 0.38);
  }

/* ===== Source: ui-polish.css ===== */
/* ============================================
   Unified component normalization: shared radii, touch feedback, mobile motion
   Kept after feature styles so it can safely normalize page-level details.
   ============================================ */

.tools-search-bar,
.bottom-nav,
#floorBar,
#indoorLegend,
.modal-content,
.app-download-drawer,
.score-eval-warning-dialog,
.course-detail-modal,
.official-links-card {
  border-radius: var(--hgu-radius-4xl);
}

.page-overlay {
  border-radius: var(--hgu-radius-4xl) var(--hgu-radius-4xl) 0 0;
}

.tool-btn,
.tool-btn.qq-channel-row-btn,
.study-feature-panel,
.study-simple-card,
.study-schedule-card,
.score-section,
.score-stat-card,
.training-plan-card,
.energy-card,
.campus-card-panel,
.eat-card,
.room-card,
.calendar-card,
.activity-card,
.club-card,
.hometown-card,
.station-card,
.weather-card,
.option-card {
  border-radius: var(--hgu-radius-polished);
}

button,
.glass-btn,
.sub-page-back,
.schedule-header-btn,
.tool-btn-action-badge,
.official-link-button,
input,
select,
textarea {
  border-radius: var(--hgu-radius-default);
}

.bottom-nav,
.location-btn,
#floorBar,
.tools-search-bar,
.tool-btn,
.study-feature-panel,
.study-simple-card,
.study-schedule-card,
.sub-page-back,
.official-link-row {
  transition-duration: var(--motion-base);
  transition-timing-function: var(--ease-standard);
}

/* Shared cards and glass surfaces */
.tool-btn,
.service-card,
.service-card-main,
.study-feature-panel,
.study-simple-card,
.study-schedule-card,
.life-freshman-card,
.life-tool-card,
.life-balance-card,
.life-package-card,
.life-canteen-card,
.life-activities-card,
.cal-section-card,
.cal-event-card,
.activity-list-card,
.score-section,
.score-stat-card,
.score-semester-card,
.training-plan-card,
.energy-balance-card-v2,
.energy-chart-card,
.energy-detail-card,
.campus-card-balance-card,
.campus-card-section,
.campus-card-summary-item,
.floor-group-card,
.window-info-card,
.elective-card,
.room-building-card,
.official-links-card {
  border-radius: var(--hgu-radius-polished);
  box-shadow: var(--hgu-shadow-card);
}

/* Shared button rhythm */
.glass-btn,
.sub-page-back,
.schedule-header-btn,
.modal-btn,
.official-link-button,
.study-tool-button,
.study-feature-action,
.study-exam-icon-btn,
.study-exam-add-btn,
.tool-btn-action-badge,
.activity-list-card.is-clickable,
.eatwhat-action-btn,
.random-refresh-btn,
.energy-recharge-btn,
.energy-month-btn,
.campus-card-period-btn,
.campus-card-recharge-btn,
.campus-card-scan-water-btn,
.hometown-copy-btn,
.phonebook-action-btn,
.station-drawer-tabs button {
  border-radius: var(--hgu-radius-default);
  transition: transform var(--motion-fast) var(--ease-standard),
              background-color var(--motion-base) ease,
              border-color var(--motion-base) ease,
              box-shadow var(--motion-base) ease,
              color var(--motion-base) ease,
              opacity var(--motion-base) ease;
}

.glass-btn:active,
.schedule-header-btn:active,
.modal-btn:active,
.official-link-button:active,
.study-tool-button:active,
.study-feature-action:active,
.study-exam-icon-btn:active,
.study-exam-add-btn:active,
.tool-btn-action-badge:active,
.activity-list-card.is-clickable:active,
.eatwhat-action-btn:active,
.random-refresh-btn:active,
.energy-recharge-btn:active,
.energy-month-btn:active,
.campus-card-period-btn:active,
.campus-card-recharge-btn:active,
.campus-card-scan-water-btn:active,
.hometown-copy-btn:active,
.phonebook-action-btn:active {
  transform: scale(0.96);
}

/* Shared tab and chip controls */
.community-view-tabs,
.study-schedule-tabs,
.training-plan-tabs,
.station-drawer-tabs,
.store-view-tabs,
.campus-card-tab-switch,
.eatwhat-canteen-tabs,
.random-type-tabs,
.elective-filter-bar,
.hometown-tabs {
  border-radius: var(--hgu-radius-xl);
}

.community-view-tab,
.study-schedule-tab,
.training-plan-tab,
.station-drawer-tabs button,
.store-view-tab,
.campus-card-tab,
.canteen-tab,
.random-type-btn,
.elective-filter-btn,
.hometown-tab {
  border-radius: var(--hgu-radius-md);
}

/* Shared search fields */
.tools-search-bar,
.eatwhat-search-bar,
.elective-search-bar,
.freshman-search,
.room-filter-card {
  border-radius: var(--hgu-radius-4xl);
  border-color: var(--hgu-border-soft);
  box-shadow: var(--hgu-shadow-card);
}

.tools-search-bar input,
.eatwhat-search-bar input,
.elective-search-bar input,
.freshman-search input,
input,
select,
textarea {
  border-radius: var(--hgu-radius-default);
}

.clear-btn,
.eatwhat-search-bar .clear-btn,
.elective-search-bar .clear-btn {
  border-radius: var(--hgu-radius-round);
}

/* Shared modals and secondary drawers */
.modal-overlay,
.secondary-drawer-overlay {
  backdrop-filter: blur(var(--hgu-blur-lg));
  -webkit-backdrop-filter: blur(var(--hgu-blur-lg));
}

.modal-card,
.modal-content,
.score-eval-warning-dialog,
.course-detail-modal,
.secondary-drawer,
.app-download-drawer,
.campus-water-drawer,
.elective-requirement-drawer,
.period-selector-drawer,
.sunset-forecast-drawer {
  border-radius: var(--hgu-radius-4xl);
  background: var(--hgu-surface-glass);
  border-color: var(--hgu-border-soft);
  box-shadow: var(--hgu-shadow-modal);
  backdrop-filter: blur(var(--hgu-blur-xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-xl));
}

.secondary-drawer {
  border-radius: var(--hgu-radius-drawer);
}

.modal-close,
.secondary-drawer-handle {
  border-radius: var(--hgu-radius-pill);
}

/* Shared empty and loading states */
.search-loading,
.channel-hot-loading,
.study-card-loading,
.study-card-empty,
.study-exam-room-empty,
.service-card-preview-empty,
.frequent-empty,
.station-empty,
.score-empty-state,
.score-detail-loading,
.training-plan-loading,
.training-plan-empty,
.library-study-loading,
.library-study-empty,
.elective-empty,
.phonebook-state {
  border-radius: var(--hgu-radius-polished);
  color: var(--subtext);
  text-align: center;
}

/* Community activities page: make small controls match the softer global radius. */
#activities-page .community-view-tabs {
  border-radius: var(--hgu-radius-pill);
  padding: 4px;
}

#activities-page .community-view-tab {
  border-radius: var(--hgu-radius-pill);
  transition: transform var(--motion-fast) var(--ease-standard),
              background-color var(--motion-base) ease,
              box-shadow var(--motion-base) ease,
              color var(--motion-base) ease;
}

#activities-page .community-view-tab:active {
  transform: scale(0.96);
}

#activities-page .club-card {
  border-radius: var(--hgu-radius-2xl);
}

#activities-page .club-logo {
  border-radius: var(--hgu-radius-md);
}

#activities-page .club-logo {
  border-radius: var(--hgu-radius-round);
}

#activities-page .club-card,
#activities-page .club-like-btn {
  transition: transform var(--motion-fast) var(--ease-standard),
              background-color var(--motion-base) ease,
              border-color var(--motion-base) ease,
              box-shadow var(--motion-base) ease;
}

#activities-page .club-card:active {
  transform: scale(0.99);
}

@media (hover: hover) and (pointer: fine) {
  #activities-page .club-card:hover {
    transform: translateY(-2px);
  }
}
.bottom-nav {
  animation: uiFloatIn var(--motion-slow) var(--ease-spring) both;
}

.location-btn {
  animation: uiFloatInCorner var(--motion-slow) var(--ease-spring) 80ms both;
}

.bottom-nav-item i,
.tool-btn img,
.study-feature-img,
.schedule-header-btn i {
  transition: transform var(--motion-base) var(--ease-spring), opacity var(--motion-base) ease;
}

.bottom-nav-item.active i {
  transform: translateY(-1px) scale(1.08);
}

.bottom-nav-item:active i,
.tool-btn:active img,
.schedule-header-btn:active i {
  transform: scale(0.9);
}

.tool-btn,
.study-feature-panel,
.study-simple-card,
.study-schedule-card {
  transform-origin: center;
}

.tool-btn:active,
.study-feature-action:active,
.study-tool-button:active,
.official-link-row:active {
  transform: scale(0.96);
}

.tools-sub-page.active {
  animation: pageEnter var(--motion-slow) var(--ease-standard) both;
}

.tools-home-grid > *,
.study-top-grid > *,
.tools-grid-section > *,
.tools-grid-section-secondary > * {
  animation: cardRise var(--motion-slow) var(--ease-standard) both;
}

.tools-home-grid > *:nth-child(2n),
.tools-grid-section > *:nth-child(2n) {
  animation-delay: 35ms;
}

.tools-home-grid > *:nth-child(3n),
.tools-grid-section > *:nth-child(3n) {
  animation-delay: 70ms;
}

/* 顶部小横条保持静态：原 handleBreath 呼吸动画已按需求移除
   （服务卡片与抽屉页共用这一根把手）。 */

@media (hover: hover) and (pointer: fine) {
  .tool-btn:hover,
  .study-feature-panel:hover,
  .study-simple-card:hover,
  .study-schedule-card:hover,
  .tools-search-bar:hover,
  .official-link-row:hover {
    transform: translateY(-2px);
  }

  .tool-btn:hover img,
  .study-feature-panel:hover .study-feature-img {
    transform: scale(1.07) rotate(1deg);
  }
}

@media (max-width: 480px) {
  .tools-home-grid {
    gap: 12px;
  }

  .tool-btn,
  .study-feature-panel,
  .study-simple-card,
  .study-schedule-card {
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  }

  .bottom-nav {
    bottom: max(14px, env(safe-area-inset-bottom));
  }
}

@keyframes uiFloatIn {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(14px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateX(-50%) translateY(0) scale(1);
  }
}

@keyframes uiFloatInCorner {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes pageEnter {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes cardRise {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes softNudge {
  0%, 100% { translate: 0 0; }
  50% { translate: 0 -1px; }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 1ms !important;
  }
}

/* Targeted post-polish overrides */
.secondary-drawer.station-drawer {
  border: 1.5px solid rgba(47, 124, 255, 0.48);
  border-bottom: none;
}

.secondary-drawer.course-detail-drawer,
.secondary-drawer.course-import-drawer,
.secondary-drawer.schedule-manage-drawer {
  border: 1.5px solid var(--text);
  border-bottom: none;
}

.secondary-drawer.course-detail-drawer .secondary-drawer-handle,
.secondary-drawer.course-import-drawer .secondary-drawer-handle,
.secondary-drawer.schedule-manage-drawer .secondary-drawer-handle {
  background: var(--text);
  opacity: 0.75;
}

/* 导入课表弹窗：浏览器（非安卓APP）提示——只能导入固定班级课表 */
.course-import-warning {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 12px;
  margin-bottom: 16px;
  border: 1px solid rgba(255, 152, 0, 0.45);
  border-radius: var(--hgu-radius-xl);
  background: rgba(255, 152, 0, 0.10);
  color: #b26a00;
  font-size: 12px;
  line-height: 1.6;
  text-align: left;
}

.course-import-warning i {
  flex: none;
  margin-top: 3px;
  font-size: 13px;
}

.course-import-warning span {
  flex: 1;
}

html[data-theme="dark"] .course-import-warning {
  border-color: rgba(255, 183, 77, 0.42);
  background: rgba(255, 152, 0, 0.16);
  color: #ffb74d;
}

.campus-card-recharge-btn,
.campus-card-scan-water-btn,
.campus-water-primary-actions button {
  border-radius: var(--hgu-radius-2xl);
}

/* ============ 课表总览：热图/列表 切换条 = 主文本绿 + 左右居中 ============ */
#scheduleOverviewViewTabs {
  justify-content: center;
}

#scheduleOverviewViewTabs .canteen-tab {
  color: var(--subtext);
  opacity: 0.55;
}

#scheduleOverviewViewTabs .canteen-tab.active {
  color: var(--text);
  opacity: 1;
  font-weight: 900;
}

#scheduleOverviewViewTabs .canteen-tab-indicator {
  background: var(--text);
  box-shadow: 0 2px 6px rgba(74, 124, 89, 0.35);
}

/* 课表总览列表：课程卡片主文本绿边框、右上角学分标签主文本绿 */
.schedule-overview-course {
  border-color: rgba(74, 124, 89, 0.45);
}

.schedule-overview-course-credit {
  color: var(--text);
  border-color: rgba(74, 124, 89, 0.4);
  background: rgba(74, 124, 89, 0.08);
}

/* ============ 底部悬浮导航栏：图标防裁切/防溢出 ============ */
.bottom-nav {
  height: 48px;
  padding: 3px 6px;
}

.bottom-nav-item {
  gap: 1px;
  overflow: visible;
  padding: 0 1px;
}

.bottom-nav-item i {
  display: block;
  width: 15px;
  height: 15px;
  font-size: 15px;
  line-height: 15px;
  text-align: center;
}

.bottom-nav-item span {
  font-size: 10px;
  line-height: 1;
  white-space: nowrap;
}

/* ============ 底部悬浮栏图标：实心样式 ============
   总悬浮栏与「今天吃什么」两条栏（都挂在 .bottom-dock 里）的图标统一用
   Font Awesome 实心字形（fas），不再做「掏空描边」处理。
   未选中图标颜色跟随按钮自身的 --subtext / --ew-theme-soft；
   亮色模式下未高亮图标额外调淡（见下方 html[data-theme="light"] 规则）。 */
html[data-theme="light"] .bottom-dock .bottom-nav-item:not(.active) i {
  color: #9aa1a8;
}

/* 抽屉收起/隐藏态：激活项也不高亮，图标一并调淡到与未选中一致（亮色模式 #9aa1a8）
   —— 否则关闭抽屉后，之前高亮的图标仍停在 --subtext(#333)，比未选中的 #9aa1a8 更显眼，
   表现为「高亮没淡化」。 */
html[data-theme="light"] body.home-panel-compact .bottom-dock .bottom-nav-item.active i,
html[data-theme="light"] body.home-panel-hidden .bottom-dock .bottom-nav-item.active i {
  color: #9aa1a8;
}

/* ============ 课表页·未导入课表空态 官方页面跳转：主文本绿（与课表管理弹窗一致） ============ */
.schedule-empty-official-links.official-links-card {
  border-color: rgba(74, 124, 89, 0.5);
}

.schedule-empty-official-links .official-links-title,
.schedule-empty-official-links .official-link-row,
.schedule-empty-official-links .official-link-button {
  color: var(--text);
}

.schedule-empty-official-links .official-link-button {
  border-color: rgba(74, 124, 89, 0.4);
  background: rgba(74, 124, 89, 0.08);
}

/* ============ 空教室查询页（#search-page）：日期课节卡 / 教室楼层卡 = 青色主题边框 ============ */
#search-page .room-filter-card,
#search-page .room-floor-card {
  border: 1.5px solid rgba(var(--study-cyan-rgb), 0.45);
}

/* 房间行操作：只点击文字区域进入课表；右侧「定位到这里」 */
#search-page .room-floor-room-btn {
  cursor: default;
}

#search-page .room-floor-room-actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

#search-page .room-floor-room-action {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 800;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  color: var(--study-cyan);
  border: 1px solid rgba(var(--study-cyan-rgb), 0.5);
  background: rgba(var(--study-cyan-rgb), 0.1);
  transition: transform 0.15s ease, background-color 0.15s ease;
}

#search-page .room-floor-room-action:active {
  transform: scale(0.94);
}

/* 课节选择器：两行布局，小字显示对应课节的时间范围 */
#search-page .period-filter-btn {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  line-height: 1.15;
}

#search-page .period-filter-btn small {
  font-size: 8px;
  font-weight: 600;
  opacity: 0.72;
  white-space: nowrap;
}

/* ============================================
   右上角操作按钮（通知/图层）：仅地图态显示，抽屉展开时隐藏
   ============================================ */.map-top-actions {
  position: fixed;
  top: var(--hgu-top-actions-top);
  right: 16px;
  z-index: 996;
  /* 通知 + 图层合并成一个圆角矩形，中间用分割线分隔（原来是两个独立圆钮）：
     玻璃底、边框、圆角、阴影都由容器出，按钮自身不再画卡片 */
  display: flex;
  flex-direction: column;
  gap: 0;
  align-items: stretch;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-2xl);
  box-shadow: var(--hgu-shadow-card);
  backdrop-filter: blur(var(--hgu-blur-md));
  -webkit-backdrop-filter: blur(var(--hgu-blur-md));
  overflow: visible;
}
body.home-panel-expanded .map-top-actions {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .2s ease, visibility 0s .2s;
}
.map-top-action-btn {
  position: relative;
  width: 56px;
  padding: 8px 0 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-xl);
  /* 图标与文本色 = 主文本色（需求从"未选中色"改回主文本色）。
     ⚠️ 用全局 token --hgu-idle-chrome（在 :root 里 = var(--text)）：
        直接写 var(--text) 会被抽屉内的页面主题覆盖（.tools-fixed-header-layer
        > [data-header-for=...] 等重定义过 --text），颜色会跟着变。 */
  color: var(--hgu-idle-chrome);
  box-shadow: var(--hgu-shadow-card);
  backdrop-filter: blur(var(--hgu-blur-md));
  -webkit-backdrop-filter: blur(var(--hgu-blur-md));
  cursor: pointer;
  font-size: 11px;
  line-height: 1.2;
}

.map-top-action-btn i {
  color: inherit;
}
.map-top-action-btn i { font-size: 18px; }
.map-top-action-btn:active { transform: scale(.94); }
.map-notice-badge {
  position: absolute;
  top: -3px;
  right: -3px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  box-sizing: border-box;
  border-radius: 999px;
  background: #e53935;
  color: #fff;
  font-size: 10px;
  font-style: normal;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  pointer-events: none;
}
.map-top-action-btn.notice-important {
  background: #e53935;
  border-color: #e53935;
  color: #fff;
}
.map-top-action-btn.notice-important .map-notice-badge {
  background: #fff;
  color: #e53935;
}
.map-top-action-btn[disabled] { opacity: .6; cursor: not-allowed; }

/* ============================================
   图层二级抽屉（外观显示 + 地图显示）
   ============================================ */
.layer-drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 18px 2px;
}
.layer-drawer-title {
  font-size: 17px;
  font-weight: 700;
  color: var(--text);
}
.layer-drawer-content {
  /* 左右不再留白：抽屉本身已有 20px 内边距，这里再叠 18px 会让开关网格明显缩在中间 */
  padding: 10px 0 26px;
  max-height: 66vh;
  overflow-y: auto;
}
.layer-drawer-section + .layer-drawer-section {
  margin-top: 20px;
}
.layer-drawer-section-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 12px;
}
.layer-marker-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
.layer-marker-switch {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 8px 2px 6px;
  background: transparent;
  border: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.layer-marker-icon {
  width: 46px;
  height: 46px;
  border-radius: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--hgu-surface-glass-soft);
  border: 1px solid rgba(128,128,128,.45);
  transition: border-color .2s, box-shadow .2s, background .2s;
}
.layer-marker-icon img {
  width: 26px;
  height: 26px;
  object-fit: contain;
  pointer-events: none;
}
.layer-marker-label {
  font-size: 12px;
  color: var(--subtext);
  font-weight: 400;
  transition: color .2s, font-weight .2s;
  pointer-events: none;
}
.layer-marker-switch.active .layer-marker-icon {
  border: 2px solid var(--text);
  background: var(--text-light);
}
.layer-marker-switch.active .layer-marker-label {
  color: var(--text);
  font-weight: 700;
}
.layer-marker-switch[disabled] {
  opacity: .6;
  cursor: not-allowed;
}
@media (max-width: 359px) {
  .layer-marker-icon { width: 40px; height: 40px; }
  .layer-marker-icon img { width: 22px; height: 22px; }
}

/* ============================================
   校园通知：通知页列表 + 紧急通知二级抽屉
   ============================================ */
.notifications-page-content {
  width: 100%;
  max-width: 520px;
  padding: 6px 0 24px;
}
.notices-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 60px 16px;
  color: var(--subtext);
  font-size: 14px;
}
.notices-empty i { font-size: 34px; opacity: .5; }
.notice-item {
  background: var(--hgu-surface-glass-strong);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-2xl);
  padding: 14px 16px;
  margin-bottom: 12px;
  box-shadow: var(--hgu-shadow-card);
}
.notice-item.is-read { opacity: .72; }
.notice-item-head { display: flex; align-items: flex-start; gap: 8px; }
.notice-item-title { font-size: 15px; font-weight: 700; color: var(--text); line-height: 1.5; flex: 1; min-width: 0; overflow-wrap: anywhere; }
.notice-item-meta { display: flex; gap: 10px; margin-top: 4px; font-size: 11px; color: var(--subtext); }
.notice-tag {
  flex-shrink: 0;
  font-size: 11px;
  line-height: 1;
  padding: 3px 7px;
  border-radius: var(--hgu-radius-pill);
  font-weight: 600;
  white-space: nowrap;
}
.notice-tag-normal { background: rgba(128,128,128,.16); color: var(--subtext); }
.notice-tag-important { background: rgba(255,152,0,.16); color: #e65100; }
.notice-tag-urgent { background: rgba(229,57,53,.14); color: #e53935; }
html[data-theme="dark"] .notice-tag-important { color: #ffb74d; }
html[data-theme="dark"] .notice-tag-urgent { color: #ff8a80; }
.notice-item-body { margin-top: 8px; font-size: 13px; line-height: 1.75; color: var(--subtext); overflow-wrap: anywhere; }
.notice-md-heading { font-size: 14px; margin: 8px 0 4px; color: var(--text); }
.notice-md-hr { border: none; border-top: 1px solid var(--hgu-border-soft); margin: 8px 0; }
.notice-md-list { margin: 4px 0 4px 18px; padding: 0; }
.notice-body-img {
  display: block;
  max-width: 100%;
  max-height: 240px;
  border-radius: var(--hgu-radius-lg);
  margin: 8px auto;
  cursor: zoom-in;
  object-fit: contain;
}
.notice-item-actions { margin-top: 10px; display: flex; justify-content: flex-end; }
.notice-read-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: inherit;
  font-size: 13px;
  padding: 7px 14px;
  border-radius: var(--hgu-radius-pill);
  border: 1px solid var(--hgu-border-soft);
  background: var(--hgu-surface-glass);
  color: var(--text);
  cursor: pointer;
}
.notice-read-btn:active { transform: scale(.96); }
.urgent-notice-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 18px 2px;
}
.urgent-notice-header-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 700;
  color: #e53935;
}
.urgent-notice-scroll {
  padding: 12px 18px 26px;
  max-height: 64vh;
  overflow-y: auto;
}
.urgent-notice-top { margin-bottom: 10px; }
.urgent-notice-title { font-size: 16px; font-weight: 700; color: var(--text); margin: 8px 0 4px; line-height: 1.5; overflow-wrap: anywhere; }
.urgent-notice-meta { font-size: 11px; color: var(--subtext); }
.urgent-notice-body { font-size: 14px; line-height: 1.8; color: var(--subtext); overflow-wrap: anywhere; }
.urgent-notice-body .notice-md-heading { font-size: 15px; }
.urgent-notice-read-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  margin-top: 14px;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  padding: 11px 0;
  border: none;
  border-radius: var(--hgu-radius-xl);
  background: var(--text);
  color: #fff;
  cursor: pointer;
}
.urgent-notice-read-btn:active { opacity: .85; }
@media (max-width: 359px) {
  .urgent-notice-scroll { max-height: 58vh; }
}

/* ============================================
   APP 版本更新：服务卡片 + 多版本日志抽屉
   ============================================ */
.home-update-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: var(--hgu-surface-glass-strong);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-2xl);
  box-shadow: var(--hgu-shadow-card);
}
.home-update-card .home-recommend-copy { flex: 1; min-width: 0; }
.home-update-card.is-downloading, .home-update-card.is-ready {
  border-color: var(--text);
}
.home-update-actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.home-update-btn {
  font: inherit;
  font-size: 12px;
  padding: 6px 10px;
  border-radius: var(--hgu-radius-pill);
  border: 1px solid var(--hgu-border-soft);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}
.home-update-btn.primary { background: var(--text); color: #fff; border-color: var(--text); }
.home-update-btn:active { transform: scale(.96); }
.home-update-percent {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  flex-shrink: 0;
}
.home-update-progress-track {
  display: block;
  height: 6px;
  border-radius: 999px;
  background: var(--hgu-border-soft);
  margin-top: 6px;
  overflow: hidden;
}
.home-update-progress-bar {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--text);
  transition: width .3s ease;
}
.home-update-card.is-error { border-color: rgba(229,57,53,.5); }
.home-update-card.is-error .home-recommend-kicker { color: #e53935; }
.update-log-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 18px 2px;
}
.update-log-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
}
.update-log-scroll {
  padding: 12px 18px 28px;
  max-height: 64vh;
  overflow-y: auto;
}
.update-log-version {
  padding: 12px 0;
}
.update-log-version + .update-log-version {
  border-top: 1px solid var(--hgu-border-soft);
}
.update-log-version h4 {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 6px;
  font-size: 14px;
  color: var(--text);
}
.update-log-date {
  font-size: 11px;
  font-weight: 400;
  color: var(--subtext);
  margin-left: 4px;
}
.update-log-body {
  font-size: 13px;
  line-height: 1.8;
  color: var(--subtext);
  overflow-wrap: anywhere;
}
.update-log-body h3, .update-log-body h4, .update-log-body h5 { margin: 8px 0 4px; color: var(--text); }
.update-log-body ul { margin: 4px 0 4px 18px; padding: 0; }
.update-log-body br { content: ""; display: block; margin: 2px 0; }
.update-log-empty { color: var(--subtext); text-align: center; padding: 30px 0; }
@media (max-width: 379px) {
  .home-update-actions { flex-wrap: wrap; justify-content: flex-end; }
  .update-log-scroll { max-height: 58vh; }
}

/* 右上角通知/图层按钮：尺寸/圆角/玻璃与定位按钮一致（用户要求） */
.map-top-action-btn {
  width: 45px;
  padding: 6px 0 4px;
  gap: 2px;
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  color: var(--text);
  backdrop-filter: blur(var(--hgu-blur-md));
  -webkit-backdrop-filter: blur(var(--hgu-blur-md));
  box-shadow: var(--hgu-shadow-card);
}
.map-top-action-btn i { font-size: 16px; line-height: 1; }
.map-top-action-btn > span:not(.map-notice-badge) { font-size: 10px; font-weight: 500; }
.map-top-action-btn:active { transform: scale(.9); }
/* 选项页“检测更新”卡片按钮主操作样式 */
.version-update-btn--primary {
  background: var(--text);
  color: #fff;
  border-color: var(--text);
}

/* 版本更新服务卡：与其它推荐卡一致（透明、无额外外壳） */
.home-recommend-card--update {
  width: 100%;
  min-height: 78px;
  flex-wrap: wrap;
  align-items: flex-start;
  row-gap: 6px;
}
.home-recommend-card--update .home-recommend-copy { flex: 1; min-width: 0; }
.home-recommend-card--update .home-recommend-title { white-space: normal; }
.home-recommend-card--update .home-update-actions {
  flex-basis: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  flex-shrink: 0;
  flex-wrap: wrap;
  margin-top: 2px;
}
.home-recommend-card--update .home-update-percent { flex-basis: 100%; text-align: right; }
.home-update-percent { flex-shrink: 0; font-size: 13px; font-weight: 700; color: var(--text); }
.home-update-track { display: block; height: 6px; border-radius: 999px; background: var(--hgu-border-soft); margin-top: 8px; overflow: hidden; min-width: 90px; }
.home-update-bar { display: block; height: 100%; border-radius: 999px; background: var(--text); transition: width .3s ease; }
.home-update-btn {
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  padding: 8px 10px;
  border-radius: var(--hgu-radius-pill);
  border: 1px solid var(--hgu-border-soft);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}
.home-update-btn.primary { background: var(--text); color: #fff; border-color: var(--text); }
.home-update-btn:active { transform: scale(.96); }

/* 强制更新服务卡片（版本 < 0.8.1 漏洞警示） */
.home-recommend-card--forcedupdate { align-items: flex-start; flex-wrap: wrap; width: 100%; row-gap: 6px; }
.home-recommend-card--forcedupdate .home-recommend-copy { flex: 1; min-width: 0; }
.home-recommend-card--forcedupdate .home-recommend-icon--danger { background: #e53935; color: #fff; }
.home-recommend-card--forcedupdate .home-recommend-kicker--danger { color: #e53935; }
.home-recommend-card--forcedupdate .home-recommend-title--danger { color: #e53935; }
.home-recommend-card--forcedupdate .home-recommend-subtitle--danger { color: #ff6a3d; white-space: normal; }
.home-forced-update-cancel {
  font: inherit; font-size: 12px; font-weight: 700; line-height: 1;
  padding: 8px 12px; border-radius: var(--hgu-radius-pill);
  border: 1px solid rgba(229, 57, 53, .5); background: transparent; color: #e53935;
  cursor: pointer; white-space: nowrap; flex-shrink: 0; margin-left: auto;
}
.home-forced-update-cancel:active { transform: scale(.96); }
/* 服务卡片底部右下角：下载安装按钮 / 浏览器打开提示文本 */
.home-forced-update-foot {
  flex-basis: 100%;
  display: inline-flex; align-items: center; justify-content: flex-end;
  gap: 6px; flex-shrink: 0; flex-wrap: wrap; margin-top: 2px;
}
.home-forced-update-download {
  font: inherit; font-size: 12px; font-weight: 700; line-height: 1;
  padding: 8px 14px; border-radius: var(--hgu-radius-pill);
  border: 1.5px solid #e53935; background: #e53935; color: #fff;
  cursor: pointer; white-space: nowrap; display: inline-flex; align-items: center; gap: 6px;
}
.home-forced-update-download:active { transform: scale(.96); }
.home-forced-update-text {
  font-size: 12px; font-weight: 700; color: #e53935;
}

/* 通知页“全部已读”按钮 */
.notifications-read-all-btn {
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 6px 10px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-pill);
  background: var(--hgu-surface-glass);
  color: var(--text);
  cursor: pointer;
}
.notifications-read-all-btn:active { transform: translateY(-50%) scale(.96); }

/* 课表管理弹窗：官方页面跳转 → 主文本色（不使用蓝色） */
#scheduleManageModal .official-links-card { border-color: var(--text); }
#scheduleManageModal .official-links-title { color: var(--text); }
#scheduleManageModal .official-link-button {
  color: var(--text);
  border-color: var(--text);
  background: transparent;
}

/* 通知/图层：圆钮 45x45 与定位按钮一致；文字独立于圆钮下方 */
.map-top-action {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.map-top-action-btn {
  width: 45px;
  height: 45px;
  padding: 0;
  gap: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  line-height: 1;
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  color: var(--text);
  backdrop-filter: blur(var(--hgu-blur-md));
  -webkit-backdrop-filter: blur(var(--hgu-blur-md));
  box-shadow: var(--hgu-shadow-card);
  cursor: pointer;
}
.map-top-action-btn:active { transform: scale(.9); }
.map-top-action-label {
  font-size: 10px;
  line-height: 1.2;
  color: var(--text);
  pointer-events: none;
}
.map-top-action-btn i { font-size: 18px; }

/* 通知 / 图层合并成一个圆角矩形：按钮自身不再画卡片（上面几处历史样式只保留
   尺寸与排版），玻璃、边框、圆角、阴影统一由 .map-top-actions 出 */
.map-top-actions .map-top-action-btn {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* 两个按钮之间一条分割线（通知在上、图层在下） */
.map-top-actions .map-top-action-btn + .map-top-action-btn {
  border-top: 1px solid var(--hgu-border-soft);
}

/* 重要通知整块变红时，上面两个角跟着容器圆角，免得顶出圆角外；
   颜色要在上面那条「按钮不再画卡片」之后重申一次，否则会被它清掉 */
.map-top-actions .map-top-action-btn.notice-important {
  background: #e53935;
  color: #fff;
  border-radius: var(--hgu-radius-2xl) var(--hgu-radius-2xl) 0 0;
}

/* 图层抽屉：分组容器 + 外观胶囊选择器 */
.layer-group {
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-2xl);
  padding: 14px;
}
.layer-group-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 12px;
}
/* 原「地图显示」标题下的街景性能提示（.layer-group-hint）已随提示一起移除 */
.layer-theme-pill {
  display: flex;
  width: 100%;
  border: 1px solid var(--text);
  border-radius: var(--hgu-radius-pill);
  overflow: hidden;
}
.layer-theme-pill button {
  flex: 1;
  min-height: 40px;
  border: 0;
  background: transparent;
  color: var(--subtext);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  padding: 0 6px;
  transition: background .2s ease, color .2s ease;
}
.layer-theme-pill button.active {
  background: var(--text);
  color: #fff;
}
/* 暗色模式：通知卡片适配 */
html[data-theme="dark"] .notice-item {
  background: rgba(255,255,255,0.07);
  border-color: rgba(255,255,255,0.14);
  box-shadow: none;
}
html[data-theme="dark"] .notices-empty {
  color: rgba(255,255,255,0.5);
}

/* ================== 网页登录二级抽屉（edu-login，仅APP内使用） ================== */
.edu-login-overlay { z-index: 10060; }

.edu-login-overlay .edu-login-drawer {
  max-height: 88vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.edu-login-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 16px 2px;
  flex: 0 0 auto;
}

.edu-login-title { color: var(--text); font-size: 17px; font-weight: 700; }

.edu-login-overlay .modal-close {
  width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; border-radius: 50%;
  background: var(--hgu-border-soft);
  color: var(--subtext);
  font-size: 20px; line-height: 1;
  cursor: pointer; padding: 0;
}

.edu-login-body {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 2px 18px calc(20px + env(safe-area-inset-bottom, 0px));
  flex: 1 1 auto;
}

.edu-login-modes {
  display: flex;
  flex-wrap: nowrap;
  align-items: stretch;
  gap: 10px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  padding-bottom: 6px;
  scrollbar-width: none;
}
.edu-login-modes::-webkit-scrollbar { display: none; }

.edu-login-mode {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  flex: 0 0 auto;
  min-width: 96px;
  max-width: 46%;
  padding: 12px 14px; border-radius: 14px;
  border: 1px solid var(--hgu-border-soft);
  background: transparent;
  color: var(--subtext);
  font-size: 15px; font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  scroll-snap-align: start;
  -webkit-tap-highlight-color: transparent;
  text-align: center;
  transition: border-color .2s ease, background .2s ease, color .2s ease;
}

.edu-login-mode.active {
  border-color: var(--text);
  color: var(--text);
  background: var(--text-light);
  box-shadow: inset 0 0 0 1px var(--text);
}

.edu-login-mode-disabled { opacity: .5; }

.edu-login-badge {
  font-size: 10px; font-weight: 600;
  color: var(--subtext);
  background: var(--hgu-border-soft);
  border-radius: 9px;
  padding: 2px 6px;
  white-space: nowrap;
}

.edu-login-hint {
  margin: 8px 2px 14px;
  font-size: 12px;
  color: var(--subtext);
  opacity: .72;
  min-height: 15px;
  line-height: 1.5;
}

.edu-login-field { display: block; margin-bottom: 12px; }
.edu-login-field span { display: block; margin-bottom: 6px; font-size: 13px; color: var(--subtext); opacity: .9; }
.edu-login-field input {
  width: 100%; box-sizing: border-box;
  padding: 12px 14px;
  font-size: 16px;
  border-radius: 13px;
  border: 1px solid var(--hgu-border-soft);
  background: var(--bg);
  color: var(--subtext);
  outline: none;
  -webkit-appearance: none;
  transition: border-color .2s ease;
}
.edu-login-field input:focus { border-color: var(--text); }

.edu-login-primary {
  width: 100%; margin-top: 4px;
  padding: 13px;
  border: none; border-radius: 14px;
  background: var(--text);
  color: #fff;
  font-size: 16px; font-weight: 700;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .2s ease;
}
.edu-login-primary:disabled { opacity: .5; cursor: default; }

.edu-login-sms { margin-top: 2px; }
.edu-login-sms-tip { margin: 0 0 12px; font-size: 13px; color: var(--subtext); line-height: 1.6; }

.edu-login-sms-send {
  width: 100%; margin: 0 0 12px;
  padding: 11px;
  border-radius: 13px;
  border: 1px solid var(--text);
  background: transparent;
  color: var(--text);
  font-size: 14px; font-weight: 600;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.edu-login-sms-send:disabled { opacity: .5; cursor: default; }

.edu-login-status {
  margin: 12px 2px 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text);
}
.edu-login-status.is-error { color: #e05c5c; }

/* 华信模式图形验证码行
   注意：原来这里的选择器是 .edu-login-captcha-input，但输入框上从来没有这个 class
   （只有 id），所以这套样式实际上一直没生效。现已给输入框补上 class 并重做样式。 */
.edu-login-captcha {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
}

.edu-login-captcha-img {
  width: 112px;
  height: 44px;
  object-fit: cover;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-sm);
  background: rgba(0, 0, 0, 0.04);
  flex: 0 0 auto;
  cursor: pointer;              /* 点击图片 = 换一张 */
}

.edu-login-captcha-input {
  flex: 1 1 auto;
  min-width: 0;
  height: 44px;                 /* 与验证码图片等高，三者视觉对齐 */
  padding: 0 12px;
  font-size: 16px;              /* ≥16px，避免 iOS 聚焦时自动放大 */
  letter-spacing: 2px;          /* 验证码字符较易辨认 */
  text-align: center;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-sm);
  background: rgba(255, 255, 255, 0.55);   /* 与社区账号输入框保持同一套取色逻辑 */
  color: var(--text);
  outline: none;
  box-sizing: border-box;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color var(--motion-fast, 160ms) ease, background 0.3s ease;
}

.edu-login-captcha-input::placeholder {
  color: var(--subtext);
  opacity: .55;
  letter-spacing: 0;            /* placeholder 不跟着拉开字距 */
  font-family: inherit;
}

.edu-login-captcha-input:focus {
  border-color: var(--text);
  background: rgba(255, 255, 255, 0.72);
}

.edu-login-captcha-refresh {
  flex: 0 0 auto;
  height: 44px;                 /* 与图片、输入框齐平 */
  padding: 0 12px;
  font-size: 13px;
  font-family: inherit;
  color: var(--text);
  background: transparent;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-sm);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color var(--motion-fast, 160ms) ease;
}

.edu-login-captcha-refresh:hover {
  border-color: var(--text);
}

html[data-theme="dark"] .edu-login-captcha-input {
  background: rgba(255, 255, 255, 0.08);
  color: var(--subtext);
}

html[data-theme="dark"] .edu-login-captcha-input::placeholder {
  color: rgba(255, 255, 255, 0.4);
}

html[data-theme="dark"] .edu-login-captcha-input:focus {
  background: rgba(255, 255, 255, 0.13);
  border-color: var(--text);
}

html[data-theme="dark"] .edu-login-captcha-img {
  background: rgba(255, 255, 255, 0.06);
}

/* 窄屏：验证码行改为两行，避免三个控件被挤扁 */
@media (max-width: 380px) {
  .edu-login-captcha {
    flex-wrap: wrap;
  }
  .edu-login-captcha-img {
    width: 100px;
  }
  .edu-login-captcha-input {
    flex: 1 1 100px;
  }
}

html[data-theme="dark"] .edu-login-primary { color: #15202b; }
html[data-theme="dark"] .edu-login-mode.active { background: var(--text-light); }

/* 华信双系统登录：分区标题与只读CAS学号 */
.edu-login-split-title {
  margin: 14px 2px 10px;
  padding-left: 10px;
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  border-left: 3px solid var(--text);
  line-height: 1.4;
}
.edu-login-form .edu-login-split-title:first-child { margin-top: 0; }
.edu-login-cas-block {
  margin-top: 2px;
  padding-top: 4px;
  border-top: 1px dashed var(--hgu-border-soft);
}
.edu-login-cas-block .edu-login-field input[readonly] {
  background: var(--hgu-border-soft);
  color: var(--subtext);
  opacity: .85;
  cursor: not-allowed;
  -webkit-user-select: none;
  user-select: none;
}

/* 华信模式：登录账号状态列表（智慧地大 / 华信教务） */
.edu-login-accounts { margin-top: 4px; }

.edu-account-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  margin-bottom: 8px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-default);
  background: rgba(255, 255, 255, 0.4);
}

.edu-account-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.edu-account-name { font-size: 13px; font-weight: 600; color: var(--text); }
.edu-account-id { font-size: 12px; color: var(--subtext); word-break: break-all; }

.edu-account-state {
  flex: 0 0 auto;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  background: var(--hgu-border-soft);
  color: var(--subtext);
}
.edu-account-state.is-ok { background: var(--text-light); color: var(--text); }
.edu-account-state.is-expired { background: rgba(224, 92, 92, .15); color: #e05c5c; }

.edu-account-expired {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 12px;
  margin-bottom: 8px;
  border-radius: var(--hgu-radius-default);
  background: rgba(224, 92, 92, .1);
  color: #e05c5c;
  font-size: 12.5px;
  line-height: 1.5;
}

.edu-account-relogin {
  align-self: stretch;
  padding: 9px 12px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
  color: #fff;
  background: #e05c5c;
  border: none;
  border-radius: var(--hgu-radius-default);
  cursor: pointer;
}

html[data-theme="dark"] .edu-account-row { background: rgba(255, 255, 255, 0.06); }
html[data-theme="dark"] .edu-account-relogin { color: #1d1a1a; }

/* ================== 几何社区（社区账号，js/community.js） ==================
 * 品牌色走「组件级 token」惯例（同 --training-green / --club-purple），不新增 :root 全局变量。
 * 全部取色基于语义 token，因此深色模式自动生效；仅少数硬编码色另补 html[data-theme="dark"]。
 * z-index：登录/资料抽屉 10058 —— 低于 .edu-login-overlay(10060)，
 *          使「教务登录」在两者同时存在时位于最上层。
 * ======================================================================= */

/* ---------- 1. 选项页账号卡（双页：智慧地大 / 几何社区） ---------- */

/* 旧的独立「学号账号」卡片并入本卡片组后不再单独显示。
   仍留在 DOM 中：navigation.js 的 initAccountInfoCard / updateAccountInfoDisplay
   会按 id 改写它，且「智慧地大」页读取的正是它写入的 localStorage。
   !important 用于压过 .account-info-card 自身与 #legacyNotificationSettings 之外的
   任何 display 规则（含 @media 内的）。 */
.account-info-card.legacy-account-hidden {
  display: none !important;
}

/* 账号卡下方的「进入后台管理」：整行可点，左侧文字 + 右侧箭头。
   只有社区账号已绑定后台账号时才显示（js/community.js 的 refreshAdminEntry）。 */
.community-admin-entry {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid rgba(120, 130, 160, .28);
  color: var(--text);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .2s ease;
}

/* ⛔ [hidden] 是 UA 规则，上面那条 display:flex 会把它盖掉 → 必须显式兜底 */
.community-admin-entry[hidden] {
  display: none !important;
}

.community-admin-entry:active { opacity: .6; }

.community-admin-entry-main {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.community-admin-entry-arrow {
  font-size: 13px;
  color: var(--subtext);
}

html[data-theme="dark"] .community-admin-entry {
  border-top-color: rgba(255, 255, 255, .16);
}

.community-account-card {
  --community-accent: var(--text);
  --community-accent-soft: var(--text-light);
  --community-accent-border: var(--text);
  width: 100%;
  /* 【修复】这里原本是 max-width: 400px（当年为了对齐旧账号卡），
     但同页其它卡片（检测更新 / 其他设置 / 关于…）都是 width:100%，
     容器 .options-page-content 的 max-width 才是 480px ——
     于是在 400~480px 的宽屏手机上，只有这张登录信息卡两边各缺 40px。
     宽度交给容器统一约束，卡片自己不再设上限。 */
  max-width: none;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--community-accent-border);
  border-radius: var(--hgu-radius-2xl);
  padding: 12px 14px 14px;
  box-shadow: var(--hgu-shadow-card);
  transition: background 0.3s ease, border-color 0.3s ease;
}

.community-account-tabs {
  display: flex;
  gap: 6px;
  padding: 3px;  background: var(--hgu-border-soft);
  border-radius: var(--hgu-radius-polished);
  margin-bottom: 12px;
}

.community-account-tab {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 6px;
  border: 1px solid transparent;
  border-radius: var(--hgu-radius-default);
  background: transparent;
  color: var(--subtext);
  font-size: 13px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: all var(--motion-fast, 160ms) ease;
  -webkit-tap-highlight-color: transparent;
}

.community-account-tab i {
  font-size: 13px;
  opacity: 0.85;
}

.community-account-tab:hover {
  color: var(--text);
}

.community-account-tab.active {
  border-color: var(--community-accent);
  background: var(--community-accent-soft);
  color: var(--text);
  box-shadow: inset 0 0 0 1px var(--community-accent);
}

.community-account-tab.active i {
  opacity: 1;
}

.community-account-pane {
  display: block;
}

.community-account-pane + .community-account-pane {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--hgu-border-soft);
}

.community-pane-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.community-pane-left {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  min-width: 0;
}

.community-pane-icon,
.community-pane-avatar {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: var(--hgu-radius-round);
  background: var(--text-light);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  position: relative;
}

.community-pane-icon i {
  font-size: 20px;
  color: var(--text);
}

.community-pane-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* 注意：仓库里既有的 .avatar-fallback 其实没有任何 CSS（只靠内联样式生效），
   这里定义自有类，避免依赖那个陷阱。 */
.community-avatar-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--text-light);
  color: var(--text);
  font-size: 18px;
}

.community-pane-text {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.community-pane-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.community-pane-sub {
  font-size: 12px;
  color: var(--subtext);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.community-pane-sub.logged-in {
  color: #4CAF50;
}

/* 华信教务会话过期提示（智慧地大卡片内第二行副标题） */
.community-pane-sub.is-expired {
  color: #e05c5c;
  white-space: normal;
  line-height: 1.4;
}

.community-pane-meta {
  margin-top: 10px;
  font-size: 12px;
  color: var(--subtext);
  line-height: 1.5;
  word-break: break-all;
}

.community-pane-footnote {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--hgu-border-soft);
  font-size: 11.5px;
  color: var(--subtext);
  line-height: 1.6;
}

.community-level-icon {
  width: 25px;
  height: 25px;
  flex: 0 0 25px;
  display: inline-block;
  object-fit: contain;
  vertical-align: middle;
}

.community-experience-card {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px dashed color-mix(in srgb, var(--community-exp-color) 35%, transparent);
}

.community-experience-progress {
  display: flex;
  align-items: center;
  gap: 7px;
}

.community-experience-level {
  width: 24px;
  height: 24px;
  flex-basis: 24px;
}

.community-experience-next {
  opacity: .62;
}

.community-experience-next.is-max {
  opacity: 1;
}

.community-experience-track {
  height: 8px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  border-radius: 999px;
  background: color-mix(in srgb, var(--community-exp-color) 16%, transparent);
}

.community-experience-track span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--community-exp-color);
  transition: width .45s var(--ease-standard, ease);
}

.community-experience-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}

.community-experience-tag {
  display: inline-flex;
  align-items: center;
  min-height: 23px;
  padding: 2px 7px;
  border: 1px solid color-mix(in srgb, var(--community-exp-color) 35%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--community-exp-color) 10%, transparent);
  color: var(--community-exp-color);
  font: inherit;
  font-size: 11px;
  line-height: 1.2;
  white-space: nowrap;
}

.community-experience-open {
  color: var(--text);
  cursor: pointer;
}

.community-experience-open:active {
  transform: scale(.97);
}

.community-experience-drawer {
  padding-bottom: max(20px, env(safe-area-inset-bottom));
}

.community-experience-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
  font-size: 17px;
}

.community-experience-drawer-head .modal-close {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: 50%;
  background: transparent;
  color: var(--subtext);
  font-size: 20px;
  line-height: 1;
}

.community-experience-drawer-level {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 12px;
  color: var(--subtext);
  font-size: 13px;
}

.community-experience-drawer-icon {
  width: 34px;
  height: 34px;
  flex-basis: 34px;
}

.community-experience-source-list {
  border-top: 1px solid var(--hgu-border-soft);
}

.community-experience-source {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 0;
  border-bottom: 1px solid var(--hgu-border-soft);
}

.community-experience-source div {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.community-experience-source b {
  color: var(--text);
  font-size: 14px;
}

.community-experience-source small {
  color: var(--subtext);
  font-size: 11.5px;
}

.community-experience-source strong {
  flex: 0 0 auto;
  color: var(--community-exp-color, var(--text));
  font-size: 15px;
}

.community-experience-drawer-note {
  margin: 12px 0 0;
  color: var(--subtext);
  font-size: 11.5px;
  line-height: 1.6;
}

/* 社区身份图标：不再使用 QQ 品牌图形（QQ 仅作为登录方式出现在登录按钮上）。
   这个类现在只负责「未登录」占位符的观感，颜色随主题 token 走。 */
.community-community-icon i {
  color: var(--text);
}

.community-login-footnote.is-app-only {
  display: flex;
  gap: 8px;
  align-items: flex-start;
}

.community-login-footnote.is-app-only i {
  margin-top: 2px;
  flex-shrink: 0;
  opacity: .85;
}

.community-login-hint {
  margin: 0;
}

/* 「智慧地大」在浏览器环境下的只读说明标签（不可点击） */
.community-readonly-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 14px;
  flex-shrink: 0;
  border: 1px dashed var(--hgu-border-soft);
  border-radius: var(--hgu-radius-default);
  font-size: 13px;
  color: var(--subtext);
  white-space: nowrap;
  cursor: default;
}

/* ---------- 2. 抽屉通用（登录 / 资料） ---------- */
.community-login-overlay,
.community-profile-overlay {
  z-index: 10058;
}

.community-login-overlay .community-login-drawer,
.community-profile-overlay .community-profile-drawer {
  max-height: 88vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.community-login-header,
.community-profile-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 2px 2px 12px;
  border-bottom: 1px solid var(--hgu-border-soft);
}

.community-login-title,
.community-profile-title {
  font-size: 17px;
  font-weight: 700;
  color: var(--text);
}

.community-login-overlay .modal-close,
.community-profile-overlay .modal-close {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-round);
  background: transparent;
  color: var(--subtext);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}

.community-login-overlay .modal-close:hover,
.community-profile-overlay .modal-close:hover {
  color: var(--text);
  border-color: var(--text);
}

.community-login-body,
.community-profile-body {
  padding: 14px 2px calc(18px + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.community-login-hint,
.community-login-footnote,
.community-login-agreement,
.community-profile-hint {
  font-size: 12px;
  color: var(--subtext);
  line-height: 1.6;
  margin: 0;
}

.community-login-footnote {
  padding: 9px 11px;
  border-radius: var(--hgu-radius-default);
  background: var(--text-light);
  color: var(--text);
}

.community-login-agreement a {
  color: var(--text);
  text-underline-offset: 2px;
}

/* ---------- 3. 表单 ---------- */
.community-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.community-field.hidden {
  display: none;
}

.community-field label {
  font-size: 12.5px;
  color: var(--subtext);
}

/* .modal-body / .modal-footer 在本仓库无统一样式；且 app.css 对 input 只有一条
   全局 border-radius 规则 —— 因此此处显式写全所有声明，不依赖继承。
   背景刻意用「半透明 + 叠加在抽屉玻璃层之上」，而不是 --hgu-surface-solid：
   后者是写死的 rgba(255,255,255,.88)，深色模式下不随主题变化，会让输入框过亮。
   深色模式另有专门覆盖（见文件末尾 html[data-theme="dark"] 段）。 */
.community-field input {
  width: 100%;
  box-sizing: border-box;
  padding: 12px 13px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-default);
  background: rgba(255, 255, 255, 0.55);
  color: var(--text);
  font-size: 16px;              /* ≥16px 可避免 iOS Safari 聚焦时自动放大 */
  font-family: inherit;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color var(--motion-fast, 160ms) ease, background 0.3s ease;
}

.community-field input::placeholder {
  color: var(--subtext);
  opacity: .55;
}

.community-field input:focus {
  border-color: var(--text);
  background: rgba(255, 255, 255, 0.72);
}

.community-field input:disabled {
  background: rgba(255, 255, 255, 0.3);
  color: var(--subtext);
  opacity: .85;
}

.community-code-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}

.community-code-row input {
  flex: 1;
  min-width: 0;
  letter-spacing: 3px;
}

.community-resend-btn {
  flex-shrink: 0;
  padding: 0 14px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-default);
  background: transparent;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  transition: all var(--motion-fast, 160ms) ease;
  white-space: nowrap;
}

.community-resend-btn:hover:not(:disabled) {
  border-color: var(--text);
}

.community-resend-btn:disabled {
  color: var(--subtext);
  opacity: .6;
  cursor: not-allowed;
}

/* ---------- 4. 按钮 ---------- */
.community-primary-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 13px 16px;
  border: none;
  border-radius: var(--hgu-radius-default);
  background: var(--text);
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: opacity var(--motion-fast, 160ms) ease, transform var(--motion-fast, 160ms) ease;
}

.community-primary-btn:hover:not(:disabled) {
  opacity: .9;
}

.community-primary-btn:active:not(:disabled) {
  transform: scale(.985);
}

.community-primary-btn:disabled {
  opacity: .55;
  cursor: not-allowed;
}

.community-primary-btn.is-busy {
  cursor: progress;
}

.community-ghost-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  padding: 12px 16px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-default);
  background: transparent;
  color: var(--text);
  font-size: 14px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: all var(--motion-fast, 160ms) ease;
}

.community-ghost-btn:hover {
  border-color: var(--text);
}

/* .modal-btn.danger 只在 #scheduleManageModal 作用域内被定义，
   所以这里自行声明危险色，不复用那个类。 */
.community-ghost-btn.danger {
  color: #ff4757;
  border-color: rgba(255, 71, 87, .35);
}

.community-ghost-btn.danger:hover {
  color: #fff;
  background: #ff4757;
  border-color: #ff4757;
}

/* 「智慧地大」页在浏览器环境下尺寸略小的引导按钮 */
.community-account-card .community-ghost-btn {
  width: auto;
  padding: 9px 14px;
  font-size: 13px;
  flex-shrink: 0;
}

/* ---------- 5. 状态行 ---------- */
.community-login-status {
  min-height: 17px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--subtext);
  word-break: break-all;
}

.community-login-status.is-error {
  color: #ff4757;
}

.community-login-status.is-success {
  color: #4CAF50;
}

/* ---------- 6. 智慧地大绑定状态行（资料抽屉内） ---------- */
.community-profile-binding {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-default);
  font-size: 13px;
  line-height: 1.5;
}

.community-binding-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--subtext);
  flex-shrink: 0;
}

.community-binding-label i {
  opacity: .85;
}

.community-binding-value {
  color: var(--text);
  font-weight: 500;
  word-break: break-all;
  text-align: right;
}

.community-binding-value.muted {
  color: var(--subtext);
  font-weight: 400;
}

/* ---------- 7. 资料抽屉 ---------- */
.community-profile-hero {
  display: flex;
  align-items: center;
  gap: 14px;
  padding-bottom: 4px;
}

.community-profile-hero .community-avatar {
  width: 64px;
  height: 64px;
  flex-shrink: 0;
  position: relative;
  border-radius: var(--hgu-radius-round);
  background: var(--text-light);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.community-profile-hero .community-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.community-profile-hero-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.community-profile-name {
  font-size: 17px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.3;
  word-break: break-all;
}

.community-profile-meta {
  font-size: 12px;
  color: var(--subtext);
  line-height: 1.4;
  word-break: break-all;
}

.community-profile-divider {
  height: 1px;
  margin: 4px 0;
  background: var(--hgu-border-soft);
}

/* ---------- 8. 深色模式 ----------
   输入框背景是硬编码的半透明白（见 .community-field input 注释），
   必须在此显式覆盖，否则深色模式下会是一块刺眼的白。 */
html[data-theme="dark"] .community-field input {
  background: rgba(255, 255, 255, 0.08);
  color: var(--subtext);
}

html[data-theme="dark"] .community-field input::placeholder {
  color: rgba(255, 255, 255, 0.4);
}

html[data-theme="dark"] .community-field input:focus {
  background: rgba(255, 255, 255, 0.13);
  border-color: var(--text);
}

html[data-theme="dark"] .community-field input:disabled {
  background: rgba(255, 255, 255, 0.05);
  color: rgba(255, 255, 255, 0.45);
}

/* 验证码「重新发送」按钮在深色下同样需要更清晰的分隔 */
html[data-theme="dark"] .community-resend-btn {
  border-color: rgba(255, 255, 255, 0.2);
}

/* 主按钮在深色下用亮绿底 + 深色字，避免绿底白字在暗色背景上发灰 */
html[data-theme="dark"] .community-primary-btn {
  color: #16241c;
}

/* 危险按钮的描边在深色下提高一点可见度 */
html[data-theme="dark"] .community-ghost-btn.danger {
  border-color: rgba(255, 71, 87, .5);
}

/* ---------- 9. 窄屏 ---------- */
@media (max-width: 380px) {
  .community-account-card {
    padding: 10px 11px 12px;
  }
  .community-account-tab {
    padding: 7px 4px;
    font-size: 12.5px;
  }
  .community-pane-title {
    font-size: 14px;
  }
  .community-pane-icon,
  .community-pane-avatar {
    width: 40px;
    height: 40px;
  }
  .community-profile-hero .community-avatar {
    width: 56px;
    height: 56px;
  }
}

/* hover 抬升类效果统一在指针设备上生效 */
@media (hover: hover) and (pointer: fine) {
  .community-account-card:hover {
    box-shadow: var(--hgu-shadow-raised, var(--hgu-shadow-card));
  }
}

@media (prefers-reduced-motion: reduce) {
  .community-account-tab,
  .community-primary-btn,
  .community-ghost-btn,
  .community-resend-btn,
  .community-account-card {
    transition: none;
  }
}

/* ============================================================
   横屏分栏布局：左侧抽屉 / 悬浮栏 / 弹窗 / 服务卡片，右侧地图与地图控件
   ------------------------------------------------------------
   由 JS 判定后给 <html> 挂上 .hgu-split 才生效（判定见 core.js
   window.hguEvaluateSplitLayout）。判定不放 CSS 媒体查询，是因为媒体查询
   只能看视口尺寸：平板横屏时浏览器/APP 的顶栏底栏会吃掉 100~200px 高度，
   高 DPR 平板的 CSS 视口宽度还可能只有 640~900px，媒体查询会把这类平板
   误判成"手机横屏"而退回底部抽屉。JS 改用 window.screen 的短边识别设备
   本身是不是平板/桌面，不受顶栏底栏占位影响。
   --hgu-split-panel-w 是左侧面板宽度，所有"左/右半屏"定位统一复用它。
   ============================================================ */
:root {
  --hgu-split-panel-w: 0px;
}

/* 旋转屏幕 / 横竖屏切换 / 分栏模式翻转的瞬间由 JS 短暂挂上：
   两套布局基准之间过渡插值会看到面板横着滑过整个屏幕 */
html.hgu-layout-instant #tools-page,
html.hgu-layout-instant #tools-page .home-compact-layer,
html.hgu-layout-instant .bottom-nav,
html.hgu-layout-instant .secondary-drawer,
html.hgu-layout-instant .map-brand-watermark,
html.hgu-layout-instant #floorBar,
html.hgu-layout-instant #indoorLegend,
html.hgu-layout-instant .location-btn {
  transition: none !important;
}

html.hgu-split {
  --hgu-split-panel-w: min(50vw, 580px);
}

/* ---------- 抽屉 / 服务卡片：整块左半屏 ----------
   贴屏幕左边，保留顶部圆角、左侧描边改为 1px 透明；三态都只改高度。
   ★ 目标：让分栏复刻竖屏的玻璃合成配方 —— 竖屏（真机验证正常）= 面板
     「left 居中 + translateX(-50%)」+「四边 1px 描边」+ 无 isolation +
     两条玻璃带都在。分栏此前 mask 被丢，是这套条件缺了两半：
       · left: 0 静态定位（实验 #7 单测 transform，真机无效）
       · border-left: none（无头逐属性隔离确认的直接触发点）
     白天"补边框"那次真机采样退化，同配置还混着 isolation: isolate 与
     停用带① —— 两者均已单独证实会杀掉真机 backdrop-filter，退化的锅
     很可能该由它们背；干净的「1px 边框」从未在真机单独测过。本规则 =
     仅分栏生效的「竖屏配方对齐」，竖屏零影响。
   ⚠️ 若真机仍失败（mask 仍丢 / 采样仍退化）：整段回退成
     left: 0 / transform: none / border-left: none 即可，勿再叠加其它
     "分栏专用"玻璃改动（每条都翻过车，见 .tools-top-glass-layer 注记）。 */
html.hgu-split #tools-page {
  left: calc(var(--hgu-split-panel-w) / 2);
  right: auto;
  transform: translateX(-50%);
  width: var(--hgu-split-panel-w);
  border-left: 1px solid transparent;
  border-right: 1px solid var(--hgu-border-soft);
  box-shadow: 6px 0 28px rgba(0, 0, 0, 0.16);
}

/* ---------- 底部悬浮栏：落在左半屏正中 ---------- */
html.hgu-split .bottom-dock {
  left: 0;
  width: var(--hgu-split-panel-w);
  max-width: none;
  justify-content: center;
  transform: none;
}

html.hgu-split .bottom-dock > .bottom-nav {
  left: auto;
}

/* 抽屉关闭提示跟随悬浮栏落在左半屏正中（左面板宽度的中点） */
html.hgu-split .drawer-close-hint {
  left: calc(var(--hgu-split-panel-w) / 2);
  max-width: calc(var(--hgu-split-panel-w) - 24px);
}

/* ---------- 地图控件：全部留在右半屏 ---------- */
/* 水印（含天气）属于地图，跟随地图挪到右侧地图区，避免被左侧抽屉盖住 */
html.hgu-split .map-brand-watermark {
  left: calc(var(--hgu-split-panel-w) + 18px);
}

/* 楼层栏原本贴屏幕左边，分栏后贴到地图区左边缘 */
html.hgu-split #floorBar {
  left: calc(var(--hgu-split-panel-w) + 20px);
}

/* 图例 / 定位按钮的右侧位置不变，但地图区底部没有服务卡片，不再需要上移避让。
   底部悬浮带整体抬高后，这里的固定值跟着加同一个抬高量，保持分栏态的相对关系。 */
html.hgu-split body.home-panel-compact #floorBar {
  bottom: calc(130px + var(--hgu-bottom-band-lift));
}

html.hgu-split body.home-panel-compact #indoorLegend {
  bottom: var(--hgu-chrome-bottom-legend);
}

html.hgu-split body.home-panel-compact .location-btn,
html.hgu-split body.home-panel-compact .location-btn.is-raised {
  bottom: var(--hgu-chrome-bottom-location);
}

/* 抽屉展开时地图仍完整可见（只是左半屏盖了一层玻璃），通知/图层按钮保持可用 */
html.hgu-split body.home-panel-expanded .map-top-actions {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity .2s ease, visibility 0s 0s;
}

/* 课表周次切换悬浮按钮：不要改它的定位。
   它挂在 .tools-sub-page 里，而 .tools-sub-page 带 transform + will-change，
   会成为 position:fixed 的包含块 —— 它的 right:16px 本来就是相对"抽屉内容列"
   定位的，横屏分栏下面板就是那一列，所以默认规则已经正确。
   之前按"视口坐标"改成 left: calc(panel - 16px) + translateX(-100%)，反而把它
   顶到面板右边缘外面去了。 */

/* ---------- 弹窗 / 二级抽屉：只在左半屏内弹出 ----------
   注意排除全屏沉浸式视图（街景 #panoBox、引导页 #onboardingOverlay、
   图片查看 .cal-zoom-overlay / .ew-image-overlay / .ew-iv、课表分享页） */
html.hgu-split .secondary-drawer-overlay,
html.hgu-split .modal-overlay,
html.hgu-split .score-eval-warning-overlay {
  left: 0;
  right: auto;
  width: var(--hgu-split-panel-w);
}

/* 二级抽屉跟随面板宽度，不再固定 580px（面板可能只有 320px） */
html.hgu-split .secondary-drawer {
  width: 100%;
  max-width: 100%;
}
/* 「今天吃什么」窗口详情页的「写评价」悬浮按钮：它挂在 body 上（要压过抽屉，
   见 .window-rate-fab 的层级说明），right: 16px 在分栏下会落到**右侧地图区**。
   分栏时把它挪回左侧抽屉面板内（贴面板右缘 16px）。

   ⚠️ 面板宽度用 min(50vw, 580px) 现算，而不是 var(--hgu-split-panel-w)：
      —— 实测无头环境里那个变量常读成空值，calc(0px - 16px) 是负的，
      按钮会被推到屏幕外。min() 与 app.css 里 --hgu-split-panel-w 的定义一致，
      这里独立算一遍，不依赖变量是否已注入。 */
html.hgu-split .window-rate-fab {
  right: auto;
  left: calc(min(50vw, 580px) - 16px);
  transform: translateX(-100%);
}

html.hgu-split .window-rate-fab:active {
  transform: translateX(-100%) scale(0.96);
}

/* ============================================================
   假期食堂营业安排
   ------------------------------------------------------------
   ① 首页顶部入口卡片（颜色跟随生活页的橙色主题，与「今天吃什么」卡片同一套）
   ② 子页面：行 = 窗口，列 = 日期；左侧窗口名列 sticky 固定，右侧横向滑动
   ============================================================ */

/* ---------- ① 首页入口卡片 ---------- */
.life-holiday-slot {
  grid-column: 1 / -1;
}

/* 后台开关关闭时保持 hidden：不占位、不留白 */
.life-holiday-slot[hidden] {
  display: none;
}

.life-holiday-card {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px;
  border: 1.5px solid var(--life-orange-border);
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  /* 同样不自带 backdrop-filter（它也在首页生活栅格里，坐在抽屉面板之上）：
     原因见 .study-feature-panel 上方那段说明。 */
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: transform var(--motion-fast) var(--ease-standard),
              background-color var(--motion-base) ease;
}

.life-holiday-card:active {
  transform: scale(0.98);
  background: var(--life-orange-soft);
}

.life-holiday-icon {
  width: 26px;
  height: 26px;
  flex: 0 0 26px;
  object-fit: contain;
}

.life-holiday-title {
  flex: 1;
  min-width: 0;
  color: var(--life-orange);
  font-size: 15px;
  font-weight: 800;
}

.life-holiday-arrow {
  flex: 0 0 auto;
  font-size: 14px;
  color: var(--life-orange);
  opacity: 0.85;
}

/* ---------- ② 子页面 ---------- */
.ch-page-content {
  padding: 0 2px 6px;
}

/* 页头（标题 + 返回按钮）跟随本功能的橙黄主题，与表格配色一致 */
#canteen-holiday-page .sub-page-title,
#canteen-holiday-page .sub-page-back,
#canteen-holiday-page .sub-page-back i {
  color: var(--ew-theme-strong);
}

.ch-loading,
.ch-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 46px 20px;
  color: var(--ew-theme-strong);
  font-size: 13px;
  opacity: 0.75;
}

.ch-empty-state i {
  font-size: 22px;
  opacity: 0.8;
}

/* 横向滚动容器：左侧窗口名列 sticky 固定，滑动时不会滑出屏幕 */
.ch-table-wrap {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--ew-theme-border);
  border-radius: var(--hgu-radius-xl);
  background: var(--hgu-surface-glass);
  backdrop-filter: blur(var(--hgu-blur-xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-xl));
}

.ch-table {
  border-collapse: separate;
  border-spacing: 0;
  width: max-content;
  min-width: 100%;
  font-size: 12.5px;
  color: var(--ew-theme-strong);
}

.ch-table th,
.ch-table td {
  padding: 8px 10px;
  text-align: center;
  white-space: nowrap;
  border-bottom: 1px solid rgba(246, 168, 33, 0.16);
  border-right: 1px solid rgba(246, 168, 33, 0.12);
}

html[data-theme="dark"] .ch-table th,
html[data-theme="dark"] .ch-table td {
  border-bottom-color: rgba(255, 200, 87, 0.16);
  border-right-color: rgba(255, 200, 87, 0.12);
}

.ch-table th:last-child,
.ch-table td:last-child {
  border-right: 0;
}

.ch-table tbody tr:last-child td {
  border-bottom: 0;
}

/* 表头行 + 窗口名列：与其余单元格同样是"玻璃"底，不再是实心色块。
   【为什么要 blur】这一列是 sticky 的，滑动时下方单元格会从它下面穿过去；
   纯透明会把穿过去的内容透出来，所以用与整张表相同的 --hgu-surface-glass
   叠加 backdrop blur：观感与其余行列一致，同时把滑过的内容糊掉。
   颜色跟随 --glass，因此浅色/暗色两套主题都自动正确。 */
.ch-table thead th,
.ch-table .ch-col-name {
  position: sticky;
  background: var(--hgu-surface-glass);
  backdrop-filter: blur(14px) saturate(1.05);
  -webkit-backdrop-filter: blur(14px) saturate(1.05);
}

.ch-table thead th {
  top: 0;
  z-index: 1;
  color: var(--ew-theme);
  font-weight: 800;
}

/* 窗口名列：横向滚动时钉在左侧；列宽固定 + 允许换行，过长的窗口名分多行显示 */
.ch-table .ch-col-name {
  left: 0;
  z-index: 2;
  width: 132px;
  min-width: 132px;
  max-width: 132px;
  text-align: left;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
  line-height: 1.35;
  border-right: 1px solid var(--ew-theme-border);
}

/* 左上角交叉单元格：同时在两个方向上固定 */
.ch-table thead .ch-col-name {
  z-index: 3;
}

/* 窗口名：点击进入窗口详情 */
.ch-window-link {
  appearance: none;
  -webkit-appearance: none;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ew-theme-strong);
  font: inherit;
  font-weight: 700;
  text-align: left;
  white-space: normal;
  overflow-wrap: anywhere;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.ch-window-link:active {
  opacity: 0.6;
}

/* 状态标签：前台只出图标（文字在 title / aria-label 里），尽量省宽度 */
.ch-tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  font-size: 11px;
  line-height: 1;
}

.ch-tag.is-open {
  color: #16a34a;
  background: rgba(22, 163, 74, 0.12);
  border: 1px solid rgba(22, 163, 74, 0.3);
}

.ch-tag.is-closed {
  color: #dc2626;
  background: rgba(220, 38, 38, 0.1);
  border: 1px solid rgba(220, 38, 38, 0.26);
}

.ch-tag.is-none {
  color: var(--ew-theme-strong);
  background: rgba(128, 128, 128, 0.08);
  border: 1px solid rgba(128, 128, 128, 0.2);
  opacity: 0.55;
}

/* 标题栏最终层级：独立于所有滚动页面，玻璃层覆盖页面绘制结果，
   内容层在玻璃之上保持清晰。 */
.tools-content-container::before {
  display: none;
}

.tools-fixed-header-layer {
  position: absolute;
  inset: 0 0 auto;
  /* 与 .tools-top-glass-layer 同高 = 标题栏下沿（top 52 + 高 44），不往下压内容 */
  height: 96px;
  z-index: 50;
  pointer-events: none;
}

.tools-fixed-header-layer::before {
  display: none;
}

/* ================== 服务卡片（紧凑形态）不显示标题栏遮罩 ==================
 * 抽屉与"服务卡片"是同一个元素（#tools-page）：紧凑态高度只有卡片那么高，
 * 而顶部那条 96px 的标题栏玻璃（.tools-fixed-header-layer 里的
 * .tools-fixed-header-glass）压在卡片上半部分，看起来就是卡片上多出来的
 * 一层模糊遮罩 —— 这一态里没有标题栏，不该有它。
 *
 * 用 opacity 过渡而不是 display: none：收起抽屉时 data-home-state 会在
 * 高度动画刚开始（冻结起始高度那一帧）就变成 compact，硬切会让玻璃"啪"地
 * 消失；淡出则跟着高度一起收掉。展开时状态在拖拽起点就回到 expanded，
 * 玻璃随即淡入，与内容淡入同步。
 * 该层是 pointer-events: none，opacity: 0 不会影响任何点击。
 * （.tools-top-glass-layer 已经全局停用，这里不再列它。） */
.tools-fixed-header-layer {
  transition: opacity .3s ease;
}

#tools-page[data-home-state="compact"] .tools-fixed-header-layer {
  opacity: 0;
  /* ★ opacity: 0 只是"看不见"，层与它的子元素**照样吃点击**。
     而 base 规则给整层设了 pointer-events: none，子元素（.is-fixed-header 是
     pointer-events: auto 的标题栏行）会把它"重新打开" —— 于是卡片态下
     卡片上半部分（标题栏那一带，实测 y 557~653）全被这层隐形的标题栏挡住，
     卡片自己的按钮点不动（用户反馈过"卡片上半部分无法点击、像是标题栏遮挡"）。
     这里必须把子元素的点击也一并关掉。 */
  pointer-events: none;
}

/* 卡片态下标题栏行本身也不接受点击（哪怕将来又给它加了 pointer-events: auto） */
#tools-page[data-home-state="compact"] .tools-fixed-header-layer > * {
  pointer-events: none !important;
}

/* 标题栏那一带的玻璃段与 .tools-top-glass-pane 共用同一套分段规则
   （见上面 .tools-top-glass-layer 那段：基础定位 + .is-band-N 的半径与遮罩）。
   抽屉顶部两条带子（① .tools-top-glass-layer 与这条②）规则完全相同，
   竖屏上重合出图；2026-10-04 曾停用①结果竖屏真机玻璃全灭，已恢复两条都在。 */

.tools-fixed-header-layer > .is-fixed-header {
  display: none;
  position: absolute !important;
  top: 52px !important;
  left: 0;
  right: 0;
  width: auto !important;
  height: 44px;
  min-height: 44px;
  margin: 0 !important;
  padding: 10px 20px;
  box-sizing: border-box;
  transform: none !important;
  z-index: 1;
  pointer-events: auto;
  background: transparent !important;
  border: 0;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  -webkit-mask-image: none !important;
  mask-image: none !important;
}

.tools-fixed-header-layer > .is-fixed-header.active {
  display: flex;
}

.tools-fixed-header-layer > .is-fixed-header.schedule-header {
  padding: 0 !important;
}

.tools-fixed-header-layer > .is-fixed-header.schedule-header > .sub-page-header-row {
  min-height: 44px;
  padding: 10px 16px;
  box-sizing: border-box;
}

.tools-fixed-header-layer > .is-fixed-header > * {
  position: relative;
  z-index: 1;
}

.tools-fixed-header-layer > .is-fixed-header > .sub-page-header-row {
  width: 100%;
  min-height: 44px;
}

.tools-home-content {
  box-sizing: border-box;
  padding-top: 96px !important;
}

.tools-sub-page.active,
#tools-page > .tools-sub-page.active,
#schedule-page,
#classroom-schedule-page {
  box-sizing: border-box;
  padding-top: 96px !important;
}

/* 课表页 / 教室课表页：**不要**把 .schedule-page-content 的 margin-top 归零。
 *
 * 课表页的纵向定位是"页面 padding-top: 96px（让开标题栏）
 *              + 内容区 margin-top: -44px（把滚动视口上提到标题栏后面）"两步。
 * 第二步是这个页面能被毛玻璃采样的**唯一来源**：
 *   去掉它，.schedule-page-content 就从 y=96 开始 —— 那正是玻璃层的下边界，
 *   于是 0~96px 里**一点内容都没有**，玻璃无论怎么调都"透不出下面的内容"。
 *   保留它，滚动视口顶边落在 y=52，课表的行会从标题栏区域经过并被采样。
 *
 * 星期栏（.schedule-table thead th，sticky top:0）吸附在滚动容器的内边距边上，
 * 内边距为 0 时它落在 y=52 + 44 = 96px，正好在标题栏下沿之下，不会被压住。
 * 两者因此可以同时成立。 */
#schedule-page .schedule-page-content,
#classroom-schedule-page .schedule-page-content {
  padding-top: 0 !important;
}

/* —— 唯一的例外：**未导入课表**（空状态）时要把 -44px 撤掉 ——
 *
 * 上面那两步（padding-top 96 + margin-top -44）是给**周次表格**用的：
 * 表格要能从标题栏后面滚过去，玻璃才有东西可采样。
 * 空状态里根本没有表格，取而代之的是页面第一颗按钮「导入课程表…」，
 * 而它正好落在 y=52~107 —— 固定标题栏（玻璃层）覆盖 0~96，
 * 于是按钮只有底部 10px 露在外面，实测 elementFromPoint 命中的是
 * `.sub-page-header-row`，表现就是「按钮点不动」。
 *
 * 所以空状态单独把 margin-top 改成 +16：内容从 y=112 开始，整体落在玻璃层
 * 下沿（96）之下，并留出 16px 呼吸感（16 = 标题栏本体原有的 margin-top）。
 * 有课表时这个类会被摘掉，上面的三步推导原样生效，玻璃采样不受影响。
 * 类由 schedule-extra.js 的 syncScheduleEmptyClass() 同步（判据 = 那颗按钮可见）。 */
#schedule-page.is-schedule-empty .schedule-page-content {
  margin-top: 16px;
}

#schedule-page .schedule-slide,
#classroom-schedule-page .schedule-slide {
  /* 44px：课表页纵向定位的三步之一，缺一不可 ——
   *   ① 页面 padding-top: 96px        让开标题栏
   *   ② 内容区 margin-top: -44px      把滚动视口**上提到标题栏后面**
   *                                   （这一步是玻璃能采样的**唯一来源**）
   *   ③ 本处 padding-top: 44px        把吸附的星期栏推回到标题栏下沿
   *
   * 少了 ③：滑动容器顶边在 y=52，星期栏（thead th，sticky top:0）就吸在
   *          y=52 —— 正好被标题栏压住。
   * 少了 ②：容器顶边落到 y=96（= 玻璃层下边界），0~96px 里**没有任何内容**，
   *          玻璃采样不到东西，看起来就是"标题栏透不出下面的内容"。
   * 两者必须同时成立：容器顶边在 52（有内容可采样），星期栏在 96（不被压住）。
   *
   * 这样也**不会**在标题栏下面留空白横条：星期栏正好落在容器顶边以下 44px，
   * 而那 44px 就是标题栏本体所占的高度。 */
  padding-top: 44px !important;
}

#schedule-page .sub-page-header,
#classroom-schedule-page .sub-page-header,
#schedule-page .is-fixed-header,
#classroom-schedule-page .is-fixed-header,
#schedule-page .schedule-header.is-fixed-header,
#classroom-schedule-page .schedule-header.is-fixed-header {
  margin: 0 !important;
  padding: 0 !important;
}

html[data-theme="dark"] [data-header-for="schedule-page"],
html[data-theme="dark"] [data-header-for="classroom-schedule-page"] {
  border-bottom-color: rgba(255, 255, 255, 0.12);
}

/* ================== 教室课表页标题：占住中间并居中 ==================
 * 这一页的设计本来就是「返回键贴左（绝对定位）+ 标题居中」——
 * 见 #classroom-schedule-page .sub-page-back / .sub-page-title 那两条页面级规则。
 * 但标题栏被 initFixedPageHeaders() 搬进 .tools-fixed-header-layer 之后，
 * 页面级选择器不再命中，行里只剩 .sub-page-header-row.schedule-header-row 的
 * justify-content: space-between —— 返回键又是绝对定位（不占行内位置），
 * 于是标题成了行内唯一的元素、被按到最左边，正好压在返回键下面。
 * （返回键还是圆角毛玻璃底时它把标题盖住，看不出来；去掉底色后就正撞在
 *   首字上，也就是"标题居左、和返回键挤在一起"。）
 * 这里把标题放回中间：flex:1 让它占满行内剩余空间、文字居中；
 * 左右各留 44px（= 一个返回键的宽度）对称内边距，长标题也不会钻到箭头底下。 */
.tools-fixed-header-layer > [data-header-for="classroom-schedule-page"] .sub-page-header-row > .sub-page-title {
  flex: 1 1 auto;
  min-width: 0;
  text-align: center;
  padding: 0 44px;
  box-sizing: border-box;
}

/* 标题栏移出页面节点后，页面级主题变量不会再自动继承；在独立标题层
   上补回各功能页的主色，避免所有标题回落到全局绿色。 */
.tools-fixed-header-layer > [data-header-for="score-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="score-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="search-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="search-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="training-plan-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="training-plan-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="calendar-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="calendar-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="elective-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="elective-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="classroom-schedule-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="classroom-schedule-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="classroom-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="classroom-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="schedule-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="schedule-page"] .sub-page-back {
  color: var(--study-cyan);
}

.tools-fixed-header-layer > [data-header-for="score-page"],
.tools-fixed-header-layer > [data-header-for="search-page"],
.tools-fixed-header-layer > [data-header-for="training-plan-page"],
.tools-fixed-header-layer > [data-header-for="calendar-page"],
.tools-fixed-header-layer > [data-header-for="elective-page"],
.tools-fixed-header-layer > [data-header-for="classroom-schedule-page"],
.tools-fixed-header-layer > [data-header-for="classroom-page"],
.tools-fixed-header-layer > [data-header-for="schedule-page"] {
  --text: var(--study-cyan);
  --text-light: rgba(var(--study-cyan-rgb), 0.14);
}

.tools-fixed-header-layer > [data-header-for="energy-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="energy-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="campus-card-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="campus-card-page"] .sub-page-back {
  color: var(--text);
}

.tools-fixed-header-layer > [data-header-for="energy-page"],
.tools-fixed-header-layer > [data-header-for="campus-card-page"] {
  --text: #2563eb;
  --text-light: rgba(37, 99, 235, 0.12);
}

.tools-fixed-header-layer > [data-header-for="activities-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="activities-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="club-detail-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="club-detail-page"] .sub-page-back {
  color: var(--club-purple);
}

.tools-fixed-header-layer > [data-header-for="eatwhat-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="eatwhat-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="window-detail-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="window-detail-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="eatwhat-random-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="eatwhat-random-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="canteen-editor-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="canteen-editor-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="canteen-mine-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="canteen-mine-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="canteen-holiday-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="canteen-holiday-page"] .sub-page-back {
  color: var(--ew-theme-strong);
}

.tools-fixed-header-layer > [data-header-for="eatwhat-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="window-detail-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="eatwhat-random-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="canteen-editor-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="canteen-mine-page"] .sub-page-back,
.tools-fixed-header-layer > [data-header-for="canteen-holiday-page"] .sub-page-back {
  border-color: var(--ew-theme-border);
}

.tools-fixed-header-layer > [data-header-for="eatwhat-random-page"][data-sub-theme="drink"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="eatwhat-random-page"][data-sub-theme="drink"] .sub-page-back {
  color: #4facfe;
}

.tools-fixed-header-layer > [data-header-for="eatwhat-random-page"][data-sub-theme="drink"] .sub-page-back {
  border-color: #4facfe;
}

.tools-fixed-header-layer > [data-header-for="hometown-groups-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="hometown-groups-page"] .sub-page-back {
  color: var(--hometown-page-accent, var(--color-life, #f07f20));
}

.tools-fixed-header-layer > [data-header-for="hometown-groups-page"] {
  --text: var(--color-life, #f07f20);
  --text-light: rgba(240, 127, 32, 0.12);
}

.tools-fixed-header-layer > [data-header-for="phonebook-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="phonebook-page"] .sub-page-back {
  color: var(--text);
}

html[data-theme="dark"] .tools-fixed-header-layer > [data-header-for="energy-page"] .sub-page-title,
html[data-theme="dark"] .tools-fixed-header-layer > [data-header-for="energy-page"] .sub-page-back,
html[data-theme="dark"] .tools-fixed-header-layer > [data-header-for="campus-card-page"] .sub-page-title,
html[data-theme="dark"] .tools-fixed-header-layer > [data-header-for="campus-card-page"] .sub-page-back {
  color: #60a5fa;
}

html[data-theme="dark"] .tools-fixed-header-layer > [data-header-for="energy-page"],
html[data-theme="dark"] .tools-fixed-header-layer > [data-header-for="campus-card-page"] {
  --text: #60a5fa;
  --text-light: rgba(96, 165, 250, 0.15);
}

html[data-theme="dark"] .tools-fixed-header-layer > [data-header-for="eatwhat-random-page"][data-sub-theme="drink"] .sub-page-title,
html[data-theme="dark"] .tools-fixed-header-layer > [data-header-for="eatwhat-random-page"][data-sub-theme="drink"] .sub-page-back {
  color: #66b3ff;
}

html[data-theme="dark"] .tools-fixed-header-layer > [data-header-for="eatwhat-random-page"][data-sub-theme="drink"] .sub-page-back {
  border-color: #66b3ff;
}

/* 保持页面在普通文档合成层中，让实时 backdrop-filter 能读取完整页面绘制结果。 */
.tools-content-container > .tools-home-content:not(.hidden),
.tools-content-container > .tools-sub-page.active,
#tools-page > .tools-sub-page.active {
  z-index: 1;
  -webkit-transform: none !important;
  transform: none !important;
  will-change: auto !important;
  backface-visibility: visible;
  -webkit-backface-visibility: visible;
}

/* ============================================================
   地图「图层胶囊栏」（原图层弹窗的四个标记开关，搬到悬浮栏上方一行）
   ------------------------------------------------------------
   位置 = 底部悬浮栏（bottom 20px + 高 45px）正上方留 12px 实缝；
   --hgu-bottom-band-lift 同时把水印 / 定位按钮 / 楼层栏 / 图例整条抬高，
   所以这一带的地图控件都不会被胶囊栏压住。

   超出可视区的按钮用「缩小 + 淡出」表现「滑出去」，滑进来的恢复原大：
   缩放由 JS 按每个按钮离栏两端的距离逐帧写 --rail-scale（见 navigation.js
   updateLayerRailScales），这里只负责把变量落到 transform / opacity 上。
   注意 transform-origin 必须是 center —— 各按钮在 flex 里等距排布，
   center 缩放只改视觉大小、不改中心距，滑动时按钮不会互相挤。

   ⚠️ 右上角现在是「通知 / 反馈 / 分享」三颗（原「图层」那颗已撤）。
      #floorBar 在左侧竖列、宽度不变，与右上角按钮在横向上互不重叠，
      所以撤掉一颗按钮不需要给 --hgu-top-actions-top 打补丁 —— 别再"顺手"调它。
   ============================================================ */
#mapLayerRail {
  position: fixed;
  left: 50%;
  bottom: var(--hgu-layer-rail-bottom);
  transform: translateX(-50%);
  z-index: 998;
  width: max-content;
  max-width: calc(100vw - 32px);
  height: var(--hgu-layer-rail-h);
  box-sizing: border-box;
  /* ★ 容器本身**不画卡片**（无底色 / 无边框 / 无模糊 / 无内边距）：
     四颗按钮直接就是胶囊，再套一层带底色的容器会变成"胶囊里还有一层胶囊"。
     ⚠️ 但这个容器**必须**保留 —— 它是唯一的横向滚动容器：
        overflow-x:auto + max-width 收窄时按钮才会被推到可视区外，
        横向滑动与 JS 的缩放才有依据。 */
  display: flex;
  align-items: center;
  gap: 6px;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  /* 竖向留给地图拖动：这里只吃掉横向手势 */
  touch-action: pan-x;
  transition: opacity .2s ease, visibility 0s 0s, bottom .32s ease;
}

#mapLayerRail::-webkit-scrollbar {
  display: none;
}

/* ★ 服务卡片态：开关行**留在原地、被服务卡片盖掉**（需求）。
   卡片态时开关行不再上移，它与卡片上半部分在纵向上重叠。
   只把它降到卡片层之下还不够 —— 卡面是半透明玻璃，
   按钮会从卡片底下透出来、还会把卡片上那些按钮的点击抢走。
   所以这一态直接让开关行淡出（保留布局，不参与绘制与命中），
   卡片收起后自动恢复。其余控件（水印 / 定位 / 图例 / 楼层栏）不受影响。 */
body.home-panel-compact #mapLayerRail {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  z-index: 1;
  transition: opacity .18s ease, visibility 0s .18s;
}

/* 抽屉完全展开：整块面板盖住地图，胶囊开关让位收起 */
body.home-panel-expanded #mapLayerRail {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .2s ease, visibility 0s .2s, bottom .32s ease;
}

/* 服务卡片态：开关随整条带一起抬高。
   ⚠️ 实际抬高量由 JS 按卡片实测高度写内联 bottom（applyMapChromeOffsets），
      与上面的水印 / 定位按钮 / 图例完全同一套规则 —— 卡片高度是内容驱动的 px 值，
      只在 CSS 里算不出来，别再加「compact 专用」的 bottom 规则跟它打架。 */

/* 滑块跟随系统 / APP 显示大小缩放，缩小时按钮跟着变大一些（与显示大小同向） */
#mapLayerRail,
#mapLayerRail * {
  -webkit-tap-highlight-color: transparent;
}

@media (min-resolution: 1.5dppx) {
  #mapLayerRail .layer-rail-pill {
    padding-left: 11px;
    padding-right: 11px;
  }
}

/* ⚠️ 这几条必须用 #mapLayerRail 提特异性，而且必须**逐条写全**：
   胶囊栏的按钮同时带着旧的 .layer-marker-switch / .layer-marker-icon 类
   （复用它们的开关状态语义），那套样式是 46px 方块 + flex-direction:column
   （图标在上、文字在下）+ 边框描边。只写差异项会踩两个坑：
     ① 同属性由旧规则赢（.layer-marker-switch 在文件里更靠后）；
     ② 没写的属性继续沿用旧的 —— flex-direction 漏写就会变成竖排，
        胶囊里只剩图标、宽度掉到 44px，连"能不能横向滑动"都跟着失效。
   所以这里把方向、显示、内边距、边框、尺寸全部显式声明。 */
#mapLayerRail .layer-rail-pill {
  flex: 0 0 auto;
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: auto;
  min-width: 0;
  height: var(--hgu-layer-rail-h);
  box-sizing: border-box;
  padding: 0 9px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: 999px;
  /* 与底部悬浮栏同一套玻璃配方（.bottom-nav 用的就是这两个变量） */
  background: var(--hgu-surface-glass);
  backdrop-filter: blur(var(--hgu-blur-md));
  -webkit-backdrop-filter: blur(var(--hgu-blur-md));
  /* ★ 不加投影：胶囊行贴在悬浮栏上方，每颗胶囊的投影会在行下缘糊成一条
     暗暗的带子，看着像"胶囊容器有一层暗色遮罩"（用户反馈过）。
     整行/容器也都保持无阴影，边界只靠 1px 描边区分。 */
  box-shadow: none;
  color: var(--subtext);
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transform: scale(var(--rail-scale, 1));
  transform-origin: center center;
  opacity: var(--rail-opacity, 1);
  /* ★ 刻意不写 transform / opacity 的 transition：
     缩放与透明度由 JS 每帧按滚动位置算（updateLayerRailScales），
     挂 CSS 过渡会和逐帧写入打架，表现就是"滑动时按钮忽大忽小发抖"。 */
  transition: background .2s ease, color .2s ease;
}

#mapLayerRail .layer-marker-icon {
  width: 14px;
  height: 14px;
  flex: 0 0 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  border: none;
  background: rgba(128, 128, 128, 0.12);
  transition: background .2s ease;
}

#mapLayerRail .layer-marker-icon img {
  width: 11px;
  height: 11px;
  object-fit: contain;
  display: block;
  pointer-events: none;
}

#mapLayerRail .layer-marker-label {
  font-size: 10px;
  font-weight: 600;
  color: inherit;
  pointer-events: none;
}

/* 高亮态：**不加描边、不换底色**，只在文字后面补一个对号，并把「文字 + 对号」
   改成高亮色（--text）。背景保持与悬浮栏同一套玻璃，选中与否靠这一抹对号区分。
   对号用 .layer-rail-check 这个真实元素（不是 ::after）：
   显隐/颜色都能单独控，也方便无障碍读屏忽略（aria-hidden）。 */
#mapLayerRail .layer-rail-pill.active {
  color: var(--text);
}

#mapLayerRail .layer-rail-pill.active .layer-marker-label {
  color: var(--text);
  font-weight: 700;
}

/* 选中态显示对号。⚠️ 选择器写成 #mapLayerRail .layer-rail-pill.active .layer-rail-check：
   下面那条（#mapLayerRail .layer-rail-check）与它同特异性、且写在更后面，
   只加 !important 会在"两条都 !important"时由后者胜出，对号永远出不来（实测过）。 */
#mapLayerRail .layer-rail-pill.active .layer-rail-check {
  display: inline-block !important;
  color: var(--text);
}

/* 对号默认不占位（选中才显示）。这条写在选中态之后，
   靠选择器特异性更低来让位 —— 不要试图用"加不加 !important"来分胜负。 */
#mapLayerRail .layer-rail-pill .layer-rail-check {
  display: none !important;
  font-size: 9px;
  line-height: 1;
  flex: 0 0 auto;
  pointer-events: none;
}

#mapLayerRail .layer-rail-pill:active {
  background: rgba(128, 128, 128, 0.22);
}

/* 被管理员强制开启的标记：整颗按钮压暗。
   用变量相乘而不是写 opacity —— 按钮的 opacity 已经是 var(--rail-opacity)
   （滑动缩放用的），直接覆盖会跟滚动时的逐帧写入互相打架。 */
#mapLayerRail .layer-rail-pill[disabled] {
  cursor: not-allowed;
  opacity: calc(var(--rail-opacity, 1) * 0.6);
}

/* ---------- 横屏分栏：胶囊栏限制在右侧地图区内 ---------- */
html.hgu-split #mapLayerRail {
  left: calc(var(--hgu-split-panel-w) + (100vw - var(--hgu-split-panel-w)) / 2);
  max-width: calc(100vw - var(--hgu-split-panel-w) - 32px);
}

/* 分栏态抽屉展开时地图仍完整可见（只是左半屏盖了一层玻璃），胶囊栏保持可用 */
html.hgu-split body.home-panel-expanded #mapLayerRail {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity .2s ease, visibility 0s 0s, bottom .32s ease;
}

/* 旋转 / 横竖屏切换 / 分栏翻转的瞬间：胶囊开关不参与过渡插值 */
html.hgu-layout-instant #mapLayerRail {
  transition: none !important;
}
/* ============================================================
   形态切换期间：底部悬浮控件不参与 bottom 过渡（hgu-chrome-instant）
   ------------------------------------------------------------
   这三态切换时容器高度有 320ms 过渡，navigation.js 的 startChromeSettleLoop()
   会逐帧重算各控件位置。如果这时控件自己还带 bottom 过渡（CSS 里是 .32s ease），
   每一帧的新目标又会被缓动"追"一次 —— 位置永远慢半拍，
   表现就是水印 / 图例卡片比服务卡片晚一步到位（用户反馈过）。
   这段时间临时关掉过渡，让它们逐帧贴着卡片一起动，与卡片完全同步。
   ⚠️ 与 hgu-layout-instant 分开：那个是"旋转/分栏翻转"用的，语义不同，
      生命周期也不同（这个是每次三态切换都会挂 700ms 再摘掉）。 */
html.hgu-chrome-instant .map-brand-watermark,
html.hgu-chrome-instant .location-btn,
html.hgu-chrome-instant #indoorLegend,
html.hgu-chrome-instant #floorBar,
html.hgu-chrome-instant #mapLayerRail {
  transition: none !important;
}

/* ============================================================
   选项页：外观设置（原图层弹窗内容，布局模仿「显示大小」，放在它上方）
   ============================================================ */
.options-map-setting-item-appearance .theme-mode-levels {
  flex: 0 1 auto;
  min-width: 0;
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  background: none;
  border: none;
  border-radius: var(--hgu-radius-xl);
}

.theme-mode-level {
  flex: 0 0 auto;
  min-height: 28px;
  padding: 3px 9px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: var(--hgu-radius-lg);
  background: rgba(128, 128, 128, 0.10);
  color: var(--subtext);
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.1;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}

.theme-mode-level.active {
  background: var(--text);
  color: #fff;
  font-weight: 600;
}

/* ============================================================
   反馈 / 联系抽屉（右上角「反馈」按钮）
   ============================================================ */
.feedback-block + .feedback-block {
  margin-top: 18px;
}

.feedback-block-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.4;
  margin-bottom: 10px;
}

.feedback-person {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-2xl);
  background: rgba(128, 128, 128, 0.06);
}

.feedback-person-avatar {
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  overflow: hidden;
  background: rgba(128, 128, 128, 0.14);
  display: flex;
  align-items: center;
  justify-content: center;
}

.feedback-person-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.feedback-person-name {
  flex: 1;
  min-width: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.feedback-person-btn {
  flex: 0 0 auto;
  border: none;
  border-radius: var(--hgu-radius-lg);
  padding: 8px 14px;
  background: var(--text);
  color: #fff;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.1;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  transition: transform 0.15s ease, opacity 0.2s ease;
}

.feedback-person-btn:active {
  transform: scale(0.95);
}

/* 反馈抽屉里的 QQ / 微信两行（与选项页原本那两行同一套观感） */
.feedback-contact-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.feedback-contact-list .feedback-item {
  background: rgba(128, 128, 128, 0.06);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-xl);
  padding: 10px 12px;
}

/* ============================================================
   分享全屏弹窗（右上角「分享」按钮）
   ------------------------------------------------------------
   全屏 + 背景高斯模糊；内容向上飞入、向下飞出（非线性缓动），
   模糊层渐显渐隐。点击任意位置关闭。

   ★ 可见性用 .is-hidden 收尾，**不能**在基态写 visibility: hidden：
     基态的 transition 是给"打开"用的；关闭时若基态立刻 hidden，
     收起动画根本来不及播（元素当场消失）—— 用户反馈过"没有关闭动画"。
     现在的分工：
       基态（可见、未激活）→ opacity/transform/visibility 的 transition
                              都带 .46s 的延迟，等飞出去了再把层藏起来；
       .active（打开）      → 过渡延迟归零，立刻开始飞入；
       .is-hidden（真正藏） → 过渡全关，条件满足时立刻生效。
   ============================================================ */
.share-fullscreen {
  position: fixed;
  inset: 0;
  z-index: 10003;
  visibility: visible;
  pointer-events: none;
  /* 关闭态：等内容和模糊层退完再真正藏起来（时长见 --share-out-ms） */
  transition: visibility 0s linear var(--share-out-ms);
}

.share-fullscreen.active {
  pointer-events: auto;
  transition: visibility 0s linear 0s;
}

/* 真正藏起来（由 closeShareModal 在动画结束后补上）。
   ⚠️ 必须带 .active 之外的状态判断：打开时永远不该命中这条。 */
.share-fullscreen.is-hidden {
  visibility: hidden;
  transition: none;
}

.share-fullscreen-blur {
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.10);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  opacity: 0;
  transition: opacity .34s ease;
}

.share-fullscreen.active .share-fullscreen-blur {
  opacity: 1;
}

.share-fullscreen-body {
  position: relative;
  z-index: 1;
  height: 100%;
  box-sizing: border-box;
  padding: calc(env(safe-area-inset-top, 0px) + 40px) 24px calc(env(safe-area-inset-bottom, 0px) + 40px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
  /* 关闭态：整体向下沉出屏幕（"向下飞出"），透明度归零 */
  transform: translateY(46vh);
  opacity: 0;
  transition: transform var(--share-out-ms) cubic-bezier(.22, 1.25, .36, 1), opacity .3s ease;
}

.share-fullscreen.active .share-fullscreen-body {
  transform: translateY(0);
  opacity: 1;
  transition: transform .52s cubic-bezier(.16, .84, .24, 1), opacity .34s ease;
}

.share-fs-brand {
  display: flex;
  align-items: center;
  gap: 10px;
}

.share-fs-brand img {
  width: 44px;
  height: 44px;
  border-radius: var(--hgu-radius-lg);
  object-fit: contain;
  display: block;
}

.share-fs-title {
  font-size: 22px;
  font-weight: 800;
  color: var(--text);
  letter-spacing: 0.02em;
}

.share-fs-small {
  font-size: 13px;
  color: var(--subtext);
  line-height: 1.4;
}

.share-fs-url {
  font-size: 22px;
  font-weight: 800;
  color: var(--text);
  letter-spacing: 0.02em;
  line-height: 1.2;
}

.share-fs-qrcode {
  width: 168px;
  height: 168px;
  max-width: 60vw;
  max-height: 60vw;
  object-fit: contain;
  border-radius: var(--hgu-radius-2xl);
  background: #fff;
  padding: 8px;
  box-sizing: border-box;
  box-shadow: var(--hgu-shadow-card);
}

.share-fs-hint {
  margin-top: 6px;
  font-size: 12px;
  color: var(--subtext);
  opacity: 0.7;
}

/* ============================================================
   桌面小组件教程弹窗（仅 APP 内，选项页「桌面小组件」）
   ============================================================ */
.widgets-intro-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.45;
}

.widgets-intro-sub {
  margin-top: 6px;
  font-size: 13px;
  color: var(--subtext);
  line-height: 1.5;
}

.widgets-steps-title {
  margin: 18px 0 10px;
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
}

.widgets-brand-tabs {
  display: flex;
  gap: 4px;
  padding: 4px;
  border-radius: var(--hgu-radius-xl);
  background: rgba(128, 128, 128, 0.08);
  border: 1px solid var(--hgu-border-soft);
  overflow-x: auto;
  scrollbar-width: none;
}

.widgets-brand-tabs::-webkit-scrollbar {
  display: none;
}

.widgets-brand-tab {
  flex: 1 1 0;
  min-width: 0;
  padding: 8px 4px;
  border: none;
  border-radius: var(--hgu-radius-lg);
  background: transparent;
  color: var(--subtext);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.15;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}

.widgets-brand-tab.active {
  background: var(--text);
  color: #fff;
}

.widgets-brand-panel {
  margin-top: 14px;
}

.widgets-brand-panel[hidden] {
  display: none !important;
}

.widgets-step {
  margin-bottom: 16px;
}

.widgets-step-text {
  font-size: 13px;
  color: var(--text);
  line-height: 1.5;
  margin-bottom: 8px;
}

.widgets-step-img {
  display: block;
  width: 100%;
  max-width: 260px;
  border-radius: var(--hgu-radius-lg);
  border: 1px solid var(--hgu-border-soft);
  background: rgba(128, 128, 128, 0.06);
}

.widgets-credit {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 18px;
  font-size: 12px;
  color: var(--subtext);
  opacity: 0.85;
}

.widgets-credit-avatar {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  background: rgba(128, 128, 128, 0.14);
}

/* ============================================================
   iOS 添加到主屏幕引导：图片素材署名（round 11）
   ------------------------------------------------------------
   与 .widgets-credit 同一套观感（灰色小字 + 圆形头像），
   只是选择器独立命名，方便两处各自调整。
   ============================================================ */
.ios-guide-credit {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px dashed var(--hgu-border-soft);
  font-size: 12px;
  color: var(--subtext);
  opacity: 0.85;
}

.ios-guide-credit-avatar {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  flex: 0 0 auto;
  background: rgba(128, 128, 128, 0.14);
}

/* ============================================================
   选项页设置行的 [hidden] 必须能压住 display:flex
   ------------------------------------------------------------
   .options-map-setting-item / .options-action-item 都是 display:flex，
   与浏览器默认的 [hidden]{display:none} 同特异性、但类规则在样式表里更靠后，
   于是整行会照常显示 —— 表现就是"网页端本该隐藏的「显示大小」
   「桌面小组件」两行仍然出现在选项页上"（实测）。
   这两行本来就是靠 JS 加 hidden 来控制"仅 APP 内显示"的，
   所以两条兜底都**不能省**：只补其中一条，另一行照样会漏出来。 */
.options-map-setting-item[hidden] {
  display: none !important;
}

/* ⛔ 同类问题还有「桌面小组件」那一行 —— 它挂的是 .options-action-item
   （同样 display:flex），上面那条只覆盖了 .options-map-setting-item，
   于是网页端「桌面小组件」照样显示出来。这条必须一起补上。 */
.options-action-item[hidden] {
  display: none !important;
}

/* ============================================================
   地图悬浮按钮的「未选中」配色（通知 / 反馈 / 分享 / 定位）
   ------------------------------------------------------------
   需求：这四处按钮的图标与文本色 = 底部悬浮栏里未选中那一档（--subtext）。
   文件里散落着好几处历史规则都用 var(--text) 给它们上色（18045 / 18413 / 18505…），
   同特异性下"更靠后"的那条会赢；而且 --text 还会被抽屉内的页面主题覆盖。
   这里在文件末尾统一收口一次：颜色走全局 token，并提一档特异性兜住历史规则。
   ⚠️ 只覆盖颜色，不动尺寸 / 玻璃 / 圆角 / 阴影 —— 那几处历史规则里的尺寸仍生效。
   重要通知（.notice-important）的红底白字是特殊态，不受这条影响（下面单独重申）。 */
#mapTopActions .map-top-action-btn,
#mapTopActions .map-top-action-btn i,
#mapTopActions .map-top-action-btn > span:not(.map-notice-badge) {
  color: var(--hgu-idle-chrome);
}

.location-btn,
.location-btn i {
  color: var(--hgu-idle-chrome);
}

/* 重要通知仍是红底白字 */
#mapTopActions .map-top-action-btn.notice-important,
#mapTopActions .map-top-action-btn.notice-important i,
#mapTopActions .map-top-action-btn.notice-important > span:not(.map-notice-badge) {
  color: #fff;
}

/* ============================================================
   课表相关：配色与边框（round 10）
   ------------------------------------------------------------ */
/* (3) 个人课表页的「第x周 周几」标题与管理按钮：
   原来吃的是学习页主题色 var(--text) = --study-cyan（青色），改成主文本色。
   主文本色走全局 token --hgu-idle-chrome（:root 里 = var(--text)），
   因为 #schedule-page 这一层把 --text 重定义成了青色。

   ⚠️ 选择器必须带上 .tools-fixed-header-layer > [data-header-for="schedule-page"] 这一层：
      文件前面另有一条 `[data-header-for="schedule-page"] .sub-page-title` 在给它上色，
      那条的特异性比 `#schedule-page .sub-page-title` 高，只写后者压不过它、改了不生效。 */
.tools-fixed-header-layer > [data-header-for="schedule-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="schedule-page"] .schedule-manage-btn,
#schedule-page .schedule-manage-btn {
  color: var(--hgu-idle-chrome);
}

.tools-fixed-header-layer > [data-header-for="schedule-page"] .schedule-manage-btn,
#schedule-page .schedule-manage-btn {
  border-color: var(--hgu-idle-chrome);
  /* 底色与旁边的刷新按钮 (#scheduleRefreshBtn) 保持一致：都是透明底、只有描边，
     不再用同色低透明度填充（原先那点浅底和刷新按钮放在一起显得一实一虚）。 */
  background: transparent;
}

/* (4) 右下角周次切换按钮（个人课表页 + 教室课表页）：
   边框颜色跟随按钮内的文本色。用 currentColor —— 两个页面的文本色不同
   （个人课表是主文本色、教室课表是青色），currentColor 会自动对上，
   不用给两个页面各写一遍。 */
#scheduleFloatNav .schedule-float-btn,
#classroomFloatNav .schedule-float-btn,
#scheduleFloatNav .schedule-float-text,
#classroomFloatNav .schedule-float-text {
  border-color: currentColor;
}

/* (5) 课表管理弹窗里的「课表调休显示」开关容器：
   原来边框是 --border（rgba(255,255,255,.4) 纯白半透明），在浅色卡面上几乎看不见，
   改成主文本色，与同一弹窗里其它按钮的边框一致。
   ⚠️ 容器这一层的 --text 是学习页主题色（青），这里同样要绕开它。 */
.schedule-manage-reschedule-toggle {
  border-color: var(--hgu-idle-chrome);
}

/* ============================================================
 * 失物招领 · 主题样式
 * 主题色：靛蓝 #4F46E5 / 青蓝 #06B6D4 / 中间蓝 #2A7EDC
 * ============================================================ */
:root {
  --lf-indigo: #4F46E5;
  --lf-indigo-light: #A5B4FC;
  --lf-cyan: #06B6D4;
  --lf-cyan-light: #67E8F9;
  --lf-mid: #2A7EDC;                 /* 靛蓝与青蓝的中点蓝 */
  --lf-grid-empty: rgba(120, 130, 160, 0.18);
}

/* ---------- 首页卡片（失物招领） ---------- */
.life-lostfound-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
  aspect-ratio: 1 / 1;
  min-height: 0;
  padding: 10px 12px;
  border: 1.5px solid var(--lf-mid);
  border-radius: var(--hgu-radius-2xl);
  background: var(--hgu-surface-glass);
  color: var(--text);
  text-align: left;
  cursor: pointer;
  box-shadow: var(--hgu-shadow-card);
  font-family: inherit;
  box-sizing: border-box;
}
.life-lostfound-top { display: flex; align-items: center; gap: 8px; }
.life-lostfound-icon { width: 24px; height: 24px; object-fit: contain; }
.life-lostfound-title { font-size: 15px; font-weight: 700; flex: 1; color: var(--lf-mid); }
.life-lostfound-arrow { margin-left: auto; opacity: .85; color: var(--lf-mid); }
.life-lostfound-heatmap { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; justify-content: center; }
.lf-heatmap {
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  grid-template-rows: repeat(3, minmax(0, 1fr));
  gap: 3px;
  width: 100%;
  max-width: 100%;
  aspect-ratio: 8 / 3;
  margin: 0 auto;
  overflow: hidden;
}
.lf-cell { display: block; width: 100%; height: 100%; min-width: 0; min-height: 0; border-radius: 4px; background: var(--lf-grid-empty); }
.lf-heatmap-stats { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; }
.lf-heatmap-stats .lf-stat-row { display: flex; justify-content: space-around; }
.lf-stat { display: inline-flex; align-items: baseline; gap: 4px; font-size: 10px; font-weight: 600; color: var(--subtext); }
.lf-stat strong { font-size: 18px; font-weight: 900; line-height: 1; }
.lf-heatmap-loading { padding: 8px; text-align: center; color: var(--text); opacity: .6; }

/* ---------- 失物招领页 ---------- */
.lostfound-content { padding: 0 12px 16px; }

/* ================== 顶部视图切换（线下招领处 / 全部 / 寻物启事 / 失物招领） ==================
 * 上图标、下文字，每颗按钮各自带边框。
 * 宽度：第一颗「线下招领处」= 页面一半，另外半宽三等分给后三颗。
 *   3 条 8px 间隙占掉 24px，所以半宽写成 calc(50% - 12px)（= 半宽里让出间隙），
 *   余下 50% - 12px 由三颗 flex:1 均分 —— 合起来正好铺满一行。
 * 配色：border 用 currentColor，做一次 tone 类就能同时改边框与文字，
 *      图标是 img，不跟着染（需求只要求边框分色）。 */
.lf-view-switch { display: flex; gap: 8px; margin: 4px 0 12px; }
.lf-view-btn {
  flex: 1 1 0; min-width: 0; box-sizing: border-box;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  padding: 8px 4px;
  border: 1.5px solid currentColor;
  border-radius: var(--hgu-radius-xl, 12px);
  background: transparent; color: var(--subtext);
  font-family: inherit; font-size: 12px; font-weight: 600; line-height: 1.2;
  cursor: pointer;
}
.lf-view-btn.is-wide { flex: 0 0 calc(50% - 12px); }
/* 后三颗只分到「半页的三分之一」（420 宽时约 55px、360 宽时只剩 ~45px），12px 字号下
 * 「寻物启事」放不进去 —— 会和「失物招领」一起被省略成「寻物…/失物…」，两颗分不清。
 * 所以窄按钮降到 11px、收窄左右内边距，并允许在 JS 插的 <wbr> 处换行（宽屏不触发，
 * 窄屏断成「寻物 / 启事」）。 */
.lf-view-btn:not(.is-wide) { font-size: 11px; padding: 8px 2px; }
/* 只留 JS 插的那个 <wbr> 作为唯一断点：汉字之间天然处处可断，不加 keep-all 的话浏览器会
 * 把「寻物启事」填满整行、断成「寻物启 / 事」，尾字孤零零一行。keep-all + wbr = 工整的 2+2。 */
.lf-view-btn:not(.is-wide) span { white-space: normal; word-break: keep-all; line-height: 1.15; }
.lf-view-btn img { width: 26px; height: 26px; object-fit: contain; display: block; }
.lf-view-btn span { max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lf-view-btn.is-mid    { color: var(--lf-mid); }
.lf-view-btn.is-indigo { color: var(--lf-indigo); }
.lf-view-btn.is-cyan   { color: var(--lf-cyan); }
.lf-view-btn.active { font-weight: 700; }
/* 选中态高亮底：.12 在浅色玻璃底上几乎看不出来，加深到 .26 并叠一层同色描边，
   让「当前在哪一屏」一眼可辨（需求：选中的高亮背景再浓一些）。 */
.lf-view-btn.is-mid.active    { background: rgba(42, 126, 220, .26); box-shadow: inset 0 0 0 1px rgba(42, 126, 220, .38); }
.lf-view-btn.is-indigo.active { background: rgba(79, 70, 229, .26); box-shadow: inset 0 0 0 1px rgba(79, 70, 229, .38); }
.lf-view-btn.is-cyan.active   { background: rgba(6, 182, 212, .26); box-shadow: inset 0 0 0 1px rgba(6, 182, 212, .38); }
/* 深色主题下浅色底纹更"跳"，同透明度就够浓了，不再叠加 */
html[data-theme="dark"] .lf-view-btn.is-mid.active    { background: rgba(42, 126, 220, .30); }
html[data-theme="dark"] .lf-view-btn.is-indigo.active { background: rgba(129, 140, 248, .28); }
html[data-theme="dark"] .lf-view-btn.is-cyan.active   { background: rgba(6, 182, 212, .28); }
html[data-theme="dark"] .lf-view-btn.is-indigo { color: var(--lf-indigo-light); }
html[data-theme="dark"] .lf-view-btn.is-cyan   { color: var(--lf-cyan-light); }

/* ================== 线下招领处（单列卡片） ================== */
/* [hidden] 兜底：作者样式里任何一条 display 都会盖掉 UA 的 `[hidden]{display:none}`，
   而这两块是靠 hidden 属性切换的（#lostfoundBrowse / #lostfoundLocations）。 */
#lostfoundBrowse[hidden],
#lostfoundLocations[hidden] { display: none !important; }

.lf-loc-card {
  border: 1.5px solid var(--lf-mid);
  border-radius: var(--hgu-radius-xl, 12px);
  background: var(--hgu-surface-glass);
  padding: 12px;
  margin-bottom: 12px;
  box-shadow: 0 2px 9px rgba(42, 126, 220, .08);
}
.lf-loc-head { display: flex; align-items: flex-start; gap: 8px; }
/* 招领点名称：比帖子卡片标题（.lf-card-title 14px）略大一号 */
.lf-loc-name {
  flex: 1 1 auto; min-width: 0;
  font-size: 16px; font-weight: 700; line-height: 1.3;
  color: var(--lf-mid); word-break: break-word;
}
.lf-loc-locate {
  flex: 0 0 auto; width: 30px; height: 30px; margin-left: auto; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--lf-mid); border-radius: 50%;
  background: rgba(42, 126, 220, .1); color: var(--lf-mid);
  font-size: 13px; cursor: pointer;
}
.lf-loc-locate i { line-height: 1; }
.lf-loc-place { display: flex; align-items: center; gap: 5px; font-size: 12px; color: #8a909c; margin-top: 6px; }
.lf-loc-place i { font-size: 11px; }
/* 图片更新时间：3 天内灰 / 超过 3 天橙 / 超过 7 天红（阈值见 lostfound.js 的 lfFreshness） */
.lf-loc-time { display: flex; align-items: center; gap: 5px; font-size: 12px; margin-top: 4px; }
.lf-loc-time i { font-size: 11px; }
.lf-loc-time.is-normal { color: #8a909c; }
.lf-loc-time.is-warn   { color: #e0872b; }
.lf-loc-time.is-danger { color: #dc4b4b; }
.lf-loc-imgs { margin-top: 10px; }
/* 线下招领处图片：**不限制预览比例**（2026-10 起），按原图比例完整显示 ——
   原来按「最高 4:3（横向）」上下裁切，长截图会被切掉一截。
   图片外面套一层 position:relative 的 .lf-loc-img-wrap，图片标签靠它做百分比定位；
   ⛔ 不要给 .lf-loc-img 加 max-height / object-fit:cover，否则标签坐标会整体偏移。 */
.lf-loc-img-wrap {
  position: relative; display: block; border-radius: 10px; overflow: hidden;
  line-height: 0; background: rgba(120, 130, 160, .08);
}
.lf-loc-img {
  width: 100%; display: block; height: auto;
  border-radius: 10px; cursor: zoom-in;
}
/* 图片标签：小红书/抖音那种「● 胶囊」—— 圆点在胶囊**外面**（左侧），胶囊是黑色半透明底 + 白字。
   坐标由 JS 按 0~1 的比例算成百分比，所以卡片宽度变了也不会错位。
   ⚠️ **锚点是圆点中心**（不是整个元素的中心）：外层只负责定位（透明），
      平移量取圆点半径 3.5px，于是圆点正好压在 (x,y) 这个图片坐标上，缩放/翻面都不会漂。
   pointer-events:none 让点击穿透到图片，点标签位置仍然能打开大图。
   大图里的同款标签见 .cal-zoom-tag、后台编辑器见 admin 的 .tag-pill（三处样式需保持一致）。 */
.lf-loc-tag {
  position: absolute; transform: translate(-3.5px, -50%);
  display: inline-flex; align-items: center; gap: 6px;
  max-width: 60%;
  pointer-events: none;
}
/* 靠右的标签翻到圆点左侧（阈值 0.5，JS 加 is-flip），否则胶囊会被图片右边缘裁掉 */
.lf-loc-tag.is-flip {
  flex-direction: row-reverse;
  transform: translate(calc(-100% + 3.5px), -50%);
}
/* 圆点带一圈深色描边：叠在浅色图片上也看得见（原来在胶囊内部靠黑底衬托，移出去后必须自带轮廓） */
.lf-loc-tag-dot {
  flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 1.5px rgba(0, 0, 0, .55), 0 1px 3px rgba(0, 0, 0, .35);
}
.lf-loc-tag-body {
  display: block; min-width: 0; max-width: 100%;
  padding: 4px 10px;
  border-radius: 999px; background: rgba(0, 0, 0, .62); color: #fff;
  font-size: 12px; line-height: 1.25; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .28);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}

.lostfound-tabs {
  position: relative;
  display: flex; gap: 8px; overflow-x: auto; padding: 8px 0 0;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.lostfound-tabs::-webkit-scrollbar { display: none; }
/* 失物招领分类切换：只高亮文本 + 底部横线，背景不染色 */
#lostfound-page .lostfound-tabs .canteen-tab.active,
.lostfound-tabs .canteen-tab.active { color: var(--lf-mid) !important; background: transparent !important; opacity: 1 !important; }
#lostfound-page .lostfound-tabs .canteen-tab-indicator,
.lostfound-tabs .canteen-tab-indicator { background: var(--lf-mid) !important; box-shadow: 0 2px 6px rgba(42, 126, 220, .35) !important; }
html[data-theme="dark"] #lostfound-page .lostfound-tabs .canteen-tab.active,
html[data-theme="dark"] .lostfound-tabs .canteen-tab.active { color: var(--lf-mid) !important; }
html[data-theme="dark"] #lostfound-page .lostfound-tabs .canteen-tab-indicator,
html[data-theme="dark"] .lostfound-tabs .canteen-tab-indicator { background: var(--lf-mid) !important; }

.lostfound-list { display: flex; gap: 10px; align-items: flex-start; }
.lf-col { flex: 1; display: flex; flex-direction: column; gap: 10px; min-width: 0; }
/* 分组结构：.lostfound-list 平时是双列 flex 行容器，加 .is-sectioned 后改成块级，
   由内层 .lf-rows 各自承担双列 flex —— 这样「已找到/已认领」的通栏分隔线才能横跨两列。 */
.lostfound-list.is-sectioned { display: block; }
.lf-rows { display: flex; gap: 10px; align-items: flex-start; }
/* 未完结帖与已完结帖（已找到 / 已认领）之间的通栏分隔线 */
.lf-resolved-divider { height: 1px; margin: 18px 0 14px; background: rgba(120, 130, 160, .3); border-radius: 1px; }
html[data-theme="dark"] .lf-resolved-divider { background: rgba(150, 160, 185, .28); }
.lf-card {
  border-radius: var(--hgu-radius-xl, 12px); background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft); overflow: hidden; cursor: pointer;
  box-shadow: 0 2px 9px rgba(127, 77, 174, .07);
}
.lf-card.is-lost { border-color: var(--lf-indigo); }
.lf-card.is-found { border-color: var(--lf-cyan); }
.lf-card.is-resolved { border-color: #b9bdc7; }
/* 已找到/已认领：只让边框与文本变灰，图片保持原样（早期用整卡 filter:grayscale 会连图片一起灰掉） */
.is-resolved .lf-card-row,
.is-resolved .lf-card-cat { color: #9aa0ab; }
/* 预览图高度上限 = 卡片宽 × 1（即最高 1:1，方形）：
   竖长图超过上限时用 cover 从「中间」裁切，只显示中间区域；横图 / 方图本身没到上限，仍完整显示。
   上限压到 1:1（此前是 4/3）→ 瀑布流卡片更矮、图片更少占屏，只影响预览显示，点击进详情仍看原图。
   用容器查询单位 cqw（1cqw = 卡片宽度的 1%）精确对齐卡片宽，避免按视口边距反推。 */
.lf-card-media { container-type: inline-size; }
.lf-card-media img {
  width: 100%; display: block; height: auto;
  max-height: calc((100vw - 34px) / 2);   /* 兜底：不支持 cqw 的旧内核按视口估算 */
  object-fit: cover; object-position: center;
}
@supports (height: 1cqw) {
  .lf-card-media img { max-height: 100cqw; }
}
.lf-card-body { padding: 8px 10px; }
.lf-card-head { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 6px; }
.lf-card-kind { flex: 0 0 auto; font-size: 11px; font-weight: 700; padding: 1px 6px; border-radius: 6px; color: #fff; }
.is-lost .lf-card-kind { background: var(--lf-indigo); }
.is-found .lf-card-kind { background: var(--lf-cyan); }
.is-resolved .lf-card-kind { background: #9aa0ab; }
.lf-card-title {
  flex: 1 1 auto; min-width: 0;
  font-size: 14px; font-weight: 600; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; word-break: break-word;
}
.is-lost .lf-card-title { color: var(--lf-indigo); }
.is-found .lf-card-title { color: var(--lf-cyan); }
.is-resolved .lf-card-title { color: #7a7f8a; }
.lf-card-cats { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.lf-card-cat { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; color: #6b7280; background: rgba(120, 130, 160, .12); padding: 1px 6px; border-radius: 6px; }
.lf-card-row { display: flex; align-items: center; gap: 5px; font-size: 12px; color: #8a909c; margin-top: 4px; }
.lf-card-row i { font-size: 11px; }

/* 失物招领页顶部标题与返回按钮：蓝色（与首页卡片、页面主题一致） */
#lostfound-page .sub-page-title,
#lostfound-page .sub-page-back { color: var(--lf-mid) !important; }
/* 发布页（独立子页）同样走蓝色主题：标题、返回、表单重点色 */
#lostfound-publish-page .sub-page-title,
#lostfound-publish-page .sub-page-back { color: var(--lf-mid) !important; }
/* 若走了 fixed-header-layer 克隆，一并覆盖 */
[data-header-for="lostfound-page"] .sub-page-title,
[data-header-for="lostfound-page"] .sub-page-back,
[data-header-for="lostfound-publish-page"] .sub-page-title,
[data-header-for="lostfound-publish-page"] .sub-page-back { color: var(--lf-mid) !important; }
.lostfound-publish-content { padding: 0 12px 24px; }
/* 与首页（失物列表页 .lostfound-content）页边距对齐：去掉 max-width 居中留白，两侧 12px */
/* 两侧留白交给外层 .lostfound-publish-content 统一控制为 12px（与首页 .lostfound-content 一致）；
   这里不再加横向 padding，否则会叠加成双倍 24px。 */
.lf-publish-form { width: 100%; box-sizing: border-box; }
/* 发布页表单文本统一用蓝色主题，避免被生活页/社团页的主文本色覆盖 */
#lostfound-publish-page .lf-field label { color: var(--lf-mid); }
#lostfound-publish-page .lf-field label small { color: rgba(42, 126, 220, .65); }
#lostfound-publish-page .lf-field label i { color: #e05656; }
#lostfound-publish-page .lf-radio { color: var(--lf-mid); }
#lostfound-publish-page .lf-publish-note { color: var(--lf-mid); opacity: .8; }
#lostfound-publish-page .lf-field input:focus,
#lostfound-publish-page .lf-field textarea:focus {
  border-color: var(--lf-mid);
  box-shadow: 0 0 0 3px rgba(42, 126, 220, .15);
  outline: none;
}
#lostfound-publish-page .lf-field input,
#lostfound-publish-page .lf-field textarea { color: var(--subtext); background: transparent; }
#lostfound-publish-page .lf-field input::placeholder,
#lostfound-publish-page .lf-field textarea::placeholder { color: var(--subtext); opacity: .5; }
/* ---------- 发布页：扁平表单 ----------
   需求：不再套卡片容器，信息直接铺在页面上；分区之间只用一条细分隔线。
   结构：物品信息标题 + 物品名输入框 → 分隔线 → 描述 + 图片 + 分类标签
        → 分隔线 → 单行字段组（左标题 / 右填写框）→ 发布按钮。 */
.lf-pub-head-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  padding: 2px 2px 4px;
}
.lf-pub-sec-title { font-size: 14px; font-weight: 700; color: var(--lf-mid); }
.lf-pub-head-row small { font-size: 11px; color: rgba(42, 126, 220, .62); }

/* 物品名：主输入框，去掉容器边框（需求：不显示输入框边框） */
.lf-pub-title {
  display: block; width: 100%; box-sizing: border-box;
  padding: 4px 2px 8px; margin: 0;
  border: none; outline: none; background: transparent;
  font-size: 19px; font-weight: 600; line-height: 1.45;
  color: var(--subtext); font-family: inherit;
  -webkit-appearance: none; appearance: none;
}
.lf-pub-title:focus { outline: none; border: none; box-shadow: none; }
.lf-pub-title::placeholder { color: var(--subtext); opacity: .4; font-weight: 500; }

/* 分区之间的细分隔线 */
/* ⚠️ 不用 --hgu-border-soft：它 = --border = rgba(255,255,255,.4)，
   在白底内容区是一条看不见的白线（浅色主题下分隔线「消失」）。写死灰色，浅/深底都看得见。 */
.lf-pub-divider {
  height: 1px; margin: 12px 0;
  background: rgba(120, 130, 160, .3);
}
html[data-theme="dark"] .lf-pub-divider { background: rgba(150, 160, 185, .28); }

/* 描述：同样无边框（与物品名同一视觉层），下方不再跟分隔线 */
.lf-pub-desc {
  display: block; width: 100%; box-sizing: border-box;
  padding: 2px 2px 6px; margin: 0 0 10px;
  border: none; outline: none; background: transparent; resize: none;
  font-size: 14px; line-height: 1.6;
  color: var(--subtext); font-family: inherit;
  -webkit-appearance: none; appearance: none;
}
.lf-pub-desc:focus { outline: none; border: none; box-shadow: none; }
.lf-pub-desc::placeholder { color: var(--subtext); opacity: .45; }

/* 分类标签：单行显示，超出可左右滑动（需求：不再换行）
   注意用双类名提高优先级 —— 下文 .lf-cat-chips 的 flex-wrap:wrap 在本文件更靠后，
   单类名会因「同优先级后者胜」把 nowrap 覆盖掉。 */
.lf-cat-chips.lf-cat-scroll {
  flex-wrap: nowrap;
  overflow-x: auto; overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  padding: 2px 2px 4px;
  scrollbar-width: none;
}
.lf-cat-chips.lf-cat-scroll::-webkit-scrollbar { display: none; }
.lf-cat-scroll .lf-cat-chip { flex: 0 0 auto; white-space: nowrap; }

/* 图片上传框与下方分类标签之间再留一点空（需求：两者之间要有留白）
   ⚠️ 只作用于发布页（.lf-publish-form）—— .lf-img-row 在「提交认领」抽屉里也用，
      那里不需要这段间距。 */
.lf-publish-form .lf-img-row { margin-bottom: 16px; }

/* ---------- 发布页：单行字段（左标题 / 右填写框） ---------- */
/* ⛔ 发布页的字段容器**不能**叫 .lf-rows —— 那是列表分组的双列 flex 行容器
 *    （见上面 .lostfound-list.is-sectioned 那段）。同名会让每一行 .lf-row 都变成
 *    横向 flex item，输入框被压到 min-width:0，表现就是「丢失/捡到时间以下的字段
 *    全挤到一行」。这里用独立类名 + 显式 block，跟列表彻底解耦。 */
.lf-pub-rows { display: block; }
.lf-row {
  display: flex; align-items: center; gap: 12px;
  min-height: 46px; padding: 2px;
  cursor: text;
}
.lf-row-label {
  flex: none; font-size: 14px; font-weight: 600; color: var(--lf-mid);
  white-space: nowrap;
}
.lf-row-label i { color: #e05656; font-style: normal; }
.lf-row > input {
  flex: 1 1 auto; min-width: 0; width: 100%;
  padding: 6px 0; border: none; outline: none; background: transparent;
  text-align: right; font-size: 14px; font-family: inherit;
  color: var(--subtext);
  -webkit-appearance: none; appearance: none;
}
.lf-row > input:focus { outline: none; border: none; box-shadow: none; }
.lf-row > input::placeholder { color: var(--subtext); opacity: .45; }
.lf-row > input::-webkit-datetime-edit { color: var(--subtext); }
/* 时间行（datetime-local）的文本必须靠右，与其它行一致。
   只在 input 上写 text-align 不够 —— WebView 里日期时间的文本由
   ::-webkit-datetime-edit（及其 fields-wrapper）自己排版，父级的 text-align
   传不下去，表现就是「其它行都靠右、只有时间靠左」。这两条伪元素规则必须留着。 */
.lf-row > input[type="datetime-local"],
.lf-row > input[type="datetime-local"]::-webkit-datetime-edit,
.lf-row > input[type="datetime-local"]::-webkit-datetime-edit-fields-wrapper {
  text-align: right;
}
/* 只读行（QQ 号）：值取自社区账号，弱化显示 */
.lf-row-readonly { cursor: default; }
.lf-row-readonly > input { opacity: .62; }
/* 开关行：整行可点，开关靠右 */
.lf-row-switch { cursor: pointer; }
.lf-row-switch > .lf-switch { margin-left: auto; }
/* 发布按钮与上一行之间留出呼吸空间 */
.lf-publish-submit { margin-top: 18px; }

/* ---------- 右下角「发布」FAB（玻璃背景 + 蓝边；分栏时约束到左侧抽屉面板右下角） ---------- */
.lf-fab {
  position: fixed; right: 16px; bottom: var(--hgu-nav-clearance, 74px); z-index: 998;
  display: none; align-items: center; gap: 6px;
  padding: 11px 18px; border: 1.5px solid var(--lf-mid); border-radius: var(--hgu-radius-pill, 999px);
  background: var(--hgu-surface-glass);
  -webkit-backdrop-filter: blur(var(--hgu-blur-xl)) saturate(1.5);
  backdrop-filter: blur(var(--hgu-blur-xl)) saturate(1.5);
  color: var(--lf-mid);
  font-size: 14px; font-weight: 600;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.16), inset 0 1px 0 rgba(255, 255, 255, 0.35);
  cursor: pointer; box-sizing: border-box;
}
body.lostfound-fab-open .lf-fab { display: flex; }
.lf-fab:active { transform: scale(0.96); }
/* 分栏（横屏分离）布局：右侧是地图，左侧是抽屉面板；把 FAB 挪回左侧面板内右下角 */
html.hgu-split .lf-fab,
body.hgu-split .lf-fab {
  right: auto;
  left: calc(min(50vw, 580px) - 16px);
  transform: translateX(-100%);
}
html.hgu-split .lf-fab:active,
body.hgu-split .lf-fab:active { transform: translateX(-100%) scale(0.96); }

/* ---------- 详情 / 揭晓 / 发布 抽屉 ---------- */
.lf-detail-drawer { display: flex; flex-direction: column; width: 100%; max-width: 600px; max-height: 92vh; }
.lf-detail-head { display: flex; align-items: center; gap: 10px; padding: 14px 16px; }
.lf-detail-kind { font-size: 13px; font-weight: 700; padding: 3px 10px; border-radius: 8px; color: #fff; }
.lf-detail-kind.is-lost { background: var(--lf-indigo); }
.lf-detail-kind.is-found { background: var(--lf-cyan); }
.lf-detail-head .modal-close { margin-left: auto; }
.lf-detail-body { padding: 0 16px 20px; overflow-y: auto; }
.lf-detail-title { font-size: 20px; margin: 6px 0; color: var(--lf-mid); }
.lf-detail-desc { color: #6b7280; font-size: 14px; line-height: 1.5; }
.lf-detail-publisher { display: flex; align-items: center; gap: 10px; margin: 12px 0; }
.lf-pub-avatar { width: 40px; height: 40px; border-radius: 50%; }
.lf-pub-name { font-weight: 600; color: var(--lf-mid); }
.lf-pub-meta { font-size: 12px; color: #8a909c; }
.lf-detail-info { background: rgba(120, 130, 160, .08); border-radius: 10px; padding: 10px 12px; }
.lf-info-row { display: flex; align-items: center; gap: 8px; font-size: 13px; color: #444; margin: 6px 0; }
.lf-info-row i { color: var(--lf-mid); }
.lf-detail-gallery { display: flex; gap: 8px; overflow-x: auto; margin: 12px 0; }
.lf-detail-gallery img { flex: 0 0 auto; width: min(72vw, 280px); height: auto; max-height: 380px; border-radius: 10px; object-fit: contain; }
.lf-detail-gallery.is-single img { height: auto; max-height: 320px; width: 100%; }
.lf-contact-card { margin-top: 14px; border: 1px dashed var(--lf-mid); border-radius: 12px; padding: 12px; background: rgba(42, 126, 220, .06); }
.lf-contact-title { font-weight: 700; margin-bottom: 8px; color: var(--lf-mid); }
.lf-contact-row { display: flex; align-items: center; gap: 10px; margin: 8px 0; }
.lf-contact-row i { color: var(--lf-mid); width: 18px; text-align: center; }
.lf-contact-row b { display: block; font-size: 12px; color: #8a909c; font-weight: 500; }
.lf-contact-row span { font-size: 14px; }
.lf-contact-cta { width: 100%; }
.lf-contact-tip { font-size: 13px; color: #6b7280; margin-bottom: 8px; }

/* 外站贴（校园集市）：发布者图标改圆角方形、联系方式区换成二维码 + 点击前往 */
.lf-pub-avatar-zanao { border-radius: 10px; object-fit: contain; background: #fff; padding: 2px; box-sizing: border-box; }
.lf-zanao-card { text-align: center; }
.lf-zanao-jump { width: 100%; margin-bottom: 12px; }
.lf-zanao-qr { display: block; margin: 0 auto; width: 100%; max-width: min(68vw, 260px); border-radius: 10px; background: #fff; cursor: zoom-in; }
/* 详情标题旁的「已找到 / 已认领」标记（后台标记 resolved 后前台可见） */
.lf-detail-done { display: inline-block; margin-left: 8px; padding: 2px 9px; border-radius: 10px; font-size: 12px; font-weight: 600; vertical-align: 2px; color: #fff; background: #2e9e5b; }
/* 列表卡片上的「校园集市」来源小标 */
.lf-card-source { display: inline-flex; align-items: center; gap: 4px; margin-left: 6px; font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 6px; color: #fff; background: #f59e0b; }
.lf-card-source img { width: 12px; height: 12px; border-radius: 3px; }

/* 待处理：发布者自己的帖子（有人验证联系方式 / 上传认领凭证）——置顶、红框、标签 */
.lf-card.is-pending { border-color: #e05656 !important; border-width: 2px; box-shadow: 0 2px 10px rgba(224, 86, 86, .2); }
.lf-card-pending { margin-left: 6px; font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 6px; color: #fff; background: #e05656; }
/* 详情底部：待处理信息（对方联系方式 / 认领凭证） */
.lf-detail-pending { margin-top: 14px; border: 1px solid rgba(224, 86, 86, .4); border-radius: 12px; padding: 12px; background: rgba(224, 86, 86, .06); }
.lf-detail-pending-title { font-weight: 700; color: #e05656; margin-bottom: 8px; }
.lf-pending-item { display: flex; align-items: center; gap: 10px; margin: 8px 0; }
.lf-pending-avatar { width: 36px; height: 36px; border-radius: 50%; flex: none; }
.lf-pending-info { min-width: 0; flex: 1; }
.lf-pending-name { font-weight: 600; color: var(--lf-mid); font-size: 14px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.lf-pending-tag { font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 6px; color: #e05656; background: rgba(224, 86, 86, .14); }
.lf-pending-row { display: flex; align-items: center; gap: 6px; font-size: 13px; color: #444; margin-top: 2px; }
.lf-pending-row i { color: var(--lf-mid); width: 16px; text-align: center; }
.lf-pending-img { margin-top: 6px; width: 100%; max-width: 240px; border-radius: 10px; cursor: pointer; }
/* 认领凭证条目：头像 + 昵称一行，图片单独一行 */
.lf-pending-item.lf-pending-claim { flex-direction: column; align-items: stretch; }
.lf-pending-head { display: flex; align-items: center; gap: 10px; }
.lf-pending-head .lf-pending-name { flex: 1; min-width: 0; }
/* 详情「待处理」灰色正文 */
.lf-detail-pending-body { font-size: 12.5px; color: #6b7280; margin: -2px 0 10px; line-height: 1.5; }
/* 认领者视角：已提交认领凭证（隐藏认领按钮） */
.lf-claim-done { margin-top: 10px; padding-top: 10px; border-top: 1px dashed rgba(224, 86, 86, .3); }
.lf-claim-done-head { display: flex; align-items: center; gap: 6px; font-weight: 600; color: var(--lf-mid); font-size: 14px; }
.lf-claim-done-head i { color: #2e9e5b; }
.lf-claim-done-img { margin-top: 8px; width: 100%; max-width: 240px; border-radius: 10px; cursor: pointer; }
/* 验证身份 / 提交认领弹窗：主文本与标签统一蓝色 */
.lf-reveal-drawer .lf-reveal-tip,
.lf-reveal-drawer .lf-field label { color: var(--lf-mid); }
.lf-reveal-drawer .lf-field-readonly small { color: rgba(42, 126, 220, .7); }
/* 联系方式 / 保管位置文本：灰色（原为页面主文本色） */
.lf-contact-row span { color: #6b7280; }
html[data-theme="dark"] .lf-contact-row span { color: #aab2c0; }

.lf-reveal-drawer { padding: 16px; width: 100%; max-width: 560px; max-height: 92vh; overflow-y: auto; }
.lf-reveal-head, .lf-publish-head { display: flex; align-items: center; gap: 8px; font-size: 17px; font-weight: 700; margin-bottom: 6px; }
/* 提交认领弹窗标题统一蓝色（与验证身份弹窗一致） */
.lf-claim-drawer .lf-reveal-head { color: var(--lf-mid); }
.lf-reveal-head .modal-close, .lf-publish-head .modal-close { margin-left: auto; }
.lf-reveal-tip, .lf-publish-note { font-size: 12px; color: #8a909c; margin: 6px 0 12px; }

.lf-field { margin: 12px 0; }
.lf-field label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; }
.lf-field label i { color: #e05656; font-style: normal; }
.lf-field label small { font-weight: 400; color: #9aa0ab; margin-left: 6px; }
.lf-field input, .lf-field textarea {
  width: 100%; padding: 10px; border: 1px solid var(--border);
  border-radius: 10px; font-size: 14px; font-family: inherit; box-sizing: border-box;
  background: transparent; color: var(--subtext);
  -webkit-appearance: none; appearance: none;
}
.lf-field input::placeholder, .lf-field textarea::placeholder { color: var(--subtext); opacity: .5; }
.lf-field-readonly input { background: rgba(120, 130, 160, .1); color: #6b7280; }
.lf-field-readonly small { display: block; color: #9aa0ab; font-size: 11px; margin-top: 4px; }

.lf-publish-toggle { display: flex; gap: 8px; margin: 10px 0; }
.lf-toggle { flex: 1; padding: 10px; border: 1.5px solid rgba(120, 130, 160, .3); border-radius: 10px; background: transparent; color: var(--subtext); font-size: 14px; font-weight: 600; cursor: pointer; }
.lf-toggle.active { background: rgba(42, 126, 220, .12); color: var(--lf-mid); border-color: var(--lf-mid); }

.lf-cat-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin: 0 0 8px; }
.lf-cat-head small { color: var(--subtext); font-size: 11px; opacity: .8; }
.lf-cat-required { color: #ef4444; font-style: normal; font-size: 12px; }
.lf-cat-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.lf-cat-chip { display: inline-flex; align-items: center; gap: 4px; padding: 4px 9px; border: 1px solid rgba(120, 130, 160, .3); border-radius: 999px; background: transparent; color: var(--subtext); font-size: 12px; cursor: pointer; }
.lf-cat-chip.active { background: rgba(42, 126, 220, .15); border-color: var(--lf-mid); color: var(--lf-mid); }
.lf-cat-chip i { font-size: 12px; }

/* 详情抽屉里的分类标签（原来详情根本不显示分类，用户点开后失去上下文） */
.lf-detail-cat { display: inline-flex; align-items: center; gap: 4px; margin-left: 4px; padding: 1px 7px; border-radius: 999px; background: rgba(42, 126, 220, .12); color: var(--lf-mid); font-size: 11px; }
.lf-detail-cat i { font-size: 10px; }

.lf-img-row { display: flex; gap: 8px; flex-wrap: wrap; }
.lf-img-item { position: relative; width: 72px; height: 72px; border-radius: 10px; overflow: hidden; }
.lf-img-item img { width: 100%; height: 100%; object-fit: cover; }
.lf-img-del { position: absolute; top: 2px; right: 2px; width: 20px; height: 20px; border: none; border-radius: 50%; background: rgba(0, 0, 0, .6); color: #fff; font-size: 13px; line-height: 1; cursor: pointer; }
.lf-img-add { display: flex; align-items: center; justify-content: center; width: 72px; height: 72px; box-sizing: border-box; text-align: center; border: 1px dashed rgba(120, 130, 160, .5); border-radius: 10px; color: #9aa0ab; font-size: 22px; cursor: pointer; }
/* file input 必须彻底移出 flex 布局，否则会占一个槽位把相机图标挤偏；图标 line-height 收紧避免视觉偏移 */
.lf-img-add > input { display: none !important; }
.lf-img-add > i { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; line-height: 1; }
/* 相机图标固定灰色：发布页的 label i 主题色会把它染红（需求：改回灰色） */
.lf-img-add i { color: #9aa0ab; }

.lf-pub-opt { display: flex; gap: 8px; margin: 4px 0 8px; }
/* 发布页顶部的「寻物启事 / 失物招领」切换：与表单里「联系方式 / 保管位置」同一套 .lf-toggle 外观 */
.lf-pub-types { display: flex; gap: 8px; margin: 0 0 14px; }
.lf-radio { display: flex; align-items: center; gap: 5px; font-size: 13px; }
.lf-toggle[data-mode] { flex: 1; }

.lf-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; width: 100%; padding: 11px; border: none; border-radius: 10px; font-size: 14px; font-weight: 600; cursor: pointer; margin-top: 8px; }
.lf-btn-primary { background: var(--lf-mid); color: #fff; }
.lf-btn-danger { background: rgba(220, 80, 80, .12); color: #d95454; }

.lf-loading, .lf-empty { text-align: center; color: #9aa0ab; padding: 40px 16px; }
.lf-empty i { font-size: 32px; display: block; margin-bottom: 10px; }
.lf-empty small { display: block; color: #b9bdc7; margin-top: 6px; }
.lf-detail-loading { padding: 60px; text-align: center; color: #9aa0ab; }

/* ---------- 发布流程：「长按定位」提示服务卡（复用 home-location-card 骨架） ---------- */
.lf-hint-card { align-items: start; }
.lf-hint-body { grid-column: 1 / -1; display: flex; align-items: center; gap: 10px; min-width: 0; }
.lf-hint-icon { width: 30px; height: 30px; object-fit: contain; flex: none; }
.lf-hint-text { flex: 1; font-weight: 600; line-height: 1.3; color: var(--text); }
/* 位置信息卡内注入的「我丢失了 / 我捡到了」按钮：靛蓝 / 青蓝 */
.home-location-action.lf-lp-pick[data-pick="lost"] { background: rgba(79, 70, 229, .12); border: 1px solid #4F46E5; color: #4F46E5; }
.home-location-action.lf-lp-pick[data-pick="found"] { background: rgba(6, 182, 212, .12); border: 1px solid #06B6D4; color: #06B6D4; }

/* ---------- 发布页：隐藏头像昵称开关 ---------- */
.lf-switch { position: relative; display: inline-block; width: 44px; height: 24px; flex: none; }
.lf-switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.lf-switch-track { position: absolute; inset: 0; border-radius: 999px; background: rgba(120, 130, 160, .35); transition: background .2s; }
.lf-switch-track::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px;
  border-radius: 50%; background: #fff; transition: transform .2s; box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
}
.lf-switch input:checked + .lf-switch-track { background: var(--lf-mid); }
.lf-switch input:checked + .lf-switch-track::after { transform: translateX(20px); }

/* 暗色模式：详情 / 发布页里的灰色正文此前写死浅色灰，暗色底上几乎不可见，统一提亮 */
html[data-theme="dark"] .lf-detail-desc,
html[data-theme="dark"] .lf-contact-tip,
html[data-theme="dark"] .lf-reveal-tip,
html[data-theme="dark"] .lf-publish-note { color: #9aa3b2; }

html[data-theme="dark"] .lf-pub-meta,
html[data-theme="dark"] .lf-contact-row b,
html[data-theme="dark"] .lf-field label small,
html[data-theme="dark"] .lf-field-readonly small,
html[data-theme="dark"] .lf-img-add { color: #8b93a3; }

html[data-theme="dark"] .lf-info-row { color: #c7ccd6; }
html[data-theme="dark"] .lf-field-readonly input,
html[data-theme="dark"] .lf-detail-loading,
html[data-theme="dark"] .lf-loading,
html[data-theme="dark"] .lf-empty { color: #8b93a3; }
html[data-theme="dark"] .lf-empty small { color: #767d8c; }

/* ============================================================
   教室课表页（#classroom-page）
   顶部教学楼选择器 + 按楼层分卡的教室胶囊列表。
   状态配色：空闲=青蓝(--study-cyan)、即将占用/即将上课=橙、被占用/正在上课=红。
   ============================================================ */
/* 教学楼选择卡片：一个卡片里多行平铺教学楼，不再左右滑动 */
.classroom-building-card {
  width: 100%;
  max-width: 430px;
  margin: 0 auto 12px;
  padding: 12px 12px 13px;
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-2xl);
  box-shadow: var(--hgu-shadow-card);
}
.classroom-building-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.classroom-building-chip {
  flex: 0 0 auto;
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 15px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-pill);
  background: var(--hgu-surface-solid);
  color: var(--subtext);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.16s, border-color 0.16s, color 0.16s;
}
.classroom-building-chip:active { transform: scale(0.97); }
.classroom-building-chip.active {
  background: var(--study-cyan);
  border-color: var(--study-cyan);
  color: #fff;
}
html[data-theme="dark"] .classroom-building-chip { background: rgba(255, 255, 255, 0.08); }
html[data-theme="dark"] .classroom-building-chip.active { background: var(--study-cyan); color: #fff; }

.classroom-floor-list {
  width: 100%;
  max-width: 430px;
  margin: 0 auto;
}

.classroom-floor-card {
  background: var(--hgu-surface-glass);
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-2xl);
  box-shadow: var(--hgu-shadow-card);
  margin-bottom: 12px;
  padding: 12px 14px 14px;
}

.classroom-floor-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.classroom-floor-card-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.25;
}
.classroom-floor-card-meta {
  font-size: 12px;
  color: var(--subtext);
}

.classroom-floor-room-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* 教室胶囊：日程图标 + 教室号 */
.classroom-room-capsule {
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 13px;
  border: 1px solid var(--hgu-border-soft);
  border-radius: var(--hgu-radius-pill);
  background: rgba(255, 255, 255, 0.38);
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.2;
  cursor: pointer;
  transition: transform 0.16s, border-color 0.16s, background 0.16s;
}
.classroom-room-capsule:active { transform: scale(0.96); }
.classroom-room-capsule i { font-size: 12px; }

.classroom-room-capsule.is-free {
  color: var(--study-cyan);
  border-color: rgba(var(--study-cyan-rgb), 0.38);
}
.classroom-room-capsule.is-soon {
  color: #e07a12;
  border-color: rgba(224, 122, 18, 0.42);
  background: rgba(255, 152, 0, 0.1);
}
.classroom-room-capsule.is-busy {
  color: #e5484d;
  border-color: rgba(229, 72, 77, 0.42);
  background: rgba(229, 72, 77, 0.1);
}

html[data-theme="dark"] .classroom-room-capsule { background: rgba(255, 255, 255, 0.06); }
html[data-theme="dark"] .classroom-room-capsule.is-soon { color: #ffb74d; background: rgba(255, 152, 0, 0.16); }
html[data-theme="dark"] .classroom-room-capsule.is-busy { color: #ff6b70; background: rgba(229, 72, 77, 0.18); }

/* 教室课表页底部官方跳转卡片：沿用搜索页那套青蓝描边。
   .official-links-card 基础样式是蓝色 rgba(0,123,255,.5)，这里换成页面主题的青蓝，
   与标题栏、房间胶囊同一色系（--study-blue-border 在 #classroom-page 上已重定义为
   rgba(var(--study-cyan-rgb), .68)，明暗两套主题都会跟着走）。 */
.classroom-official-links {
  width: 100%;
  max-width: 430px;
  margin: 18px auto 0;
  border-color: var(--study-blue-border);
}

/* 教室课表页空态：加载中 / 无数据 / 未同步 */
.classroom-empty-state {
  width: 100%;
  max-width: 430px;
  margin: 0 auto;
  padding: 34px 16px;
  text-align: center;
  color: var(--subtext);
}
.classroom-empty-state i {
  font-size: 34px;
  opacity: 0.35;
  color: var(--study-cyan);
}
.classroom-empty-state p {
  margin: 10px 0 0;
  font-size: 14px;
  color: var(--text);
}
.classroom-empty-state small {
  display: block;
  margin-top: 6px;
  font-size: 12px;
  opacity: 0.8;
}

/* 两份数据（教室课表 / 空闲教室占用）都没有的教室：不猜"空闲"，用灰调区分 */
.classroom-room-capsule.is-unknown {
  color: var(--subtext);
  border-color: var(--hgu-border-soft);
  opacity: 0.72;
}

/* ============================================================
   教务「未缴学费」提示条
   成绩 / 培养方案 / 公选课页顶部；由 APP 检测到教务欠费拦截时下发。
   ============================================================ */
.edu-unpaid-notice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 10px 0 0;
  padding: 12px 14px;
  border: 1px solid rgba(230, 126, 34, 0.42);
  border-radius: var(--hgu-radius-xl);
  background: rgba(255, 152, 0, 0.12);
  color: #b25f04;
  font-size: 13px;
  line-height: 1.6;
}
.edu-unpaid-notice[hidden] { display: none; }
.edu-unpaid-notice i {
  flex-shrink: 0;
  margin-top: 2px;
  color: #e67e22;
  font-size: 14px;
}
html[data-theme="dark"] .edu-unpaid-notice {
  color: #ffb74d;
  border-color: rgba(255, 183, 77, 0.42);
  background: rgba(255, 152, 0, 0.16);
}
html[data-theme="dark"] .edu-unpaid-notice i { color: #ffb74d; }
.edu-unpaid-notice-text { display: block; min-width: 0; flex: 1; }
.edu-unpaid-notice-origin { display: block; font-weight: 600; }
.edu-unpaid-notice-tail { display: block; margin-top: 2px; opacity: 0.88; }

/* ============================================
   赞助页（我的 → 关于下方的「赞助」）
   ============================================
   结构见 index.html 的 #sponsor-page，渲染见 js/sponsor.js。
   顶部是仿爱发电嵌入卡片的**自绘**版本（官方 iframe 跨域，改不了内部配色），
   下面依次是赞助目标卡片和按月分组的赞助者列表。
   全部用站点现有的 token（--text / --subtext / --hgu-surface-glass / --hgu-radius-*），
   不在暗色模式下另写一套颜色 —— 变量本身已经随主题翻转了。
*/
/* ---------- 紫色主题（整页主文本色） ----------
   爱发电的品牌色是紫，整页主色跟着走，跟顶部创作者卡片统一。
   做法是**在页面节点上直接覆盖 `--text`**：页面里所有 var(--text)（标题、图标、
   金额、百分比、进度条、达成边框、空态）一次性变紫，不用一处一处改 ——
   这是本站既有的页面级覆盖做法（校历页 cyan、饭点页粉色、社团页 --club-purple）。
   ⚠️ 两个坑：
   ① 子页面标题栏运行时会被搬进 .tools-fixed-header-layer，**不继承** #sponsor-page
      的变量，所以下面必须单独补 [data-header-for="sponsor-page"]，漏了就是
      「紫内容 + 绿标题」；
   ② 变量值取自原来 hero 卡片用的那对紫（亮 #6d4bcb / 暗 #c9b8fb），
      亮色下够深才压得住浅玻璃底，暗色下要浅才看得清。 */
:root {
  --sponsor-purple: #6d4bcb;
  --sponsor-purple-rgb: 109, 75, 203;
}
html[data-theme="dark"] {
  --sponsor-purple: #c9b8fb;
  --sponsor-purple-rgb: 201, 184, 251;
}

#sponsor-page {
  --text: var(--sponsor-purple);
  --text-light: rgba(var(--sponsor-purple-rgb), .14);
}
#sponsor-page .sub-page-title,
#sponsor-page .sub-page-back { color: var(--sponsor-purple); }

/* 标题栏被搬进固定层以后，页面级变量够不着 —— 这里再写一遍 */
.tools-fixed-header-layer > [data-header-for="sponsor-page"] {
  --text: var(--sponsor-purple);
  --text-light: rgba(var(--sponsor-purple-rgb), .14);
}
.tools-fixed-header-layer > [data-header-for="sponsor-page"] .sub-page-title,
.tools-fixed-header-layer > [data-header-for="sponsor-page"] .sub-page-back {
  color: var(--sponsor-purple);
}

.sponsor-page-content {
  gap: 14px;
  align-items: stretch;
}

.sponsor-loading {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 60px 0;
  color: var(--subtext);
  font-size: 13px;
  opacity: .8;
}
.sponsor-loading i { font-size: 22px; color: var(--text); }

.sponsor-empty {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 48px 20px;
  text-align: center;
  background: var(--hgu-surface-glass);
  border: 1px dashed var(--text);
  border-radius: var(--hgu-radius-polished);
  color: var(--subtext);
}
.sponsor-empty > i { font-size: 26px; color: var(--text); opacity: .85; }
.sponsor-empty p { margin: 0; font-size: 15px; font-weight: 600; color: var(--text); }
.sponsor-empty span { font-size: 12px; opacity: .85; line-height: 1.6; }
.sponsor-empty-inline { padding: 28px 16px; }
.sponsor-retry-btn {
  margin-top: 6px;
  padding: 8px 18px;
  border-radius: var(--hgu-radius-pill);
  border: 1px solid var(--text);
  background: transparent;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
}

/* ---------- 顶部创作者卡片（毛玻璃卡 + 爱发电紫点缀） ---------- */
/* 卡片本身仍是站点统一的玻璃拟态，只有**边框、图标、文字、按钮**走爱发电紫
   （#946ce6 家族）。⇒ 底色不写死，继续用 --hgu-surface-glass，亮/暗主题自动翻转。
   ⚠️ 紫色不写成单一 hex：亮色下要深一点（#6d4bcb）才压得住浅底，
   暗色下要浅一点（#c9b8fb）才看得清 —— 每处都配了一条 dark 覆盖。 */
.sponsor-hero {
  width: 100%;
  padding: 16px 16px 14px;
  border-radius: var(--hgu-radius-polished);
  border: 1px solid rgba(148, 108, 230, .48);
  background:
    radial-gradient(120% 100% at 100% 0%, rgba(148, 108, 230, .17) 0%, rgba(148, 108, 230, 0) 62%),
    var(--hgu-surface-glass);
  box-shadow: var(--hgu-shadow-card);
  backdrop-filter: blur(var(--hgu-blur-3xl));
  -webkit-backdrop-filter: blur(var(--hgu-blur-3xl));
  display: flex;
  flex-direction: column;
  gap: 12px;
}
html[data-theme="dark"] .sponsor-hero {
  border-color: rgba(185, 160, 245, .44);
  background:
    radial-gradient(120% 100% at 100% 0%, rgba(148, 108, 230, .26) 0%, rgba(148, 108, 230, 0) 62%),
    var(--hgu-surface-glass);
}
.sponsor-hero-main {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.sponsor-hero-avatar {
  width: 52px;
  height: 52px;
  border-radius: var(--hgu-radius-round);
  overflow: hidden;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(148, 108, 230, .12);
  border: 1px solid rgba(148, 108, 230, .5);
  color: #6d4bcb;
  font-size: 20px;
}
html[data-theme="dark"] .sponsor-hero-avatar {
  border-color: rgba(185, 160, 245, .45);
  color: #c9b8fb;
}
.sponsor-hero-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sponsor-hero-info { min-width: 0; flex: 1; }
.sponsor-hero-name {
  font-size: 16px;
  font-weight: 600;
  color: #6d4bcb;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
html[data-theme="dark"] .sponsor-hero-name { color: #c9b8fb; }
.sponsor-hero-meta {
  margin-top: 4px;
  font-size: 12px;
  color: rgba(109, 75, 203, .78);
}
html[data-theme="dark"] .sponsor-hero-meta { color: rgba(201, 184, 251, .8); }
.sponsor-hero-intro {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.7;
  color: rgba(109, 75, 203, .86);
  white-space: pre-wrap;
  word-break: break-word;
}
html[data-theme="dark"] .sponsor-hero-intro { color: rgba(201, 184, 251, .84); }
.sponsor-hero-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 40px;
  padding: 0 16px;
  border-radius: var(--hgu-radius-pill);
  border: 1px solid rgba(148, 108, 230, .55);
  background: linear-gradient(135deg, #9d76ea 0%, #7a55d8 100%);
  color: #fff;              /* 始终白色，不跟主题翻转 */
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  box-shadow: 0 6px 16px rgba(124, 92, 214, .28);
  transition: transform .18s ease, box-shadow .18s ease, filter .18s ease;
}
html[data-theme="dark"] .sponsor-hero-btn {
  border-color: rgba(185, 160, 245, .5);
  background: linear-gradient(135deg, #8a63e0 0%, #6a45c8 100%);
  box-shadow: 0 6px 16px rgba(0, 0, 0, .3);
}
.sponsor-hero-btn-icon {
  width: 16px;
  height: 16px;
  object-fit: contain;
  display: block;
}
.sponsor-hero-btn:hover { filter: brightness(1.06); }
.sponsor-hero-btn:active { transform: scale(.98); box-shadow: 0 3px 10px rgba(124, 92, 214, .24); }

/* ---------- 分区标题 ---------- */
.sponsor-section { width: 100%; display: flex; flex-direction: column; gap: 10px; }
.sponsor-section-head {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 2px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
}
.sponsor-section-head > i { font-size: 13px; opacity: .9; }
.sponsor-section-extra {
  margin-left: auto;
  font-size: 11.5px;
  font-weight: 400;
  color: var(--subtext);
  opacity: .75;
}

/* ---------- 目标卡片 ---------- */
.sponsor-goal-list { display: flex; flex-direction: column; gap: 10px; }
.sponsor-goal {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 13px 14px;
  border-radius: var(--hgu-radius-polished);
  background: var(--hgu-surface-glass);
  border: 1px solid rgba(var(--sponsor-purple-rgb), .34);
  box-shadow: var(--hgu-shadow-card);
}
.sponsor-goal.is-done { border-color: var(--sponsor-purple); }
/* 图标 44×44 —— 与首页驿站图标（.station-icon-wrap）同尺寸，透明底、contain 不变形 */
.sponsor-goal-icon {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: var(--hgu-radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: transparent;
  color: var(--text);
  font-size: 18px;
}
.sponsor-goal-icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  border-radius: var(--hgu-radius-md);
}
.sponsor-goal-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.sponsor-goal-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}
/* 标题 + 周期标签：标签跟在名字后面，不能把整行顶宽 */
.sponsor-goal-title {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.sponsor-goal-name {
  /* 必须能缩：名字是 nowrap，不给 flex/min-width 会把整张卡片顶出去 */
  flex: 0 1 auto;
  min-width: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--sponsor-purple);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 周期标签：单次 / 每月 / 每年 */
.sponsor-goal-tag {
  flex: 0 0 auto;
  padding: 0 6px;
  border-radius: var(--hgu-radius-xs);
  border: 1px solid rgba(var(--sponsor-purple-rgb), .4);
  background: rgba(var(--sponsor-purple-rgb), .1);
  color: var(--sponsor-purple);
  font-size: 10.5px;
  font-weight: 600;
  line-height: 16px;
  white-space: nowrap;
}
.sponsor-goal-amount {
  margin-left: auto;
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.sponsor-goal-desc {
  font-size: 12px;
  line-height: 1.6;
  color: var(--subtext);
  opacity: .78;
}
.sponsor-goal-bar {
  width: 100%;
  height: 6px;
  border-radius: var(--hgu-radius-pill);
  background: rgba(128, 128, 128, .22);
  overflow: hidden;
  margin-top: 2px;
}
.sponsor-goal-bar > i {
  display: block;
  height: 100%;
  border-radius: var(--hgu-radius-pill);
  background: var(--text);
  transition: width .45s cubic-bezier(.22, .9, .3, 1);
}
.sponsor-goal-bar > i.is-done {
  background: linear-gradient(90deg, var(--sponsor-purple), #a97bee);
}
.sponsor-goal-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  color: var(--subtext);
  opacity: .8;
  line-height: 1.5;
  min-width: 0;
}
.sponsor-goal-foot > span:first-child {
  /* 长周期文案（"2026 年 10 月 · 还差 ¥1,234"）只许缩、不许顶宽 */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sponsor-goal-percent {
  margin-left: auto;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  opacity: .95;
}

/* ---------- 赞助者（按月分组） ---------- */
.sponsor-month-list { display: flex; flex-direction: column; gap: 12px; }
.sponsor-month {
  border-radius: var(--hgu-radius-polished);
  background: var(--hgu-surface-glass);
  border: 1px solid rgba(var(--sponsor-purple-rgb), .34);
  box-shadow: var(--hgu-shadow-card);
  overflow: hidden;
}
.sponsor-month-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  background: var(--hgu-surface-glass-soft);
  border-bottom: 1px solid rgba(var(--sponsor-purple-rgb), .26);
}
.sponsor-month-label { font-size: 12.5px; font-weight: 600; color: var(--text); }
.sponsor-month-count { margin-left: auto; font-size: 11px; color: var(--subtext); opacity: .75; }
.sponsor-people { display: flex; flex-direction: column; }
.sponsor-person {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  min-height: 46px;
}
.sponsor-person + .sponsor-person { border-top: 1px solid rgba(var(--sponsor-purple-rgb), .16); }
.sponsor-person-avatar {
  width: 34px;
  height: 34px;
  border-radius: var(--hgu-radius-round);
  overflow: hidden;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(128, 128, 128, .16);
  color: var(--subtext);
  font-size: 13px;
}
.sponsor-person-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sponsor-person-name {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--subtext);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sponsor-person-amount {
  flex-shrink: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* 窄屏（≤380px）：标题 + 周期标签独占一行，金额换到下一行右对齐。
   不加这条的话「服务器与域名续费」这种 8 字标题在 360 宽的手机上会被压成 5 个字加省略号 ——
   加了周期标签之后更容易挤，这锅不能算到标签头上。 */
@media (max-width: 380px) {
  .sponsor-goal-head { flex-wrap: wrap; row-gap: 2px; }
  .sponsor-goal-title { flex: 1 1 100%; }
}

@media (max-width: 360px) {
  .sponsor-hero-avatar { width: 46px; height: 46px; }
  .sponsor-person { padding: 8px 12px; }
}
