/* ============================================================
 SevenJohn · 系统样式表
 设计语言：编辑风（editorial）——衬线大标题、近黑强调色、
 发丝边框、零阴影平面、克制减速动效。参照 refero 式"真实产品"质感。
 ============================================================ */

/* 基础平滑滚动 */
html {
  scroll-behavior: smooth;
}

/* 字体排版系统 */
body {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "PingFang SC",
    "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  font-variant-numeric: tabular-nums;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* 展示衬线：只用于 Hero 与区块大标题（拉丁走 Georgia，中文走宋体） */
.font-display {
  font-family: Georgia, "Times New Roman", "Songti SC", "STSong", "SimSun", serif;
  font-weight: 400;
  letter-spacing: -0.01em;
}

h1, h2, h3 {
  text-wrap: balance;
  letter-spacing: -0.02em;
}

/* 发丝边框令牌 */
:root {
  --hairline: rgba(18, 30, 60, 0.10);
  --hairline-strong: rgba(18, 30, 60, 0.18);
  /* 丝滑入场曲线：无过冲的柔和弹簧（现代对话框动效标准答案） */
  --ease-swift: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-exit: cubic-bezier(0.4, 0, 0.2, 1);
}
.dark {
  --hairline: rgba(255, 255, 255, 0.10);
  --hairline-strong: rgba(255, 255, 255, 0.20);
}

/* 吸顶导航毛玻璃 */
.site-nav {
  /* ❗与控件层同一套配方写法（blur 在前、saturate 用倍数）：原来写的是亮色时代的
     saturate(180%) blur(20px)，值差不多但写法不统一，读代码时分不清是不是两套体系 */
  backdrop-filter: blur(20px) saturate(1.5);
  -webkit-backdrop-filter: blur(20px) saturate(1.5);
}

/* 二级导航「更多」下拉（原生 details 开合，关闭逻辑在 app.js） */
.nav-more { position: relative; }
.nav-more > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
}
.nav-more > summary::-webkit-details-marker { display: none; }
.nav-more > summary::after {
  content: "▾";
  margin-left: 0.25rem;
  font-size: 0.625rem;
  opacity: 0.7;
}
.nav-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 0.65rem);
  z-index: 50;
  min-width: 8.5rem;
  padding: 0.3rem;
  display: flex;
  flex-direction: column;
  border-radius: 0.75rem;
  border: 1px solid rgba(0, 0, 0, 0.08);
  background: #ffffff;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
}
.dark .nav-menu {
  background: #161617;
  border-color: rgba(255, 255, 255, 0.12);
}
.nav-menu a {
  padding: 0.4rem 0.6rem;
  border-radius: 0.5rem;
  white-space: nowrap;
  color: #86868b;
}
.nav-menu a:hover {
  background: rgba(0, 0, 0, 0.05);
  color: #1d1d1f;
}
.dark .nav-menu a:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #ffffff;
}

/* 项目卡与详情弹窗共用：我的角色 / 周期 / 技术难点与解法 */
.project-facts {
  display: grid;
  gap: 0.4rem;
  padding: 0.875rem 1rem;
  border-radius: 0.75rem;
  border: 1px solid var(--hairline);
  background: rgba(0, 0, 0, 0.02);
  font-size: 0.8125rem;
  line-height: 1.65;
}
.dark .project-facts { background: rgba(255, 255, 255, 0.03); }
.project-facts .pf-row {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: 0.75rem;
}
.project-facts .pf-k {
  color: #86868b;
  font-size: 0.75rem;
  padding-top: 0.1rem;
}
.project-facts .pf-v { color: #1d1d1f; }
.dark .project-facts .pf-v { color: #d2d2d7; }

/* 键盘无障碍跳转链接：默认视觉隐藏，Tab 聚焦时浮现 */
.skip-link {
  position: absolute;
  left: 1rem;
  top: -3rem;
  z-index: 50;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  background: #1d1d1f;
  color: #ffffff;
  font-size: 0.75rem;
  transition: top 0.18s ease-out;
}
.skip-link:focus {
  top: 0.75rem;
}

/* 键盘可访问性焦点环 */
:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
  border-radius: 0.375rem;
}

/* 极简自定义滚动条 */
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: #c6c8ce;
  border-radius: 9999px;
}
.dark ::-webkit-scrollbar-thumb {
  background: #3a3a3c;
}
::-webkit-scrollbar-thumb:hover {
  background: #86868b;
}

/* 主按钮：近黑实心，无渐变无高光无缩放 */
.btn-primary {
  background: #1d1d1f;
  color: #ffffff;
  border-radius: 0.625rem;
  font-weight: 500;
  transition: background-color 0.15s ease;
}
.btn-primary:hover {
  background: #000000;
}
.btn-primary:active {
  transform: scale(0.98);
}
.dark .btn-primary {
  background: #f5f5f7;
  color: #1d1d1f;
}
.dark .btn-primary:hover {
  background: #ffffff;
}

/* 次按钮：发丝边框 + 透明底 */
.btn-secondary {
  border-radius: 0.625rem;
  font-weight: 500;
  border: 1px solid var(--hairline-strong);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.btn-secondary:hover {
  border-color: var(--hairline-strong);
  background: rgba(18, 30, 60, 0.04);
}
.dark .btn-secondary:hover {
  background: rgba(255, 255, 255, 0.06);
}
.btn-secondary:active {
  transform: scale(0.98);
}

/* 卡片：平面 + 发丝边框，无阴影无上浮 */
.bento-card {
  border-radius: 0.75rem;
  transition: border-color 0.2s ease;
}
.dark .bento-card {
  background: #141415;
  border: 1px solid var(--hairline);
}
.dark .bento-card:hover {
  border-color: var(--hairline-strong);
}
html:not(.dark) .bento-card {
  background: #ffffff;
  border: 1px solid var(--hairline);
}
html:not(.dark) .bento-card:hover {
  border-color: var(--hairline-strong);
}

/* 数字：等宽 + 常规字重（编辑风不做巨型描边数字） */
.stat-number {
  letter-spacing: -0.02em;
  font-weight: 600;
  line-height: 1;
}

/* 弹窗：柔和弹簧进出场（无过冲，出比入快） */
.modal-overlay {
  animation: fade-in 0.22s var(--ease-swift);
}
.modal-panel {
  animation: sheet-in 0.35s var(--ease-swift);
}

@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes sheet-in {
  from { opacity: 0; transform: translateY(14px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}

/* 弹窗关闭（加速退出） */
.modal-overlay.is-closing {
  animation: fade-out 0.18s var(--ease-exit) both;
}
.modal-overlay.is-closing .modal-panel {
  animation: sheet-out 0.18s var(--ease-exit) both;
}
@keyframes fade-out {
  to { opacity: 0; }
}
@keyframes sheet-out {
  to { opacity: 0; transform: translateY(10px) scale(0.98); }
}

/* ============================================================
   动效编排：减速入场、错峰浮现、导航滚动状态
   仅动画 transform / opacity，保证合成器 60fps
   ============================================================ */

/* Hero 入场：首屏元素级联升起，纯 CSS 无 JS 依赖 */
@keyframes hero-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
.hero-anim {
  animation: hero-rise 0.5s var(--ease-swift) both;
  animation-delay: calc(var(--i, 0) * 70ms);
}

/* 滚动浮现：朴素淡入上移（无模糊、无缩放） */
.js .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.5s var(--ease-swift), transform 0.5s var(--ease-swift);
  transition-delay: var(--reveal-delay, 0ms);
}
.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}
/* 封面图随卡片浮现做 1.02 → 1 微缩放 */
.js .reveal .reveal-img {
  transform: scale(1.02);
  transition: transform 0.55s var(--ease-swift);
}
.js .reveal.is-visible .reveal-img {
  transform: scale(1);
}

/* 项目卡封面统一排版：五张卡同一比例（1298:667 实拍比例）、同一裁切，高度不再随图飘 */
/* 小块包裹型：图不全高（限高 480），顶对齐裁切，嵌在卡片留白内的圆角盒里（见 .cover-box） */
.cover-img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 480px;
  object-fit: cover;
  object-position: top;
}
/* 卡片上的介绍视频（FileButler / NetOps / Fluxion）：16:9 完整可见，控制条不许被裁 */
.cover-video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: #000;
}
/* 视频海报态的播放键覆盖层（video-gate.js 建层）：居中圆钮，与液态玻璃气质同族 */
.video-play-gate {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.30) 0%, rgba(0, 0, 0, 0) 40%);
}
.cover-box { position: relative; }   /* 覆盖层的定位锚（cover-box 原本无定位） */
.video-play-btn {
  width: 3.75rem;
  height: 3.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  background: rgba(8, 10, 16, 0.55);
  color: rgba(240, 245, 252, 0.92);
  cursor: pointer;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.35);
  transition: transform 0.25s var(--ease-swift), background 0.25s ease;
}
.video-play-btn:hover { transform: scale(1.06); background: rgba(8, 10, 16, 0.72); }
.video-play-btn svg { width: 1.6rem; height: 1.6rem; }
/* ===== 一屏一产品（翻页箭头的"一页"= 完整一张卡）：桌面且视口足够高时，
   卡限高视口、文字区收紧、封面弹性吃剩余空间（object-fit 裁切）；
   矮视口自动退回自由滚动 ===== */
@media (min-width: 640px) and (min-height: 760px) {
  #products > article.bento-card {
    display: flex;
    flex-direction: column;
    height: calc(100vh - 88px);       /* 64 顶部导航 + 24 呼吸：恰好一屏 */
  }
  #products > article.bento-card > div:first-child {  /* 文字区收紧 */
    padding: 1.75rem 1.75rem 1.25rem;
  }
  #products > article.bento-card > div:last-child {   /* 封面容器：吃剩余高度 */
    flex: 1 1 0;
    min-height: 170px;
    display: flex;
    flex-direction: column;
  }
  #products > article.bento-card .cover-box {
    flex: 1 1 0;
    min-height: 0;
    display: flex;
  }
  #products > article.bento-card .cover-img {
    height: 100%;
    max-height: none;
  }
  /* 一屏模式下视频改为 contain：完整可见 + 控制条贴底，黑边兜底 */
  #products > article.bento-card .cover-video {
    height: 100%;
    flex: 1 1 0;
    min-height: 0;
    aspect-ratio: auto;
    object-fit: contain;
  }
}

/* 导航滚动状态：顶部无边框，下滑后浮现边框 */
header.site-header {
  transition: border-color 0.3s ease, background-color 0.3s ease;
}
header.site-header:not(.is-scrolled) {
  border-bottom-color: transparent;
}

/* 背景光粒子画布：固定铺满、置于页面内容之下、不拦截任何交互 */
#particle-canvas {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

/* ============================================================
   首屏：文案靠上、背景星河铺满全屏
   ============================================================ */
#home {
  position: relative;
  min-height: calc(100svh - 48px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  overflow: hidden;
  padding-top: max(5.5rem, 14svh);
  padding-bottom: 5rem;
}
#home > *:not(.hero-veil):not(.hero-who) {
  position: relative;
  z-index: 2;
  max-width: 56rem;
}
/* 叙事区恒深色：两主题下的文字与按钮统一成深色底上的配色 */
#home h1 { color: #f5f7fa !important; }
#home #site-subtitle { color: #cfe0ff !important; }   /* 副标题接手原来第二行标题的强调色 */
#home p { color: #aab5c9 !important; }
/* 亮线网络会穿透文字：深色光晕把字和线条隔开 */
#home h1, #home p {
  text-shadow: 0 1px 2px rgba(3, 6, 14, 0.85), 0 0 22px rgba(3, 6, 14, 0.6);
}
#home .btn-primary { background: #f5f5f7; color: #1d1d1f; }
#home .btn-primary:hover { background: #ffffff; }
#home a:not(.btn-primary) { color: #c8d2e2 !important; }
#home .font-bold { color: #f5f7fa !important; }
#home .rounded-full { border-color: rgba(255, 255, 255, 0.22) !important; }
/* 文字可读性遮罩：3D 舞台在画布上，文字要靠它压住背景 */
.hero-veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 62% 52% at 50% 44%,
      rgba(5, 7, 12, 0.58) 0%, rgba(5, 7, 12, 0.26) 58%, rgba(5, 7, 12, 0) 82%),
    linear-gradient(to bottom,
    rgba(5, 7, 12, 0.62) 0%, rgba(5, 7, 12, 0.36) 20%,
    rgba(5, 7, 12, 0.12) 36%, rgba(5, 7, 12, 0) 52%,
    rgba(5, 7, 12, 0) 66%, rgba(5, 7, 12, 0.30) 86%,
    rgba(5, 7, 12, 0.70) 100%);
}
/* 头像卡挪到左下角：像 igloo 的角标，不占舞台中心；整卡可点进「关于我」 */
#home .hero-who {
  position: absolute;
  left: 26px;
  bottom: 22px;
  z-index: 2;
  margin: 0 !important;
  padding-top: 0 !important;
  cursor: pointer;
  border-radius: 14px;
  transition: background 0.25s ease, transform 0.25s ease;
}
#home .hero-who:hover {
  background: rgba(255, 255, 255, 0.05);
  transform: translateY(-2px);
}
#home .hero-who-more {
  transition: transform 0.25s ease;
}
#home .hero-who:hover .hero-who-more {
  transform: translateX(3px);
  color: #f5f7fa !important;
}
/* CTA 里的音乐入口：保留但降权，弱边框幽灵样式 */
#home .hero-ghost {
  background: transparent;
  border: 1px solid rgba(200, 210, 226, 0.28);
  color: #aab5c9 !important;
  /* ❗形状与 .btn-primary / .btn-secondary 同档（0.625rem）。原来没写圆角，是个直角矩形，
     与旁边的「浏览项目」并排时一个圆润一个方正（2026-09-30 用户指出） */
  border-radius: 0.625rem;
  /* glass-spec 的 ::before 要贴着宿主定位；这里是 static 按钮，必须显式给 */
  position: relative;
  transition: color 0.25s ease, border-color 0.25s ease;
}
#home .hero-ghost:hover {
  color: #e8eefc !important;
  border-color: rgba(200, 210, 226, 0.55);
}
/* 移动端：veil 中央暗晕覆盖比例按竖屏收窄，第二行标题提亮补对比 */
@media (max-width: 639px) {
  #home #site-subtitle {
    color: #e3edff !important;
  }
  /* ❗左下角标里的文字也压在亮线网络上（原来只给 h1/p 加了阴影，角标是 div 吃不到），
     移动端实测「做本地 AI 应用与桌面工具」被亮线穿过时发白难读 */
  #home h1, #home p,
  #home .hero-who, #home .hero-who * {
    text-shadow: 0 1px 3px rgba(3, 6, 14, 0.95), 0 0 26px rgba(3, 6, 14, 0.8);
  }
  .hero-veil {
    background:
      radial-gradient(ellipse 88% 46% at 50% 40%,
        rgba(5, 7, 12, 0.72) 0%, rgba(5, 7, 12, 0.38) 58%, rgba(5, 7, 12, 0) 82%),
      linear-gradient(to bottom,
      rgba(5, 7, 12, 0.62) 0%, rgba(5, 7, 12, 0.36) 20%,
      rgba(5, 7, 12, 0.12) 36%, rgba(5, 7, 12, 0) 52%,
      rgba(5, 7, 12, 0) 66%, rgba(5, 7, 12, 0.30) 86%,
      rgba(5, 7, 12, 0.70) 100%);
  }
  /* 角标抬高避开音乐 FAB（FAB 默认占底部中央） */
  #home .hero-who {
    left: 20px;
    bottom: 6rem;
  }
  /* 移动端正文：Tailwind 的 text-sm（14px）在手机上偏小，抬到 15px 并把行高放松到 1.75
     （2026-09-30 体检：卡片描述 14px/23 ≈ 1.64，关于我 14px/20 ≈ 1.43，后者偏挤） */
  #products article p.text-sm,
  #about p.text-sm {
    font-size: 0.9375rem;
    line-height: 1.75;
  }
  /* 产品卡手机端收紧（2026-09-30 用户反馈"每一个框变得奇大无比"）：
     p-8/px-8 的 32px 留白在 390px 视口上占比过高，块间距再一叠，一张卡滚过两屏。
     留白整体降一档、facts 改竖排、卡间距 64→40，让卡回到"内容为主" */
  #products > article.bento-card > div:first-child {
    padding: 1.25rem 1.25rem 0.25rem;
  }
  #products > article.bento-card > div:last-child {
    padding: 0.625rem 1.25rem 1.25rem;
  }
  #products > article.bento-card .project-facts .pf-row {
    grid-template-columns: 1fr;   /* 4.5rem 标签列 + 窄值列在手机上换行碎；改标签在上、值在下 */
    gap: 0.1rem;
  }
  #products > article.bento-card .project-facts .pf-k {
    padding-top: 0;
  }
  #products > article.bento-card .project-facts {
    padding: 0.7rem 0.85rem;
  }
  #products.space-y-16 > :not([hidden]) ~ :not([hidden]) {
    margin-top: 2.5rem;
  }
  /* 点按区：顶栏四个可点元素原高 20–28px（搜索 26×26、菜单 28×28、查看作品 24、品牌名 20），
     低于 iOS 44 / Material 48 的建议。用透明 ::after 把命中区撑到 ~40px，视觉尺寸一律不变。
     ❗选择器限定在顶栏那一行——抽屉菜单里的链接高度本就 ~40px，再扩会互相重叠点错 */
  header.site-header > div > a,
  header.site-header > div > div > a,
  header.site-header > div > div > button {
    position: relative;
  }
  header.site-header > div > a::after,
  header.site-header > div > div > a::after,
  header.site-header > div > div > button::after {
    content: "";
    position: absolute;
    inset: -10px -7px;
    border-radius: 9999px;
  }
  /* 点按区（2026-09-30 审计 B1）：产品卡按钮行命中区同样不足（了解更多 59×16、
     GitHub 圆钮 32×32、网盘下载高 32、GitHub Releases 高 34）。同款 ::after 撑法，
     视觉不变；hero CTA 行的「更多项目见 GitHub」链接一并补。按钮之间 gap 12px
     足够容纳左右扩 6px，不会互相重叠点错 */
  #products article [data-link],                       /* 网盘下载 / GitHub Releases */
  #products article button[onclick*="openProjectModal"],  /* 了解更多 > */
  #products article a[href*="github.com"][class*="rounded-full"],  /* GitHub 圆钮 */
  #home .hero-ghost,
  #home a[href*="github.com"].inline-flex {
    position: relative;
  }
  #products article [data-link]::after,
  #products article button[onclick*="openProjectModal"]::after,
  #products article a[href*="github.com"][class*="rounded-full"]::after,
  #home .hero-ghost::after,
  #home a[href*="github.com"].inline-flex::after {
    content: "";
    position: absolute;
    inset: -9px -8px;
    border-radius: 9999px;
  }
}

/* 滚动中浮层退场：手机阅读时音乐 FAB 压在正文上，滚动期间淡到 .28，停手 700ms 复原
   （类由 app.js initNavScrollState 维护；桌面端也生效，读长文时不抢视线） */
body.is-scrolling .music-fab {
  opacity: 0.28;
}

/* 逐页下翻按钮：固定底部居中（音乐 FAB 占最底，箭头在其正上方一档），点击滑到下一个区块（显隐由 app.js 切 opacity） */
#page-next {
  position: fixed;
  bottom: 4.6rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 40;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background: rgba(8, 10, 16, 0.42);
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: rgba(232, 237, 245, 0.9);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.28);
  cursor: pointer;
  transition: opacity 0.2s ease, background 0.2s ease;
}
#page-next:hover { background: rgba(8, 10, 16, 0.62); color: #ffffff; }
/* 产品区：卡片收窄、奇偶分列 —— 文字一列、3D 实体一列（igloo 式版面） */
#products article {
  max-width: 46rem;
}
#products article:nth-of-type(odd) { margin-right: auto; }
#products article:nth-of-type(even) { margin-left: auto; }

/* 深色叙事区上：导航强制 dark 配色（无论当前主题），滚出后还原 */
.site-header.on-cover {
  background: rgba(0, 0, 0, 0.55) !important;
  border-color: rgba(255, 255, 255, 0.10) !important;
}
.site-header.on-cover a,
.site-header.on-cover button {
  color: rgba(232, 237, 245, 0.92) !important;
}
.site-header.on-cover a:hover,
.site-header.on-cover button:hover { color: #ffffff !important; }
.site-header.on-cover .btn-primary { background: #f5f5f7 !important; color: #1d1d1f !important; }
.site-header.on-cover .btn-primary:hover { background: #ffffff !important; }

/* ScrollSpy：当前区块对应的导航链接高亮（下划线不占布局，随主题/封面配色） */
header.site-header nav a.nav-active {
  color: #1d1d1f !important;
  text-decoration: underline;
  text-underline-offset: 6px;
  text-decoration-thickness: 1px;
}
html.dark header.site-header nav a.nav-active {
  color: #ffffff !important;
}
@media (max-width: 720px) {
  #home { padding-top: max(4.5rem, 11svh); padding-bottom: 4.5rem; }
  /* 角标抬高避开音乐 FAB（FAB 默认占底部中央） */
  #home .hero-who { left: 16px; bottom: 6rem; }
}

/* ============================================================
   View Transitions（页面级）
   1. 明暗切换 = 从点击处圆形扩散开新主题
   ============================================================ */

/* 明暗切换的圆形扩散：旧快照保持不动，新快照由 JS 驱动 clip-path 展开 */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}

/* 移动端菜单：展开下拉，收起上滑退出 */
/* ❗抽屉必须脱离文档流（2026-09-30 用户实测锚点全错 434px 的根因）：菜单原本是
   static 下拉块，展开时把全页内容推低 ~434px，点击瞬间所有锚点 rect.top 都带着
   这 434px，抽屉一关内容弹回，滚动全部过冲。挂在 sticky 头部内用 top:100% 锚到
   头部正下方，既跟随头部又不再推挤文档流 */
#mobile-menu {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 40;
  max-height: calc(100vh - 100%);
  overflow-y: auto;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.22);
}
#mobile-menu:not(.hidden) {
  animation: menu-drop 0.26s var(--ease-swift);
}
#mobile-menu:not(.hidden) > * {
  animation: menu-item 0.3s var(--ease-swift) both;
  animation-delay: calc(var(--i, 0) * 40ms);
}
#mobile-menu.is-closing {
  animation: menu-close 0.18s cubic-bezier(0.4, 0, 0.2, 1) both;
}
@keyframes menu-drop {
  from { opacity: 0; transform: translateY(-10px); }
}
@keyframes menu-item {
  from { opacity: 0; transform: translateY(-8px); }
}
@keyframes menu-close {
  to { opacity: 0; transform: translateY(-10px); }
}

/* ============================================================
   弹窗内容切换：方向性交叉过渡（翻章左右滑，切版本上下淡）
   仅动画 transform / opacity
   ============================================================ */
@keyframes content-out-next { to { opacity: 0; transform: translateX(-24px); } }
@keyframes content-out-prev { to { opacity: 0; transform: translateX(24px); } }
@keyframes content-out-fade { to { opacity: 0; transform: translateY(-10px); } }

@keyframes content-in-next {
  from { opacity: 0; transform: translateX(28px); }
  to   { opacity: 1; transform: none; }
}
@keyframes content-in-prev {
  from { opacity: 0; transform: translateX(-28px); }
  to   { opacity: 1; transform: none; }
}
@keyframes content-in-fade {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

.modal-content-in { animation: content-in-fade 0.28s var(--ease-swift); }

.content-out-next { animation: content-out-next 0.16s var(--ease-exit) forwards; }
.content-out-prev { animation: content-out-prev 0.16s var(--ease-exit) forwards; }
.content-out-fade { animation: content-out-fade 0.16s var(--ease-exit) forwards; }

.content-in-next { animation: content-in-next 0.3s var(--ease-swift); }
.content-in-prev { animation: content-in-prev 0.3s var(--ease-swift); }
.content-in-fade { animation: content-in-fade 0.3s var(--ease-swift); }

/* ============================================================
   View Transitions：弹窗内容真·交叉溶解
   （旧内容滑出与新内容滑入同时进行，消灭两段式中间的空档；
     不支持的浏览器回退到上方 .content-in-* 单段淡入）
   ============================================================ */
#article-modal-content,
#project-modal-content {
  view-transition-name: modal-content;
}
::view-transition-old(modal-content),
::view-transition-new(modal-content) {
  height: 100%;
  overflow: clip;
}
html.vt-next::view-transition-old(modal-content) { animation: 0.18s var(--ease-exit) both vt-out-next; }
html.vt-next::view-transition-new(modal-content) { animation: 0.32s var(--ease-swift) both vt-in-next; }
html.vt-prev::view-transition-old(modal-content) { animation: 0.18s var(--ease-exit) both vt-out-prev; }
html.vt-prev::view-transition-new(modal-content) { animation: 0.32s var(--ease-swift) both vt-in-prev; }
html.vt-fade::view-transition-old(modal-content) { animation: 0.16s var(--ease-exit) both vt-out-fade; }
html.vt-fade::view-transition-new(modal-content) { animation: 0.3s var(--ease-swift) both vt-in-fade; }
@keyframes vt-out-next { to { opacity: 0; transform: translateX(-24px); } }
@keyframes vt-in-next { from { opacity: 0; transform: translateX(28px); } }
@keyframes vt-out-prev { to { opacity: 0; transform: translateX(24px); } }
@keyframes vt-in-prev { from { opacity: 0; transform: translateX(-28px); } }
@keyframes vt-out-fade { to { opacity: 0; transform: translateY(-10px); } }
@keyframes vt-in-fade { from { opacity: 0; transform: translateY(12px); } }

/* 代码块一键复制按钮（代码块固定深色底，明暗主题共用一套样式） */
.code-copy-btn {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  padding: 0.2rem 0.6rem;
  border-radius: 0.375rem;
  font-size: 0.7rem;
  line-height: 1.2;
  color: #8b949e;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.12);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.code-copy-btn:hover {
  color: #f5f5f7;
  border-color: rgba(255, 255, 255, 0.3);
}

/* ⌘K 搜索命令面板 */
/* 输入框豁免全局焦点环：面板本身即焦点上下文，输入光标就是焦点指示 */
#search-input:focus-visible {
  outline: none;
}
/* 空状态：图标 + 两行提示 */
.search-empty {
  padding: 2.1rem 1rem 2.3rem;
  text-align: center;
}
.search-empty svg {
  display: block;
  width: 22px;
  height: 22px;
  margin: 0 auto 10px;
  opacity: 0.45;
}
.search-empty .t1 {
  font-size: 0.8rem;
  color: #86868b;
}
.search-empty .t2 {
  margin-top: 4px;
  font-size: 0.7rem;
  color: rgba(134, 134, 139, 0.62);
}
/* 底部提示键帽（与右上 ESC 键帽同款） */
.search-kbd {
  display: inline-block;
  margin: 0 0.05rem;
  padding: 0.05rem 0.32rem;
  border-radius: 0.25rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 9px;
  line-height: 1.5;
  color: #86868b;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.13);
}
.search-item.is-selected {
  background: rgba(18, 30, 60, 0.05);
}
.dark .search-item.is-selected {
  background: rgba(255, 255, 255, 0.06);
}
.search-item mark {
  background: transparent;
  color: inherit;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* 长文自动目录 */
.toc-box {
  border: 1px solid var(--hairline);
  background: rgba(18, 30, 60, 0.02);
  border-radius: 0.5rem;
  padding: 0.7rem 1rem;
  margin-bottom: 1.25rem;
  font-size: 0.85rem;
}
.dark .toc-box {
  background: rgba(255, 255, 255, 0.03);
}
.toc-box summary {
  cursor: pointer;
  font-weight: 600;
  color: inherit;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.toc-box summary::before {
  content: '▸';
  transition: transform 0.15s ease;
}
.toc-box[open] summary::before {
  transform: rotate(90deg);
}
.toc-link {
  display: block;
  padding: 0.3rem 0.5rem;
  border-radius: 0.375rem;
  color: inherit;
  text-decoration: none;
  transition: background-color 0.15s ease;
}
.toc-link:hover {
  background: rgba(18, 30, 60, 0.05);
}
.dark .toc-link:hover {
  background: rgba(255, 255, 255, 0.06);
}

/* 全局轻提示 */
.sj-toast {
  position: fixed;
  bottom: 5rem;
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  z-index: 70;
  padding: 0.55rem 1.1rem;
  border-radius: 0.5rem;
  background: rgba(29, 29, 31, 0.94);
  color: #f5f5f7;
  font-size: 0.8rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.sj-toast.is-show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* 本地文本批注（仅存访客本机） */
mark.sj-note {
  background: rgba(255, 214, 10, 0.32);
  color: inherit;
  border-bottom: 2px solid rgba(255, 214, 10, 0.85);
  cursor: pointer;
  padding: 0.05em 0;
}
.sj-popover {
  position: absolute;
  z-index: 20;
  width: 250px;
  padding: 0.75rem;
  border-radius: 0.625rem;
  background: #ffffff;
  border: 1px solid var(--hairline);
  box-shadow: 0 8px 24px -8px rgba(0, 0, 0, 0.2);
  animation: content-in-fade 0.18s cubic-bezier(0.16, 1, 0.3, 1);
}
.dark .sj-popover {
  background: #232325;
  border-color: var(--hairline);
}
.sj-popover textarea {
  width: 100%;
  padding: 0.45rem 0.6rem;
  border-radius: 0.5rem;
  border: 1px solid var(--hairline);
  background: transparent;
  color: inherit;
  font-size: 0.8rem;
  resize: none;
  outline: none;
}
.sj-popover textarea:focus {
  border-color: var(--hairline-strong);
}
.sj-popover-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.4rem;
  margin-top: 0.5rem;
}
.sj-popover-actions button {
  padding: 0.25rem 0.7rem;
  border-radius: 0.375rem;
  font-size: 0.7rem;
  cursor: pointer;
  transition: all 0.15s ease;
  border: 1px solid var(--hairline);
  background: transparent;
  color: inherit;
}
.sj-popover-actions button[data-act='save'],
.sj-popover-actions button[data-act='del'] {
  background: #1d1d1f;
  border-color: #1d1d1f;
  color: #ffffff;
}
.dark .sj-popover-actions button[data-act='save'],
.dark .sj-popover-actions button[data-act='del'] {
  background: #f5f5f7;
  border-color: #f5f5f7;
  color: #1d1d1f;
}
.sj-note-view {
  font-size: 0.8rem;
  line-height: 1.5;
  color: inherit;
}

/* 情绪反馈按钮（本地版） */
.emotion-btn {
  border-color: var(--hairline);
  background: transparent;
  color: #86868b;
}
.emotion-btn:hover {
  border-color: var(--hairline-strong);
  color: inherit;
}
.emotion-btn.is-active {
  background: #1d1d1f;
  border-color: #1d1d1f;
  color: #ffffff;
}
.dark .emotion-btn.is-active {
  background: #f5f5f7;
  border-color: #f5f5f7;
  color: #1d1d1f;
}

/* 版本切换与阅读偏好小按钮 */
.pref-btn {
  padding: 0.15rem 0.55rem;
  border-radius: 0.375rem;
  font-size: 0.7rem;
  color: #86868b;
  background: transparent;
  border: 1px solid var(--hairline);
  cursor: pointer;
  transition: all 0.15s ease;
}
.pref-btn:hover {
  color: inherit;
  border-color: var(--hairline-strong);
}
.pref-btn.is-active {
  background: #1d1d1f;
  color: #ffffff;
  border-color: #1d1d1f;
}
.dark .pref-btn.is-active {
  background: #f5f5f7;
  color: #1d1d1f;
  border-color: #f5f5f7;
}

/* 尊重减少动效 */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .modal-overlay,
  .modal-panel {
    animation: none !important;
  }
  .bento-card:hover,
  .btn-primary:active,
  .btn-secondary:active {
    transform: none !important;
  }
  .hero-anim {
    animation: none !important;
  }
  .js .reveal {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .js .reveal .reveal-img {
    transform: none !important;
    transition: none !important;
  }
  header.site-header {
    transition: none !important;
  }
  #particle-canvas {
    display: none;
  }
  #mobile-menu:not(.hidden),
  #mobile-menu.is-closing,
  .modal-content-in,
  .content-out-next,
  .content-out-prev,
  .content-out-fade,
  .content-in-next,
  .content-in-prev,
  .content-in-fade {
    animation: none !important;
  }
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

/* Markdown 文章详情排版 */
.markdown-body {
  line-height: 1.8;
  font-size: 1rem;
}
.markdown-body h1,
.markdown-body h2,
.markdown-body h3 {
  font-weight: 600;
  margin-top: 1.6rem;
  margin-bottom: 0.75rem;
  line-height: 1.3;
}
.markdown-body h1 { font-size: 1.6rem; border-bottom: 1px solid var(--hairline); padding-bottom: 0.5rem; }
.markdown-body h2 { font-size: 1.3rem; }
.markdown-body h3 { font-size: 1.1rem; }
.markdown-body p {
  margin-bottom: 1rem;
}
.markdown-body ul, .markdown-body ol {
  padding-left: 1.25rem;
  margin-bottom: 1rem;
}
.markdown-body ul { list-style-type: disc; }
.markdown-body ol { list-style-type: decimal; }
.markdown-body li { margin-bottom: 0.35rem; }
.markdown-body blockquote {
  border-left: 2px solid var(--hairline-strong);
  padding-left: 0.875rem;
  margin: 1rem 0;
  color: #86868b;
  padding: 0.2rem 0.875rem;
}
.markdown-body pre {
  border-radius: 0.5rem;
  margin: 1rem 0;
  padding: 0.875rem 1rem;
  background: #0d1117 !important;
  overflow-x: auto;
  border: 1px solid rgba(255, 255, 255, 0.08);
}
.markdown-body code:not(pre code) {
  background-color: rgba(18, 30, 60, 0.06);
  color: inherit;
  padding: 0.15rem 0.35rem;
  border-radius: 0.25rem;
  font-size: 0.88em;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}
.dark .markdown-body code:not(pre code) {
  background-color: rgba(255, 255, 255, 0.08);
}

/* ===== 底部居中悬浮音乐播放器（js/player.js 驱动；左右下角分别被头像卡/星河控制台占了，
        且角落按钮不好按——居中是拇指/视线热区） ===== */
.music-fab {
  position: fixed;
  left: 50%;
  margin-left: -1.5rem;   /* 宽 3rem 的一半，不用 transform 以免和 hover scale 打架 */
  bottom: 1.2rem;
  touch-action: none;      /* 拖拽换位：不让触摸当成滚动 */
  cursor: grab;            /* js/player.js 拖拽时提示可抓取 */
  user-select: none;
  z-index: 40;
  width: 3rem;
  height: 3rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background: #ffffff;
  color: #1d1d1f;
  border: 1px solid rgba(0, 0, 0, 0.1);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  cursor: pointer;
  transition: transform 0.25s var(--lg-spring), border-color 0.2s ease, opacity 0.25s ease;
}
.music-fab:hover {
  transform: scale(1.06);
  border-color: rgba(0, 0, 0, 0.35);
}
.dark .music-fab {
  background: #1d1d1f;
  color: #f5f5f7;
  border-color: rgba(255, 255, 255, 0.15);
}
.dark .music-fab:hover {
  border-color: rgba(255, 255, 255, 0.45);
}
/* 播放中：柔和的扩散圈提示 */
.music-fab::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: 9999px;
  border: 2px solid currentColor;
  opacity: 0;
  pointer-events: none;
}
.music-fab.is-playing::after {
  animation: music-pulse 2s ease-out infinite;
}
@keyframes music-pulse {
  0%   { opacity: 0.45; transform: scale(1); }
  70%  { opacity: 0;    transform: scale(1.45); }
  100% { opacity: 0;    transform: scale(1.45); }
}

/* 图标显隐（默认音符 / 播放中暂停） */
.music-icon {
  width: 20px;
  height: 20px;
  display: block;
}
.music-fab .icon-pause,
#music-play .icon-pause { display: none; }
.music-fab.is-playing .icon-music { display: none; }
.music-fab.is-playing .icon-pause { display: block; }
#music-play.is-playing .icon-play { display: none; }
#music-play.is-playing .icon-pause { display: block; }

/* 展开面板：FAB 上方弹出（水平居中对齐 FAB） */
.music-panel {
  position: fixed;
  left: 50%;
  bottom: 5rem;
  transform: translate(-50%, 8px);
  z-index: 40;
  width: min(300px, calc(100vw - 2.5rem));
  padding: 0.875rem;
  border-radius: 0.75rem;
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid rgba(210, 210, 215, 0.6);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.16);
  color: #1d1d1f;
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.22s ease, transform 0.22s cubic-bezier(0.16, 1, 0.3, 1), visibility 0.22s;
}
.music-panel.music-open {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  pointer-events: auto;
}
.dark .music-panel {
  background: rgba(29, 29, 31, 0.96);
  border-color: rgba(255, 255, 255, 0.12);
  color: #f5f5f7;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
}

.music-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.625rem;
}
.music-title {
  font-size: 0.85rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#music-close {
  flex-shrink: 0;
  display: flex;
  padding: 0.2rem;
  border: none;
  background: none;
  color: #86868b;
  cursor: pointer;
  border-radius: 0.375rem;
  transition: color 0.2s ease;
}
#music-close:hover { color: #1d1d1f; }
.dark #music-close:hover { color: #f5f5f7; }
#music-close .music-icon { width: 15px; height: 15px; }

/* 进度行（时间码 0.7rem→0.75rem：11.2px 低于 12px 可读下限，2026-09-30 审计 B2） */
.music-progress {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.75rem;
  color: #86868b;
  font-variant-numeric: tabular-nums;
}
#music-seek {
  flex: 1;
  -webkit-appearance: none;
  appearance: none;
  height: 4px;
  border-radius: 9999px;
  background: rgba(134, 134, 139, 0.3);
  outline: none;
  cursor: pointer;
}
#music-seek::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 12px;
  height: 12px;
  border-radius: 9999px;
  background: #1d1d1f;
  border: none;
}
.dark #music-seek::-webkit-slider-thumb { background: #f5f5f7; }
#music-seek::-moz-range-thumb {
  width: 12px;
  height: 12px;
  border-radius: 9999px;
  background: #1d1d1f;
  border: none;
}
.dark #music-seek::-moz-range-thumb { background: #f5f5f7; }

/* 控制按钮排 */
.music-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  margin: 0.625rem 0 0.5rem;
}
.music-controls button {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.35rem;
  border: none;
  background: none;
  color: #1d1d1f;
  cursor: pointer;
  border-radius: 0.5rem;
  transition: opacity 0.2s ease, transform 0.15s ease;
}
.dark .music-controls button { color: #f5f5f7; }
.music-controls button:hover { opacity: 0.65; }
.music-controls button:active { transform: scale(0.92); }
#music-play {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 9999px;
  background: #1d1d1f;
  color: #f5f5f7 !important;
}
.dark #music-play { background: #f5f5f7; color: #1d1d1f !important; }
#music-play:hover { opacity: 0.85; }
#music-play .music-icon { width: 22px; height: 22px; }
#music-play .icon-play { margin-left: 2px; } /* 三角形视觉居中 */

/* 循环模式按钮：顺序循环 / 单曲循环 两态切换 */
#music-mode .icon-mode-one { display: none; }
#music-mode.mode-one .icon-mode-list { display: none; }
#music-mode.mode-one .icon-mode-one { display: block; }
#music-mode.mode-one { color: #0071e3; }
.dark #music-mode.mode-one { color: #6fb8ff; }

/* 歌单 */
.music-list {
  max-height: 10.5rem;
  overflow-y: auto;
  border-top: 1px solid rgba(210, 210, 215, 0.5);
  padding-top: 0.375rem;
  margin: 0;
  list-style: none;
}
.dark .music-list { border-top-color: rgba(255, 255, 255, 0.1); }
.music-list li { display: flex; align-items: center; gap: 2px; }
.music-list li > button:first-child { flex: 1; min-width: 0; }
.music-list button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.4rem 0.5rem;
  border: none;
  background: none;
  color: #86868b;
  font-size: 0.78rem;
  cursor: pointer;
  border-radius: 0.375rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: background 0.15s ease, color 0.15s ease;
}
.music-list button:hover { background: rgba(0, 0, 0, 0.05); color: #1d1d1f; }
.dark .music-list button:hover { background: rgba(255, 255, 255, 0.08); color: #f5f5f7; }
.music-list button.is-current {
  color: #1d1d1f;
  font-weight: 600;
}
.dark .music-list button.is-current { color: #f5f5f7; }
/* 上移/下移小按钮：自定义歌单顺序（0.72rem→0.75rem：11.5px 低于 12px 可读下限，2026-09-30 审计 B2） */
.music-list .song-move {
  width: 1.6rem;
  min-width: 1.6rem;
  flex: none;
  padding: 0.35rem 0;
  text-align: center;
  font-size: 0.75rem;
  line-height: 1;
  color: #b0b0b8;
}
.music-list .song-move:hover { color: #1d1d1f; }
.dark .music-list .song-move:hover { color: #f5f5f7; }

/* 移动端：面板贴底居中防溢出 */
@media (max-width: 480px) {
  .music-fab { margin-left: -1.5rem; bottom: 1rem; }
  .music-panel { bottom: 4.4rem; }
}

/* ============================================================
   点亮层（2026-09-29）：星光蓝强调色
   色相取自 3D 推理场的冷蓝辉光与 HUD 角标，让正文层与背景同源。
   全部为装饰性颜色 / 伪元素 / filter，不动布局与交互逻辑。
   ============================================================ */
:root {
  --accent: #8fb8ff;
  --accent-dim: rgba(143, 184, 255, 0.35);
}

/* 选区：星光蓝淡染 */
::selection {
  background: rgba(143, 184, 255, 0.26);
}

/* hero 眉标：呼吸信号点（推理场"在线"的心跳） */
.hero-eyebrow::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 0.6rem;
  vertical-align: 0.08em;
  border-radius: 9999px;
  background: var(--accent);
  box-shadow: 0 0 8px rgba(143, 184, 255, 0.8);
  animation: eyebrow-breathe 2.8s ease-in-out infinite;
}
@keyframes eyebrow-breathe {
  0%, 100% { opacity: 0.4; }
  50%      { opacity: 1; }
}

/* 理念编号染色 + 列顶发丝线（编辑风版式） */
.phil-no {
  color: var(--accent) !important;
  font-weight: 600;
}
#philosophy .grid > .reveal {
  border-top: 1px solid var(--hairline);
  padding-top: 1.1rem;
}

/* hero 副题行：星光渐变字（不支持的浏览器回退为亮蓝白） */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  #home #site-subtitle {
    color: transparent !important;
    background: linear-gradient(180deg, #f2f7ff 0%, #a9c4f5 100%);
    -webkit-background-clip: text;
    background-clip: text;
  }
}

/* 封面 hover：冷蓝环境光晕 + 图像轻微提亮（不动布局） */
.cover-box {
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.cover-box:hover {
  border-color: var(--accent-dim);
  box-shadow:
    0 0 0 1px rgba(143, 184, 255, 0.10),
    0 12px 40px -12px rgba(96, 150, 255, 0.18);
}
.cover-img { transition: filter 0.35s ease; }
.cover-box:hover .cover-img {
  filter: brightness(1.05) saturate(1.04);
}

/* 文章 / 随笔卡 hover：左缘冷蓝指示线 */
#articles-list > article,
#essays-list > article {
  position: relative;
}
#articles-list > article::before,
#essays-list > article::before {
  content: "";
  position: absolute;
  left: -1px;
  top: 16%;
  bottom: 16%;
  width: 2px;
  border-radius: 2px;
  background: var(--accent);
  opacity: 0;
  transform: scaleY(0.5);
  transition: opacity 0.25s ease, transform 0.25s var(--ease-swift);
  pointer-events: none;
}
#articles-list > article:hover::before,
#essays-list > article:hover::before {
  opacity: 0.9;
  transform: none;
}

/* ScrollSpy 活动态：下划线染星光蓝 */
header.site-header nav a.nav-active {
  text-decoration-color: var(--accent);
}

/* 逐页箭头 hover：边框呼应星光蓝 */
#page-next:hover {
  border-color: rgba(143, 184, 255, 0.38);
}

/* hero GitHub 链接：箭头 hover 位移 */
#home a.inline-flex svg {
  transition: transform 0.2s var(--ease-swift);
}
#home a.inline-flex:hover svg {
  transform: translateX(2px);
}

/* footer：顶部星光渐变发丝线 */
footer {
  position: relative;
}
footer::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 12%;
  right: 12%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(143, 184, 255, 0.45), transparent);
  pointer-events: none;
}

/* 滚动条 hover 染色（微调呼应） */
::-webkit-scrollbar-thumb:hover {
  background: #6f8cbd;
}

/* 减少动效：停掉新增的呼吸与过渡 */
@media (prefers-reduced-motion: reduce) {
  .hero-eyebrow::before { animation: none; }
  .cover-box,
  .cover-img,
  #home a.inline-flex svg,
  #articles-list > article::before,
  #essays-list > article::before {
    transition: none;
  }
}

/* ============================================================
   液态玻璃控件层（2026-09-29）
   配方来源：D:/Android/液态玻璃参数手册 / glass-recipe.json 暗色板
   纪律：玻璃只上控件/浮层（吸顶导航、弹窗、FAB、箭头），滚动内容层禁上；
        feDisplacementMap 折射是内核彩票（Chrome 152 全灭 / 154 可渲染 /
        WebKit 丢整条声明），站点用「毛玻璃 + rim 五件套 + 1px 色散 +
        跟手 specular」做材质厚度，不赌滤镜管线；全部套 @supports 降级。
   ============================================================ */
:root {
  --lg-spring: cubic-bezier(.32, 1.6, .45, 1);
  --lg-rim-dark:
    inset 0 0 0 .5px rgba(255, 255, 255, .24),
    inset 0 1px 1px rgba(255, 255, 255, .28),
    inset 0 -1px 1px rgba(0, 0, 0, .10),
    inset 1px 0 0 rgba(120, 170, 255, .06),
    inset -1px 0 0 rgba(255, 150, 120, .05);
}

/* 跟手 specular：JS 只写 --sx/--sy，光斑跟随指针
   ❗不写 position —— 宿主各自定位（modal-panel=relative、music-panel/page-next=fixed），
   2026-09-29 曾在此写 relative 把 music-panel 的 fixed 覆盖掉，面板掉进文档流在页尾占了 304px */
.glass-spec::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(200px circle at var(--sx, 50%) var(--sy, -30%),
    rgba(255, 255, 255, .08), transparent 62%);
  opacity: 0;
  transition: opacity .35s ease;
}
.glass-spec:hover::before { opacity: 1; }

/* 吸顶导航 = Liquid Glass regular：内容滚到栏下自动透出毛玻璃（scroll edge effect） */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  header.site-header.is-scrolled {
    background: linear-gradient(180deg, rgba(30, 32, 40, .50), rgba(14, 15, 18, .42)) !important;
    -webkit-backdrop-filter: blur(24px) saturate(1.5);
    backdrop-filter: blur(24px) saturate(1.5);
    border-bottom-color: rgba(255, 255, 255, .07) !important;
    box-shadow: var(--lg-rim-dark), 0 8px 30px rgba(0, 0, 0, .25);
  }

  /* 半高 sheet：blur(40) + 暗板 tint .86（配方 §4 sheet 档） */
  .dark .modal-panel {
    background: linear-gradient(180deg, rgba(32, 34, 42, .88), rgba(16, 17, 20, .84));
    -webkit-backdrop-filter: blur(40px) saturate(1.4);
    backdrop-filter: blur(40px) saturate(1.4);
    border-color: transparent;
    box-shadow: var(--lg-rim-dark), 0 24px 80px rgba(0, 0, 0, .5);
  }

  /* 音乐 FAB：小圆玻璃 + 按压 squish（spring 曲线） */
  .dark .music-fab {
    background: rgba(30, 32, 40, .55);
    -webkit-backdrop-filter: blur(20px) saturate(1.5);
    backdrop-filter: blur(20px) saturate(1.5);
    box-shadow: var(--lg-rim-dark), 0 8px 24px rgba(0, 0, 0, .35);
  }
  .dark .music-fab:active { transform: scale(.96); transition-duration: .08s; }

  /* 音乐面板：条带玻璃 */
  .dark .music-panel {
    background: linear-gradient(180deg, rgba(30, 32, 40, .72), rgba(14, 15, 18, .66));
    -webkit-backdrop-filter: blur(28px) saturate(1.5);
    backdrop-filter: blur(28px) saturate(1.5);
    border-color: transparent;
    box-shadow: var(--lg-rim-dark), 0 16px 48px rgba(0, 0, 0, .4);
  }

  /* 下翻箭头：小圆玻璃 */
  #page-next {
    background: rgba(20, 22, 28, .42);
    -webkit-backdrop-filter: blur(16px) saturate(1.4);
    backdrop-filter: blur(16px) saturate(1.4);
    border-color: rgba(255, 255, 255, .14);
    box-shadow: var(--lg-rim-dark), 0 8px 24px rgba(0, 0, 0, .3);
  }
  #page-next:active { transform: translateX(-50%) scale(.94); }

  /* hero 音乐入口悬在 3D 舞台上：轻玻璃化 */
  #home .hero-ghost {
    background: rgba(20, 22, 30, .32);
    -webkit-backdrop-filter: blur(10px) saturate(1.4);
    backdrop-filter: blur(10px) saturate(1.4);
    box-shadow: var(--lg-rim-dark);
  }
}

/* 弹窗遮罩只负责压暗，模糊让位给面板玻璃（避免双重糊） */
.modal-overlay.lg-dim { background: rgba(5, 7, 12, .55) !important; }

/* 辅助功能降级备注：不做 prefers-reduced-transparency 否决——本机 Windows
   透明效果关闭时 Chromium 会报 reduce，会连站主的玻璃一起吞掉（2026-09-29 实测）。
   兜底只靠 @supports 能力检测；真的需要低透明度的访客可用系统「增强对比」等方案。 */
/* 手机上隐藏「下翻一页」箭头：它固定在底部居中，一定会压住正文；触摸设备本来就是滑动浏览，
   翻书隐喻只在桌面成立（2026-09-30 定，桌面端保留）。音乐 FAB 仍留着手势可达。
   ❗必须写在 #page-next 基础规则之后——媒体查询不加特指度，同选择器后写的赢 */
@media (max-width: 639px) {
  #page-next {
    display: none;
  }
}
