/* ============================================================
   个人工具间 — 设计系统 v4 ·《双境山水》
   白天 =「客路青山外，行舟绿水前」青竹幕墙 + 静水小舟 + 大面积留白
   夜晚 =「柴门闻犬吠，风雪夜归人」蓝灰雪林 + 唯一一扇暖灯
   色板从用户提供的两张参考图的配色里抽取；画作见 public/theme-art/
   data-theme 由 JS 解析成实际 light / dark
   ============================================================ */

:root {
  /* 竹青：强调色。**两套主题都是绿** —— 2026-09-20 用户第二次要求
     "暗色模式仍然没有改变，并且还有很多红色"，所以暗色也从朱砂红换掉了。
     这里改的是源头，文件末尾的 v6 层是同一套值（保留那层是为了留下改动记录）。 */
  --accent:        #3c6e4e;
  --accent-deep:   #2c5540;
  --accent-soft:   rgba(60,110,78,.12);
  --accent-ring:   rgba(60,110,78,.22);

  /* 墨：白天是青绿灰的墨，不是纯黑 */
  --ink:           #26302a;
  --ink-soft:      #4d5a51;
  --ink-faint:     #8b988f;

  /* 宣纸：带一点青的米白 —— 比纯白暖，比米黄清 */
  --paper:         #eef2ec;
  --mist:          #dfe8dd;
  --mist-2:        #cfdcd2;
  --glass:         rgba(252,253,250,.68);
  --glass-strong:  rgba(252,253,250,.88);
  --glass-soft:    rgba(252,253,250,.40);
  --bg-glass:      rgba(252,253,250,.82);   /* 手机吸顶栏（以前没定义 → 内容从底下穿过去） */
  --sunken:        rgba(38,48,42,.06);

  --line:          rgba(38,48,42,.10);
  --line-strong:   rgba(38,48,42,.19);

  --shadow-s: 0 1px 2px rgba(30,42,36,.05);
  --shadow-m: 0 8px 22px -12px rgba(30,42,36,.22), 0 2px 7px -4px rgba(30,42,36,.10);
  --shadow-l: 0 20px 48px -26px rgba(30,42,36,.30), 0 6px 16px -8px rgba(30,42,36,.16);

  --ink-deep:      #1d2621;
  --ink-mid:       #5c6b62;
  --ink-light:     #9aa8a0;
  --jade:          #4a7c59;
  --peach:         #d4a574;
  --amber:         #c07a3a;
  --danger:        #c0392b;   /* 以前没定义 → 同步出错时颜色直接失效 */

  /* 双境山水 · 白天 */
  --jade-1:        #a8c29a;
  --jade-2:        #7d9b7a;
  --jade-3:        #3d5a45;
  --water:         #cfe0da;
  --water-deep:    #9fb3b0;
  --snow:          #fbfdfe;
  --warm:          #d9a15c;
  --warm-glow:     rgba(217,161,92,.34);

  --r-s: 10px; --r-m: 14px; --r-l: 20px; --r-xl: 28px; --r-full: 999px;
  --nav-h: 60px;
  /* 不再声明装不上的书法字体（CSP 禁外链 + 离线优先 = 永远加载不到）。
     「笔锋」交给 SVG 笔画和排版节奏，字体只负责读起来舒服。 */
  --font: "PingFang SC", "HarmonyOS Sans SC", "Hiragino Sans GB", "Microsoft YaHei",
          "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif;
  --font-display: "Songti SC", "STSong", "Source Han Serif SC", "Noto Serif SC",
          "SimSun", "PingFang SC", "Microsoft YaHei", serif;
  --font-mono: ui-monospace, "Cascadia Code", Consolas, monospace;

  /* 场景画作（?v 是资源指纹：换画必须 +1，否则 Service Worker 会一直给旧图） */
  --art-page:  url('/theme-art/day-page.jpg?v=5-5');
  --art-hero:  url('/theme-art/day-hero.jpg?v=5-5');
  --art-stock: url('/theme-art/day-stock.jpg?v=5-5');
}

:root[data-theme="dark"] {
  /* 暗色的强调色 = 冷钢蓝。**不是绿** —— 亮色的背景是青竹所以用竹青，
     暗色的背景是雪夜（冷蓝），绿不搭。用户原话：「不要是绿色，符合背景色」。
     这一套和文件末尾 v8 那层是同一个值（那层留着是为了记录改动过程）。 */
  --accent:        #547b99;
  --accent-deep:   #3f5f79;
  --accent-soft:   rgba(84,123,153,.20);
  --accent-ring:   rgba(84,123,153,.34);

  --ink:           #e6ecf2;
  --ink-soft:      #a8b4c0;
  --ink-faint:     #76848f;

  --paper:         #141b24;
  --mist:          #1e2833;
  --mist-2:        #2a3644;
  --glass:         rgba(20,27,36,.66);
  --glass-strong:  rgba(20,27,36,.86);
  --glass-soft:    rgba(255,255,255,.05);
  --bg-glass:      rgba(16,22,30,.86);
  --sunken:        rgba(230,236,242,.07);

  --line:          rgba(230,236,242,.12);
  --line-strong:   rgba(230,236,242,.20);

  --shadow-s: 0 1px 2px rgba(0,0,0,.45);
  --shadow-m: 0 10px 28px -14px rgba(0,0,0,.65), 0 2px 8px -4px rgba(0,0,0,.35);
  --shadow-l: 0 24px 56px -26px rgba(0,0,0,.85), 0 6px 18px -8px rgba(0,0,0,.55);

  --ink-deep:      #0f151c;
  --ink-mid:       #33404e;
  --ink-light:     #5d6b79;
  --jade:          #5a9b72;
  --peach:         #e8a87c;
  --amber:         #f0b04a;
  --danger:        #ef6b5e;

  /* 双境山水 · 夜晚（雪夜压得很沉，只留一扇窗的暖） */
  --jade-1:        #5d7a63;
  --jade-2:        #41584a;
  --jade-3:        #26362c;
  --water:         #27343f;
  --water-deep:    #161f28;
  --snow:          #e9eff5;
  --warm:          #f6b96a;
  --warm-glow:     rgba(255,201,122,.42);

  --art-page:  url('/theme-art/night-page.jpg?v=5-5');
  --art-hero:  url('/theme-art/night-hero.jpg?v=6-3');
  /* 手机专用的**竖幅**首页画。
     为什么单独要一张：手机卡片是竖的、横画塞进去只能横向切一刀，小屋必然被切。
     用户要"整间小屋完整又大地填满卡片"，所以用 WorkBuddy 的混元生图
     专门出了一张竖构图（小屋居中、上留星空下留雪地），从这里开始用。
     生成 + 裁切：_tools/_cbc-prompt.txt → crop-render.mjs（见交接文档 v7 那节）。 */
  /* ⚠️ 这张图（手机端首页卡片里的画）**不要再换** —— 用户明确要求保持现状。
     2026-09-20 我因为做"图片减重"时误用了 traveler-ai.png 当源图，把它换成了雪原旅人，
     用户很不满意，已改回月夜森林。改这张图=改用户每天第一眼看到的东西。
     内容变了必须升这个 ?v=（否则浏览器/Service Worker 会拿旧缓存）。 */
  --art-hero-m: url('/theme-art/night-hero-m.jpg?v=5');
  --art-stock: url('/theme-art/night-stock.jpg?v=5-5');
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html, body {
  margin: 0; min-height: 100%;
  background: var(--paper); color: var(--ink);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}
body { overscroll-behavior-y: none; }

button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
a { color: var(--accent); text-decoration: none; }
h1, h2, h3, h4 { margin: 0; font-weight: 660; letter-spacing: -.026em; }
img { display: block; }


/* ---------------- 骨架 ---------------- */
.app { position: relative; z-index: 1; }

.content {
  max-width: 1180px;
  margin: 0 auto;
  padding: 96px 20px 168px;
}
@media (max-width: 719px) {
  /* 底部要同时给「播放器 + 底部导航」留位置，否则列表最后几项会被挡住 */
  .content { padding: calc(18px + env(safe-area-inset-top, 0px)) 16px 218px; }}

.page-head {
  display: flex; align-items: flex-end; gap: 14px;
  margin: 0 0 22px;
}
.page-title { font-size: 30px; font-weight: 680; letter-spacing: -.032em; flex: 1; }
@media (max-width: 719px) { .page-title { font-size: 25px; }}
.page-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* ---------------- 悬浮胶囊导航（水墨风：细墨线 + 宣纸底 + 朱砂红 active） ---------------- */
.topnav {
  position: fixed; z-index: 40;
  left: 50%; transform: translateX(-50%);
  top: calc(16px + env(safe-area-inset-top, 0px));
  display: flex; align-items: center; gap: 4px;
  padding: 6px 8px;
  max-width: min(96vw, 1000px);
  background: var(--glass-strong);
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  box-shadow: var(--shadow-m);
  font-family: "Noto Serif SC", "PingFang SC", serif;
}
.topnav .brand {
  display: flex; align-items: center; gap: 8px;
  padding: 0 12px 0 6px; margin-right: 4px;
  border-right: 1px solid var(--line);
  height: 38px;
}
/* 品牌图标：朱砂红印章风格，不再是蓝色渐变方块 */
.brand-mark {
  width: 30px; height: 30px; border-radius: 6px; flex-shrink: 0;
  display: grid; place-items: center; font-size: 14px; font-weight: 700; color: #fff;
  background: var(--accent);
  font-family: "Ma Shan Zheng", "ZCOOL XiaoWei", serif;
  box-shadow: 0 2px 6px -2px rgba(178,58,46,.4);
}
.brand-name { font-size: 14px; font-weight: 500; white-space: nowrap; letter-spacing: .02em; font-family: "ZCOOL XiaoWei", "Noto Serif SC", serif; }

.topnav .nav { display: flex; align-items: center; gap: 2px; }
.nav-item {
  display: flex; align-items: center; gap: 7px;
  padding: 9px 14px; border-radius: var(--r-full);
  font-size: 14px; color: var(--ink-soft); white-space: nowrap;
  font-family: "Noto Serif SC", "PingFang SC", serif;
  letter-spacing: .01em;
  transition: background .16s, color .16s, transform .2s cubic-bezier(.2,.9,.3,1);
}
.nav-item .ico, .nav-ico { font-size: 15px; line-height: 1; display: inline-flex; }
.nav-item:hover { background: var(--sunken); color: var(--ink); transform: translateY(-1px); }
/* 朱砂红 active：像印章盖在导航上 */
.nav-item.active, .nav-item.on {
  background: var(--accent); color: #fff; font-weight: 500;
  box-shadow: 0 2px 8px -3px rgba(178,58,46,.45);
}
.nav-icon-btn:hover { background: var(--sunken); color: var(--ink); transform: scale(1.09); }
.topnav .spacer { flex: 1; }
.nav-icon-btn {
  width: 38px; height: 38px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center; font-size: 15px; color: var(--ink-soft);
  transition: background .16s, color .16s;
}
.nav-icon-btn:hover { background: var(--sunken); color: var(--ink); }
.nav-icon-btn.danger:hover { background: var(--accent-soft); color: var(--accent); }

/* 窄屏（手机）：导航挪到底部，顶栏交给后面那条 display:none
   平板（720–899）不算窄屏 —— 顶栏放得下，见下面的「平板」块 */
@media (max-width: 719px) {
  .topnav { left: 12px; right: 12px; transform: none; max-width: none; justify-content: space-between; }
  .topnav .nav { display: none; }}

/* ---------------- 平板（720–899）----------------
   平板竖屏（iPad mini 744 起）以前被当成手机：顶栏整个消失、
   只剩底部一条 10.5px 小字的标签栏，又空又难按。
   实测 744px 放得下完整顶栏（6 个导航项 + 品牌 + 右侧按钮 ≈ 690px），
   所以平板跟桌面一样用顶部导航，只是把间距收紧一点。 */
@media (min-width: 720px) and (max-width: 899px) {
  .topnav { padding: 6px; gap: 3px; }
  .topnav .brand { padding: 0 8px 0 4px; }
  .nav-item { padding: 9px 9px; gap: 5px; font-size: 13px; }
}

/* ---------------- 浮动胶囊导航（手机：底部） ---------------- */
.tabbar {
  display: none;
  position: fixed; z-index: 40;
  left: 12px; right: 12px;
  bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  padding: 7px;
  grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  background: var(--glass-strong);
  border: 1px solid var(--line);
  border-radius: var(--r-l);
  backdrop-filter: blur(22px) saturate(180%);
  -webkit-backdrop-filter: blur(22px) saturate(180%);
  box-shadow: var(--shadow-l);
}
@media (max-width: 719px) { .tabbar { display: grid; }}
.tab {
  min-width: 0; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  padding: 8px 2px; border-radius: var(--r-m);
  font-size: 10.5px; color: var(--ink-faint); white-space: nowrap;
  transition: color .16s, background .16s;
}
.tab .ico { font-size: 18px; line-height: 1; }
.tab > span:last-child { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.tab.active, .tab.on { color: var(--ink); background: var(--sunken); font-weight: 620; }

/* ---------------- 卡片：宣纸感 + 细墨线描边 + 淡阴影 ---------------- */
.card {
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: 22px;
  backdrop-filter: blur(14px) saturate(130%);
  -webkit-backdrop-filter: blur(14px) saturate(130%);
  box-shadow: var(--shadow-m);
  /* 宣纸纹理：极淡噪点 */
  position: relative;
}
.card::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='1.4' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.17  0 0 0 0 0.17  0 0 0 0 0.17  0 0 0 0.025 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  opacity: .5; mix-blend-mode: multiply; pointer-events: none;
  border-radius: inherit;
}
.card > * { position: relative; z-index: 1; }
.card + .card { margin-top: 14px; }

/* 标题用衬线字体，像毛笔提顿 */
.page-title { font-family: "ZCOOL XiaoWei", "Ma Shan Zheng", "Noto Serif SC", serif; letter-spacing: .02em; }
.section-title {
  font-size: 12px; font-weight: 500; color: var(--ink-soft);
  font-family: "Noto Serif SC", "PingFang SC", serif;
  letter-spacing: .06em;
  margin: 26px 0 12px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 6px;
}
.section-title:first-child { margin-top: 0; }

/* ---------------- 按钮：墨色描边 + 朱砂红 primary ---------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 10px 17px; border-radius: var(--r-full);
  font-size: 14px; font-weight: 500; white-space: nowrap;
  font-family: "Noto Serif SC", "PingFang SC", serif;
  background: var(--glass-strong); color: var(--ink);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-s);
  transition: transform .12s, background .18s, border-color .18s, box-shadow .18s;
}
.btn:hover { border-color: var(--line-strong); box-shadow: var(--shadow-m); }
.btn:active { transform: scale(.97); }
/* 朱砂红 primary：像印泥盖出来的按钮 */
.btn.primary {
  background: var(--accent); color: #fff; border-color: var(--accent);
  box-shadow: 0 6px 18px -6px rgba(178,58,46,.55);
}
.btn.primary:hover {
  background: var(--accent-deep); border-color: var(--accent-deep);
  box-shadow: 0 10px 24px -8px rgba(178,58,46,.65);
}
.btn.ghost { background: transparent; box-shadow: none; }
.btn.danger { color: var(--accent); }
.btn:disabled { opacity: .5; pointer-events: none; }
.btn.sm { padding: 7px 13px; font-size: 12.5px; }

/* ---------------- 输入 ---------------- */
.input, select.input {
  padding: 11px 16px; border-radius: var(--r-full);
  font-size: 13.5px; font-family: inherit; color: var(--ink);
  background: var(--glass-strong);
  border: 1px solid var(--line);
  outline: none; min-width: 0;
  transition: border-color .18s, box-shadow .18s;
}
.input:focus { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-ring); }
.input::placeholder { color: var(--ink-faint); }
select.input { cursor: pointer; appearance: none; padding-right: 34px;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-faint) 50%), linear-gradient(135deg, var(--ink-faint) 50%, transparent 50%);
  background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
.grid.auto { grid-template-columns: repeat(auto-fit, minmax(172px, 1fr)); }

.stat {
  background: var(--glass); border: 1px solid var(--line);
  border-radius: var(--r-l); padding: 17px 19px;
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  box-shadow: var(--shadow-s);
}
.stat .k { font-size: 11.5px; color: var(--ink-faint); margin-bottom: 6px; letter-spacing: .02em; }
.stat .v { font-size: 24px; font-weight: 690; letter-spacing: -.035em; font-variant-numeric: tabular-nums; }
.stat .v small { font-size: 12.5px; font-weight: 520; color: var(--ink-soft); margin-left: 3px; letter-spacing: 0; }

.mod {
  display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
  padding: 19px; text-align: left;
  background: var(--glass); border: 1px solid var(--line);
  border-radius: var(--r-l);
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  box-shadow: var(--shadow-s);
  transition: transform .18s cubic-bezier(.2,.8,.3,1), box-shadow .18s, border-color .18s;
}
.mod:hover { transform: translateY(-2px); box-shadow: var(--shadow-m); border-color: var(--line-strong); }
.mod .emoji { font-size: 24px; line-height: 1; }
.mod .name { font-size: 15px; font-weight: 640; letter-spacing: -.02em; }
.mod .note { font-size: 11.5px; color: var(--ink-faint); }
.mod.soon { opacity: .72; }
.hero-cover img { width: 100%; height: 100%; object-fit: cover; }
.hero-cover .mosaic img { width: 100%; height: 100%; object-fit: cover; }
.btn-play {
  padding: 13px 26px; font-size: 14.5px; font-weight: 640;
  background: linear-gradient(160deg, var(--accent), var(--accent-deep));
  color: #fff; border: none; border-radius: var(--r-full);
  display: inline-flex; align-items: center; gap: 9px;
  box-shadow: 0 14px 30px -14px color-mix(in srgb, var(--accent) 95%, transparent);
  transition: transform .12s, filter .18s;
}
.btn-play:hover { filter: brightness(1.07); }
.btn-play:active { transform: scale(.975); }
.segmented button {
  padding: 8px 17px; border-radius: var(--r-full);
  font-size: 13px; color: var(--ink-soft);
  transition: background .16s, color .16s;
}
.segmented button.active { background: var(--ink); color: var(--paper); font-weight: 600; }
.track-art img { width: 100%; height: 100%; object-fit: cover; }
.heart.on { color: var(--accent); opacity: 1; }
.photo-cell img { width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .3s, transform .4s cubic-bezier(.2,.8,.3,1); }
.photo-cell img.loaded { opacity: 1; }
.photo-cell:hover img { transform: scale(1.055); }
.toolbar .search .input { width: 100%; padding-left: 41px; }
.toolbar .search .input::-webkit-search-cancel-button { -webkit-appearance: none; }
.pc-btn.main {
  width: 44px; height: 44px; font-size: 15px;
  background: linear-gradient(160deg, var(--accent), var(--accent-deep));
  color: #fff; box-shadow: 0 10px 20px -10px color-mix(in srgb, var(--accent) 95%, transparent);
}
.pc-btn.main:hover { filter: brightness(1.07); color: #fff; }
@keyframes fade { from { opacity: 0; } }
.lightbox img { max-width: 92vw; max-height: 84dvh; object-fit: contain; border-radius: var(--r-m); box-shadow: 0 40px 90px -30px rgba(0,0,0,.9); }
.lb-fav.on { color: #ffb3c1; background: rgba(232,70,95,.28); }

/* ---------------- 键值表 ---------------- */
.kv { display: grid; grid-template-columns: 116px 1fr; gap: 10px 16px; font-size: 12.5px; align-items: baseline; }
.kv dt { color: var(--ink-faint); }
.kv dd { margin: 0; word-break: break-all; font-family: ui-monospace, "Cascadia Code", Consolas, monospace; font-size: 12px; color: var(--ink-soft); }
@media (max-width: 560px) { .kv { grid-template-columns: 1fr; gap: 3px 0; } .kv dd { margin-bottom: 9px; }}

.row { display: flex; align-items: center; gap: 10px; padding: 10px 13px; margin-bottom: 8px;
       background: var(--glass-soft); border: 1px solid var(--line); border-radius: var(--r-m); font-size: 12.5px; }
.row .tag { color: var(--ink-faint); font-size: 11px; min-width: 84px; flex-shrink: 0; }
.row .val { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
            font-family: ui-monospace, Consolas, monospace; font-size: 12px; color: var(--ink-soft); }

/* ---------------- 空状态 ---------------- */
.empty { display: flex; flex-direction: column; align-items: center; justify-content: center;
         gap: 12px; padding: 78px 20px; text-align: center; color: var(--ink-soft); }
.empty .big { font-size: 50px; opacity: .5; }
.empty h3 { font-size: 16.5px; color: var(--ink); }
.empty p { margin: 0; font-size: 13px; max-width: 470px; line-height: 1.75; }
.empty code { background: var(--sunken); padding: 2px 8px; border-radius: 7px; font-size: 12px; border: 1px solid var(--line); }

/* ---------------- 轻提示 ---------------- */
.toast-wrap { position: fixed; z-index: 200; left: 50%; transform: translateX(-50%);
              bottom: calc(150px + env(safe-area-inset-bottom,0px));
              display: flex; flex-direction: column; gap: 8px; align-items: center; pointer-events: none; }
.toast {
  padding: 11px 20px; font-size: 12.5px;
  background: var(--glass-strong); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-full);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  box-shadow: var(--shadow-l);
  animation: toast-in .24s cubic-bezier(.2,.9,.3,1);
}
@keyframes toast-in { from { opacity: 0; transform: translateY(12px) scale(.95); } }

/* 滚动条 */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 999px; border: 3px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--ink-faint); background-clip: content-box; }
::-webkit-scrollbar-track { background: transparent; }
.btn-play:disabled { background: var(--sunken); color: var(--ink-faint); cursor: default; box-shadow: none; }
:root[data-theme="dark"] .st-new      { color: #93aaff; }
:root[data-theme="dark"] .st-learning { color: #f0b070; }
:root[data-theme="dark"] .st-young    { color: #5fd3ac; }
:root[data-theme="dark"] .st-mature   { color: #9aa1b3; }
.fc-bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-deep)); border-radius: 4px; }
.rv-actions > .btn-play { width: 100%; justify-content: center; }
.grade-btn b { font-size: 14px; font-weight: 640; }
.grade-btn span { font-size: 11px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.g-again b { color: #d9455f; }
.g-hard b { color: #c07420; }
.g-good b { color: var(--water-deep); }
.g-easy b { color: #3d6b4c; }

kbd {
  display: inline-block; padding: 1px 6px; margin-left: 4px;
  font-family: inherit; font-size: 11px;
  background: rgba(255,255,255,.22); border-radius: 5px;
  border: 1px solid rgba(255,255,255,.28);
}

@media (max-width: 520px) {
  .grade-btn b { font-size: 13px; }
  .grade-btn span { font-size: 10px; }}
.hourglass {
  width: 76px; height: 76px; border-radius: 50%;
  display: grid; place-items: center; position: relative;
  background: var(--glass); border: 1px solid var(--line);
  box-shadow: var(--shadow-m);
}
.hourglass::after {
  content: ''; position: absolute; inset: -1px; border-radius: 50%;
  border: 2px solid transparent; border-top-color: var(--accent);
  animation: hg-spin 1s linear infinite;
}
.hourglass span {
  font-size: 30px; line-height: 1;
  animation: hg-flip 2.4s cubic-bezier(.6,0,.4,1) infinite;
}
@keyframes hg-flip {
  0%, 42%  { transform: rotate(0deg); }
  50%, 92% { transform: rotate(180deg); }
  100%     { transform: rotate(360deg); }
}
@keyframes hg-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .hourglass span { animation: none; }
  .hourglass::after { animation-duration: 2.4s; }}

/* ---------- 导航按钮的按下 / 选中反馈 ---------- */
.tab, .nav-item { position: relative; }
.tab .ico, .tab-ico, .nav-item .ico, .nav-ico { transition: transform .24s cubic-bezier(.2,.9,.3,1); }
.tab:active .ico, .tab:active .tab-ico, .nav-item:active .ico, .nav-item:active .nav-ico { transform: scale(.78); }
.tab.active .ico, .tab.on .tab-ico, .nav-item.active .ico, .nav-item.on .nav-ico { animation: tab-pop .38s cubic-bezier(.2,.9,.3,1); }
@keyframes tab-pop {
  0%   { transform: scale(.66) translateY(0); }
  55%  { transform: scale(1.26) translateY(-2px); }
  100% { transform: scale(1.1) translateY(-1px); }
}
.tab.active::before, .tab.on::before, .nav-item.active::before, .nav-item.on::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: var(--accent); opacity: .16;
  animation: tab-ripple .5s cubic-bezier(.2,.9,.3,1);
}
@keyframes tab-ripple { from { transform: scale(.6); opacity: .38; } to { transform: scale(1); opacity: .16; } }
.tab:active { background: var(--sunken); }
.nav-item:active { background: var(--sunken); }
@media (prefers-reduced-motion: reduce) {
  .tab.active .ico, .tab.on .tab-ico, .nav-item.active .ico, .nav-item.on .nav-ico,
  .tab.active::before, .tab.on::before, .nav-item.active::before, .nav-item.on::before { animation: none; }}

/* ---------- 视图切换：内容依次淡入上浮 ---------- */
.view-enter > * { animation: fade-up .42s cubic-bezier(.2,.8,.3,1) backwards; }
.view-enter > *:nth-child(1) { animation-delay: .00s; }
.view-enter > *:nth-child(2) { animation-delay: .05s; }
.view-enter > *:nth-child(3) { animation-delay: .10s; }
.view-enter > *:nth-child(4) { animation-delay: .15s; }
.view-enter > *:nth-child(5) { animation-delay: .20s; }
.view-enter > *:nth-child(6) { animation-delay: .25s; }
.view-enter > *:nth-child(n+7) { animation-delay: .28s; }
@keyframes fade-up { from { opacity: 0; transform: translateY(14px); } }
@media (prefers-reduced-motion: reduce) { .view-enter > * { animation: none; }}
.hh-stats b { color: var(--ink); font-weight: 660; font-variant-numeric: tabular-nums; }
.hh-stats i { width: 3px; height: 3px; border-radius: 50%; background: var(--ink-faint); opacity: .6; }

@media (max-width: 640px) {
  .hh-actions .btn-play, .hh-actions .btn { flex: 1 1 auto; justify-content: center; }}
.today-ring span { position: relative; z-index: 1; font-size: 15px; font-weight: 680; font-variant-numeric: tabular-nums; }
.si-art img { width: 100%; height: 100%; object-fit: cover; }
.storebar i { display: block; transition: width .5s cubic-bezier(.2,.8,.3,1); }
.storelegend span { display: flex; align-items: center; gap: 7px; }
.storelegend i { width: 9px; height: 9px; border-radius: 3px; display: block; }
.storelegend b { color: var(--ink); font-weight: 600; }

/* 手机端微调 */
@media (max-width: 640px) {
  .stat .v { font-size: 22px; }
  .mod { padding: 16px; }
  .today-card .btn-play { width: 100%; justify-content: center; }}
.hh-metrics > div { flex: 1 1 0; min-width: 66px; padding-right: 14px; }
.hh-metrics b {
  display: block; font-size: 23px; font-weight: 700; letter-spacing: -.035em;
  font-variant-numeric: tabular-nums; line-height: 1.15;
}
.hh-metrics span { font-size: 11px; color: var(--ink-faint); letter-spacing: .01em; }
.metrics .metric b { display: block; font-size: 20px; font-weight: 690; letter-spacing: -.035em; font-variant-numeric: tabular-nums; }
.metrics .metric span { font-size: 10.5px; color: var(--ink-faint); white-space: nowrap; }
.metrics > i { width: 1px; height: 22px; background: var(--line); flex-shrink: 0; }

@media (max-width: 719px) {
  /* 手机上完全不显示顶部胶囊，导航只靠底部
     （平板 720–899 不在此列 —— 顶栏放得下，见上面「平板」块） */
  .topnav { display: none !important; }

  .content { padding: calc(6px + env(safe-area-inset-top, 0px)) 14px 196px; }

  /* 页面标题变粘性细条，带主题 / 退出 */
  .page-head {
    position: sticky; top: 0; z-index: 30;
    margin: 0 -14px 14px; padding: 9px 14px;
    gap: 6px; align-items: center;
    background: var(--bg-glass);
    backdrop-filter: blur(20px) saturate(180%);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    border-bottom: 1px solid var(--line);
  }
  .page-title { font-size: 18.5px; }
  .page-head .nav-icon-btn { width: 34px; height: 34px; font-size: 14px; }
  .page-actions { font-size: 12px !important; }

  .section-title { margin: 18px 0 9px; font-size: 10.5px; letter-spacing: .08em; }

  /* 统计卡强制两列（之前 auto-fit 在 390px 下会塌成一列 → 滑不到头） */
  .grid.auto { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }

  .stat { padding: 13px 15px; border-radius: var(--r-m); }
  .stat .k { font-size: 11px; margin-bottom: 3px; }
  .stat .v { font-size: 20px; }

  .card { padding: 16px; border-radius: var(--r-l); }
  .card + .card { margin-top: 10px; }
  .hh-metrics b { font-size: 20px; }
  .hh-metrics > div { min-width: 58px; padding-right: 8px; }
  .hh-actions .btn-play, .hh-actions .btn { flex: 1 1 0; justify-content: center; padding: 11px 12px; font-size: 13.5px; }

  .mod { padding: 13px 11px; gap: 7px; border-radius: var(--r-m); }
  .mod .name { font-size: 13px; }
  .mod .note { font-size: 10.5px; }
  .metrics .metric b { font-size: 18px; }
  .metrics .metric span { font-size: 10px; }

  /* 底部胶囊导航更紧凑 */
  .tabbar { padding: 6px; border-radius: var(--r-l); }
  .tab { padding: 6px 2px; font-size: 10px; gap: 2px; }
  .tab .ico { font-size: 17px; }}

@media (max-width: 380px) {
  .hh-metrics b { font-size: 18px; }}
.mh-art img { width: 100%; height: 100%; object-fit: cover; }
.mh-actions .btn-play { padding: 9px 16px; font-size: 13px; }
.mh-actions .btn { padding: 9px 12px; }

/* ---------- 工具栏：手机端搜索独占一行 ---------- */
@media (max-width: 640px) {
  .mh-actions .btn-play { padding: 8px 13px; font-size: 12.5px; }
  .mh-actions .btn { padding: 8px 11px; }}
.ub-track i { display: block; height: 100%; width: 0;
              background: linear-gradient(90deg, var(--accent), var(--accent-deep));
              border-radius: 999px; transition: width .25s ease-out; }
.upload-bar.done .ub-track i { background: linear-gradient(90deg, #34c08b, #3d6b4c); }
.ac-art img { width: 100%; height: 100%; object-fit: cover; }

/* ============================================================
   手机浏览器的视口修正
   安卓 Edge / Chrome 的地址栏会随滚动伸缩，导致 100dvh 不断变化，
   固定定位的底部导航和播放器就会跟着跳、界面像被"缩小"了。
   ============================================================ */
html {
  height: 100%;
  overscroll-behavior: none;          /* 关掉下拉刷新和橡皮筋回弹 */
  -webkit-text-size-adjust: 100%;
}
body {
  min-height: 100%;
  overscroll-behavior-y: none;
  touch-action: manipulation;         /* 去掉 300ms 点击延迟 */
}
/* 用 svh（小视口高度，地址栏展开时的值）而不是 dvh（会变），布局才稳定 */
.app { min-height: 100svh; }
@keyframes hero-breathe {
  from { transform: translateX(-50%) scale(1); opacity: .82; }
  to   { transform: translateX(-50%) scale(1.1); opacity: 1; }
}
@keyframes emoji-float {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  45%      { transform: translateY(-7px) rotate(-6deg); }
  70%      { transform: translateY(2px) rotate(3deg); }
}
@keyframes grad-slide { to { background-position: 260% 0; } }

/* ---------- 胶囊按钮 ---------- */
.pill {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 13px 26px; border-radius: var(--r-full);
  font-size: 15px; font-weight: 620; letter-spacing: -.01em;
  border: 1px solid transparent;
  transition: transform .22s cubic-bezier(.2,.9,.3,1), box-shadow .28s,
              background .28s, border-color .28s, color .28s;
}
.pill-ico { font-size: 16px; transition: transform .3s cubic-bezier(.2,.9,.3,1); }
.pill:hover .pill-ico { transform: scale(1.22) rotate(-8deg); }
.pill:active { transform: scale(.965); }

.pill.dark {
  background: var(--ink); color: var(--paper);
  box-shadow: 0 8px 20px -10px rgba(0,0,0,.7);
}
.pill.dark:hover {
  transform: translateY(-2px);
  box-shadow: 0 16px 34px -12px rgba(0,0,0,.75), 0 0 0 4px var(--accent-ring);
}
.pill.light {
  background: var(--glass-strong); color: var(--ink);
  border-color: var(--line); box-shadow: var(--shadow-s);
}
.pill.light:hover {
  transform: translateY(-2px);
  border-color: var(--accent); color: var(--accent);
  box-shadow: var(--shadow-m), 0 0 0 4px var(--accent-ring);
}
/* 扫光：鼠标移上去一道光刷过 */
.pill::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 35%, rgba(255,255,255,.42) 50%, transparent 65%);
  transform: translateX(-130%);
  transition: transform .75s cubic-bezier(.2,.8,.3,1);
}
.pill:hover::after { transform: translateX(130%); }

/* ---------- 功能卡片行 ---------- */
.feat-row {
  display: grid; gap: 12px;
  /* auto-fit：有几张卡就排几列。
     之前写死 repeat(6)，模块减到 5 个之后就空出一格，看着像掉了图标。 */
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  margin: 6px auto 26px; max-width: 940px; padding: 0 4px;
}
@media (max-width: 900px) { .feat-row { grid-template-columns: repeat(3, minmax(0, 1fr)); max-width: 520px; }}
@media (max-width: 380px) { .feat-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }}

.feat {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 22px 10px 18px;
  background: var(--glass); border: 1px solid var(--line);
  border-radius: var(--r-l);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  box-shadow: var(--shadow-s);
  transition: transform .26s cubic-bezier(.2,.9,.3,1),
              border-color .26s, box-shadow .3s, background .26s;
}
.feat:hover {
  transform: translateY(-7px);
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  box-shadow: 0 22px 40px -18px rgba(60,90,220,.42), 0 0 0 4px var(--accent-ring);
  background: var(--glass-strong);
}
.feat:active { transform: translateY(-3px) scale(.975); }

.feat-ico {
  width: 46px; height: 46px; border-radius: 15px;
  display: grid; place-items: center;
  color: var(--ink-soft); background: var(--sunken);
  transition: color .26s, background .26s, transform .32s cubic-bezier(.2,.9,.3,1), box-shadow .3s;
}
.feat-ico svg { width: 23px; height: 23px; display: block; }
.feat:hover .feat-ico {
  color: #fff;
  background: linear-gradient(145deg, var(--accent), var(--accent-deep));
  transform: scale(1.09) rotate(-4deg);
  box-shadow: 0 10px 20px -10px color-mix(in srgb, var(--accent) 90%, transparent);
}
.feat-label { font-size: 13.5px; font-weight: 620; letter-spacing: -.01em; transition: color .22s; }
.feat:hover .feat-label { color: var(--accent); }
.feat-stat { font-size: 10.5px; color: var(--ink-faint); }
.feat.soon { opacity: .6; }
.feat.soon:hover { opacity: .85; }

.feat::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 35%, rgba(255,255,255,.5) 50%, transparent 65%);
  transform: translateX(-130%);
  transition: transform .8s cubic-bezier(.2,.8,.3,1);
}
.feat:hover::before { transform: translateX(130%); }
:root[data-theme="dark"] .live-pill { color: #5fd3ac; background: rgba(52,192,139,.14); }
.live-pill b { font-weight: 680; }
@keyframes live-pulse {
  0%   { transform: scale(.5); opacity: .7; }
  100% { transform: scale(1.7); opacity: 0; }
}

/* ---------- 手机端 ---------- */
@media (max-width: 640px) {
  .pill { padding: 11px 20px; font-size: 13.5px; }
  .hero2-btns .pill { flex: 1 1 0; justify-content: center; }
  .feat { padding: 16px 8px 14px; gap: 8px; border-radius: var(--r-m); }
  .feat-ico { width: 40px; height: 40px; border-radius: 13px; }
  .feat-ico svg { width: 20px; height: 20px; }
  .feat-label { font-size: 12.5px; }
  .feat-stat { font-size: 10px; }}

@media (prefers-reduced-motion: reduce) {
  .pill::after, .feat::before { display: none; }}

/* 手机端统一把毛玻璃调薄：backdrop-filter 是 GPU 大户，
   20px 降到 10px 肉眼几乎看不出，但滚动会明显顺很多。 */
@media (max-width: 899px) {
  .topnav, .tabbar, .card, .stat, .mod, .feat, .metrics, .track-list,
  .music-head, .segmented, .player, .upload-bar, .album-card {
    backdrop-filter: blur(10px) saturate(150%);
    -webkit-backdrop-filter: blur(10px) saturate(150%);
  }
  /* 列表项一律不做毛玻璃，它们数量多 */
  .track, .row, .url-item, .strip-item { backdrop-filter: none; -webkit-backdrop-filter: none; }}

/* 顶栏右侧的主题 / 退出 */
.nav-tail {
  display: flex; align-items: center; gap: 2px;
  margin-left: 6px; padding-left: 8px; border-left: 1px solid var(--line);
}
@media (min-width: 720px) { .m-only { display: none !important; }}
@media (max-width: 719px) { .nav-tail { display: none; }}

/* 首页时把页面标题藏掉 */
body.on-home .page-title { display: none; }
body.on-home .page-head { border-bottom-color: transparent; justify-content: flex-end; }

/* 功能卡片再厚一点，接近参考站的比例 */
.feat { padding: 26px 10px 22px; }
.feat-ico { width: 52px; height: 52px; border-radius: 17px; }
.feat-ico svg { width: 26px; height: 26px; }
.feat-label { font-size: 14px; }
@media (max-width: 640px) {
  .feat { padding: 16px 8px 14px; }
  .feat-ico { width: 40px; height: 40px; border-radius: 13px; }
  .feat-ico svg { width: 20px; height: 20px; }
  .feat-label { font-size: 12.5px; }}

/* ============================================================
   每个模块一套配色 —— 水墨色系：玉绿 / 黛青 / 赭石 / 墨灰，
   情报站不写规则、走默认朱砂红
   ============================================================ */
.feat[data-m="photos"]   { --fc: #6b7280; --fc2: #494f59; }
.feat[data-m="music"]    { --fc: #6b7280; --fc2: #494f59; }
.feat[data-m="quiz"]     { --fc: #5f8f72; --fc2: #3d6b4c; }
.feat[data-m="stock"]    { --fc: #c07a3a; --fc2: #96551f; }
.feat[data-m="review"]   { --fc: #5f8f72; --fc2: #3d6b4c; }
.feat[data-m="learn"]    { --fc: #5a7d9a; --fc2: #3d5c78; }
.feat[data-m="settings"] { --fc: #6b7280; --fc2: #494f59; }

.feat-ico {
  color: var(--fc, var(--ink-soft));
  background: color-mix(in srgb, var(--fc, var(--accent)) 15%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fc, var(--accent)) 22%, transparent);
}
.feat:hover .feat-ico {
  color: #fff;
  background: linear-gradient(145deg, var(--fc), var(--fc2));
  box-shadow: 0 10px 22px -10px color-mix(in srgb, var(--fc2) 85%, transparent);
}
/* 卡片的悬停光晕也用它自己的颜色 */
.feat:hover {
  border-color: color-mix(in srgb, var(--fc, var(--accent)) 50%, transparent);
  box-shadow: 0 22px 40px -18px color-mix(in srgb, var(--fc2, #3a63e0) 45%, transparent),
              0 0 0 4px color-mix(in srgb, var(--fc, var(--accent)) 16%, transparent);
}
.feat:hover .feat-label { color: var(--fc, var(--accent)); }

/* ============================================================
   登录设备列表
   ============================================================ */
.dev-row {
  cursor: default;
  transition: border-color .18s, background .18s;
}
.dev-row:hover { border-color: var(--line-strong); background: var(--glass-strong); }
.dev-ico { font-size: 19px; flex-shrink: 0; line-height: 1; }
.dev-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.dev-name {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 620; letter-spacing: -.01em;
}
.dev-name em {
  font-style: normal; font-size: 10.5px; font-weight: 620;
  color: var(--accent); background: var(--accent-soft);
  padding: 1.5px 8px; border-radius: var(--r-full);
}
.dev-sub { font-size: 11px; color: var(--ink-faint); }

.action {
  display: flex; flex-direction: column; align-items: flex-start; gap: 5px;
  padding: 13px 16px; text-align: left;
  background: var(--glass); border: 1px solid var(--line);
  border-radius: var(--r-m);
  transition: transform .2s cubic-bezier(.2,.9,.3,1),
              border-color .2s, box-shadow .25s, background .2s;
}
.action:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  box-shadow: var(--shadow-m), 0 0 0 3px var(--accent-ring);
  background: var(--glass-strong);
}
.action:active { transform: translateY(0) scale(.985); }
.action:disabled { opacity: .6; cursor: default; transform: none; box-shadow: none; }
.action.primary .act-top { color: var(--accent); }
.jb-track i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--accent), var(--accent-deep));
  border-radius: 999px; transition: width .3s ease-out;
}
/* 拿不到具体进度时（比如普通扫描）走来回滑动的不确定态 */
.job-bar.indeterminate .jb-track i {
  width: 35% !important;
  animation: job-slide 1.1s ease-in-out infinite;
}
@keyframes job-slide {
  0%   { transform: translateX(-110%); }
  100% { transform: translateX(320%); }
}

/* ============================================================
   记忆曲线 · 知识点打卡
   ============================================================ */

/* ---- 顶部：今天还剩几个 ---- */
.ck-hero {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 18px 20px; margin-bottom: 14px;
  background: var(--glass-strong); border: 1px solid var(--line);
  border-radius: var(--r-l);
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  box-shadow: var(--shadow-s);
}
.ck-hero-l { flex: 1; min-width: 200px; }
.ck-date { font-size: 12px; color: var(--ink-faint); margin-bottom: 5px; }
.ck-big { font-size: 17px; font-weight: 640; letter-spacing: -.02em; }
/* ---- 记忆曲线：窗口化鼓励语 ---- */
.ck-quote {
  margin-top: 10px; padding: 9px 13px;
  border-radius: var(--r-s);
  font-size: 12.5px; font-weight: 500; line-height: 1.55;
  color: var(--ink-soft); font-style: italic;
  background: var(--sunken); border: 1px solid var(--line);
}
body.on-home .ck-quote { display: none; }

.ck-big b { color: var(--accent); font-size: 22px; font-variant-numeric: tabular-nums; }

/* ---- 四格统计 ---- */
.ck-stats {
  display: grid; gap: 10px; margin-bottom: 18px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 560px) { .ck-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }}
.ck-stat {
  padding: 14px 12px; text-align: center;
  background: var(--glass); border: 1px solid var(--line);
  border-radius: var(--r-m);
  transition: transform .2s cubic-bezier(.2,.9,.3,1), border-color .2s, box-shadow .25s;
}
.ck-stat:hover { transform: translateY(-2px); border-color: var(--line-strong); box-shadow: var(--shadow-s); }
.ck-stat b {
  display: block; font-size: 24px; font-weight: 700; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums; line-height: 1.1;
}
.ck-stat span { font-size: 11px; color: var(--ink-faint); }
.ck-stat.hot b { color: #ff8c1a; }
.ck-stat.hot { border-color: color-mix(in srgb, #ff8c1a 40%, transparent);
               background: color-mix(in srgb, #ff8c1a 8%, var(--glass)); }

/* ---- 柱状图 ---- */
.ck-chart-wrap {
  padding: 16px 18px 14px; margin-bottom: 20px;
  background: var(--glass); border: 1px solid var(--line);
  border-radius: var(--r-l);
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
}
.ck-chart-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.ck-range { display: flex; gap: 2px; padding: 2px; background: var(--sunken); border-radius: var(--r-full); }
.ck-rb {
  padding: 4px 11px; border-radius: var(--r-full);
  font-size: 11px; font-weight: 600; color: var(--ink-faint);
  transition: background .18s, color .18s;
}
.ck-rb:hover { color: var(--ink); }
.ck-rb.on { background: var(--paper); color: var(--ink); box-shadow: var(--shadow-s); }

.ck-chart {
  display: flex; align-items: flex-end; gap: 2px;
  height: 118px; padding-top: 16px;
}
.ck-bar {
  flex: 1 1 0; min-width: 0; height: 100%;
  /* 关键：<button> 默认有 padding 1px 6px，而每根柱子只有 ~9px 宽，
     左右各 6px 的内边距会把内容盒挤成 0 宽，里面 width:100% 的柱子就消失了。
     所以这里必须把 padding / border / background 全部清掉。 */
  padding: 0; border: 0; background: none;
  display: flex; flex-direction: column; justify-content: flex-end;
  position: relative; border-radius: 3px; cursor: pointer;
}
.ck-bar i {
  display: block; width: 100%; height: var(--h, 0%);
  min-height: 3px; border-radius: 3px 3px 2px 2px;
  background: var(--line-strong);
  transition: height .4s cubic-bezier(.2,.9,.3,1), background .2s, filter .18s, transform .18s;
  transform-origin: bottom;
}
.ck-bar.has i { background: linear-gradient(180deg, var(--jade-1), var(--accent-deep)); }
.ck-bar.today i { background: linear-gradient(180deg, #ffc46b, #ff8c1a); }
.ck-bar:hover i { filter: brightness(1.18); transform: scaleY(1.04); }
.ck-bar.on i { box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px var(--accent); }
.ck-bar em {
  position: absolute; top: -2px; left: 50%; transform: translateX(-50%);
  font-size: 8.5px; font-style: normal; font-weight: 700;
  color: var(--ink-faint); opacity: 0; transition: opacity .18s;
  pointer-events: none;
}
.ck-bar.has em, .ck-bar:hover em { opacity: 1; }
.ck-bar.today em { color: #ff8c1a; }

.ck-axis {
  display: flex; justify-content: space-between;
  margin-top: 7px; font-size: 10px; color: var(--ink-faint);
}
.ck-chart-foot {
  display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--line);
  font-size: 11.5px; color: var(--ink-faint);
}
.ck-chart-foot b { color: var(--ink); font-weight: 680; }
#ck-daytip { color: var(--accent); }
.ck-item.is-due { border-left: 3px solid var(--accent); }
.ck-list.later .ck-item { opacity: .78; }
.ck-name { font-size: 14px; font-weight: 640; letter-spacing: -.015em; }
.ck-cat {
  font-size: 10px; font-weight: 620; padding: 1.5px 7px; border-radius: var(--r-full);
  color: var(--ink-soft); background: var(--sunken);
}
.ck-item-sub b { color: var(--ink-soft); font-weight: 660; }
.ck-go { padding: 8px 20px; font-size: 13px; }

/* ---- 添加知识点 ---- */
.ck-add {
  display: flex; gap: 9px; flex-wrap: wrap; align-items: center;
  margin-top: 20px; padding: 14px 16px;
  background: var(--glass); border: 1px dashed var(--line-strong);
  border-radius: var(--r-m);
}
.ck-add .input { flex: 1 1 220px; }
.ck-add select.input { flex: 0 0 118px; }

/* ---- 排期说明 ---- */
.ck-plan {
  margin-top: 16px; padding: 14px 16px;
  background: var(--sunken); border: 1px solid var(--line);
  border-radius: var(--r-m); font-size: 12.5px; color: var(--ink-soft);
}
.ck-plan summary { cursor: pointer; font-weight: 620; color: var(--ink); user-select: none; }
.ck-plan summary:hover { color: var(--accent); }
.ck-plan p { margin: 12px 0 10px; line-height: 1.75; }
.ck-plan-row { display: flex; gap: 7px; flex-wrap: wrap; margin: 10px 0; }
.ck-chip {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 7px 12px; border-radius: var(--r-m);
  background: var(--paper); border: 1px solid var(--line);
}
.ck-chip b { font-size: 12px; font-weight: 660; }
.ck-chip i { font-size: 10px; font-style: normal; color: var(--ink-faint); }
.ck-plan-note { color: var(--ink-faint) !important; font-size: 11.5px !important; }

@media (max-width: 640px) {
  .ck-hero { padding: 14px 15px; gap: 12px; }
  .ck-big { font-size: 15px; }
  .ck-chart { height: 96px; gap: 1.5px; }
  .ck-chart-wrap { padding: 13px 13px 12px; }
  .ck-bar em { font-size: 8px; }
  .ck-go { padding: 7px 15px; font-size: 12.5px; }}

/* ---- 知识点卡片网格：每个卡片带自己的迷你柱状图 ---- */
.ck-grid {
  display: grid; gap: 11px;
  grid-template-columns: repeat(auto-fill, minmax(228px, 1fr));
}
@media (max-width: 520px) { .ck-grid { grid-template-columns: 1fr; }}
.ck-grid.later { opacity: .84; }

.ck-card {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: 9px;
  padding: 14px 15px 12px; cursor: pointer;
  background: var(--glass); border: 1px solid var(--line);
  border-radius: var(--r-m);
  transition: transform .2s cubic-bezier(.2,.9,.3,1), border-color .2s, box-shadow .25s, background .2s;
}
.ck-card:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  box-shadow: var(--shadow-m), 0 0 0 3px var(--accent-ring);
  background: var(--glass-strong);
}
.ck-card.is-due { border-left: 3px solid var(--accent); }
.ck-card-top { display: flex; align-items: center; gap: 8px; }
.ck-card-top .ck-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ck-card-meta { display: flex; align-items: center; gap: 9px; font-size: 11px; color: var(--ink-faint); flex-wrap: wrap; }
.ck-ontime b { color: #3d6b4c; font-weight: 700; }
.ck-late { color: #d9822b; }
.ck-streak { color: #ff8c1a; font-weight: 640; }
.ck-card-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding-top: 9px; border-top: 1px solid var(--line);
}
.ck-card-foot .ck-stage { font-size: 11px; color: var(--ink-faint); }
.ck-card-foot .ck-go { padding: 6px 15px; font-size: 12px; }

/* 卡片里的迷你柱状图（14 天） */
.ck-mini { display: flex; align-items: flex-end; gap: 2px; height: 30px; }
.ck-mini i {
  flex: 1 1 0; min-width: 0; height: var(--h, 0%); min-height: 2px;
  border-radius: 2px; background: color-mix(in srgb, var(--accent) 16%, transparent);
  transition: height .35s cubic-bezier(.2,.9,.3,1), background .2s;
}
.ck-mini i.has { background: linear-gradient(180deg, var(--jade-1), var(--accent-deep)); }
.ck-card.is-due .ck-mini i.has { background: linear-gradient(180deg, #a9c9b4, #4a7c59); }

/* ---- 弹层（通用） ---- */
.modal-wrap {
  position: fixed; inset: 0; z-index: 120;
  display: grid; place-items: center; padding: 18px;
  background: color-mix(in srgb, #0b1020 48%, transparent);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  opacity: 0; transition: opacity .22s;
}
.modal-wrap.on { opacity: 1; }
.modal {
  position: relative; width: min(560px, 100%); max-height: 88vh; overflow: auto;
  padding: 22px 22px 18px;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-xl, 22px);
  box-shadow: var(--shadow-l);
  transform: translateY(12px) scale(.98);
  transition: transform .26s cubic-bezier(.2,.9,.3,1);
}
.modal-wrap.on .modal { transform: none; }
.modal-x {
  position: absolute; top: 12px; right: 12px;
  width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center; font-size: 14px; color: var(--ink-faint);
  transition: background .18s, color .18s, transform .18s;
}
.modal-x:hover { background: var(--sunken); color: var(--ink); transform: rotate(90deg); }

/* ---- 知识点详情 ---- */
.ckm-head { margin-bottom: 14px; padding-right: 34px; }
.ckm-title { font-size: 19px; font-weight: 700; letter-spacing: -.025em; }
.ckm-sub { font-size: 12px; color: var(--ink-faint); margin-top: 4px; }

.ckm-praise {
  display: flex; align-items: center; gap: 11px;
  padding: 13px 15px; margin-bottom: 16px;
  border-radius: var(--r-m); font-size: 13px; font-weight: 600; line-height: 1.5;
  background: var(--sunken); border: 1px solid var(--line);
}
.ckm-ico { font-size: 24px; flex-shrink: 0; }
.ckm-praise.lv1 { background: color-mix(in srgb, #d9822b 10%, transparent); border-color: color-mix(in srgb, #d9822b 30%, transparent); color: #b96a1c; }
.ckm-praise.lv2 { background: color-mix(in srgb, #4a7c59 8%, transparent); border-color: color-mix(in srgb, #4a7c59 24%, transparent); color: #3d6b4c; }
.ckm-praise.lv3 { background: color-mix(in srgb, #2f9e8a 12%, transparent); border-color: color-mix(in srgb, #2f9e8a 30%, transparent); color: #1d7a6a; }
.ckm-praise.lv4 { background: color-mix(in srgb, #ff8c1a 12%, transparent); border-color: color-mix(in srgb, #ff8c1a 32%, transparent); color: #c96a10; }
.ckm-praise.lv5 { background: linear-gradient(135deg, color-mix(in srgb, #ffc46b 20%, transparent), color-mix(in srgb, #ff8c1a 14%, transparent)); border-color: color-mix(in srgb, #ff8c1a 38%, transparent); color: #b8610a; }

.ckm-nums {
  display: grid; gap: 8px; margin-bottom: 18px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.ckm-num {
  padding: 11px 6px; text-align: center;
  background: var(--sunken); border-radius: var(--r-s, 12px);
}
.ckm-num b { display: block; font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.ckm-num span { font-size: 10.5px; color: var(--ink-faint); }
.ckm-num.big b { color: #3d6b4c; }

.ckm-section {
  font-size: 11.5px; font-weight: 660; color: var(--ink-faint);
  margin: 18px 0 10px; letter-spacing: .02em;
}
.ckm-rows { display: flex; flex-direction: column; gap: 1px; margin-top: 16px; }
.ckm-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 9px 12px; font-size: 12.5px; background: var(--sunken);
}
.ckm-row:first-child { border-radius: var(--r-s, 12px) var(--r-s, 12px) 0 0; }
.ckm-row:last-child { border-radius: 0 0 var(--r-s, 12px) var(--r-s, 12px); }
.ckm-row span { color: var(--ink-faint); }
.ckm-row b { font-weight: 660; }

.ckm-recent { display: flex; gap: 6px; flex-wrap: wrap; }
.ckm-chip {
  padding: 5px 10px; border-radius: var(--r-full);
  font-size: 11px; font-variant-numeric: tabular-nums;
  background: color-mix(in srgb, #4a7c59 14%, transparent); color: #3d6b4c;
}
.ckm-chip.late { background: color-mix(in srgb, #d9822b 14%, transparent); color: #b96a1c; }
.ckm-chip i { font-style: normal; opacity: .8; font-size: 10px; }

.ckm-act { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 20px; }
.ckm-act .btn, .ckm-act .btn-play { flex: 1 1 auto; justify-content: center; }

@media (max-width: 560px) {
  .ckm-nums { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .modal { padding: 18px 16px 14px; }
  .ckm-title { font-size: 17px; }}

/* ============================================================
   情报站 —— 动漫绿
   ============================================================ */
.intel-hero {
  position: relative; overflow: hidden;
  border-radius: var(--r-xl, 22px);
  margin-bottom: 20px;
  box-shadow: var(--shadow-m);
  border: 1px solid var(--line-strong);
  min-height: 250px;
  display: flex; flex-direction: column; justify-content: flex-end;
}
.scene {
  position: absolute; inset: 0; width: 100%; height: 100%;
  display: block; object-fit: cover;
}
.intel-hero::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, transparent 34%, rgba(30,28,22,.10) 62%, rgba(30,28,22,.52) 100%);
}
.intel-quote {
  position: relative; z-index: 2;
  padding: 30px 30px 26px;
  text-align: center;
}
.iq-text {
  font-size: clamp(17px, 2.6vw, 26px);
  font-weight: 700; line-height: 1.55; letter-spacing: -.02em;
  color: #ffffff;
  text-shadow: 0 2px 14px rgba(30,28,22,.75), 0 1px 3px rgba(30,28,22,.9);
}
.iq-author {
  margin-top: 11px; font-size: 13px; font-weight: 600;
  color: rgba(255,255,255,.94);
  text-shadow: 0 1px 8px rgba(30,28,22,.8);
}
.intel-day {
  position: absolute; top: 14px; right: 16px; z-index: 2;
  padding: 4px 11px; border-radius: var(--r-full);
  font-size: 10.5px; font-weight: 600;
  color: var(--accent-deep); background: rgba(255,253,245,.78);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}

.intel-tabs { display: flex; gap: 9px; margin-bottom: 18px; flex-wrap: wrap; }
.itab {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 17px; border-radius: var(--r-full);
  font-size: 13px; font-weight: 620;
  background: var(--glass); border: 1px solid var(--line); color: var(--ink-soft);
  transition: transform .2s cubic-bezier(.2,.9,.3,1), border-color .2s, background .2s, color .2s, box-shadow .25s;
}
.itab:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--accent) 40%, transparent); color: var(--ink); }
.itab.on {
  background: linear-gradient(145deg, var(--accent), var(--accent-deep));
  border-color: transparent; color: #fff;
  box-shadow: 0 10px 22px -12px rgba(142,42,32,.8);
}
.itab-ico { font-size: 15px; }
.itab-n {
  font-size: 10.5px; font-weight: 700; padding: 1px 7px;
  border-radius: var(--r-full); background: var(--sunken); color: var(--ink-faint);
}
.itab.on .itab-n { background: rgba(255,255,255,.26); color: #fff; }

.intel-list { display: flex; flex-direction: column; gap: 11px; }
.intel-card {
  padding: 16px 18px;
  background: var(--glass); border: 1px solid var(--line);
  border-radius: var(--r-m);
  transition: transform .2s cubic-bezier(.2,.9,.3,1), border-color .2s, box-shadow .25s, background .2s;
}
.intel-card:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--accent) 36%, transparent);
  box-shadow: var(--shadow-m), 0 0 0 3px color-mix(in srgb, var(--accent) 10%, transparent);
  background: var(--glass-strong);
}
.ic-top { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; margin-bottom: 8px; }
.ic-tag {
  flex-shrink: 0; padding: 2px 9px; border-radius: var(--r-full);
  font-size: 10.5px; font-weight: 660;
  color: var(--accent-deep); background: var(--accent-soft);
}
.ic-title { font-size: 14.5px; font-weight: 660; letter-spacing: -.02em; line-height: 1.4; margin: 0; }
.ic-body { font-size: 12.5px; line-height: 1.8; color: var(--ink-soft); margin: 0 0 11px; }
.ic-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding-top: 10px; border-top: 1px solid var(--line); flex-wrap: wrap;
}
.ic-src { font-size: 11px; color: var(--ink-faint); }
.ic-link {
  font-size: 11.5px; font-weight: 620; color: var(--accent); white-space: nowrap;
  transition: color .18s, transform .18s;
}
.ic-link:hover { color: var(--accent-deep); text-decoration: underline; }

/* 「某某人说」 */
.intel-card.say { position: relative; padding-left: 22px; }
.intel-card.say::before {
  content: ''; position: absolute; left: 0; top: 14px; bottom: 14px; width: 3px;
  border-radius: 3px; background: linear-gradient(180deg, #8fbfa0, #4a7c59);
}
.say-mark {
  position: absolute; top: 2px; right: 16px;
  font-size: 54px; line-height: 1; font-weight: 800;
  color: color-mix(in srgb, #4a7c59 13%, transparent); pointer-events: none;
}
.say-text {
  position: relative; margin: 0 0 13px;
  font-size: 14px; line-height: 1.8; font-weight: 520;
  color: var(--ink);
}
.say-by { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.say-avatar {
  width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center;
  font-size: 14px; font-weight: 700; color: #fff;
  background: linear-gradient(145deg, #5f8f72, #4a7c59);
}
.say-who { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.say-who b { font-size: 12.5px; font-weight: 660; }
.say-who i { font-size: 11px; font-style: normal; color: var(--ink-faint); }

.intel-note {
  margin: 22px 0 0; font-size: 11px; line-height: 1.75;
  color: var(--ink-faint); text-align: center;
}

@media (max-width: 640px) {
  .intel-hero { min-height: 210px; }
  .intel-quote { padding: 22px 18px 20px; }
  .iq-text { font-size: 17px; }
  .intel-tabs { gap: 7px; }
  .itab { padding: 8px 13px; font-size: 12px; flex: 1 1 auto; justify-content: center; }
  .intel-card { padding: 13px 14px; }
  .ic-title { font-size: 13.5px; }
  .say-mark { font-size: 42px; }}

/* ============================================================
   同步状态徽章（顶栏）
   ============================================================ */
.sync-badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 12px; border-radius: var(--r-full);
  font-size: 11.5px; font-weight: 620; white-space: nowrap;
  border: 1px solid var(--line); background: var(--sunken); color: var(--ink-faint);
  transition: background .2s, color .2s, border-color .2s, transform .18s;
}
.sync-badge:hover { transform: translateY(-1px); border-color: var(--line-strong); color: var(--ink); }
.sync-badge[data-st="ok"] { color: #3d6b4c; border-color: color-mix(in srgb, #4a7c59 30%, transparent); background: color-mix(in srgb, #4a7c59 10%, transparent); }
.sync-badge[data-st="off"] { color: #b96a1c; border-color: color-mix(in srgb, #d9822b 30%, transparent); background: color-mix(in srgb, #d9822b 10%, transparent); }
.sync-badge[data-st="sync"] { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 35%, transparent); background: var(--accent-soft); }
.sync-badge[data-st="err"] { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 35%, transparent); background: color-mix(in srgb, var(--danger) 10%, transparent); }
.sync-badge[data-st="sync"]::before { content: ''; width: 9px; height: 9px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (max-width: 640px) { .sync-badge { padding: 5px 9px; font-size: 10.5px; }}

/* 备份区 */
.backup-row { display: flex; gap: 9px; flex-wrap: wrap; }
.backup-row .btn { flex: 1 1 auto; justify-content: center; }
.drop-zone {
  margin-top: 12px; padding: 22px; text-align: center;
  border: 1px dashed var(--line-strong); border-radius: var(--r-m);
  font-size: 12.5px; color: var(--ink-faint);
  transition: border-color .2s, background .2s;
}
.drop-zone.over { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
/* 备份区的说明文字 */
.bk-help { margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--line); }
.bk-help p {
  margin: 0 0 9px; font-size: 12px; line-height: 1.8; color: var(--ink-faint);
  padding-left: 11px; border-left: 2px solid var(--line);
}
.bk-help p:last-child { margin-bottom: 0; }
.bk-help b { color: var(--ink-soft); font-weight: 640; }
.bk-help code {
  font-size: 11px; padding: 1px 5px; border-radius: 5px;
  background: var(--sunken); color: var(--ink-soft);
}
.bk-warn { color: #b96a1c; font-weight: 600; }
.bk-last { margin: 12px 0 0; font-size: 11.5px; color: var(--ink-faint); text-align: right; }
.hero3-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); display: block; }
.hr-fg {
  fill: none; stroke: url(#hr-grad); stroke-width: 9; stroke-linecap: round;
  transition: stroke-dashoffset 1.1s cubic-bezier(.16,1,.3,1);
  filter: drop-shadow(0 3px 8px color-mix(in srgb, var(--accent) 40%, transparent));
}
.hero3-ring[data-pct="100"] .hr-fg { stroke: #4a7c59; filter: drop-shadow(0 3px 8px rgba(74,124,89,.45)); }
.hr-mid b {
  font-size: 27px; font-weight: 700; letter-spacing: -.04em; line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--ink);
}
.hr-mid span { font-size: 10px; color: var(--ink-faint); letter-spacing: .02em; }
.hm-item {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 12px; border-radius: var(--r-full);
  font-size: 12px; color: var(--ink-soft);
  background: var(--sunken); border: 1px solid transparent;
  transition: transform .22s cubic-bezier(.2,.9,.3,1), background .2s, border-color .2s;
}
.hm-item:hover { transform: translateY(-2px); border-color: var(--line-strong); }
.hm-item b { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ink); }
.hm-item.hot { color: #c96a10; background: color-mix(in srgb, #ff8c1a 12%, transparent);
               border-color: color-mix(in srgb, #ff8c1a 28%, transparent); }
.hm-item.hot b { color: #b8610a; }

/* ---- 接下来 ---- */
.next-up {
  display: flex; align-items: center; gap: 11px; flex-wrap: wrap;
  padding: 11px 16px; margin-bottom: 16px;
  background: var(--glass); border: 1px solid var(--line);
  border-radius: var(--r-m);
  animation: fade-up .4s cubic-bezier(.16,1,.3,1) both;
  transition: border-color .2s, box-shadow .25s, transform .2s;
}
.next-up:hover { transform: translateY(-1px); border-color: color-mix(in srgb, var(--accent) 35%, transparent); box-shadow: var(--shadow-s); }
.nu-label { font-size: 10.5px; font-weight: 660; letter-spacing: .06em; color: var(--ink-faint); }
.nu-name { flex: 1; min-width: 90px; font-size: 13.5px; font-weight: 640; }
.nu-when { font-size: 11.5px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.nu-go {
  padding: 6px 16px; border-radius: var(--r-full);
  font-size: 12.5px; font-weight: 650; color: #fff;
  background: linear-gradient(145deg, var(--accent), var(--accent-deep));
  box-shadow: 0 6px 14px -8px color-mix(in srgb, var(--accent) 90%, transparent);
  transition: transform .2s cubic-bezier(.2,.9,.3,1), box-shadow .2s, filter .2s;
}
.nu-go:hover { transform: translateY(-1px) scale(1.04); filter: brightness(1.08); }
.nu-go:active { transform: scale(.96); }

/* ---- 底部复习节奏 ---- */
.home-foot {
  position: relative; z-index: 2;
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line);
}
.hf-title { font-size: 11px; font-weight: 660; color: var(--ink-soft); letter-spacing: .05em; margin-right: 3px; }
.hf-chip {
  display: inline-flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 6px 11px; border-radius: var(--r-s, 12px);
  background: var(--glass-strong); border: 1px solid var(--line-strong);
  transition: transform .22s cubic-bezier(.2,.9,.3,1), border-color .2s, background .2s;
}
.hf-chip:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--accent) 35%, transparent); background: var(--accent-soft); }
.hf-chip b { font-size: 11.5px; font-weight: 660; }
.hf-chip i { font-size: 9.5px; font-style: normal; color: var(--ink-faint); }

/* ============================================================
   通用动效
   ============================================================ */

/* 涟漪 */
.fx-ripple {
  position: absolute; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, currentColor 0%, transparent 68%);
  opacity: .22; transform: scale(0);
  animation: fx-ripple .62s cubic-bezier(.16,1,.3,1) forwards;
}
@keyframes fx-ripple { to { transform: scale(1); opacity: 0; } }

/* 触屏按压回弹 */
.fx-press { transform: scale(.955) !important; transition: transform .12s ease-out !important; }

/* 交错入场 */
.fx-stagger { opacity: 0; }
.fx-in { animation: fx-in .5s cubic-bezier(.16,1,.3,1) both; }
@keyframes fx-in {
  from { opacity: 0; transform: translateY(14px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

/* 滚动显现 */
.reveal { opacity: 0; transform: translateY(16px); transition: opacity .5s, transform .55s cubic-bezier(.16,1,.3,1); }
.reveal.fx-shown { opacity: 1; transform: none; }

/* 打卡粒子 */
.fx-spark {
  position: fixed; z-index: 200; pointer-events: none;
  font-size: 13px; font-weight: 700; color: var(--accent);
  animation: fx-spark .82s cubic-bezier(.16,1,.3,1) forwards;
}
@keyframes fx-spark {
  0%   { opacity: 1; transform: translate(-50%, -50%) scale(.5); }
  60%  { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1.15); }
}

/* 卡片倾斜时的光泽跟随鼠标 */
.feat::after, .ck-card::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none; opacity: 0; transition: opacity .3s;
  background: radial-gradient(280px circle at var(--mx, 50%) var(--my, 50%),
              rgba(255,255,255,.55), transparent 60%);
}
.feat:hover::after, .ck-card:hover::after { opacity: 1; }

/* 按钮/链接统一的手感 */
.btn, .pill, .tab, .nav-item, .itab, .ck-rb, .action, .feat, .ck-card, .intel-card {
  -webkit-tap-highlight-color: transparent;
  will-change: transform;
}
.btn:active, .pill:active, .tab:active, .nav-item:active, .itab:active, .action:active {
  transform: scale(.965);
}

/* 图标在悬停时轻微放大 —— 给按钮一点"活气" */
.btn .act-top, .feat-label, .tab span { transition: transform .22s cubic-bezier(.2,.9,.3,1); }
.feat:hover .feat-label { transform: translateY(-1px); }

@media (max-width: 720px) {
  .hr-mid b { font-size: 23px; }
  .hero3-btns .pill { flex: 1 1 auto; justify-content: center; }
  .hm-item { padding: 4px 10px; font-size: 11px; }
  .home-foot { gap: 6px; }
  .hf-chip { padding: 5px 9px; }}
/* ============================================================
   首页 v4 —— 苹果式线条勾勒标题 + 彩色毛玻璃 + 森林风景
   ============================================================ */
.hero4 {
  position: relative; overflow: hidden;
  border-radius: var(--r-xl, 22px);
  margin-bottom: 14px;
  display: flex; flex-direction: column; justify-content: flex-start;
  border: 1px solid var(--line-strong);
  box-shadow: 0 18px 50px -22px rgba(44,44,44,.28), var(--shadow-m);
  isolation: isolate;
}

/* 水墨纸底：宣纸渐变 + 一抹淡墨晕染（不再用彩色光斑） */
.h4-sky {
  position: absolute; inset: 0; z-index: 0;
  background:
    radial-gradient(ellipse 90% 46% at 18% 8%, rgba(44,44,44,.06) 0%, transparent 58%),
    radial-gradient(ellipse 80% 40% at 84% 4%, rgba(44,44,44,.045) 0%, transparent 55%),
    linear-gradient(180deg, #f0e9d8 0%, #f5f0e6 58%, #f5f0e6 100%);
}
:root[data-theme="dark"] .h4-sky {
  background:
    radial-gradient(ellipse 90% 46% at 18% 8%, rgba(232,228,217,.05) 0%, transparent 58%),
    radial-gradient(ellipse 80% 40% at 84% 4%, rgba(232,228,217,.035) 0%, transparent 55%),
    linear-gradient(180deg, #1c2028 0%, #1a1d23 58%, #1a1d23 100%);
}
.h4-blob { display: none; }





.h4-inner {
  position: relative; z-index: 2;
  /* 底部留 216px 给森林（森林高 210px）—— 不留的话按钮会压在树上 */
  padding: 32px 34px 216px;
}

/* ---- 苹果式线条标题 ---- */
.h4-title {
  display: block; width: 100%; max-width: 620px; height: auto;
  margin: 6px 0 10px -4px; overflow: visible;
}
.h4-title text {
  font-family: 'SF Pro Display', -apple-system, 'Segoe UI', 'Microsoft YaHei', sans-serif;
  font-size: 72px; font-weight: 800; letter-spacing: -.02em;
}
/* 每个字母单独勾勒：--i 是字母序号，delay 用 calc 错开 */
.h4-stroke {
  fill: none;
  stroke: url(#ws-grad);
  stroke-width: 1.5;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.h4-stroke tspan {
  /* 1400 必须**大于任何一个字母的路径长度**。
     原来是 320 —— 比 "W" 的路径短，于是 W 有一段在动画一开始就已经露出来了，
     看上去就是"W 一出来就是坏的/断的"。这是那个 bug 的根因。 */
  stroke-dasharray: 1400;
  stroke-dashoffset: 1400;
  animation: ws-draw .78s cubic-bezier(.3,.9,.3,1) forwards;
  animation-delay: calc(var(--i) * .075s + .1s);
}
.h4-fill {
  fill: url(#ws-grad);
  opacity: 0;
  /* 必须等描边全部走完再上色。原来 1.6s，而最后一笔大约 1.85s 才收 —— 
     中途上色会看到"还没画完的字忽然实心"的跳变。 */
  animation: ws-fill .9s ease 1.75s forwards;
}
@keyframes ws-draw { to { stroke-dashoffset: 0; } }
@keyframes ws-fill { to { opacity: 1; } }
/* 必须有明确的 to —— 只写 from 的话终点是元素自身的值（这里是 opacity:0），
   结果就是 0 -> 0，元素永远不出现。这是刚才日期/按钮全不见的原因。 */
@keyframes h4-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

.h4-date {
  font-size: 12.5px; font-weight: 600; color: var(--ink-soft);
  letter-spacing: .01em; margin-bottom: 2px;
  opacity: 0; animation: h4-in .6s cubic-bezier(.16,1,.3,1) .1s forwards;
}
.h4-sub {
  font-size: 13.5px; font-weight: 600; letter-spacing: .05em;
  color: var(--ink-soft); margin-bottom: 18px;
  opacity: 0; animation: h4-in .6s cubic-bezier(.16,1,.3,1) 1.7s forwards;
}
.h4-meta, .h4-btns {
  opacity: 0; animation: h4-in .6s cubic-bezier(.16,1,.3,1) forwards;
}
.h4-meta { animation-delay: 1.9s; }
.h4-btns { animation-delay: 2.05s; }

.h4-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.hero4 .hm-item {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 13px; border-radius: var(--r-full);
  font-size: 12px; font-weight: 600; color: var(--ink-soft);
  background: var(--glass);
  border: 1px solid var(--line-strong);
  backdrop-filter: blur(14px) saturate(180%);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
  box-shadow: 0 4px 14px -8px rgba(44,44,44,.35);
  transition: transform .24s cubic-bezier(.2,.9,.3,1), background .24s, box-shadow .24s;
}
.hero4 .hm-item:hover { transform: translateY(-2px); background: rgba(255,253,245,.86); box-shadow: 0 8px 20px -10px rgba(44,44,44,.45); }
.hero4 .hm-item b { font-weight: 750; font-variant-numeric: tabular-nums; color: var(--ink); }
.hero4 .hm-item.hot {
  color: #b8610a;
  background: linear-gradient(135deg, rgba(255,224,178,.92), rgba(255,196,120,.82));
  border-color: rgba(255,255,255,.9);
}
.hero4 .hm-item.hot b { color: #8a3f02; }
.hero4 .hm-item.due {
  color: var(--accent-deep);
  background: var(--accent-soft);
}
.hero4 .hm-item.due b { color: var(--accent-deep); }

.h4-btns { display: flex; gap: 10px; flex-wrap: wrap; }
/* 朱砂主按钮 + 宣纸副按钮 */
.hero4 .pill.dark {
  background: linear-gradient(145deg, var(--accent), var(--accent-deep));
  box-shadow: 0 12px 26px -12px rgba(142,42,32,.75);
}
.hero4 .pill.light {
  background: rgba(255,253,245,.74);
  border-color: var(--line-strong);
  backdrop-filter: blur(14px) saturate(180%);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
  color: var(--ink);
}

/* 页面上其它卡片也换成彩色毛玻璃 */
.feat, .ck-stat, .ck-chart-wrap, .ck-card, .intel-card, .ck-hero, .next-up, .action, .card {
  backdrop-filter: blur(18px) saturate(190%);
  -webkit-backdrop-filter: blur(18px) saturate(190%);
}
.feat { background: linear-gradient(150deg, rgba(255,255,255,.72), rgba(255,255,255,.52)); }
.feat:hover { background: linear-gradient(150deg, rgba(255,255,255,.9), rgba(255,255,255,.7)); }

@media (max-width: 720px) {
  .h4-inner { padding: 22px 18px 186px; }
  .h4-title { max-width: 100%; margin-bottom: 8px; }
  .h4-title text { font-size: 82px; }
  .h4-sub { font-size: 12px; margin-bottom: 14px; }
  .h4-meta { gap: 6px; }
  .hero4 .hm-item { padding: 5px 10px; font-size: 11px; }
  .h4-btns .pill { flex: 1 1 auto; justify-content: center; }}

@media (prefers-reduced-motion: reduce) {
  .h4-stroke { animation: none; stroke-dashoffset: 0; }
  .h4-fill, .h4-date, .h4-sub, .h4-meta, .h4-btns { animation: none; opacity: 1; }
  .h4-blob { animation: none; }}
/* ---- 场景里的动效：云飘、光点浮 ---- */
.fc-cloud { animation: fc-drift 70s linear infinite; }
@keyframes fc-drift {
  0%   { transform: translateX(0); }
  100% { transform: translateX(46px); }
}
.fc-cloud:nth-of-type(2) { animation-duration: 95s; animation-direction: reverse; }
.fc-cloud:nth-of-type(3) { animation-duration: 120s; }

.fc-mote {
  animation: fc-float 7s ease-in-out infinite;
  animation-delay: var(--d, 0s);
  transform-origin: center;
}
@keyframes fc-float {
  0%, 100% { transform: translateY(0) scale(1);   opacity: .35; }
  50%      { transform: translateY(-14px) scale(1.35); opacity: .95; }
}
.h4-inner { padding: 32px 34px 246px; }

@media (prefers-reduced-motion: reduce) {
  .fc-cloud, .fc-mote { animation: none; }}
/* ============================================================
   风景配色 —— 白天阳光森林 / 夜晚星空月色
   全部走 CSS 变量，切主题只换配色，SVG 不用重画
   ============================================================ */
:root {
  /* 白天 —— 水墨留白：淡墨远山 + 墨色圆冠树影 */
  --sc-cloud:      #ffffff;
  --sc-cloud-b:    #f2ecdc;
  --sc-star:       #ffffff;   --sc-star-o: 0;
  --sc-orb:        #fdfbf3;   --sc-moon-bite-o: 0;
  --sc-rays:       #fffbe0;   --sc-rays-o: .10;
  --sc-birds:      #8a8574;   --sc-birds-o: .5;

  --sc-haze1:      #ffffff00; --sc-haze2: #f5f0e66b; --sc-haze3: #f0ead9b3;

  --sc-far:        #cfc9b8;   --sc-far-o: .48;

  --sc-hill1a:     #d3ccbb;   --sc-hill1b: #c2bba9;
  --sc-hill2a:     #a29c8c;   --sc-hill2b: #8a8474;
  --sc-hill3a:     #6b665a;   --sc-hill3b: #4f4b41;

  --sc-tr1:        #9a9484;
  --sc-tr2:        #75705f;
  --sc-tr3:        #4f4b41;

  --sc-lake1:      #cfeef2;   --sc-lake2: #a9dcea;  --sc-lake3: #7cc4dd;
  --sc-reflect:    #fff6cf;   --sc-ripple: #ffffff;
  --sc-bank:       #4f4b4138;

  --sc-glow1:      #fffdf4f2; --sc-glow2: #f3ecd799; --sc-glow3: #f3ecd700;
  --sc-mote1:      #fffdf0f2; --sc-mote2: #fff6c800;
}

:root[data-theme="dark"] {
  /* 夜 —— 不用纯黑，深灰蓝夜山 */
  --sc-cloud:      #262b34;
  --sc-cloud-b:    #1d222b;
  --sc-star:       #e8e4d9;   --sc-star-o: .9;
  --sc-orb:        #d8d4c8;   --sc-moon-bite-o: 1;
  --sc-rays:       #b9bdd0;   --sc-rays-o: .08;
  --sc-birds:      #6b7280;   --sc-birds-o: .4;

  --sc-haze1:      #0b122600; --sc-haze2: #1a1f2a59; --sc-haze3: #20263366;

  --sc-far:        #262b34;   --sc-far-o: .62;

  --sc-hill1a:     #262b34;   --sc-hill1b: #20242d;
  --sc-hill2a:     #1a1e26;   --sc-hill2b: #15181f;
  --sc-hill3a:     #101319;   --sc-hill3b: #0b0e12;

  --sc-tr1:        #23262e;
  --sc-tr2:        #1a1d23;
  --sc-tr3:        #111318;

  --sc-lake1:      #35507e;   --sc-lake2: #263c62;  --sc-lake3: #192747;
  --sc-reflect:    #e8eeff;   --sc-ripple: #9fb6e0;
  --sc-bank:       #0d1729a6;

  --sc-glow1:      #e8e4d9cc; --sc-glow2: #b9bdd060; --sc-glow3: #8fa3d600;
  --sc-mote1:      #e8e4d9f2; --sc-mote2: #ffe06600;   /* 萤火虫 */
}

/* 场景元素按变量上色 */
.sc-cloud   { fill: var(--sc-cloud); }
.sc-cloud-b { fill: var(--sc-cloud-b); opacity: .55; }
.sc-stars   { fill: var(--sc-star); opacity: var(--sc-star-o); }
:root[data-theme="dark"] .sc-moon-bite { opacity: var(--sc-moon-bite-o); }
.sc-rays    { fill: var(--sc-rays); opacity: var(--sc-rays-o); }
.sc-birds   { stroke: var(--sc-birds); stroke-width: 1.7; fill: none;
              stroke-linecap: round; opacity: var(--sc-birds-o); }
.sc-far     { fill: var(--sc-far); opacity: var(--sc-far-o); }
.sc-tr1     { fill: var(--sc-tr1); }
.sc-tr2     { fill: var(--sc-tr2); }
.sc-tr3     { fill: var(--sc-tr3); }
.sc-reflect ellipse:nth-child(1) { opacity: .75; }
.sc-reflect ellipse:nth-child(2) { opacity: .45; }
.sc-reflect ellipse:nth-child(3) { opacity: .26; }
.sc-reflect ellipse:nth-child(4) { opacity: .15; }

/* 星星闪烁 */
.fc-twinkle {
  animation: fc-twinkle 3.4s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}
@keyframes fc-twinkle {
  0%, 100% { opacity: .25; }
  50%      { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .fc-twinkle { animation: none; opacity: .8; }}

/* 云的速度错开 */
.fc-cloud:nth-of-type(2) { animation-duration: 95s; animation-direction: reverse; }
.fc-cloud:nth-of-type(3) { animation-duration: 120s; }

/* 夜空下，卡片和文字要更透亮一点 */
:root[data-theme="dark"] .hero4 {
  border-color: color-mix(in srgb, var(--snow) 22%, transparent);
  box-shadow: 0 18px 50px -22px rgba(0,0,0,.7);
}
/* ---- 全站背景风景：固定在视口底部，压得很淡 ----
   它的作用是让每个页面都有「地平线」，而不是只有首页有。
   透明度调低，保证上面的卡片和文字始终清楚。 */
.page-scene {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 0;
  width: 100%; height: 46vh; min-height: 240px; max-height: 460px;
  pointer-events: none;
  opacity: .5;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 34%);
  mask-image: linear-gradient(180deg, transparent 0%, #000 34%);
}
:root[data-theme="dark"] .page-scene { opacity: .62; }

/* 内容要在风景之上 */
.app { position: relative; z-index: 1; }
/* ---- 夜晚主题下的文字/按钮配色 ----
   首页这些文字原来写死了深绿（--h4-date / --h4-sub），
   放到深色夜空上就看不清了，这里逐个换成浅色。 */
:root[data-theme="dark"] .h4-date { color: var(--ink); }
:root[data-theme="dark"] .h4-sub  { color: var(--ink-soft); }

:root[data-theme="dark"] .hero4 .hm-item {
  color: var(--ink-soft); background: var(--glass);
  border-color: var(--line); box-shadow: var(--shadow-s);
}
:root[data-theme="dark"] .hero4 .hm-item b { color: var(--ink); }
:root[data-theme="dark"] .hero4 .hm-item.hot {
  color: var(--warm);
  background: color-mix(in srgb, var(--warm) 16%, var(--glass));
  border-color: color-mix(in srgb, var(--warm) 32%, transparent);
}
:root[data-theme="dark"] .hero4 .hm-item.hot b { color: #fff2dc; }
:root[data-theme="dark"] .hero4 .hm-item.due {
  color: var(--accent); background: var(--accent-soft); border-color: var(--accent-ring);
}
:root[data-theme="dark"] .hero4 .hm-item.due b { color: var(--accent); }

/* 主按钮：夜里用深蓝黑，别用纯黑 */
:root[data-theme="dark"] .hero4 .pill.dark {
  background: linear-gradient(145deg, #23303f, #16202b);
  color: var(--ink);
  box-shadow: 0 12px 26px -12px rgba(0,0,0,.9), inset 0 1px 0 rgba(255,255,255,.09);
}
:root[data-theme="dark"] .hero4 .pill.light {
  background: rgba(232,228,217,.08);
  border-color: rgba(232,228,217,.22);
  color: #e8e4d9;
}
:root[data-theme="dark"] .hero4 .pill.light:hover { color: #fff; border-color: rgba(232,228,217,.42); }

/* 首页那块玻璃在夜里要透一点，不然天空全被盖住 */
:root[data-theme="dark"] .hero4::before { opacity: .5; }

/* 全站的卡片在夜里也别是纯黑，带一点暖灰（宣纸夜色） */
/* ============================================================
   海景配色 —— 水墨江景（宋画平远：淡墨远水 → 浓墨近浪）
   全部走 CSS 变量，切主题只换配色，SVG 不用重画
   ============================================================ */
:root {
  /* ---- 标题「WorkSpace」：墨分五色（焦浓重淡清）---- */
  --tt-1: #1f2b23;  --tt-2: #2e3d34;  --tt-3: #405649;  --tt-4: #5b7363;  --tt-5: #7d9385;

  /* ---- 情报站山水卡（淡墨远山 + 宣纸天空）---- */
  --sc-sky1: #f0ead9;  --sc-sky2: #f4efe2;  --sc-sky3: #f8f4ea;
  --sc-sun1: #f5efdc;
  --sc-bird: #8a8574;
  --sc-m1a: #cfc9b8;  --sc-m1b: #c2bba8;
  --sc-m2a: #a8a292;  --sc-m2b: #8f897a;
  --sc-m3a: #75705f;  --sc-m3b: #5d594c;
  --sc-ga:  #4a463c;  --sc-gb:  #36332b;

  /* ---- 首页江景（OCEAN_SVG）---- */
  --oc-sky1: #f2ecdb;  --oc-sky2: #f5f0e2;  --oc-sky3: #f8f4ea;  --oc-hzglow: #f0e9d5;
  --oc-sea-a: #c9c3b3; --oc-sea-b: #a29c8b; --oc-sea-c: #75705e; --oc-sea-d: #4a463b;
  --oc-crest-s: #2c2c2c;
  --oc-crest-l: #fdfbf3;
  --oc-spec1: #fffdf4cc; --oc-spec2: #fffdf400;
  --oc-boat-refl: rgba(255,253,245,.30);
  --oc-sand1: #efe8d5; --oc-sand2: #e2d9c2; --oc-sand3: #d6ccb1;
  --oc-wet1: #d9d1bd;  --oc-wet2: #c3baa1;
  --oc-glow1: #fffdf4f2; --oc-glow2: #f3ecd799; --oc-glow3: #f3ecd700;
  --oc-orb-c: #fdfbf3;
  --oc-mote1: #fffdf0e6; --oc-mote2: #fff6c800;
  --oc-path1: #fffbe9a8; --oc-path2: #fffbe900;
  --oc-vignette: rgba(44,44,44,.20);
  --oc-foam:  #ffffff;
  --oc-horizon: #ffffff96;
  --oc-wave1: #b5af9e; --oc-wave2: #8f8979; --oc-wave3: #655f50;
  --oc-hull:  #46423a; --oc-sail: #fdfbf3;  --oc-sail2: #e5dfcd;
  --oc-mast:  #46423a;
  --oc-moonbite-o: 0;
}
:root[data-theme="dark"] {
  /* 夜 —— 灰蓝夜山 + 月光江面 */
  --tt-1: #f6fafd;  --tt-2: #e3ecf4;  --tt-3: #c6d4e0;  --tt-4: #a3b4c3;  --tt-5: #8296a6;

  --sc-sky1: #1c2028;  --sc-sky2: #191d24;  --sc-sky3: #161a20;
  --sc-sun1: #e8e4d9;
  --sc-bird: #6b7280;
  --sc-m1a: #2a2f39;  --sc-m1b: #242933;
  --sc-m2a: #1f242d;  --sc-m2b: #191d25;
  --sc-m3a: #14181f;  --sc-m3b: #0f1218;
  --sc-ga:  #0b0e13;  --sc-gb:  #070a0e;

  --oc-sky1: #191d24;  --oc-sky2: #161a21;  --oc-sky3: #14171d;  --oc-hzglow: #232833;
  --oc-sea-a: #23262e; --oc-sea-b: #1d2027; --oc-sea-c: #16181e; --oc-sea-d: #101216;
  --oc-crest-s: #000000;
  --oc-crest-l: #b9bdd0;
  --oc-spec1: #e8e4d9b3; --oc-spec2: #e8e4d900;
  --oc-boat-refl: rgba(232,228,217,.22);
  --oc-sand1: #22252c; --oc-sand2: #1b1e24; --oc-sand3: #15171c;
  --oc-wet1: #1d2026;  --oc-wet2: #171a1f;
  --oc-glow1: #e8e4d973; --oc-glow2: #b9bdd048; --oc-glow3: #8fa3d600;
  --oc-orb-c: #cfcabb;
  --oc-mote1: #e8e4d9e6; --oc-mote2: #ffe06600;
  --oc-path1: #e8e4d99e; --oc-path2: #e8e4d900;
  --oc-vignette: #000000;
  --oc-foam:  #a8a49a;
  --oc-horizon: #a8a49a66;
  --oc-wave1: #20232b; --oc-wave2: #1a1d23; --oc-wave3: #131519;
  --oc-hull:  #2c2f37; --oc-sail: #b5b1a3;  --oc-sail2: #8d897c;
  --oc-mast:  #3a3d44;
  --oc-moonbite-o: 1;
}

/* ---- 场景元素上色 ---- */
.oc-orb-c { fill: var(--oc-orb-c); }
.oc-moon-bite { fill: var(--oc-sea-a); opacity: var(--oc-moonbite-o); }
.oc-horizon { fill: var(--oc-horizon); }
.oc-path { mix-blend-mode: screen; }
/* 白天是宣纸底，光路太实会像一束追光，压淡一点更像水痕 */
:root:not([data-theme="dark"]) .oc-path { opacity: .5; }
:root[data-theme="dark"] .oc-path { opacity: .85; }

.oc-glitter ellipse { fill: #ffffff; }
.oc-glitter ellipse:nth-child(1) { opacity: .82; }
.oc-glitter ellipse:nth-child(2) { opacity: .62; }
.oc-glitter ellipse:nth-child(3) { opacity: .48; }
.oc-glitter ellipse:nth-child(4) { opacity: .36; }
.oc-glitter ellipse:nth-child(5) { opacity: .26; }
.oc-glitter ellipse:nth-child(6) { opacity: .18; }
.oc-glitter ellipse:nth-child(7) { opacity: .12; }
:root[data-theme="dark"] .oc-glitter ellipse { fill: #f2f6ff; }

/* ---- 帆船 ---- */
.oc-hull  { fill: var(--oc-hull); }
.oc-sail  { fill: var(--oc-sail); }
.oc-sail2 { fill: var(--oc-sail2); }
.oc-mast  { stroke: var(--oc-mast); stroke-width: 1.4; stroke-linecap: round; }

.oc-boat {
  animation: oc-sail-move var(--dur, 30s) ease-in-out infinite;
  animation-delay: var(--delay, 0s);
  transform-box: fill-box; transform-origin: center bottom;
}
/* 一边横移一边随浪起伏 */
@keyframes oc-sail-move {
  0%   { transform: translate(-26px, 0)      rotate(-1.6deg); }
  25%  { transform: translate(-8px, -3.5px)  rotate(1.2deg); }
  50%  { transform: translate(10px, 1.5px)   rotate(-1deg); }
  75%  { transform: translate(24px, -3px)    rotate(1.4deg); }
  100% { transform: translate(-26px, 0)      rotate(-1.6deg); }
}

/* ---- 海浪：三组不同速度、不同深浅的波浪左右推移 ---- */
.oc-wave { opacity: var(--wo, 1); }
.oc-wave path { fill: var(--oc-wave1); }
.oc-w2 path { fill: var(--oc-wave2); }
.oc-w3 path { fill: var(--oc-wave3); }
.oc-wave {
  animation: oc-wave-slide var(--wd, 12s) linear infinite;
}
@keyframes oc-wave-slide {
  from { transform: translateX(0); }
  to   { transform: translateX(-160px); }
}

/* ---- 浪花：轻微呼吸 ---- */
.oc-foam { fill: var(--oc-foam); opacity: .75; animation: oc-foam 5.5s ease-in-out infinite; }
@keyframes oc-foam {
  0%, 100% { opacity: .55; transform: translateY(0); }
  50%      { opacity: .92; transform: translateY(-1.6px); }
}

/* ---- 场景容器：绝对定位贴底（原来挂在 .h4-forest 上，改名后忘了跟过来，导致场景不显示）---- */
.oc-scene {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1;
}
@media (max-width: 720px) { .oc-scene { height: 178px; }}

@media (prefers-reduced-motion: reduce) {
  .oc-boat, .oc-wave, .oc-foam { animation: none !important; }}

/* ============================================================
   手机底部导航的互动
   ============================================================ */
.tab {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 7px 4px 5px; border-radius: var(--r-m);
  transition: transform .22s cubic-bezier(.2,.9,.3,1), background .22s, color .22s;
}
.tab-ico {
  font-size: 19px; line-height: 1;
  transition: transform .32s cubic-bezier(.34,1.56,.64,1), filter .22s;
  will-change: transform;
}
.tab span:last-child { font-size: 10px; transition: color .2s, transform .22s; }

/* 按下：图标缩一下再弹回来 */
.tab:active { background: var(--sunken); }
.tab:active .tab-ico { transform: scale(.82); }

/* 选中：图标放大上浮 + 弹跳，文字上色 */
.tab.on .tab-ico {
  transform: translateY(-2px) scale(1.16);
  filter: drop-shadow(0 4px 8px color-mix(in srgb, var(--accent) 55%, transparent));
  animation: tab-bounce .46s cubic-bezier(.34,1.56,.64,1);
}
.tab.on span:last-child { color: var(--accent); font-weight: 660; }
.tab.on { background: var(--accent-soft); }

@keyframes tab-bounce {
  0%   { transform: translateY(0) scale(.9); }
  55%  { transform: translateY(-5px) scale(1.24); }
  100% { transform: translateY(-2px) scale(1.16); }
}

/* 选中时底下一个小圆点 */
.tab::after {
  content: ''; position: absolute; bottom: 2px; left: 50%;
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--accent); opacity: 0;
  transform: translateX(-50%) scale(0);
  transition: opacity .24s, transform .3s cubic-bezier(.34,1.56,.64,1);
}
.tab.on::after { opacity: 1; transform: translateX(-50%) scale(1); }

/* 点按涟漪（ui.js 会插入 .fx-ripple） */
.tab .fx-ripple { background: radial-gradient(circle, var(--accent) 0%, transparent 68%); opacity: .28; }

@media (prefers-reduced-motion: reduce) {
  .tab.on .tab-ico { animation: none; }}

/* ============================================================
   触屏（平板 / 手机）专用收尾
   ============================================================
   两件事在手指下才是问题，鼠标下完全不存在：

   1) 悬停位移"粘住"：桌面鼠标划过才有 :hover，划走就还原。
      触屏上没有"划走"这回事 —— iOS 会在你点一下的瞬间给元素套上
      :hover，然后一直挂到你去点别的地方。表现出来就是：刚点过的
      导航、卡片、按钮一直歪着、浮着、放大着，看着像坏了。
      这里只撤掉位移，颜色反馈保留（那个不会让人觉得错乱）。

   2) 同步状态按钮只有 31px 高。鼠标点得准，手指点不准。
      只在触屏上撑到 40px（苹果的建议值是 44，再大就顶到顶栏了）。
   ============================================================ */
@media (hover: none) {
  .nav-item:hover, .sync-badge:hover, .mod:hover, .itab:hover,
  .next-up:hover, .hf-chip:hover, .hm-item:hover,
  .hero4 .hm-item:hover, .ck-stat:hover {
    transform: none;
  }
  .nav-icon-btn:hover, .pill:hover .pill-ico,
  .feat:hover .feat-label, .nu-go:hover, .modal-x:hover {
    transform: none;
  }
  .photo-cell:hover img { transform: none; }
  .pill:hover::after, .feat:hover::before { transform: none; }

  /* 顺手把同步按钮撑到能点的高度。用 hover 判断而不是 pointer:coarse ——
     后者在部分安卓平板（以及无头浏览器）上报的是 pointer:none，会漏掉。 */
  .sync-badge { min-height: 40px; padding: 8px 14px; }

  /* 情报卡里的来源链接只有 17px 高，手指基本点不中。
     上下加内边距把它撑开，视觉上仍然是一行小字。 */
  .ic-link { display: inline-flex; align-items: center; min-height: 40px; padding: 0 2px; }
}

/* ============================================================
   Java 学习页 · 路线图
   ============================================================ */
.learn-hero {
  padding: 20px 24px; margin-bottom: 18px;
  border-radius: var(--r-l);
  background: linear-gradient(135deg, rgba(178,58,46,.08), rgba(74,124,89,.06));
  border: 1px solid var(--line);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--shadow-m);
}
.learn-h-title { font-size: 20px; font-weight: 700; letter-spacing: -.02em; }
.learn-h-desc  { font-size: 12.5px; color: var(--ink-soft); margin-top: 6px; line-height: 1.6; }
.learn-h-progress { margin-top: 12px; font-size: 12.5px; color: var(--ink-faint); }
.learn-h-progress b { color: #e08a2c; font-size: 16px; font-variant-numeric: tabular-nums; }

.learn-stages { display: grid; gap: 12px; }
.learn-stage {
  padding: 16px 18px;
  background: var(--glass); border: 1px solid var(--line);
  border-radius: var(--r-l);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--shadow-s);
  transition: transform .2s cubic-bezier(.2,.9,.3,1), border-color .2s;
}
.learn-stage:hover { transform: translateY(-2px); border-color: var(--line-strong); }
.learn-stage.done {
  border-color: color-mix(in srgb, #4a7c59 40%, transparent);
  background: color-mix(in srgb, #4a7c59 6%, var(--glass));
}
.ls-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.ls-num {
  width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center; font-size: 12px; font-weight: 700;
  color: #fff; background: linear-gradient(145deg, var(--accent), var(--accent-deep));
}
.learn-stage.done .ls-num { background: linear-gradient(145deg, #4a7c59, #3d6b4c); }
.ls-name { font-size: 15px; font-weight: 640; letter-spacing: -.01em; flex: 1; }
.ls-status { font-size: 11.5px; color: var(--ink-faint); }
.learn-stage.done .ls-status { color: #4a7c59; font-weight: 600; }

.ls-items {
  display: flex; flex-wrap: wrap; gap: 6px; list-style: none; padding: 0; margin: 0 0 12px;
}
.ls-items li {
  font-size: 11.5px; padding: 4px 10px; border-radius: var(--r-full);
  background: var(--sunken); border: 1px solid var(--line);
  color: var(--ink-soft);
}
.learn-stage.done .ls-items li { color: var(--ink-faint); text-decoration: line-through; opacity: .7; }

.ls-actions { display: flex; gap: 8px; }

.learn-tip {
  margin-top: 18px; padding: 14px 16px;
  background: var(--sunken); border: 1px solid var(--line); border-radius: var(--r-m);
}
.learn-tip b { font-size: 13px; }
.learn-tip p { margin: 6px 0 0; font-size: 12px; color: var(--ink-soft); line-height: 1.75; }

@media (max-width: 560px) {
  .learn-h-title { font-size: 17px; }
  .learn-stage { padding: 14px; }
  .ls-items li { font-size: 10.5px; padding: 3px 8px; }
  .ls-actions .btn { flex: 1 1 auto; justify-content: center; }
}








/* ============================================================
   以下由 extra.css 合并进来（原文件已删除）
   原来它靠"在 app.css 之后再加载"来覆盖，现在合并成一份样式表，
   股票页遗留的深色行情终端配色已统一换成设计令牌。
   ============================================================ */
/* ============================================================
   新功能的样式（股票页 / 划词讲解 / 情报站新板块 / 首页与风景增强）
   ------------------------------------------------------------
   单独一个文件是有意的：app.css 是已经稳定的设计系统，新东西堆进去
   容易互相踩。这个文件在 app.css **之后**加载，所以同名规则天然覆盖前者。
   ============================================================ */

/* ---------- 0. 装饰层不吃鼠标事件 ----------
   .aurora / .oc-scene / .page-scene 是纯装饰，但它们铺在内容上面：
   不给 pointer-events:none 的话，鼠标划到按钮上时命中的其实是这层画面，
   手型光标不会出现、点击也会被吃掉。这是「光标在情报站按钮那儿会消失」的根因。 */
.aurora, .aurora *, .oc-scene, .page-scene, .h4-sky, .h4-sky *,
.sc-stars, .sc-rays, .oc-glitter, .oc-path, .sc-cloud, .oc-boat, .sc-birds {
  pointer-events: none !important;
}

/* ============================================================
   一、划词讲解
   ============================================================ */
.ex-btn {
  position: fixed; z-index: 90;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px; border-radius: var(--r-full);
  font-size: 13px; font-weight: 620; letter-spacing: .2px;
  color: #fff; cursor: pointer;
  background: linear-gradient(135deg, var(--accent), var(--accent-deep) 70%);
  box-shadow: 0 8px 22px -8px rgba(139, 21, 21, .6), 0 2px 6px rgba(16, 18, 28, .18);
  animation: ex-pop .16s cubic-bezier(.2, 1.3, .5, 1);
}
.ex-btn:hover { transform: translateY(-1px); }
.ex-btn:active { transform: scale(.96); }
.ex-btn .ex-spark { font-size: 11px; opacity: .9; }
@keyframes ex-pop { from { opacity: 0; transform: scale(.86) translateY(4px); } }

.ex-wrap {
  position: fixed; inset: 0; z-index: 95;
  display: flex; align-items: flex-end; justify-content: center;
  padding: 18px 16px calc(18px + env(safe-area-inset-bottom));
  background: rgba(12, 14, 20, .30);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  opacity: 0; transition: opacity .2s ease;
}
.ex-wrap.on { opacity: 1; }
@media (min-width: 760px) { .ex-wrap { align-items: center; }}

.ex-card {
  position: relative; width: 100%; max-width: 460px;
  padding: 20px 20px 16px; border-radius: var(--r-xl);
  background: var(--glass-strong); border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-l);
  transform: translateY(14px) scale(.98); transition: transform .24s cubic-bezier(.2, .9, .3, 1);
}
.ex-wrap.on .ex-card { transform: none; }
.ex-x {
  position: absolute; top: 10px; right: 12px;
  width: 30px; height: 30px; border-radius: 50%;
  font-size: 13px; color: var(--ink-faint); cursor: pointer;
}
.ex-x:hover { background: var(--sunken); color: var(--ink); }
.ex-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; padding-right: 34px; }
.ex-term { font-size: 21px; font-weight: 760; letter-spacing: -.3px; }
.ex-cat {
  font-size: 11px; font-weight: 620; padding: 3px 8px; border-radius: var(--r-full);
  color: var(--accent-deep); background: var(--accent-soft);
}
.ex-hit { font-size: 11px; color: var(--ink-faint); }
.ex-brief { margin: 0 0 12px; font-size: 15px; line-height: 1.75; color: var(--ink); }
.ex-ex {
  padding: 11px 13px; border-radius: var(--r-m); font-size: 13.5px; line-height: 1.7;
  color: var(--ink-soft); background: var(--sunken);
  border-left: 3px solid var(--accent);
}
.ex-ex-k { display: block; font-size: 11px; font-weight: 700; color: var(--accent-deep); margin-bottom: 3px; letter-spacing: .3px; }
.ex-foot {
  display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 11px; border-top: 1px solid var(--line);
  font-size: 11px; color: var(--ink-faint);
}
.ex-ai-off b { color: var(--ink-soft); }
.stock-hero .sh-clock b { color: var(--ink-soft); font-weight: 620; }
.st-idx .n { display: block; font-size: 11.5px; color: var(--ink-faint); margin-bottom: 5px; white-space: nowrap; }
.st-idx .p { display: block; font-size: 17px; font-weight: 740; color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: -.2px; }
.st-idx .c { display: block; font-size: 12px; font-weight: 640; margin-top: 3px; font-variant-numeric: tabular-nums; }
.st-hit .hk.hk-hk { background: #c2410c; }
.st-hit .hk.hk-us { background: #1d4ed8; }
.st-hit .hk.hk-bj { background: #6d28d9; }
.st-tab.on { color: #fff; background: var(--accent); border-color: var(--accent); }
@media (max-width: 420px) { .st-board { grid-template-columns: 1fr; }}
.st-bd .bt { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.st-bd .bt b { font-size: 14.5px; font-weight: 640; }
.st-bd .bt i { font-style: normal; font-size: 13.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.st-bd .bs { margin-top: 5px; font-size: 11px; color: var(--ink-faint); }

/* ============================================================
   三、股票页背景：卡通荧光 3D K 线
   ============================================================ */
.kb-bg svg { width: 100%; height: 100%; display: block; }
@keyframes kb-bob {
  0%, 100% { transform: translateY(0) scaleY(1); }
  38% { transform: translateY(-5px) scaleY(1.05); }
  72% { transform: translateY(3px) scaleY(.97); }
}
@keyframes kb-scan { 0% { transform: translateY(-10%); } 100% { transform: translateY(110%); } }
.kb-grid line { animation: kb-grid 5.5s ease-in-out infinite; }
@keyframes kb-grid { 0%, 100% { opacity: .18; } 50% { opacity: .42; } }
@keyframes kb-draw { 0% { stroke-dashoffset: 900; } 55%, 100% { stroke-dashoffset: 0; } }
@keyframes kb-tip { 0%, 100% { transform: translateY(0); opacity: .85; } 50% { transform: translateY(-6px); opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .kb-candle, .kb-glow, .kb-scan, .kb-grid line, .kb-line, .kb-tip { animation: none !important; }}

/* ============================================================
   四、情报站新板块：今日解读 / 股市小课堂 / 更多标签
   ============================================================ */
.itabs-wrap { display: flex; gap: 7px; overflow-x: auto; padding: 2px 2px 8px; scrollbar-width: none; margin-bottom: 6px; }
.itabs-wrap::-webkit-scrollbar { display: none; }
.itabs-wrap .itab { flex: 0 0 auto; }

.mr-card {
  position: relative; overflow: hidden;
  margin: 0 0 14px; padding: 17px 17px 15px;
  border-radius: var(--r-xl); border: 1px solid var(--line);
  background: linear-gradient(155deg, var(--glass-strong), var(--glass));
  box-shadow: var(--shadow-m);
}
:root[data-theme="dark"] .mr-card {
  background: linear-gradient(155deg, var(--glass-strong), var(--glass));
}
.mr-card::before {
  content: ''; position: absolute; inset: -40% -10% auto; height: 150px;
  background: radial-gradient(60% 100% at 30% 0%, color-mix(in srgb, var(--jade-2) 30%, transparent), transparent 70%);
  pointer-events: none;
}
.mr-top { position: relative; display: flex; align-items: center; gap: 9px; margin-bottom: 10px; }
.mr-badge {
  font-size: 11px; font-weight: 700; letter-spacing: .4px;
  padding: 4px 9px; border-radius: var(--r-full); color: #fff;
  background: linear-gradient(135deg, var(--jade-2), var(--accent));
}
.mr-tone { font-size: 12px; color: var(--ink-faint); }
.mr-head { position: relative; margin: 0 0 11px; font-size: 14.5px; line-height: 1.75; font-weight: 600; color: var(--ink); }
.mr-lines { position: relative; margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 7px; }
.mr-lines li {
  position: relative; padding-left: 15px; font-size: 13px; line-height: 1.7; color: var(--ink-soft);
}
.mr-lines li::before {
  content: ''; position: absolute; left: 2px; top: 9px; width: 5px; height: 5px;
  border-radius: 50%; background: var(--accent);
}
.mr-struct {
  margin: 12px 0 0; padding: 11px 13px; border-radius: var(--r-m);
  font-size: 13px; line-height: 1.7; color: var(--ink-soft);
  background: var(--sunken); border-left: 3px solid var(--accent);
}
.mr-scenes { margin: 11px 0 0; display: flex; flex-direction: column; gap: 6px; }
.mr-scene { font-size: 12.5px; line-height: 1.7; color: var(--ink-soft); padding-left: 15px; position: relative; }
.mr-scene::before { content: '→'; position: absolute; left: 0; color: var(--ink-faint); }
.mr-foot {
  margin-top: 13px; padding-top: 10px; border-top: 1px solid var(--line);
  font-size: 11px; line-height: 1.6; color: var(--ink-faint);
}

.lt-card {
  display: flex; gap: 14px; align-items: flex-start;
  margin: 0 0 14px; padding: 16px 17px;
  border-radius: var(--r-xl); border: 1px solid var(--line);
  background: linear-gradient(140deg, color-mix(in srgb, var(--warm) 20%, var(--glass-strong)), color-mix(in srgb, var(--warm) 8%, var(--glass)));
  box-shadow: var(--shadow-s);
}
:root[data-theme="dark"] .lt-card {
  background: linear-gradient(140deg, var(--glass-strong), var(--glass));
}
.lt-ico {
  flex: 0 0 42px; height: 42px; border-radius: 13px;
  display: grid; place-items: center; font-size: 21px;
  background: linear-gradient(135deg, var(--warm), var(--amber));
  box-shadow: 0 8px 18px -9px var(--warm-glow);
}
.lt-body { flex: 1; min-width: 0; }
.lt-kicker { font-size: 10.5px; font-weight: 700; letter-spacing: .5px; color: var(--amber); }
:root[data-theme="dark"] .lt-kicker { color: var(--warm); }
.lt-title { margin: 3px 0 7px; font-size: 16px; font-weight: 720; letter-spacing: -.2px; color: var(--ink); }
.lt-text { margin: 0; font-size: 13.5px; line-height: 1.8; color: var(--ink-soft); }
.lt-tip {
  margin: 10px 0 0; padding: 9px 12px; border-radius: var(--r-m);
  font-size: 12.5px; line-height: 1.65; color: var(--ink-soft);
  background: var(--glass); border-left: 3px solid var(--warm);
}
:root[data-theme="dark"] .lt-tip { background: var(--sunken); }

/* ============================================================
   五、首页：励志的话 + 风景增强
   ============================================================ */
.h4-quote {
  position: relative; max-width: 30ch; margin: 14px 0 18px;
  padding-left: 13px; border-left: 3px solid var(--accent);
}
.h4-quote .q {
  display: block; font-size: 16px; line-height: 1.7; font-weight: 620;
  color: var(--ink);
}
.h4-quote .a {
  display: block; margin-top: 6px; font-size: 12px; font-style: normal;
  color: var(--ink-faint);
}
:root[data-theme="dark"] .h4-quote { border-left-color: var(--accent); }
:root[data-theme="dark"] .h4-quote .q { color: #ece8dc; text-shadow: 0 2px 14px rgba(10,12,16,.88), 0 1px 4px rgba(10,12,16,.9); }
:root[data-theme="dark"] .h4-quote .a { color: #a8a49a; text-shadow: 0 1px 8px rgba(10,12,16,.8); }
:root[data-theme="dark"] .h4-date { text-shadow: 0 1px 8px rgba(10,12,16,.7); }
@keyframes oc-spec { 0%, 100% { opacity: .55; transform: translateX(0); } 50% { opacity: .9; transform: translateX(6px); } }
.oc-crest { animation: oc-crest 9s ease-in-out infinite alternate; }
@keyframes oc-crest { from { transform: translateX(-14px); } to { transform: translateX(14px); } }
.oc-wet { animation: oc-wet 5.5s ease-in-out infinite; }
@keyframes oc-wet { 0%, 100% { opacity: .5; } 50% { opacity: .82; } }
.oc-mist { animation: oc-mist 26s linear infinite; }
@keyframes oc-mist { from { transform: translateX(-30px); } to { transform: translateX(30px); } }
.oc-boat-body { animation: oc-boat-ride 6.4s ease-in-out infinite; }
@keyframes oc-boat-ride { 0%, 100% { transform: translateY(0) rotate(-.6deg); } 50% { transform: translateY(-2.4px) rotate(.8deg); } }
.page-scene .ps-rim { mix-blend-mode: screen; }
.page-scene .ps-mist { animation: oc-mist 34s linear infinite; }

/* ---------- 海景配色（已并入 app.css 的水墨配色块，这里不再覆盖） ----------
   注意：这个文件在 app.css 之后加载，如果在这里再定义 --oc-*，
   会把水墨配色盖回旧的蓝色。补差的变量统一放 app.css。 */

/* 标题：W 的左笔画原来贴着 SVG 左边缘，stroke 会溢出被裁掉（看起来像少了一笔）。
   现在 viewBox 往左留了余量，这里再把 overflow 打开兜底。 */
.h4-title { overflow: visible; }
.h4-title text { letter-spacing: 0; }

/* ---------- 海景铺满整块 hero ----------
   .oc-scene 原来只写了 left/right/bottom + 固定高度：SVG 是「替换元素」，
   宽度取的是固有尺寸（高 × viewBox 比例）。老 viewBox 是 800×250（很宽），
   所以看上去是铺满的；新 viewBox 改成 800×620 之后固有宽度只有 230px，
   于是场景缩成了左边一个方块。这里显式给全宽全高，让它真正当背景。
   内容区的底部内边距也不用留 216px 了（那是给"贴底一条"预留的）。 */
.oc-scene { inset: 0; width: 100%; height: 100%; }
.h4-inner { padding-bottom: 124px; }
@media (min-width: 721px) { .h4-inner { padding-bottom: 156px; }}
:root[data-theme="dark"] .oc-orb-c,
:root[data-theme="dark"] .oc-orb-in {
  mask: url(#oc-moon-cut);
  -webkit-mask: url(#oc-moon-cut);
}
.oc-flare { fill: var(--oc-spec1); opacity: .28; }
.oc-glitter ellipse { fill: var(--oc-spec1); opacity: .55; }
.oc-path-core { opacity: .8; }
.oc-haze-band { mix-blend-mode: screen; }
.oc-boat-refl { fill: var(--oc-boat-refl); }
.oc-hull-hi { fill: none; stroke: var(--oc-sail); stroke-width: 1; opacity: .45; }

/* 浪：亮面 + 暗面。只画亮面会像纸片，暗面才让浪"立"起来 */
.oc-wave .oc-crest {
  fill: none; stroke: var(--oc-crest-l); stroke-width: 1.5;
  stroke-linecap: round; opacity: .42;
}
.oc-wave .oc-wave-sh { fill: var(--oc-crest-s); opacity: .17; }

/* 云：受光面 + 底面阴影 */
.sc-cloud-sh { fill: var(--sc-cloud-b); opacity: .8; }
.sc-cloud-hi { fill: #ffffff; opacity: .5; }
:root[data-theme="dark"] .sc-cloud-hi { opacity: .16; }
@keyframes kb-line-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes kb-breathe { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }
:root[data-theme="dark"] .st-live.on { color: #7ff0c2; }

.st-idx-card { padding: 4px 6px; }

/* 红涨绿跌：两套主题都用同一套（A 股习惯） */
.up { color: #e0344a !important; }
.down { color: #12a271 !important; }
.flat { color: var(--ink-faint) !important; }
:root[data-theme="dark"] .up { color: #ff6478 !important; }
:root[data-theme="dark"] .down { color: #2ee0a2 !important; }
@media (max-width: 460px) { .st-board { grid-template-columns: 1fr; }}
@keyframes kb-fade { 0%, 100% { opacity: .95; } 50% { opacity: .5; } }
@keyframes kb-ring { 0% { transform: scale(.5); opacity: .8; } 100% { transform: scale(2.4); opacity: 0; } }

/* ---------- 顶栏：开市状态 + 更新时间 ---------- */
.st-top {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-bottom: 14px; font-size: 11.5px; color: var(--ink-faint);
}
.st-live {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 999px;
  color: var(--ink-faint); background: var(--sunken);
  border: 1px solid var(--line);
}
.st-live i { width: 6px; height: 6px; border-radius: 50%; background: #64748b; }
.st-live.on { color: #7ff0c2; border-color: rgba(52, 211, 153, .35); background: rgba(16, 185, 129, .12); }
.st-live.on i { background: #34d399; box-shadow: 0 0 0 0 rgba(52, 211, 153, .8); animation: st-pulse 1.9s ease-out infinite; }
@keyframes st-pulse { 0% { box-shadow: 0 0 0 0 rgba(52, 211, 153, .7); } 100% { box-shadow: 0 0 0 9px rgba(52, 211, 153, 0); } }
.st-upd { font-variant-numeric: tabular-nums; }
.st-more i { font-style: normal; color: var(--ink-faint); }
.st-idx {
  display: grid; grid-template-columns: 1fr auto 78px;
  align-items: center; gap: 10px; width: 100%;
  padding: 9px 10px; border-radius: 12px; cursor: pointer; text-align: left;
  border-bottom: 1px solid var(--line);
  transition: background .16s ease, transform .16s ease;
}
.st-idx:last-child { border-bottom: none; }
.st-idx:hover { background: var(--sunken); transform: translateX(2px); }
.st-idx-n { font-size: 13.5px; color: var(--ink-soft); }
.st-idx-p { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.2px; }
.st-idx-c { font-size: 12.5px; font-weight: 640; text-align: right; font-variant-numeric: tabular-nums; }


/* ---------- 搜索 ---------- */
.st-toolbar { display: flex; gap: 8px; margin-bottom: 18px; }
.st-search { position: relative; flex: 1; }
.st-search input {
  width: 100%; padding: 12px 14px 12px 38px;
  border-radius: 14px; font-size: 14px; color: var(--ink);
  background: var(--sunken);
  border: 1px solid var(--line);
}
.st-search input::placeholder { color: var(--ink-faint); }
.st-search input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.st-search .ico { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); font-size: 14px; opacity: .55; pointer-events: none; }
.st-results {
  position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 40;
  max-height: 288px; overflow-y: auto; padding: 6px; border-radius: 16px;
  background: var(--glass-strong); border: 1px solid var(--line-strong);
  box-shadow: 0 24px 50px -20px rgba(0, 0, 0, .8);
}
.st-hit {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 11px; border-radius: 11px; cursor: pointer; text-align: left;
}
.st-hit:hover { background: var(--sunken); }
.st-hit .hk { flex: 0 0 26px; font-size: 10px; font-weight: 700; text-align: center; padding: 3px 0; border-radius: 6px; color: #fff; background: #3b82f6; }
.st-hit .hk-hk { background: #c2410c; }
.st-hit .hk-us { background: #1d4ed8; }
.st-hit .hk-bj { background: #6d28d9; }
.st-hit .hn { flex: 1; font-size: 14px; color: var(--ink); }
.st-hit .hc { font-size: 11.5px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }

/* ---------- 自选 ---------- */
.st-watch { display: flex; flex-direction: column; gap: 8px; }
.st-row {
  display: flex; align-items: center; gap: 11px;
  padding: 12px 13px; border-radius: 15px; cursor: pointer;
  background: var(--sunken);
  border: 1px solid var(--line);
  transition: transform .16s ease, background .16s ease, border-color .16s ease;
}
.st-row:hover { transform: translateY(-2px); background: var(--sunken); border-color: var(--line-strong); }
.st-row .nm { flex: 1; min-width: 0; }
.st-row .nm b { display: block; font-size: 15px; font-weight: 660; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-row .nm span { display: block; font-size: 11px; color: var(--ink-faint); margin-top: 2px; font-variant-numeric: tabular-nums; }
.st-row .px { text-align: right; font-variant-numeric: tabular-nums; }
.st-row .px b { display: block; font-size: 16px; font-weight: 700; }
.st-row .px span { display: block; font-size: 12px; font-weight: 620; margin-top: 3px; }
.st-row .del { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; font-size: 13px; color: var(--ink-faint); cursor: pointer; }
.st-row .del:hover { background: rgba(255, 90, 120, .16); color: #ff7d92; }
.st-empty b { font-size: 15px; color: var(--ink); }

/* ---------- 折叠的榜单 ---------- */
.st-acc-wrap { margin-bottom: 8px; border-radius: 15px; overflow: hidden; background: var(--sunken); border: 1px solid var(--line); }
.st-acc {
  display: grid; grid-template-columns: 34px 1fr auto 22px;
  align-items: center; gap: 8px; width: 100%;
  padding: 13px 13px; cursor: pointer; text-align: left;
}
.st-acc:hover { background: var(--sunken); }
.st-acc-no { font-size: 11px; font-weight: 700; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.st-acc-t { font-size: 14px; font-weight: 620; color: var(--ink-soft); }
.st-acc-n { font-size: 11.5px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.st-acc-c { font-size: 13px; color: var(--ink-faint); transition: transform .22s ease; text-align: right; }
.st-acc.on .st-acc-c { transform: rotate(180deg); }
.st-acc-body { padding: 2px 12px 12px; animation: st-drop .22s ease; }
@keyframes st-drop { from { opacity: 0; transform: translateY(-6px); } }
.st-rank { display: flex; flex-direction: column; }
.st-rank-row {
  display: grid; grid-template-columns: 22px 1fr auto 74px;
  align-items: center; gap: 9px; width: 100%;
  padding: 9px 8px; border-radius: 10px; cursor: pointer; text-align: left;
  border-bottom: 1px solid var(--line);
}
.st-rank-row:last-child { border-bottom: none; }
.st-rank-row:hover { background: var(--sunken); }
.st-rank-i { font-size: 11px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.st-rank-n { font-size: 13.5px; color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-rank-p { font-size: 13.5px; font-weight: 640; font-variant-numeric: tabular-nums; }
.st-rank-c { font-size: 12.5px; font-weight: 620; text-align: right; font-variant-numeric: tabular-nums; }

.st-board { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 460px) { .st-board { grid-template-columns: 1fr; }}
.st-bd-cap { font-size: 11px; color: var(--ink-faint); margin-bottom: 6px; }
.st-bd { display: grid; grid-template-columns: 1fr auto; gap: 2px 8px; padding: 8px 9px; border-radius: 11px; background: var(--sunken); margin-bottom: 6px; }
.st-bd-n { font-size: 13px; color: var(--ink-soft); }
.st-bd-c { font-size: 12.5px; font-weight: 640; font-variant-numeric: tabular-nums; }
.st-bd-s { grid-column: 1 / -1; font-size: 10.5px; color: var(--ink-faint); }
.st-note b { color: var(--ink-faint); }
.st-dark .mr-head { color: var(--ink); }
.st-dark .mr-lines li { color: var(--ink-soft); }
.st-dark .mr-lines li::before { background: var(--accent); }
.st-dark .mr-tone { color: var(--ink-faint); }
.st-dark .mr-struct { background: var(--sunken); color: var(--ink-soft); border-left-color: var(--accent); }
.st-dark .mr-scene { color: var(--ink-soft); }
.st-dark .mr-scene::before { color: var(--ink-faint); }
.st-dark .mr-foot { color: var(--ink-faint); border-top-color: var(--line); }
.st-dark .lt-kicker { color: var(--warm); }
.st-dark .lt-title { color: var(--ink); }
.st-dark .lt-text { color: var(--ink-soft); }
.st-dark .lt-tip { background: var(--sunken); color: var(--ink-soft); }

/* ---------- 详情弹层（也跟着深色走） ---------- */
.st-modal { max-width: 520px; }
.st-modal .modal-x { color: var(--ink-faint); }
.st-modal .modal-x:hover { background: var(--sunken); color: var(--ink); }
.stm-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin-bottom: 14px; padding-right: 34px; }
.stm-name { font-size: 20px; font-weight: 750; letter-spacing: -.3px; color: var(--ink); }
.stm-code { font-size: 11.5px; color: var(--ink-faint); font-variant-numeric: tabular-nums; margin-top: 3px; }
.stm-price { text-align: right; font-variant-numeric: tabular-nums; }
.stm-price b { display: block; font-size: 26px; font-weight: 760; letter-spacing: -.6px; }
.stm-price span { display: block; font-size: 13px; font-weight: 640; margin-top: 2px; }
.stm-chart { margin: 6px 0 12px; }
.stm-chart svg { width: 100%; height: 150px; display: block; }
.stm-chart-empty { height: 150px; display: grid; place-items: center; color: var(--ink-faint); font-size: 12px; }
.stm-legend { display: flex; gap: 14px; font-size: 11px; color: var(--ink-faint); margin-top: 4px; }
.stm-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 12px 0; }
.stm-cell { padding: 9px 10px; border-radius: 12px; background: var(--sunken); }
.stm-cell span { display: block; font-size: 10.5px; color: var(--ink-faint); margin-bottom: 3px; }
.stm-cell b { font-size: 13.5px; font-weight: 660; color: var(--ink); font-variant-numeric: tabular-nums; }
.stm-act { display: flex; gap: 9px; flex-wrap: wrap; }

/* ============================================================
   沙漏板块图（股票页的主角）
   上漏斗 = 涨的板块（红圆），下漏斗 = 跌的板块（绿圆），腰最窄；
   圆圈大小按成交额，越靠近腰越小 —— 看着像沙子在往下漏。
   ============================================================ */
.hg-card {
  padding: 6px 8px 2px; margin: 0 0 10px;
  border-radius: var(--r-xl);
  background: linear-gradient(170deg, var(--glass), var(--glass-soft));
  border: 1px solid var(--line);
  box-shadow: var(--shadow-s);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.hg-svg { display: block; width: 100%; height: auto; }
.hg-frame { fill: url(#hg-glass); stroke: var(--line-strong); stroke-width: 1; }
.hg-waist { stroke: var(--line-strong); stroke-width: 1; }
.hg-cap { fill: var(--ink-faint); font-size: 12px; font-weight: 620; text-anchor: middle; }
.hg-cap.u { fill: #e0344a; }
.hg-cap.d { fill: #12a271; }
:root[data-theme="dark"] .hg-cap.u { fill: #ff6478; }
:root[data-theme="dark"] .hg-cap.d { fill: #2ee0a2; }

.hg-c { cursor: pointer; animation: hg-float 6.5s ease-in-out infinite; animation-delay: calc(var(--i) * -.35s); }
.hg-c circle { stroke: #ffffff; stroke-opacity: .55; stroke-width: 1; }
.hg-c.u circle { fill: url(#hg-up); }
.hg-c.d circle { fill: url(#hg-dn); }
.hg-c:hover circle { stroke-opacity: 1; stroke-width: 2.2; }
.hg-c text { text-anchor: middle; fill: #ffffff; font-weight: 700; pointer-events: none; }
.hg-p { opacity: .92; font-weight: 600 !important; }
@keyframes hg-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }
.hg-sand circle { fill: var(--ink-faint); opacity: .5; animation: hg-fall 2.6s ease-in infinite; }
.hg-sand .s2 { animation-delay: .8s; }
.hg-sand .s3 { animation-delay: 1.6s; }
@keyframes hg-fall { 0% { opacity: 0; transform: translateY(-14px); } 40% { opacity: .65; } 100% { opacity: 0; transform: translateY(18px); } }
@media (prefers-reduced-motion: reduce) { .hg-c, .hg-sand circle { animation: none !important; } }
.hg-note { margin: 0 0 16px; font-size: 11.5px; line-height: 1.75; color: var(--ink-faint); text-align: center; }
.hg-empty { padding: 26px 16px; text-align: center; font-size: 12.5px; color: var(--ink-faint); }

/* 抽屉里的小提示块（跟主题走） */
.st-hint {
  padding: 12px 13px; border-radius: var(--r-m);
  font-size: 12.5px; line-height: 1.7; color: var(--ink-faint);
  background: var(--sunken);
}

/* ============================================================
   板块柱状图：红柱在上（涨）、绿柱在下（跌），带荧光扫光
   ============================================================ */
.bar-card {
  padding: 12px 10px 4px; margin: 0 0 14px;
  border-radius: var(--r-xl);
  background: linear-gradient(170deg, var(--glass), var(--glass-soft));
  border: 1px solid var(--line);
  box-shadow: var(--shadow-s);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.bar-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: 0 4px 6px; }
.bar-t { font-size: 13px; font-weight: 700; color: var(--ink); letter-spacing: .3px; }
.bar-sum { font-size: 12px; font-weight: 620; }
.bar-sum i { font-style: normal; color: var(--ink-faint); margin: 0 5px; }
.bar-svg { display: block; width: 100%; height: auto; overflow: visible; }
.bar-grid { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 5; }
.bar-axis { stroke: var(--line-strong); stroke-width: 1.2; }
.bar-bg { fill: var(--sunken); opacity: .55; }
.bar-g { cursor: pointer; }
.bar-fg { filter: drop-shadow(0 0 6px rgba(255, 93, 115, .55)); animation: bar-glow 3.4s ease-in-out infinite; animation-delay: calc(var(--i) * -.28s); }
.bar-g.d .bar-fg { filter: drop-shadow(0 0 6px rgba(34, 211, 165, .5)); }
.bar-cap { opacity: .95; }
.bar-p { font-size: 9.5px; font-weight: 700; text-anchor: middle; font-variant-numeric: tabular-nums; }
.bar-p.u { fill: #ffffff; }
.bar-p.d { fill: #06301f; }
.bar-n { font-size: 9px; fill: var(--ink-soft); text-anchor: start; }
.bar-g:hover .bar-n { fill: var(--ink); font-weight: 700; }
@keyframes bar-glow { 0%, 100% { opacity: .88; } 50% { opacity: 1; } }

/* 会来回扫过的荧光带（一闪一闪走过去） */
.bar-sweep { animation: bar-sweep 4.2s cubic-bezier(.45, 0, .55, 1) infinite; mix-blend-mode: screen; }
@keyframes bar-sweep {
  0% { transform: translateX(0); opacity: 0; }
  12% { opacity: 1; }
  62%, 100% { transform: translateX(470px); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .bar-fg, .bar-sweep { animation: none !important; }
}

/* ============================================================
   分段控件（蚂蚁/雪球那种：一排胶囊切面板，不再一层层展开）
   ============================================================ */
/* ---------- 股票页首屏结构修正（审计报告 P0-1 / P0-2）----------
   改之前：DOM 顺序是 `st-top → 行业板块卡(642px) → 分段导航 → 内容面板`，
   手机 390×844 实测分段落在 y=767，而固定底栏是 y=760–832 —— **整块被盖住**，
   指数卡也在首屏之外。用户打开股票页只看到一屏"涨100·跌0"榜单。

   改动（配合 stock.js 的渲染顺序）：
     ① 分段导航提到「行业板块」前面，紧跟在状态行下面；
     ② 行业板块降级成「大盘」面板里的一块，默认只给前 5 行；
     ③ 分段导航做**粘性**，滚到哪儿都够得着；
     ④ 切换分段时给面板一个高亮闪动（st-flash），"点了有反应"看得见。 */
.st-segs {
  display: flex; gap: 6px; overflow-x: auto;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
  position: sticky;
  top: 0;                       /* 手机端 .page-head 是 sticky top:0，这里贴在它下面 */
  z-index: 12;
  margin: 0 -2px 10px;
  padding: 8px 2px 9px;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--paper) 82%, transparent) 0%,
    color-mix(in srgb, var(--paper) 62%, transparent) 100%);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  border-radius: 0 0 var(--r-m) var(--r-m);
}
.st-segs::-webkit-scrollbar { display: none; }
/* 分段键：热区抬到 40px（审计 P2-1 说 33px 偏小） */
.st-seg { padding: 10px 16px; min-height: 40px; }

/* 切换分段时闪一下，明确"内容变了" */
.st-flash { animation: st-flash .5s ease; }
@keyframes st-flash {
  0% { background: var(--accent-soft); }
  100% { background: transparent; }
}
/* 折叠态的板块卡再矮一点，别抢首屏 */
.sec-slot[data-clamp] .sec-row:nth-child(n+7) { display: none; }

.st-seg {
  flex: 0 0 auto; padding: 7px 15px; border-radius: var(--r-full); cursor: pointer;
  font-size: 13px; font-weight: 620; color: var(--ink-soft);
  background: var(--glass); border: 1px solid var(--line);
  transition: transform .16s ease, background .16s ease, color .16s ease;
}
.st-seg:hover { transform: translateY(-1px); }
.st-seg.on {
  color: #ffffff; border-color: transparent;
  background: linear-gradient(135deg, var(--accent), var(--accent-deep));
  box-shadow: 0 8px 20px -10px var(--accent);
}
.st-panel { animation: st-panel-in .22s ease; }
@keyframes st-panel-in { from { opacity: 0; transform: translateY(6px); } }

/* ============================================================
   划词卡里的「知识库」那一段
   本地检索、标出处；没命中的话给你一个「＋ 收录进知识库」
   ============================================================ */
.ex-kb { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line-strong); }
.ex-kb-h {
  display: flex; align-items: baseline; gap: 8px; margin-bottom: 9px;
  font-size: 12px; font-weight: 700; letter-spacing: .3px; color: var(--accent-deep);
}
.ex-kb-s { font-weight: 400; font-size: 11px; color: var(--ink-faint); }
.ex-kb-i {
  padding: 10px 12px; margin-bottom: 8px; border-radius: var(--r-m);
  background: var(--sunken); border-left: 3px solid var(--accent);
}
.ex-kb-t { display: flex; align-items: baseline; gap: 7px; font-size: 13.5px; font-weight: 700; color: var(--ink); }
.ex-kb-t i { font-style: normal; font-size: 10.5px; font-weight: 500; color: var(--ink-faint); }
.ex-kb-t em { font-style: normal; font-size: 10px; color: var(--accent-deep); opacity: .85; }
.ex-kb-b { margin-top: 5px; font-size: 13px; line-height: 1.7; color: var(--ink-soft); }
.ex-kb-e { margin-top: 5px; font-size: 12px; line-height: 1.65; color: var(--ink-faint); }
.ex-kb-f { margin-top: 6px; font-size: 10.5px; color: var(--ink-faint); }
.ex-act { display: flex; align-items: center; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.ex-act-hint { font-size: 11.5px; color: var(--ink-faint); }

/* ============================================================
   板块列表（红在上、绿在下）—— 用列表 + 比例条，不做花哨图形
   ============================================================ */
.sec-card {
  padding: 12px 12px 10px; margin: 0 0 14px;
  border-radius: var(--r-xl);
  background: linear-gradient(170deg, var(--glass), var(--glass-soft));
  border: 1px solid var(--line);
  box-shadow: var(--shadow-s);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: 0 2px 10px; }
.sec-title { font-size: 13px; font-weight: 700; color: var(--ink); letter-spacing: .3px; }
.sec-sum { font-size: 12px; font-weight: 620; }
.sec-sum i { font-style: normal; color: var(--ink-faint); margin: 0 4px; }
.sec-cap { padding: 2px 2px 6px; font-size: 11px; color: var(--ink-faint); }
.sec-row {
  display: grid; grid-template-columns: 5.6em 1fr 4.2em;
  align-items: center; gap: 9px; width: 100%;
  padding: 7px 4px; border-radius: var(--r-s); cursor: pointer; text-align: left;
}
.sec-row:hover { background: var(--sunken); }
.sec-n { font-size: 13px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sec-track { height: 7px; border-radius: 4px; background: var(--sunken); overflow: hidden; }
.sec-track i { display: block; height: 100%; border-radius: 4px; transition: width .3s ease; }
.sec-track i.up { background: linear-gradient(90deg, rgba(224, 52, 74, .5), #e0344a); box-shadow: 0 0 8px rgba(224, 52, 74, .4); }
.sec-track i.down { background: linear-gradient(90deg, rgba(18, 162, 113, .5), #12a271); box-shadow: 0 0 8px rgba(18, 162, 113, .4); }
.sec-p { font-size: 12.5px; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.sec-split { height: 1px; margin: 9px 2px; background: linear-gradient(90deg, transparent, var(--line-strong), transparent); }

/* ============================================================
   打卡确认（「你真的复习了吗？」）+ 20 分钟倒计时
   ============================================================ */
.ck-ask { text-align: center; }
.ck-ask-ico { font-size: 34px; line-height: 1; margin-bottom: 8px; }
.ck-ask-t { font-size: 16.5px; font-weight: 700; color: var(--ink); margin-bottom: 7px; }
.ck-ask-s { font-size: 12.5px; line-height: 1.75; color: var(--ink-faint); }
.ck-ask-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 18px; }
.ck-cd {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 9px; border-radius: var(--r-full);
  font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: #a35b06; background: rgba(245, 158, 11, .16);
}
.ck-cd.warn { color: #ffffff; background: #e0344a; animation: ck-cd-pulse 1s ease-in-out infinite; }
@keyframes ck-cd-pulse { 50% { opacity: .6; } }
.ck-card.just-done { opacity: .78; }

/* 「下一张还有多久」那一行 */
.ck-next {
  margin: 0 0 12px; padding: 9px 13px; border-radius: var(--r-m);
  font-size: 12.5px; font-weight: 620; color: var(--accent-deep);
  background: var(--glass); border: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
}

/* ============================================================
   WIN 拼图：12 个方块盖在卡通 "WIN" 上，打卡点亮一块
   ============================================================ */
.win-box {
  position: relative; padding: 8px; border-radius: var(--r-l);
  background: var(--sunken); overflow: hidden;
}
.win-art { position: relative; height: 116px; display: grid; place-items: center; }
.win-svg { width: 100%; height: 100%; display: block; }
.win-grid {
  position: absolute; inset: 8px; display: grid;
  grid-template-columns: repeat(var(--cols, 6), 1fr);
  grid-template-rows: repeat(var(--rows, 2), 1fr);
  gap: 3px;
}
.win-grid i {
  border-radius: 6px;
  background: var(--line-strong);
  backdrop-filter: blur(4px) saturate(.4); -webkit-backdrop-filter: blur(4px) saturate(.4);
  transition: background .5s ease, box-shadow .5s ease, transform .35s ease;
}
.win-grid i.on {
  background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .34), 0 0 12px var(--warm-glow);
}
.win-meta { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 10px 2px 2px; }
.win-name { font-size: 13.5px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.win-count { font-size: 12px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.win-count b { font-size: 15px; color: var(--accent-deep); }
.win-note { margin: 8px 0 0; font-size: 12px; line-height: 1.7; color: var(--ink-faint); }
.win-note b { color: var(--accent-deep); }
:root[data-theme="dark"] .win-grid i { background: var(--line-strong); }

/* 个股弹层：改回跟主题一致（上面那套深色配色是上一版终端风留下的） */
.st-modal {
  background: var(--glass-strong) !important;
  border: 1px solid var(--line-strong) !important;
  color: var(--ink);
}
.stm-name { color: var(--ink); }
.stm-code { color: var(--ink-faint); }
.stm-chart-empty { color: var(--ink-faint); }
.stm-legend { color: var(--ink-faint); }
.stm-cell { background: var(--sunken); }
.stm-cell span { color: var(--ink-faint); }
.stm-cell b { color: var(--ink); }
.st-modal .modal-x { color: var(--ink-faint); }
.st-modal .modal-x:hover { background: var(--sunken); color: var(--ink); }
.st-modal .up { color: #e0344a !important; }
.st-modal .down { color: #12a271 !important; }
:root[data-theme="dark"] .st-modal .up { color: #ff6478 !important; }
:root[data-theme="dark"] .st-modal .down { color: #2ee0a2 !important; }

/* ============================================================
   以下为 v4 视觉层（源文件：D:\dev\_tools\_theme-v4-layer.css）
   ============================================================ */
/* ============================================================
   v4 视觉层 ——《双境山水·实景画作》
   ------------------------------------------------------------
   这一层由 theme-surgery.mjs 追加到 app.css 末尾，因此天然覆盖前面的旧规则。
   内容分四块：
     1. 全站背景画作 + 可读性蒙版 + 雾气漂移
     2. 首页 / 情报站 / 股票 的开场画面
     3. 统一的宣纸玻璃组件质感 + 墨晕悬停 + 印章按压
     4. 缺失的加载态、键盘焦点、无障碍降级
   ============================================================ */

/* ============================================================
   1. 全站背景：画作 + 蒙版 + 纸纹
   ============================================================ */
.aurora {
  position: fixed; inset: 0; z-index: 0;
  overflow: hidden; pointer-events: none;
  background: var(--paper);
  /* 不再用 contain:strict —— 它会把内部的 fixed 子元素压塌 */
}
/* ::before = 画作 + 上下左右压纸色的可读性蒙版 */
.aurora::before {
  content: ''; position: absolute;
  /* 性能工单 PERF-FE-005：原来是 inset: -3% -2%（多铺一圈），
     但下面已经有 transform: scale(1.03) 兜边了，再往外铺是白多一层像素。
     另外删掉了 will-change: transform —— 它让这一层**常驻**一个合成层，
     而这一层是全屏的、还挂着 52 秒动画，等于一直占着显存。 */
  inset: 0;
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--paper) 92%, transparent) 0%,
      color-mix(in srgb, var(--paper) 42%, transparent) 18%,
      color-mix(in srgb, var(--paper) 26%, transparent) 52%,
      color-mix(in srgb, var(--paper) 78%, transparent) 100%),
    linear-gradient(90deg,
      color-mix(in srgb, var(--paper) 72%, transparent) 0%,
      color-mix(in srgb, var(--paper) 30%, transparent) 30%,
      transparent 58%),
    var(--art-page);
  background-size: cover, cover, cover;
  background-position: center, center, center top;
  background-repeat: no-repeat;
  opacity: .86;
  transform: scale(1.03);
  animation: mist-drift 52s ease-in-out infinite alternate;
}
:root[data-theme="dark"] .aurora::before { opacity: .92; }
/* ::after = 宣纸颗粒，压在最上面（极淡噪点） */
.aurora::after {
  content: ''; position: absolute; inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.16  0 0 0 0 0.2  0 0 0 0 0.17  0 0 0 0.028 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  opacity: .55; mix-blend-mode: multiply; pointer-events: none;
}
:root[data-theme="dark"] .aurora::after { mix-blend-mode: screen; opacity: .3; }

@keyframes mist-drift {
  from { transform: translate3d(0, 0, 0) scale(1.03); }
  to   { transform: translate3d(-1.5%, -1.2%, 0) scale(1.075); }
}

/* 竖屏也直接用同一张横画 —— background-size: cover 会自己裁出中间那段。
   之前专门生成竖幅是为了控制裁切位置，但那样等于把同一幅画做两遍，
   风格还容易跑偏；交给 cover 更稳，也少两张要维护的图。 */

/* ============================================================
   2. 开场画面
   ============================================================ */

/* ---- 首页：整幅画作 + 分层视差 + 落雪 ---- */
.hero4 {
  position: relative; overflow: hidden;
  min-height: min(64vh, 520px);
  border: 1px solid color-mix(in srgb, var(--snow) 30%, transparent);
  box-shadow: 0 26px 60px -30px color-mix(in srgb, var(--ink) 55%, transparent), var(--shadow-m);
  /* 左侧压一层纸色让"墨"立得住，但**不能压死画面** ——
     上一版压到 91%，结果用户说"这么大个背景全是白色有什么意思"。
     现在的分寸：左边保证文字可读，右边从中间就开始让出画作，
     底部也只压一点，小舟和水面要看得见。
     ⚠️ 这一套是**给亮色（青竹那张画）**调的。暗色在文件末尾有单独覆盖，
     因为暗色要的是原来那张"雪夜小屋"的取景，不能被这里顺手改掉。 */
  background-image:
    linear-gradient(96deg,
      color-mix(in srgb, var(--paper) 74%, transparent) 0%,
      color-mix(in srgb, var(--paper) 44%, transparent) 32%,
      color-mix(in srgb, var(--paper) 12%, transparent) 58%,
      transparent 78%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--paper) 26%, transparent) 0%,
      transparent 24%,
      color-mix(in srgb, var(--paper) 30%, transparent) 88%,
      color-mix(in srgb, var(--paper) 52%, transparent) 100%),
    var(--art-hero);
  background-size: cover, cover, cover;
  background-position: center, center, center 52%;
  background-repeat: no-repeat;
}
@media (max-width: 719px) {
  .hero4 { min-height: 58vh; background-position: center, center, center 46%; }
}

/* ---------- ⑦ 手机顶部那条"白条子" ----------
   用户原话：「这顶部这个条子，太影响美观了，你要么做成原来的玻璃透明效果，
   要么就取消掉这个白条子」。

   它是 `.page-head`（手机端变成粘性标题条）的 `background: var(--bg-glass)`，
   在亮色下就是一整条白。这里改成**从上往下淡出的透明渐变**：
   不撕掉粘性（滚动时还得挡住字），但没有硬边、也没有那块白。 */
@media (max-width: 719px) {
  .page-head {
    background: linear-gradient(180deg,
      color-mix(in srgb, var(--paper) 62%, transparent) 0%,
      color-mix(in srgb, var(--paper) 30%, transparent) 58%,
      transparent 100%);
    backdrop-filter: blur(10px) saturate(150%);
    -webkit-backdrop-filter: blur(10px) saturate(150%);
    border-bottom: none;
  }
  /* 首页连标题都不显示，那一条更没必要挡着画 */
  body.on-home .page-head {
    background: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

/* ---------- ⑩ 暗色首页卡片：**故意不单独覆盖** ----------
   这里原来有一条 `:root[data-theme="dark"] .hero4 { ... }`，
   本意是"只给暗色调取景和蒙版"。但它其实**从建起来那天就是死的** ——
   注释被写坏（先是注释提前闭合、后来是正文里出现嵌套注释符号），
   整条规则被解析器丢掉，所以暗色卡片一直用的是下面 `.hero4` 基础规则的取景（center 52%）+ 蒙版。

   也就是说：**用户看到的"原样"就是基础规则那一套。**
   2026-09-20 我把注释修好之后它突然生效了（取景变成 18%、蒙版也变重），
   反而把用户熟悉的画面改掉了。按"调回原状"的要求，这里**整条删掉**，
   让暗色继续用基础规则 —— 与用户一直看到的一致。

   ⚠️ 以后要单独调暗色卡片的取景，请**另起一条规则并验 `getComputedStyle`**，
      确认它真的生效（这个坑本项目踩过两次）：
        在页面里读 el 的 background-position，值必须等于你写的那个。
    ⚠️ 注释正文里绝对不要出现注释起止符号。 */
@media (max-width: 719px) {
  :root[data-theme="dark"] .hero4 { background-position: center, center, center 24%; }
}

/* 手机上把画往左挪一点，让那间小屋（和它亮着的窗）落在画面里。
   ⚠️ 2026-09-20 第二次返工：这个 30% 是**错的**，用户要的是"卡片里的小屋跟原来那张图一样"。
   原来的样子（他 00:32 那张截图）就是最朴素的 `background-position: center` ——
   手机卡片是竖的、画是横的，`cover` 横向切中间那一刀，切出来的正好是
   小屋的右半边（含两扇亮窗），落在卡片左半边、被纸色蒙版压暗 —— 那是**设计如此**。
   我把它挪到 30% 反而把窗户推到了画面外。**恢复 center。** */
@media (max-width: 719px) {
  :root[data-theme="dark"] .hero4 {
    /* 手机端暗色：换成**竖幅**那张画（小屋完整居中），所以不用再靠裁切去凑。
       蒙版也顺势调轻：竖幅里小屋就在正中，纸色只要保证文字可读就行。 */
    background-image:
      linear-gradient(97deg,
        color-mix(in srgb, var(--paper) 72%, transparent) 0%,
        color-mix(in srgb, var(--paper) 46%, transparent) 30%,
        color-mix(in srgb, var(--paper) 18%, transparent) 58%,
        transparent 84%),
      linear-gradient(180deg,
        color-mix(in srgb, var(--paper) 30%, transparent) 0%,
        transparent 26%,
        color-mix(in srgb, var(--paper) 46%, transparent) 86%,
        color-mix(in srgb, var(--paper) 68%, transparent) 100%),
      var(--art-hero-m);
    background-size: cover, cover, cover;
    background-position: center, center, center 38%;
    background-repeat: no-repeat;
  }
}
/* 旧的纸底/彩色光斑层不再需要（画作本身就是底） */
.h4-sky, :root[data-theme="dark"] .h4-sky { background: none; }
.h4-blob { display: none; }
.h4-inner { padding: 34px 34px 38px; }
@media (max-width: 719px) { .h4-inner { padding: 24px 20px 30px; } }

/* 画作之上，标题与句子要保证对比度 */
.hero4 .h4-date,
.hero4 .h4-quote .q,
.hero4 .h4-quote .a,
.h4-sub {
  text-shadow: 0 1px 2px color-mix(in srgb, var(--paper) 92%, transparent),
               0 6px 20px color-mix(in srgb, var(--paper) 72%, transparent);
}
:root[data-theme="dark"] .hero4 .h4-date,
:root[data-theme="dark"] .hero4 .h4-quote .q,
:root[data-theme="dark"] .hero4 .h4-quote .a {
  text-shadow: 0 2px 14px rgba(6, 10, 16, .88), 0 1px 4px rgba(6, 10, 16, .9);
}
.h4-quote { max-width: 34ch; }
.h4-quote .q { font-size: 16.5px; line-height: 1.72; }
.hero4 .pill.light {
  background: color-mix(in srgb, var(--paper) 78%, transparent);
  border-color: color-mix(in srgb, var(--ink) 16%, transparent);
  color: var(--ink);
}
/* 首页主按钮：夜里唯一那点暖光 */
:root[data-theme="dark"] .hero4 .pill.dark {
  background: linear-gradient(145deg, color-mix(in srgb, var(--warm) 88%, #000) 0%, color-mix(in srgb, var(--warm) 62%, #000) 100%);
  color: #1a1206;
  box-shadow: 0 14px 30px -14px var(--warm-glow), inset 0 1px 0 rgba(255, 255, 255, .28);
}

/* 视差场景层：JS 只改 --py，合成全交给 GPU */
.scene-layer {
  position: absolute; left: 0; right: 0; bottom: 0; width: 100%;
  pointer-events: none; z-index: 1;
  transform: translate3d(0, var(--py, 0px), 0);
  will-change: transform;
}
.scene-layer.mid  { opacity: .72; }
.scene-layer.near { opacity: .9; }
/* 落雪 / 雨丝画布 */
.scene-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; z-index: 2;
}
@media (prefers-reduced-motion: reduce) {
  .scene-layer { transform: none !important; }
  .scene-canvas { display: none; }
}

/* ---- 情报站：整块画作当卡头 ---- */
.intel-hero {
  position: relative; overflow: hidden;
  min-height: 268px;
  border: 1px solid color-mix(in srgb, var(--snow) 26%, transparent);
  box-shadow: 0 22px 50px -28px color-mix(in srgb, var(--ink) 50%, transparent), var(--shadow-m);
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--paper) 30%, transparent) 0%,
      transparent 40%,
      color-mix(in srgb, var(--paper) 62%, transparent) 100%),
    var(--art-page);
  background-size: cover, cover;
  background-position: center, center 32%;
}
.intel-hero::after {
  background: linear-gradient(180deg, transparent 30%, color-mix(in srgb, var(--paper) 72%, transparent) 100%);
}
/* 旧的水墨 SVG 不再挂载（改走上面的背景画作） */
.scene { display: none; }
.iq-text {
  color: var(--ink);
  text-shadow: 0 1px 2px color-mix(in srgb, var(--paper) 88%, transparent);
}
.iq-author { color: var(--ink-soft); text-shadow: none; }
:root[data-theme="dark"] .iq-text {
  color: #f2f7fb; text-shadow: 0 2px 16px rgba(6, 10, 16, .9);
}
:root[data-theme="dark"] .iq-author { color: color-mix(in srgb, #f2f7fb 78%, transparent); }
.intel-day {
  color: var(--ink-soft);
  background: var(--glass-strong);
  border: 1px solid var(--line);
}

/* ---- 股票页：江面画作当页头 ---- */
.st-page-hero, .stock-hero {
  position: relative; overflow: hidden;
  background-image:
    linear-gradient(180deg, color-mix(in srgb, var(--paper) 36%, transparent) 0%, color-mix(in srgb, var(--paper) 78%, transparent) 100%),
    var(--art-stock);
  background-size: cover, cover;
  background-position: center, center 40%;
  border: 1px solid var(--line);
  border-radius: var(--r-l);
}

/* ============================================================
   3. 统一的宣纸玻璃 + 墨晕悬停 + 印章按压
   ============================================================ */

/* 所有卡片走同一套配方：宣纸底 + 细墨线 + 顶部一道受光 */
.card, .stat, .mod, .feat, .ck-hero, .ck-stat, .ck-chart-wrap, .ck-card,
.intel-card, .next-up, .action, .learn-stage, .hg-card, .bar-card,
.sec-card, .mr-card, .lt-card {
  background: var(--glass);
  border: 1px solid var(--line);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  box-shadow: var(--shadow-s);
}
:root[data-theme="dark"] .card,
:root[data-theme="dark"] .stat,
:root[data-theme="dark"] .mod,
:root[data-theme="dark"] .feat,
:root[data-theme="dark"] .ck-hero,
:root[data-theme="dark"] .ck-stat,
:root[data-theme="dark"] .ck-chart-wrap,
:root[data-theme="dark"] .ck-card,
:root[data-theme="dark"] .intel-card,
:root[data-theme="dark"] .next-up,
:root[data-theme="dark"] .action,
:root[data-theme="dark"] .learn-stage,
:root[data-theme="dark"] .card {
  background: var(--glass);
  border-color: var(--line);
}
/* 悬停：从边缘晕开一层淡墨，而不是换一整个底色 */
.feat:hover, .ck-card:hover, .intel-card:hover, .action:hover,
.learn-stage:hover, .ck-stat:hover, .card:hover {
  background: var(--glass-strong);
  border-color: color-mix(in srgb, var(--ink) 20%, transparent);
  box-shadow: var(--shadow-m);
}
:root[data-theme="dark"] .feat:hover,
:root[data-theme="dark"] .ck-card:hover,
:root[data-theme="dark"] .intel-card:hover {
  border-color: color-mix(in srgb, var(--snow) 24%, transparent);
}
/* 卡片的受光面 + 墨晕（跟着鼠标，ui.js 写 --mx/--my） */
.feat::after, .ck-card::after, .intel-card::after, .card::after {
  background: radial-gradient(300px circle at var(--mx, 50%) var(--my, 0%),
              color-mix(in srgb, var(--snow) 62%, transparent), transparent 62%);
  mix-blend-mode: soft-light;
}
:root[data-theme="dark"] .feat::after,
:root[data-theme="dark"] .ck-card::after {
  mix-blend-mode: screen;
}

/* 主按钮 = 印章：按下时一圈朱砂扩散 */
.btn.primary, .pill.dark, .nu-go, .itab.on, .st-seg.on, .ls-num {
  background: linear-gradient(145deg, var(--accent), var(--accent-deep));
  border-color: transparent; color: #fff;
  box-shadow: 0 10px 24px -14px color-mix(in srgb, var(--accent) 85%, transparent);
}
.btn.primary:hover, .pill.dark:hover, .nu-go:hover {
  box-shadow: 0 16px 34px -14px color-mix(in srgb, var(--accent) 90%, transparent);
}
.btn:focus-visible, .pill:focus-visible, .nav-item:focus-visible, .tab:focus-visible,
.itab:focus-visible, .nav-icon-btn:focus-visible, .ic-link:focus-visible,
.input:focus-visible, .action:focus-visible, .feat:focus-visible,
.st-seg:focus-visible, .ck-bar:focus-visible, .modal-x:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-m);
}
::selection { background: var(--accent-soft); color: var(--ink); }

/* 涟漪改成朱砂色（ui.js 插入 .fx-ripple） */
.fx-ripple { background: radial-gradient(circle, var(--accent) 0%, transparent 68%); opacity: .2; }
.fx-spark { color: var(--accent); }

/* 统一的强调色：把旧版散落的蓝/橙硬编码收拢 */
.ck-bar.has i, .ck-mini i.has { background: linear-gradient(180deg, var(--jade-1), var(--jade-3)); }
.ck-bar.today i { background: linear-gradient(180deg, color-mix(in srgb, var(--warm) 92%, #fff), var(--warm)); }
.ck-bar.today em, .ck-stat.hot b, .ck-streak, .hm-item.hot b { color: var(--warm); }
.ck-stat.hot { border-color: color-mix(in srgb, var(--warm) 40%, transparent);
               background: color-mix(in srgb, var(--warm) 10%, var(--glass)); }
.ck-item.is-due, .ck-card.is-due { border-left-color: var(--accent); }
.ck-ontime b, .ckm-num.big b, .sync-badge[data-st="ok"] { color: var(--jade-3); }
:root[data-theme="dark"] .ck-ontime b,
:root[data-theme="dark"] .ckm-num.big b { color: var(--jade); }
.ck-late, .bk-warn { color: var(--amber); }
.say-avatar { background: linear-gradient(145deg, var(--jade-1), var(--jade-3)); }
.intel-card.say::before { background: linear-gradient(180deg, var(--jade-1), var(--jade-3)); }
.say-mark { color: color-mix(in srgb, var(--jade-2) 16%, transparent); }
.section-title {
  font-family: var(--font-display);
  font-size: 12.5px; letter-spacing: .08em; color: var(--ink-soft);
  border-bottom: 1px solid var(--line);
}
.page-title, .ckm-title, .learn-h-title, .ex-term {
  font-family: var(--font-display); font-weight: 660; letter-spacing: .01em;
}
.learn-hero {
  background: linear-gradient(135deg, var(--accent-soft), color-mix(in srgb, var(--jade-1) 14%, transparent));
  border: 1px solid var(--line);
}
.learn-h-progress b { color: var(--amber); }
.sync-badge[data-st="err"] { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 35%, transparent);
  background: color-mix(in srgb, var(--danger) 10%, transparent); }

/* ============================================================
   4. 加载态 / 焦点 / 降级
   ============================================================ */
/* .loading 以前根本没定义（模板里一直在用）—— 现在是宣纸上的三点墨 */
.loading {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; padding: 64px 20px; color: var(--ink-faint); font-size: 13px;
}
.loading p { margin: 0; letter-spacing: .04em; }
.hourglass { background: var(--glass); border: 1px solid var(--line); box-shadow: var(--shadow-s); }
.hg-top, .hg-bot {
  position: absolute; width: 8px; height: 8px; border-radius: 50%;
  background: var(--ink-faint); opacity: .5;
}
.hg-top { transform: translate(-9px, -4px); animation: hg-b 1.4s ease-in-out infinite; }
.hg-bot { transform: translate(9px, 4px); animation: hg-b 1.4s ease-in-out infinite .7s; }
@keyframes hg-b { 0%, 100% { opacity: .22; transform: translate(var(--tx, 0), 0) scale(.8); } 50% { opacity: .75; } }
.hg-top { --tx: -9px; } .hg-bot { --tx: 9px; }

/* 骨架屏：先把结构画出来，别让页面空着 */
.sk {
  border-radius: var(--r-m);
  background: linear-gradient(100deg, var(--sunken) 22%, color-mix(in srgb, var(--ink) 8%, transparent) 40%, var(--sunken) 58%);
  background-size: 220% 100%;
  animation: sk-sweep 1.5s ease-in-out infinite;
}
@keyframes sk-sweep { from { background-position: 130% 0; } to { background-position: -30% 0; } }
.sk-line { height: 12px; margin: 9px 0; }
.sk-line.w60 { width: 60%; } .sk-line.w40 { width: 40%; }
.sk-card { height: 96px; margin-bottom: 12px; }

/* 页面切换：一层水墨洇开 */
.page-wipe {
  position: fixed; inset: 0; z-index: 300; pointer-events: none;
  background: radial-gradient(120% 90% at 50% 42%,
              color-mix(in srgb, var(--paper) 96%, transparent) 0%,
              color-mix(in srgb, var(--paper) 70%, transparent) 46%,
              transparent 72%);
  opacity: 0;
  animation: page-wipe .52s ease-out;
}
@keyframes page-wipe {
  0%   { opacity: .0; transform: scale(.86); }
  22%  { opacity: .92; }
  100% { opacity: 0; transform: scale(1.14); }
}

/* 全站降级：动效一律关掉，但静态层次保留 */
@media (prefers-reduced-motion: reduce) {
  .aurora::before { animation: none !important; }
  .page-wipe, .sk { animation: none !important; }
  .page-wipe { display: none; }
  .feat:hover, .ck-card:hover, .intel-card:hover, .action:hover,
  .learn-stage:hover, .ck-stat:hover, .card:hover, .mod:hover, .tab:active .tab-ico {
    transform: none;
  }
}

/* ---------- 视差场景层补差 ----------
   .scene-svg 没有显式尺寸时，SVG 会按固有比例撑开（宽度 800 → 实际只占 800px），
   hero 宽 1200 时就只铺了一半。必须显式 100%。 */
.scene-svg { display: block; width: 100%; height: auto; }
.hero4 .h4-inner { position: relative; z-index: 3; }
.hero4 .scene-canvas { z-index: 2; }
/* 品牌标识现在是一枚 SVG 印章，不再是"朱砂方块 + 工" */
.brand-mark {
  background: none; border-radius: 8px; overflow: hidden;
  box-shadow: 0 4px 12px -4px rgba(0, 0, 0, .45);
}
.brand-mark svg { display: block; }

/* ---------- 三个"有结构没样式"的小地方（覆盖检查扫出来的） ---------- */
.ckm-text { font-size: 13px; line-height: 1.55; }
.itab-name { white-space: nowrap; }
.ex-src {
  display: block; margin-top: 8px;
  font-size: 11px; color: var(--ink-faint); line-height: 1.6;
}
.ck-modal { max-width: 560px; }

/* ---------- 情报站栏目条（标题 + 批次说明 + 更新按钮） ---------- */
.intel-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 4px 0 14px; padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.ib-title {
  font-family: var(--font-display); font-size: 14px; font-weight: 660;
  color: var(--ink); letter-spacing: .01em;
}
.ib-meta {
  flex: 1; min-width: 140px;
  font-size: 11px; color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.intel-bar .btn { flex-shrink: 0; }
@media (max-width: 640px) {
  .ib-title { font-size: 13px; }
  .ib-meta { flex-basis: 100%; order: 3; }
  .intel-bar .btn { margin-left: auto; }
}

/* ============================================================
   学习页（learn.js）
   ============================================================ */
.lg-list { display: flex; flex-direction: column; gap: 12px; }

/* ---- 每日一练 ---- */
.lg-prob { padding: 18px 20px; }
.lg-p-head { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; margin-bottom: 8px; }
.lg-p-title { font-family: var(--font-display); font-size: 15.5px; font-weight: 660; letter-spacing: .01em; margin: 0; }
.lg-lv {
  flex-shrink: 0; padding: 2px 9px; border-radius: var(--r-full);
  font-size: 10.5px; font-weight: 660;
  color: var(--ink-soft); background: var(--sunken);
}
.lg-lv.lv1, .lg-lv.d1 { color: var(--jade-3); background: color-mix(in srgb, var(--jade-1) 22%, transparent); }
.lg-lv.lv2, .lg-lv.d2 { color: var(--amber); background: color-mix(in srgb, var(--warm) 20%, transparent); }
.lg-lv.lv3, .lg-lv.d3 { color: var(--accent-deep); background: var(--accent-soft); }
:root[data-theme="dark"] .lg-lv.lv1,
:root[data-theme="dark"] .lg-lv.d1 { color: var(--jade); }
:root[data-theme="dark"] .lg-lv.lv3,
:root[data-theme="dark"] .lg-lv.d3 { color: var(--accent); }

.lg-p-links { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.lg-p-meta { font-size: 11px; color: var(--ink-faint); }
.lg-p-tags { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.lg-chip.sm { padding: 3px 9px; font-size: 11px; font-weight: 600; cursor: default; background: var(--sunken); border-color: transparent; }
.lg-chip.sm:hover { transform: none; }
.lg-ans {
  width: 100%; border-radius: var(--r-m); resize: vertical;
  font-family: var(--font); font-size: 13px; line-height: 1.75;
  padding: 12px 14px;
}
.lg-actions {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--line);
}
.lg-actions .btn { flex-shrink: 0; }
.lg-saved { font-size: 11px; color: var(--ink-faint); margin-left: auto; }

/* ---- 面试题库 ---- */
.lg-filters { display: flex; gap: 7px; flex-wrap: wrap; align-items: center; margin-bottom: 12px; }
.lg-chip {
  padding: 6px 13px; border-radius: var(--r-full);
  font-size: 12px; font-weight: 600; color: var(--ink-soft);
  background: var(--glass); border: 1px solid var(--line);
  transition: transform .16s cubic-bezier(.2,.9,.3,1), background .16s, color .16s, border-color .16s;
}
.lg-chip:hover { transform: translateY(-1px); border-color: color-mix(in srgb, var(--ink) 24%, transparent); }
.lg-chip.on {
  color: #fff; border-color: transparent;
  background: linear-gradient(145deg, var(--accent), var(--accent-deep));
  box-shadow: 0 8px 20px -12px color-mix(in srgb, var(--accent) 85%, transparent);
}
.lg-progress { margin-left: auto; font-size: 11.5px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.lg-progress b { color: var(--ink); font-weight: 700; }

.lg-q { padding: 13px 16px; }
.lg-q.open { border-color: color-mix(in srgb, var(--accent) 26%, transparent); }
.lg-q-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.lg-q-mod { font-size: 10.5px; color: var(--ink-faint); }
.lg-rated {
  font-size: 10px; font-weight: 660; padding: 1px 7px; border-radius: var(--r-full);
  background: var(--sunken); color: var(--ink-soft);
}
.lg-rated.know { color: var(--jade-3); background: color-mix(in srgb, var(--jade-1) 24%, transparent); }
:root[data-theme="dark"] .lg-rated.know { color: var(--jade); }
.lg-rated.dont, .lg-rated.weak { color: var(--accent-deep); background: var(--accent-soft); }
:root[data-theme="dark"] .lg-rated.dont,
:root[data-theme="dark"] .lg-rated.weak { color: var(--accent); }
.lg-q-text { font-size: 14px; font-weight: 620; letter-spacing: -.005em; margin: 0; flex: 1 1 100%; line-height: 1.55; }
.lg-q-a {
  margin-top: 11px; padding: 12px 14px; border-radius: var(--r-m);
  background: var(--sunken); border-left: 3px solid var(--accent);
  font-size: 13px; line-height: 1.85; color: var(--ink-soft);
}
.lg-q.open .lg-q-a { animation: fade-up .3s cubic-bezier(.2,.8,.3,1); }

@media (max-width: 640px) {
  .lg-prob { padding: 15px 15px; }
  .lg-p-title { font-size: 14px; }
  .lg-progress { flex-basis: 100%; margin-left: 0; }
  .lg-actions .btn { flex: 1 1 auto; justify-content: center; }
  .lg-saved { margin-left: 0; flex-basis: 100%; }
}

/* ============================================================
   v5 —— 按用户反馈调整
   ① 内页背景：画作要真的看得见（之前被压成一片白）
   ② 所有卡片统一成首页那片大玻璃的质感
   ③ 手机底部导航：线性图标 + 玻璃 + 明确的选中态
   ④ 首页句子的出处链接
   ============================================================ */

/* ---------- ⑤ 图标预览（设置 → 外观）----------
   加这一块的直接原因：用户说"图标根本没变"。文件确实换了（时间戳能查），
   但他看到的是设备自己缓存的旧图标。把当前图标直接画在设置页里，
   一眼就能分清"服务器上是什么"和"我设备上缓存了什么"。 */
.icon-preview { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.ip-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.ip-label { font-size: 12px; color: var(--ink-soft); font-weight: 620; }
.ip-row img {
  display: block; border-radius: 10px;
  box-shadow: 0 6px 18px -8px rgba(10, 16, 24, .5), 0 0 0 1px var(--line);
}
.ip-svg { border-radius: 16px; }
.ip-note { margin: 12px 0 6px; font-size: 12px; line-height: 1.8; color: var(--ink-soft); }
.ip-list { margin: 0; padding-left: 18px; }
.ip-list li { font-size: 12px; line-height: 1.85; color: var(--ink-soft); margin-bottom: 4px; }
.ip-list b { color: var(--ink); }
.ip-list kbd {
  font-family: inherit; font-size: 11px; padding: 1px 6px; border-radius: 5px;
  background: var(--sunken); border: 1px solid var(--line);
}

/* 设置 → 外观 里的「版本 + 检查更新」那一行。
   加它是为了以后用户说"没变化"时能一句话定位：让他报这行显示的数字。 */
.build-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 16px; padding-top: 14px;
  border-top: 1px solid var(--line);
}
.build-tag { font-size: 12px; color: var(--ink-soft); }
.build-tag b { color: var(--ink); font-variant-numeric: tabular-nums; }

/* ---------- 整站飘雪（背景层） ----------
   画在 .aurora 里 —— 那一层是 fixed + overflow:hidden + pointer-events:none，
   所以雪花自然被裁在视口内、不挡点击，位置在**画作之上、内容之下**。
   只在暗色主题显示：亮色是青竹那张画，下雪不合逻辑。 */
.snow-layer {
  position: absolute; inset: 0;
  display: block; pointer-events: none;
  opacity: 1;
  transition: opacity .8s ease;
}
:root[data-theme="light"] .snow-layer { opacity: 0; }

/* ---------- ② 玻璃的四个参数：亮色是"白玻璃"，暗色是"墨玻璃" ---------- */
:root {
  --glass-a: rgba(255, 255, 255, .60);
  --glass-b: rgba(255, 255, 255, .30);
  --glass-edge: rgba(255, 255, 255, .55);
  --glass-shine: rgba(255, 255, 255, .60);
}
:root[data-theme="dark"] {
  --glass-a: rgba(22, 30, 40, .62);
  --glass-b: rgba(16, 23, 31, .44);
  --glass-edge: rgba(233, 239, 245, .14);
  --glass-shine: rgba(255, 255, 255, .08);
}

.card, .stat, .mod, .feat, .ck-hero, .ck-stat, .ck-chart-wrap, .ck-card,
.intel-card, .next-up, .action, .learn-stage, .hg-card, .bar-card, .sec-card,
.mr-card, .lt-card, .lg-prob, .lg-q, .ex-card, .gate-card {
  background: linear-gradient(150deg, var(--glass-a), var(--glass-b));
  border: 1px solid var(--glass-edge);
  backdrop-filter: blur(24px) saturate(185%);
  -webkit-backdrop-filter: blur(24px) saturate(185%);
  box-shadow: var(--shadow-m), inset 0 1px 0 var(--glass-shine);
}
.card:hover, .feat:hover, .ck-card:hover, .intel-card:hover, .action:hover,
.learn-stage:hover, .ck-stat:hover, .lg-prob:hover, .lg-q:hover {
  background: linear-gradient(150deg, color-mix(in srgb, var(--glass-a) 86%, #fff), var(--glass-a));
  border-color: color-mix(in srgb, var(--glass-edge) 70%, var(--accent));
  box-shadow: var(--shadow-l), inset 0 1px 0 var(--glass-shine);
}
:root[data-theme="dark"] .card:hover,
:root[data-theme="dark"] .feat:hover,
:root[data-theme="dark"] .ck-card:hover,
:root[data-theme="dark"] .intel-card:hover {
  background: linear-gradient(150deg, var(--glass-a), var(--glass-b));
  border-color: color-mix(in srgb, var(--snow) 26%, transparent);
}
/* 首页那几个小方块：跟大玻璃同一套配方，图标给一块小玻璃底 */
.feat {
  padding: 26px 12px 22px;
  background: linear-gradient(150deg, var(--glass-a), var(--glass-b));
}
.feat-ico {
  width: 54px; height: 54px; border-radius: 18px;
  background: linear-gradient(150deg, var(--glass-edge), transparent);
  box-shadow: inset 0 1px 0 var(--glass-shine), 0 6px 16px -10px rgba(12, 20, 28, .5);
}
.feat:hover .feat-ico {
  background: linear-gradient(150deg, var(--fc, var(--accent)), var(--fc2, var(--accent-deep)));
  box-shadow: 0 12px 24px -12px color-mix(in srgb, var(--fc2, var(--accent-deep)) 80%, transparent);
}
.feat-stat { color: var(--ink-soft); }

/* ---------- ③ 手机底部导航 ---------- */
.tabbar {
  padding: 8px 8px calc(8px + env(safe-area-inset-bottom, 0px));
  border-radius: 24px;
  background: var(--glass-a);
  border: 1px solid var(--glass-edge);
  backdrop-filter: blur(28px) saturate(200%);
  -webkit-backdrop-filter: blur(28px) saturate(200%);
  box-shadow: 0 -8px 34px -16px rgba(10, 16, 24, .45), var(--shadow-l);
}
.tab {
  padding: 7px 2px 6px; border-radius: 16px; gap: 3px;
  color: var(--ink-faint); font-size: 10px;
}
.tab-ico {
  width: 24px; height: 24px; display: grid; place-items: center;
  font-size: 19px; line-height: 1;
}
.tab-ico svg { width: 22px; height: 22px; stroke-width: 1.6; display: block; }
.tab-txt { font-size: 10px; }
.tab.on { background: color-mix(in srgb, var(--accent) 13%, transparent); }
.tab.on .tab-ico svg { stroke-width: 2.1; }
.tab.on .tab-txt { color: var(--accent); font-weight: 700; }
:root[data-theme="dark"] .tab.on { background: color-mix(in srgb, var(--accent) 20%, transparent); }
/* 选中态的圆点保留，但跟着玻璃层走 */
.tab::after { bottom: 1px; }
@media (max-width: 380px) {
  .tab-ico svg { width: 20px; height: 20px; }
  .tab-txt { font-size: 9.5px; }
}

/* ---------- ① 背景画作：别再压成一片白 ---------- */
.aurora::before {
  opacity: 1;
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--paper) 58%, transparent) 0%,
      color-mix(in srgb, var(--paper) 22%, transparent) 15%,
      color-mix(in srgb, var(--paper) 14%, transparent) 52%,
      color-mix(in srgb, var(--paper) 52%, transparent) 88%,
      color-mix(in srgb, var(--paper) 72%, transparent) 100%),
    linear-gradient(96deg,
      color-mix(in srgb, var(--paper) 42%, transparent) 0%,
      color-mix(in srgb, var(--paper) 14%, transparent) 34%,
      transparent 66%),
    var(--art-page);
  background-size: cover, cover, cover;
  background-position: center, center, center top;
}
:root[data-theme="dark"] .aurora::before {
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--paper) 56%, transparent) 0%,
      color-mix(in srgb, var(--paper) 20%, transparent) 15%,
      color-mix(in srgb, var(--paper) 10%, transparent) 52%,
      color-mix(in srgb, var(--paper) 46%, transparent) 88%,
      color-mix(in srgb, var(--paper) 68%, transparent) 100%),
    linear-gradient(96deg,
      color-mix(in srgb, var(--paper) 40%, transparent) 0%,
      color-mix(in srgb, var(--paper) 12%, transparent) 34%,
      transparent 66%),
    var(--art-page);
}
/* 直接压在画作上的文字（章节标题、脚注）补一层纸色描边，保证读得清 */
.section-title, .intel-note, .home-foot, .hg-note, .ck-plan, .learn-tip,
.lg-saved, .st-note, .bk-last, .page-title, .footer-note {
  text-shadow: 0 1px 2px color-mix(in srgb, var(--paper) 92%, transparent),
               0 4px 14px color-mix(in srgb, var(--paper) 70%, transparent);
}
:root[data-theme="dark"] .section-title,
:root[data-theme="dark"] .intel-note,
:root[data-theme="dark"] .page-title {
  text-shadow: 0 1px 3px rgba(4, 8, 12, .8), 0 4px 16px rgba(4, 8, 12, .6);
}

/* ---------- ④ 首页句子的出处 ---------- */
.h4-quote-src {
  display: inline-block; margin-top: 6px;
  font-size: 11.5px; color: var(--ink-soft); text-decoration: none;
  border-bottom: 1px dashed color-mix(in srgb, var(--ink) 30%, transparent);
}
.h4-quote-src:hover { color: var(--accent); border-bottom-color: var(--accent); }
.h4-quote .q { font-size: 17px; }
@media (max-width: 719px) {
  .h4-quote .q { font-size: 15.5px; }
  .card, .intel-card, .feat, .ck-card { backdrop-filter: blur(16px) saturate(170%); -webkit-backdrop-filter: blur(16px) saturate(170%); }
}

/* ============================================================
   v6 —— 用户第三轮反馈
   ① 切页面不再白一下（.page-wipe 删除，这里顺手把它的样式也清掉）
   ② 红色按键 → 竹青（跟亮色的青竹背景适配；暗色不动）
   ③ 苹果那种玻璃：更强的模糊 + 顶边高光 + 内阴影
   ④ 首页那排按键换成宣纸签条（古风），不再是一个个白方块
   ⑤ 打卡卡片的三种状态文案（待打卡 / 打卡已结束）
   ⑥ 学习页新增「范围」那几行
   ============================================================ */

/* ---------- ① 删掉过场的样式（JS 那边已经不再创建它了） ---------- */
.page-wipe { display: none !important; }

/* ---------- ② 绿色强调色：亮色 + 暗色都换 ----------
   原来是朱砂红 #b23a2e（暗色是 #d4574a）。

   ⚠️ 这里犯过一次错：第一版只在亮色 `:root` 里覆盖，还在文档里写了"只有亮色"，
   结果用户看到暗色里那条红色的引用竖线、红色的选中态，直接问
   「暗色模式仍然没有改变，并且还有很多红色」。
   **以后再改配色，两套主题要一起看，别只顾一套。**

   ⚠️ 同时注意：用户反复强调过 **暗色的背景画作（雪夜小屋）不要动** ——
   这里只动强调色，`--art-*`、纸色蒙版、暗色的 hero 渐变一律不碰。

   暗色底是雪夜蓝，绿色要比亮色的更亮一点才浮得起来。 */
:root {
  --accent:        #3c6e4e;
  --accent-deep:   #2c5540;
  --accent-soft:   rgba(60, 110, 78, .12);
  --accent-ring:   rgba(60, 110, 78, .22);
}
:root[data-theme="dark"] {
  --accent:        #5fa87a;
  --accent-deep:   #417a56;
  --accent-soft:   rgba(95, 168, 122, .18);
  --accent-ring:   rgba(95, 168, 122, .32);
}
/* 危险/报错仍然是红的 —— 那是语义色，不该跟着主题变绿 */
:root { --danger: #c0392b; }
:root[data-theme="dark"] { --danger: #ef6b5e; }

/* ---------- ③ 苹果玻璃 ----------
   不透明度调过一轮：第一版给到 .60/.34，结果学习页那种"长文字压在大面积玻璃上"
   的场景字全糊了（截图能看到）。苹果自己的材质在**承载内容**时其实相当不透，
   只有在导航栏那种"装饰性"表面上才透。所以这里分成两档：
     --glass-a/b      内容卡片：够透能看见画，但字必须立得住
     --glass-chrome-* 导航/底栏：更透，因为它上面只有短标签 */
:root {
  --glass-a: rgba(255, 255, 255, .80);
  --glass-b: rgba(255, 255, 255, .62);
  --glass-edge: rgba(255, 255, 255, .70);
  --glass-shine: rgba(255, 255, 255, .92);
  --glass-blur: blur(30px) saturate(190%);
  --glass-chrome-a: rgba(255, 255, 255, .58);
  --glass-chrome-b: rgba(255, 255, 255, .38);
}
:root[data-theme="dark"] {
  --glass-a: rgba(26, 35, 47, .78);
  --glass-b: rgba(15, 22, 31, .62);
  --glass-edge: rgba(233, 239, 245, .17);
  --glass-shine: rgba(255, 255, 255, .10);
  --glass-blur: blur(30px) saturate(170%);
  --glass-chrome-a: rgba(22, 30, 41, .62);
  --glass-chrome-b: rgba(13, 19, 27, .46);
}
/* 一块"苹果玻璃"的配方：强模糊 + 顶部一道高光 + 底部一道极淡的暗边 + 柔和投影 */
.card, .stat, .mod, .feat, .ck-hero, .ck-stat, .ck-chart-wrap, .ck-card,
.intel-card, .next-up, .action, .learn-stage, .hg-card, .bar-card, .sec-card,
.mr-card, .lt-card, .lg-prob, .lg-q, .ex-card, .gate-card, .topnav, .tabbar {
  background: linear-gradient(160deg, var(--glass-a), var(--glass-b));
  border: 1px solid var(--glass-edge);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  box-shadow:
    inset 0 1px 0 var(--glass-shine),
    inset 0 -1px 0 color-mix(in srgb, var(--ink) 6%, transparent),
    0 12px 32px -18px color-mix(in srgb, var(--ink) 55%, transparent),
    0 2px 8px -4px color-mix(in srgb, var(--ink) 22%, transparent);
}
/* 悬停：玻璃稍微"抬起"，高光更亮一点 */
.feat:hover, .ck-card:hover, .intel-card:hover, .action:hover, .lg-q:hover, .card:hover {
  background: linear-gradient(160deg, color-mix(in srgb, var(--glass-a) 80%, #fff), var(--glass-a));
  box-shadow:
    inset 0 1px 0 #fff,
    inset 0 -1px 0 color-mix(in srgb, var(--ink) 8%, transparent),
    0 20px 44px -22px color-mix(in srgb, var(--ink) 60%, transparent);
}
:root[data-theme="dark"] .feat:hover,
:root[data-theme="dark"] .ck-card:hover,
:root[data-theme="dark"] .intel-card:hover {
  background: linear-gradient(160deg, var(--glass-a), var(--glass-b));
}
/* 手机端把模糊降一档：backdrop-filter 是 GPU 大户，30px 在手机上会明显掉帧 */
@media (max-width: 899px) {
  :root { --glass-blur: blur(18px) saturate(180%); }
  :root[data-theme="dark"] { --glass-blur: blur(18px) saturate(165%); }
}

/* 导航栏 / 底部导航：只要短标签，可以更透一点（苹果那种"飘在内容上"的感觉） */
.topnav, .tabbar {
  background: linear-gradient(180deg, var(--glass-chrome-a), var(--glass-chrome-b));
}

/* 学习页那种长文字，再多给一点底色 —— 字读不清，再好看也白搭 */
.lg-q, .lg-prob, .intel-card, .card {
  background: linear-gradient(160deg,
    color-mix(in srgb, var(--glass-a) 88%, var(--paper)),
    var(--glass-a));
}

/* ---------- ④ 首页那排按键：宣纸签条 ---------- */
.feat-row { gap: 14px; }
.feat {
  padding: 24px 12px 20px;
  border-radius: 4px 4px 16px 16px;         /* 上窄下圆，像一张挂着的签条 */
  background:
    linear-gradient(180deg,
      color-mix(in srgb, #fffdf7 78%, transparent),
      color-mix(in srgb, #f7f3e8 58%, transparent));
  border: 1px solid color-mix(in srgb, var(--ink) 16%, transparent);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .9),
    0 14px 30px -20px color-mix(in srgb, var(--ink) 60%, transparent);
  position: relative;
}
/* 顶部一道墨线（像签条上沿的那道边） */
.feat > .feat-ico::before {
  content: '';
  position: absolute; left: 16%; right: 16%; top: 9px; height: 1px;
  background: linear-gradient(90deg, transparent,
    color-mix(in srgb, var(--ink) 34%, transparent), transparent);
}
/* 图标：一枚墨圈，里面是线性图标 */
.feat-ico {
  width: 52px; height: 52px; border-radius: 50%;
  background: radial-gradient(circle at 50% 34%, rgba(255, 255, 255, .92), rgba(255, 255, 255, .40));
  border: 1.5px solid color-mix(in srgb, var(--ink) 26%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9);
  color: var(--ink);
}
.feat:hover .feat-ico {
  background: radial-gradient(circle at 50% 34%, rgba(255, 255, 255, .95), color-mix(in srgb, var(--accent) 18%, transparent));
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: inset 0 1px 0 #fff, 0 0 0 4px var(--accent-soft);
}
/* 标签用衬线、字距打开一点，才有"题字"的感觉 */
.feat-label { font-family: var(--font-display); font-size: 14.5px; letter-spacing: .06em; font-weight: 600; }
.feat-stat { font-family: var(--font-display); letter-spacing: .04em; }
:root[data-theme="dark"] .feat {
  background: linear-gradient(180deg, var(--glass-a), var(--glass-b));
  border-color: color-mix(in srgb, var(--snow) 16%, transparent);
}
:root[data-theme="dark"] .feat-ico {
  background: radial-gradient(circle at 50% 34%, rgba(255, 255, 255, .10), rgba(255, 255, 255, .03));
  border-color: color-mix(in srgb, var(--snow) 24%, transparent);
  color: var(--ink);
}
:root[data-theme="dark"] .feat:hover .feat-ico { color: var(--accent); border-color: var(--accent); }

/* ---------- ⑤ 打卡卡片的状态字 ---------- */
.ck-cd {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11.5px; font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
}
.ck-cd.warn { color: var(--amber); }
.ck-cd.due { color: var(--accent); font-weight: 660; }
.ck-cd.done {
  color: var(--ink-faint); letter-spacing: .04em;
  background: var(--sunken); border-radius: var(--r-full);
  padding: 1px 9px;
}

/* ---------- ⑥ 学习页：范围 / 细分 / 难度 三行 ---------- */
.lg-scope {
  display: flex; flex-direction: column; gap: 8px;
  margin-bottom: 14px; padding: 12px 14px;
  background: var(--glass-soft);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
}
.lg-scope-row { display: flex; gap: 7px; flex-wrap: wrap; align-items: center; }
.lg-scope-label {
  flex: 0 0 34px;
  font-family: var(--font-display); font-size: 12px; letter-spacing: .12em;
  color: var(--ink-faint);
}
.lg-scope-hint { font-size: 11.5px; color: var(--ink-faint); padding-left: 34px; }
.lg-chip i {
  font-style: normal; font-size: 10px; opacity: .65; margin-left: 3px;
  font-variant-numeric: tabular-nums;
}
@media (max-width: 640px) {
  .lg-scope { padding: 10px 11px; }
  .lg-scope-label { flex-basis: 100%; }
  .lg-scope-hint { padding-left: 0; }
}

/* ---------- ⑨ 暗色的强调色：从竹青改成"跟雪夜背景配"的钢蓝 + 霜白玻璃 ----------
   用户原话：「暗色界面的下面分类框不要是绿色啊，我跟你说了做适配，不要是绿色，符合背景色」
   以及「那个进入记忆曲线还是金色的给我改成透明」。

   想清楚一件事：**亮色的背景是青竹，所以绿是对的；暗色的背景是雪夜（冷蓝），绿就不搭了。**
   "适配"的意思是跟着各自的画走，而不是两套主题都用同一个强调色。所以暗色改成：
     · 强调色 → 冷钢蓝（跟夜空同一族，白字仍然读得清）
     · 底部导航选中态 → 霜白玻璃（不带任何色相，跟任何背景都配）—— 这是用户点名的那块
     · 主按钮（进入记忆曲线 / 打卡 / 全部打卡）→ 透明玻璃，不再是金色
   亮色一律不动。 */
:root[data-theme="dark"] {
  --accent:        #547b99;   /* 冷钢蓝 */
  --accent-deep:   #3f5f79;
  --accent-soft:   rgba(84, 123, 153, .20);
  --accent-ring:   rgba(84, 123, 153, .34);
  --ice:           #a8c6dc;   /* 霜白偏蓝：给直接压在画上的文字和竖线用 */
}

/* 底部导航选中态：霜白玻璃，不带色相（用户点名"不要绿色"的就是这一块） */
:root[data-theme="dark"] .tab.on {
  background: linear-gradient(180deg, rgba(255, 255, 255, .20), rgba(255, 255, 255, .08));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .26);
}
:root[data-theme="dark"] .tab.on .tab-txt,
:root[data-theme="dark"] .tab.on .tab-ico,
:root[data-theme="dark"] .tab.on .tab-ico svg { color: var(--ink); }
:root[data-theme="dark"] .tab.on .tab-txt { font-weight: 700; }

/* 主按钮：金色/彩色渐变 → 透明玻璃 */
:root[data-theme="dark"] .btn-play {
  background: linear-gradient(160deg, rgba(255, 255, 255, .17), rgba(255, 255, 255, .07));
  color: var(--ink);
  border: 1px solid rgba(255, 255, 255, .22);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .24), 0 12px 26px -18px rgba(0, 0, 0, .65);
}
:root[data-theme="dark"] .btn-play:hover {
  background: linear-gradient(160deg, rgba(255, 255, 255, .24), rgba(255, 255, 255, .11));
  filter: none;
}
:root[data-theme="dark"] .btn-play:disabled {
  background: rgba(255, 255, 255, .05);
  color: var(--ink-faint);
  border-color: rgba(255, 255, 255, .10);
  box-shadow: none;
}

/* 首页句子的竖线和「出处」：用霜白，不再跟着强调色变绿 */
:root[data-theme="dark"] .h4-quote { border-left-color: var(--ice); }
:root[data-theme="dark"] .h4-quote-src { color: var(--ice); border-bottom-color: color-mix(in srgb, var(--ice) 40%, transparent); }
:root[data-theme="dark"] .h4-quote-src:hover { color: #fff; border-bottom-color: #fff; }

/* 导航（桌面顶栏）选中态在暗色下同样去掉色相 */
:root[data-theme="dark"] .nav-item.on {
  background: linear-gradient(180deg, rgba(255, 255, 255, .18), rgba(255, 255, 255, .07));
  color: var(--ink);
}

/* 首页那两个胶囊按钮：「进入记忆曲线」原来是金色（--warm，夜里那点暖光），
   用户原话「还是金色的给我改成透明」→ 改成透明玻璃。
   旁边那颗「情报站」跟着用同一套玻璃，两颗才像一对（原来一颗金一颗灰）。
   注意：`.hero4 .pill.dark` 的旧规则在 ~2999 行，**必须在它后面写**才盖得住。 */
:root[data-theme="dark"] .hero4 .pill.dark {
  background: linear-gradient(160deg, rgba(255, 255, 255, .18), rgba(255, 255, 255, .07));
  color: var(--ink);
  border: 1px solid rgba(255, 255, 255, .24);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .26), 0 12px 28px -18px rgba(0, 0, 0, .7);
}
:root[data-theme="dark"] .hero4 .pill.dark:hover {
  background: linear-gradient(160deg, rgba(255, 255, 255, .27), rgba(255, 255, 255, .12));
  color: #fff;
}
:root[data-theme="dark"] .hero4 .pill.light {
  background: linear-gradient(160deg, rgba(255, 255, 255, .11), rgba(255, 255, 255, .04));
  border-color: rgba(255, 255, 255, .17);
  color: var(--ink);
}
:root[data-theme="dark"] .hero4 .pill.light:hover {
  background: linear-gradient(160deg, rgba(255, 255, 255, .18), rgba(255, 255, 255, .08));
  color: #fff;
  border-color: rgba(255, 255, 255, .28);
}

/* ============================================================
   v14 —— 审计报告 P1-2 / P1-3 / P2-1：可读性与热区
   （另一个智能体做的只读审计。逐条复测过：P1-1/P1-4/P2-2/P2-5 其实已经是好的，
     这里只修真正还在的问题。）

   ⚠️ 按分层规矩**追加到文件末尾** —— 这个 CSS 是分层覆盖的，
      写在中间会被后面的同特异性规则盖掉（前面踩过这个坑）。
   ============================================================ */

/* ---- ① 辅助文字对比度 ---- */
:root {
  /* --ink-faint 原来是 #8b988f：在 #eef2ec 底上只有约 2.7:1，远低于 WCAG AA 的 4.5。
     它是占位符 / 提示 / 小标签的主力色，是全站影响面最大的一处。
     换成 #5f6b62 之后约 4.95:1。 */
  --ink-faint: #5f6b62;
}
:root[data-theme="dark"] {
  /* 暗色同理：#76848f 约 4.0:1，提亮到 #8494a1 约 4.7:1 */
  --ink-faint: #8494a1;
  /* ★ 这条是审计实测 **1.39:1** —— #26362c 是近黑的绿，压在深色卡上等于看不见，
     「✓ 已同步」那种徽标文字用的就是它。只改这一个值，不动暗色的整体观感。 */
  --jade-3: #8fc4a0;
}

/* ---- ② 最小字号：把承载语义的小字抬到 11~12px ---- */
.hf-chip i { font-size: 11px; }                    /* 首页「复习节奏」的时间，原 9.5px */
.sync-badge { font-size: 11px; }                   /* 原 10.5px */
@media (max-width: 640px) { .sync-badge { font-size: 11px; } }
.ck-cd { font-size: 12px; }                        /* 打卡状态字，原 11.5px */
.sec-cap, .hg-note, .st-hint { font-size: 12px; }  /* 说明性小字 */

/* ---- ③ 压在画作上的小字补一层描边兜底（内页卡外区域原来没有）---- */
.sec-head, .sec-cap, .hg-note, .st-hint, .st-upd, .st-live,
.intel-note, .kv dt, .row .tag, .dev-sub, .learn-h-desc {
  text-shadow: 0 1px 2px color-mix(in srgb, var(--paper) 88%, transparent),
               0 2px 10px color-mix(in srgb, var(--paper) 62%, transparent);
}

/* ---- ④ 触屏热区：图标键 34×34 → 44×44 ---- */
.nav-icon-btn { min-width: 44px; min-height: 44px; }
@media (max-width: 719px) {
  .page-head .nav-icon-btn { width: 44px; height: 44px; font-size: 15px; }
}

/* ============================================================
   v16 —— 全面测试报告：可读性回归（用探针实测出来的，不是照抄旧结论）

   工具：_tools/_probe-a11y.js —— 扫描全页，逐元素算实测对比度与字号。
   发现的真问题集中在两类：
     ① 涨跌色（红涨绿跌）在**亮色**下太亮：.down 2.88:1、.up 3.90:1
     ② 警示橙 #ff8c1a / #d9822b 更浅：连续打卡数字 2.02:1、晚打卡 3.05:1
   外加一批 10~11px 的语义小字。
   ============================================================ */

/* ---- ① 涨跌色与警示色：按主题各给一套，保证 ≥4.5:1 ---- */
:root {
  --up-ink:   #c0273a;   /* 红涨（原来是 #e0344a，浅底上只有 3.9:1） */
  --down-ink: #0b6e4d;   /* 绿跌（原来是 #12a271，只有 2.88:1） */
  --warn-ink: #8f5a12;   /* 警示橙（原来 #ff8c1a / #d9822b，最低 2.02:1） */
}
:root[data-theme="dark"] {
  --up-ink:   #ff6b7d;
  --down-ink: #34d399;
  --warn-ink: #f0b04a;
}
/* .up/.down 原来带 !important，这里同样带才盖得住 */
.up { color: var(--up-ink) !important; }
.down { color: var(--down-ink) !important; }
.ck-late, .bk-warn, .ck-streak, .ck-stat.hot b { color: var(--warn-ink); }

/* ---- ② 语义小字抬到 11.5~12.5px（原先 10~11px）---- */
.ck-cat { font-size: 11.5px; }
.ck-chip i { font-size: 11.5px; }
.ck-stat span { font-size: 12px; }
.ck-card-meta, .ck-card-meta span, .ck-card-meta b { font-size: 12px; }
.ck-ontime, .ck-late, .ck-streak { font-size: 12px; }
.ck-stage { font-size: 12px; }
.dev-name em { font-size: 11.5px; }
.dev-sub { font-size: 12px; }
.row .tag { font-size: 12px; }
.intel-note { font-size: 12px; }
.st-live, .st-upd { font-size: 12px; color: var(--ink-soft); }
.bk-help p, .bk-help code { font-size: 12.5px; }
.ip-list li, .ip-note { font-size: 12.5px; }

/* ---- ③ 差一点点就达标的两处（4.43:1）---- */
.ck-plan-note { color: var(--ink-soft); }
.btn-play:disabled, .btn:disabled { color: var(--ink-soft); }

/* ============================================================
   v17 —— 收尾剩下的 4 处对比度（v16 之后探针复扫出来的）
   ⚠️ `.ck-plan-note` 原来带 `!important`，所以覆盖它也必须带 ——
      这也是上一版没修掉它的原因。
   ============================================================ */
.ck-plan-note { color: var(--ink-soft) !important; }
.row .tag { color: var(--ink-soft); }
/* 「中等」难度标签与学习页进度数字：原来都用 --amber（浅底上 3.05:1） */
.learn-h-progress b,
.lg-lv.lv2, .lg-lv.d2 { color: var(--warn-ink); }

/* ============================================================
   v18 —— 收尾：小字号 + 「减少动效」覆盖不全（全面测试报告 P2-5）
   ============================================================ */

/* ---- ① 最后几处 10.5~11.5px 的语义小字 ---- */
.hf-title { font-size: 12px; }
.hf-chip i, .hf-chip b { font-size: 12px; }
.ck-chip i { font-size: 12px; }
.ck-plan-note { font-size: 12.5px !important; }
.itab-n { font-size: 11.5px; }
.sync-badge { font-size: 11.5px; }

/* ---- ② prefers-reduced-motion：真正全覆盖 ----
   审计实测：开了"减少动效"之后仍有 15 个元素在动
   （首页标题描边 ws-draw ×9、卡片入场 fx-in ×5、next-up 的 fade-up）。
   原来只在几处零散写了 animation:none，漏了描边与入场动画。
   这里用"一刀切 + 显式复位"兜住，并放在**文件末尾**确保盖得住前面的分层规则。 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  /* 描边类动画（stroke-dashoffset）与入场动画的**终态**要显式写出来，
     否则 0.001ms 走完之后仍可能停在起始态（比如字还是空心的）。 */
  .ws-draw, .h4-fill, .fx-in, .fx-stagger, .next-up, .view-enter > *,
  .h4-date, .h4-sub, .h4-meta, .h4-btns, .sk {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }
  .h4-fill { stroke-dashoffset: 0 !important; fill-opacity: 1 !important; }
  .ws-draw { stroke-dashoffset: 0 !important; }
}

/* ============================================================
   v19 —— 性能工单：毛玻璃降本（PERF-FE-004）

   `backdrop-filter` 的代价是**每个元素新建一个合成层，并逐帧采样背后的像素做模糊**。
   而这些卡片背后正好是 `.aurora::before` —— 一张**正在做 52 秒常驻动画的全屏画作层**。
   背景每帧都在动 → 模糊必须每帧重算。一屏 6~10 张卡片 = 6~10 次高斯模糊 + 每张 4 段阴影。
   ============================================================ */

/* ① 移动端把模糊从 18px 降到 10px（采样半径小一半以上，肉眼仍是磨砂） */
@media (max-width: 768px) {
  :root { --glass-blur: blur(10px) saturate(170%); }
  :root[data-theme="dark"] { --glass-blur: blur(10px) saturate(160%); }
}

/* ② **列表卡片**不做模糊，改用接近不透明的底色。
   列表滚动时卡片与背景是相对运动，模糊没有任何缓存空间，是纯亏。
   只降级这两类列表卡片 —— `.topnav` / `.tabbar` 是设计语言的核心（用户明确喜欢那层玻璃），
   **不动**。 */
.ck-card, .intel-card {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  background: var(--glass-solid, rgba(255, 255, 255, .88));
}
:root[data-theme="dark"] .ck-card,
:root[data-theme="dark"] .intel-card {
  background: var(--glass-solid-dark, rgba(26, 35, 47, .90));
}

/* ============================================================
   v20 —— 干掉卡片底部那"一大坨绿色"

   根因不在图片，在**两层遗留的 SVG**：
   `public/app.js` 的 `sceneLayers()` 往卡片里插了 `.scene-layer` ×2，
   内容是 `SCENE_FAR` / `SCENE_NEAR` —— 用 `var(--jade-3)`（青绿）画的**水墨坡地**，
   `position: absolute; bottom: 0`，正好贴在卡片底部。

   它们是**早期"整个首页用 CSS 画水墨"那个方案**的产物：
   那时候需要自己画山、画坡、画水面；现在卡片背景已经换成真画作（月夜森林），
   这两层就变成了纯多余的青绿色块 —— 用户截图里那条"一大坨绿"就是它。

   为什么一开始没发现：它跟图片的色调混在一起，直到把卡片取景挪到"树干+月光"，
   周围变干净了，这块绿才凸显出来。

   ⚠️ 只隐藏**暗色**下的这两层（用户要求"其他不变"；亮色里它跟青竹同色，不影响观感）。
   ============================================================ */
:root[data-theme="dark"] .hero4 .scene-layer { display: none; }

/* ============================================================
   v21 · 暗色主题「雪夜暖窗」：P7 暖窗呼吸 × P9 玻璃夜景
   ------------------------------------------------------------
   用户指令（2026-09-21）："现在开始做主题，做与主题的适配，其他不动"。
   所以本段**只作用于 :root[data-theme="dark"]**，亮色（day-*）一个字节都不碰。

   四件事：
   1) 暗色画作换成 AI 修复版（写实渲染的高清雪夜：雪林幕墙 / 暖窗小屋 / 柴门 / 雪中归人）；
   2) 首页卡片加"暖窗光影"—— 暖核 + 向上散射光束（雪夜雾气）+ 呼吸光晕 + 雪地反光。
      它由一张**与画作同尺寸、同定位**的透明 WebP 承载（night-glow*.webp），
      靠 background-size/position 与画作一起缩放，所以**像素级对齐、光精准落在窗户上**，
      不需要 JS、也不需要知道屏幕坐标。
   3) P9 · 玻璃令牌调成冷蓝夜色（亮度基本不动，只挪色相，避免"越改越黑"）；
   4) 内页 / 股票页背景换同源"淡化派生版"（模糊 + 压暗），只统一氛围、不抢内容。

   ★ 暖窗坐标由脚本扫描暖色像素质心测得（_theme/build-theme-art.mjs 会打印）：
       桌面 1536×665 → nx .5465 / ny .7105；手机 900×1263 → nx .5209 / ny .8563。
     换图必须重跑该脚本重出 glow，否则光会飘到别处。
   ★ 回退：整段删掉即可恢复原状（旧图 night-hero.jpg 等仍在 public/theme-art/）。
   ============================================================ */

/* ---- 1) 画作与光影层资源 ---- */
:root[data-theme="dark"] {
  /* PERF-NET-004：夜色 HD 四张换 WebP（PSNR>=41.4dB 视觉无损，425KB->258KB）。
     画作内容与暖窗坐标不变；亮色 HD 与 --art-intel 本来就是 WebP。 */
  --art-page:   url('/theme-art/night-page-hd.webp?v=23');
  --art-hero:   url('/theme-art/night-hero-hd.webp?v=23');
  --art-hero-m: url('/theme-art/night-hero-m-hd.webp?v=23');
  --art-stock:  url('/theme-art/night-stock-hd.webp?v=23');
  --art-glow:   url('/theme-art/night-glow.webp?v=21');
  --art-glow-m: url('/theme-art/night-glow-m.webp?v=21');

  /* P9 · 冷蓝玻璃：比原来更蓝一点，亮度保持不变 */
  --glass:        rgba(16,24,36,.64);
  --glass-strong: rgba(13,21,33,.84);
  --bg-glass:     rgba(12,19,29,.84);
  --glass-soft:   rgba(226,238,246,.055);

  /* 窗光（与画作实测取色一致） */
  --window:   #fa8037;
  --window-2: #ffb066;
}

/* ---- 2) 首页卡片：暖窗光影（呼吸）。position 必须与画作一致才对齐 ---- */
:root[data-theme="dark"] .hero4::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background-image: var(--art-glow);
  background-size: cover; background-position: center 52%; background-repeat: no-repeat;
  mix-blend-mode: screen; opacity: .92; pointer-events: none;
  animation: warm-breathe 4.2s ease-in-out infinite;
}
@keyframes warm-breathe {
  0%, 100% { opacity: .72; }
  50%      { opacity: 1; }
}
@media (max-width: 719px) {
  /* 手机暗色卡片：取景从 38% 调到 66% —— 配合竖图下方补的那段雪原，
     把暖窗"顶"到卡片约 70% 处（原来它贴在卡片最下缘）。
     ⚠️ 光影层必须用**同一个 position**，否则光会从窗户上飘走。 */
  :root[data-theme="dark"] .hero4 { background-position: center, center, center 80%; }
  :root[data-theme="dark"] .hero4::after {
    background-image: var(--art-glow-m);
    background-position: center 80%;
  }
}

/* prefer-reduced-motion：文件末尾那条全局兜底已经把动画时长压到 .001ms，
   这里再显式写一次终态，确保关掉动效后光晕**仍然可见**（不是消失）。 */
@media (prefers-reduced-motion: reduce) {
  :root[data-theme="dark"] .hero4::after { animation: none !important; opacity: .92; }
}

/* ============================================================
   v22 · 情报站卡头：换成「孤舟蓑笠翁，独钓寒江雪」
   ------------------------------------------------------------
   用户给了一张参考图（附 MJ 提示词），要求把**情报站页顶部那张卡头**的背景
   换成它，并且要清晰。原卡头用的是 --art-page —— 而 v21 里我把 --art-page
   换成了"淡化派生版"（blur + 压暗），所以卡片看起来是糊的。

   这里给它一个**专用变量 --art-intel**，与内页背景彻底解耦：
   以后动内页不会再连累卡头，动卡头也不会影响内页。

   图是参考图裁出画作区（自动定位 y=722..1430）后经 AI 修复提清晰度的版本，
   底部条已裁掉（出图水印在那里）。只作用于暗色；亮色仍是青竹那张。
   ============================================================ */
:root[data-theme="dark"] {
  --art-intel: url('/theme-art/night-intel-hd.webp?v=22');
}
:root[data-theme="dark"] .intel-hero {
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--paper) 30%, transparent) 0%,
      transparent 40%,
      color-mix(in srgb, var(--paper) 62%, transparent) 100%),
    var(--art-intel);
  background-size: cover, cover;
  background-position: center, center 32%;
}

/* ============================================================
   v23 · 首页「叠卡」组件（Overlap Row）
   ------------------------------------------------------------
   用户要求（2026-09-21）：取消首页那排分类图标卡，换成这个 ——
   元素互相压住 1/3，末尾一个圆显示剩余数量，点一下**依次散开**并显示名称，
   再点收回。（参考图：Overlap Row 头像组）

   · 折叠步长 = 直径 × 2/3 → 正好"压住三分之一"（--fold）
   · 展开步长 = 直径 + 8（--open）
   · 每个元素按 --i 递增 transition-delay → 依次散开 / 依次收回
   · 折叠时第 5 个起叠到第 4 个位置并透明，改由末尾那个 +N 圆表达"还剩几个"
   · 位移全部走 transform（不触发布局），z-index 递增 → 右边的压住左边的
   ============================================================ */
.ovl { margin: 26px 2px 6px; }
.ovl-row {
  --d: 52px;      /* 圆直径 */
  --fold: 35px;   /* 折叠步长 = 直径 × 2/3 ≈ 34.7 */
  --open: 60px;   /* 展开步长 = 直径 + 8 */
  position: relative; display: block; height: var(--d);
  margin-bottom: 24px;   /* 给展开后的名称留位 */
  cursor: pointer; outline: none;
  -webkit-tap-highlight-color: transparent;
  /* 卡片接管时行会变高（把下面的内容自然推开） */
  transition: height .42s cubic-bezier(.22,.86,.28,1), margin-bottom .42s cubic-bezier(.22,.86,.28,1);
}
.ovl-i {
  position: absolute; left: 0; top: 0; width: var(--d);
  display: flex; flex-direction: column; align-items: center;
  transform: translateX(calc(var(--i) * var(--fold)));
  transition: transform .58s cubic-bezier(.22,.86,.28,1), opacity .34s ease;
  transition-delay: calc(var(--i) * 46ms);
}
.ovl-c {
  width: var(--d); height: var(--d); border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: var(--glass, rgba(255,255,255,.72));
  border: 1px solid var(--line-strong, rgba(0,0,0,.12));
  box-shadow: var(--shadow-s, 0 1px 2px rgba(0,0,0,.12)), 0 8px 20px -12px rgba(0,0,0,.35);
}
.ovl-ico { display: block; width: 19px; height: 19px; color: var(--accent); }
.ovl-ico svg { width: 100%; height: 100%; display: block; }
.ovl-v {
  font-size: 12px; font-weight: 620; letter-spacing: -.02em; color: var(--ink);
  font-variant-numeric: tabular-nums; line-height: 1; margin-top: 2px;
}
.ovl-n {
  margin-top: 7px; font-size: 11px; white-space: nowrap; color: var(--ink-soft);
  opacity: 0; transform: translateY(-4px);
  transition: opacity .32s ease, transform .32s cubic-bezier(.2,.8,.3,1);
  transition-delay: calc(var(--i) * 46ms + 110ms);
}
.ovl:not(.open) .ovl-i:nth-child(n+5) {
  transform: translateX(calc(3 * var(--fold)));
  opacity: 0;
}
.ovl-more {
  /* 与第 4 个球按**同样的步长**叠上去（也压住 1/3）——
     原来写成 3×步长+5px，正好和第 4 个球重合，看起来像"少了一个" */
  position: absolute; left: calc(4 * var(--fold)); top: 0; z-index: 9;
  width: var(--d); height: var(--d); border-radius: 50%;
  display: grid; place-items: center;
  font-size: 12.5px; font-weight: 640; letter-spacing: -.02em;
  color: var(--accent);
  background: var(--accent-soft, rgba(0,0,0,.06));
  border: 1px dashed color-mix(in srgb, var(--accent) 44%, transparent);
  transition: opacity .26s ease, transform .26s ease;
  pointer-events: none;
}
.ovl.open .ovl-i { transform: translateX(calc(var(--i2, var(--i)) * var(--open))); opacity: 1; }
.ovl.open .ovl-n { opacity: 1; transform: none; }
.ovl.open .ovl-more { opacity: 0; transform: scale(.86); }
.ovl-i:nth-child(1) { z-index: 1; }
.ovl-i:nth-child(2) { z-index: 2; }
.ovl-i:nth-child(3) { z-index: 3; }
.ovl-i:nth-child(4) { z-index: 4; }
.ovl-i:nth-child(5) { z-index: 5; }
.ovl-i:nth-child(6) { z-index: 6; }
/* 键盘可达：整组是一个 role=button */
.ovl-row:focus-visible .ovl-c { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft, rgba(0,0,0,.08)); }
/* 暗色：圆用冷蓝玻璃，不要纯黑 */
:root[data-theme="dark"] .ovl-c {
  background: var(--glass);
  border-color: var(--line-strong);
  box-shadow: 0 1px 2px rgba(0,0,0,.5), 0 10px 24px -14px rgba(0,0,0,.8);
}
:root[data-theme="dark"] .ovl-more {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  border-color: color-mix(in srgb, var(--accent) 54%, transparent);
}
/* 窄屏：收一档，保证 6 个能铺开 */
@media (max-width: 380px) {
  .ovl-row { --d: 46px; --fold: 31px; --open: 53px; }
  .ovl-ico { width: 17px; height: 17px; }
  .ovl-v { font-size: 11px; }
  .ovl-n { font-size: 10px; }
}
/* 桌面：放大、更舒展 */
@media (min-width: 720px) {
  .ovl-row { --d: 58px; --fold: 39px; --open: 74px; }
  .ovl-ico { width: 21px; height: 21px; }
  .ovl-v { font-size: 13px; }
  .ovl-n { font-size: 11.5px; }
}

/* ---------- 小球「脱离」成大卡片 ----------
   用户要的效果：点球 → 球从那一排里"抽出来"，长成一张卡片；
   它后面的球自己前移补位；再点卡片收回成球。
   卡片放在球的**下方**（同宽），缩放原点对准被点那颗球的 x ——
   于是视觉上就是"从这颗球里抽出来铺开"，而不是凭空冒出来。 */
.ovl-i.is-active {
  opacity: 0;
  transform: translateX(calc(var(--i2, var(--i)) * var(--open))) scale(.55);
  pointer-events: none;
}
.ovl-card {
  position: absolute; left: 0; right: 0; top: calc(var(--d) + 22px); z-index: 20;
  min-height: 104px;
  display: flex; align-items: center; gap: 15px;
  padding: 16px 18px;
  border-radius: 22px;
  background: var(--glass, rgba(255,255,255,.8));
  border: 1px solid var(--line-strong, rgba(0,0,0,.12));
  box-shadow: var(--shadow-m, 0 10px 28px -14px rgba(0,0,0,.35));
  opacity: 0; pointer-events: none;
  transform: scale(.4);
  transform-origin: var(--ax, 26px) calc(-1 * (var(--d) + 22px));
  transition: opacity .24s ease, transform .5s cubic-bezier(.22,.86,.28,1);
}
.ovl.has-card .ovl-card { opacity: 1; pointer-events: auto; transform: none; }
.ovl.has-card .ovl-row { height: calc(var(--d) + 22px + 104px); margin-bottom: 14px; }
.ovl-cd-ico {
  flex: 0 0 auto; width: 48px; height: 48px; border-radius: 16px;
  display: grid; place-items: center;
  background: var(--accent-soft, rgba(0,0,0,.06)); color: var(--accent);
}
.ovl-cd-ico svg { width: 24px; height: 24px; display: block; }
.ovl-cd-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ovl-cd-k { font-size: 10.5px; letter-spacing: .16em; color: var(--ink-faint); }
.ovl-cd-big {
  font-family: var(--font-display, Georgia, serif);
  font-size: 33px; line-height: 1.12; color: var(--ink); letter-spacing: .01em;
}
.ovl-cd-sub { font-size: 12px; color: var(--ink-soft); }
.ovl-cd-tail {
  margin-left: auto; align-self: flex-end;
  font-size: 11px; color: var(--ink-faint); white-space: nowrap;
}
:root[data-theme="dark"] .ovl-card {
  background: var(--glass-strong, rgba(20,27,36,.9));
  border-color: var(--line-strong);
}
@media (min-width: 720px) {
  .ovl.has-card .ovl-row { height: calc(var(--d) + 22px + 118px); }
  .ovl-card { min-height: 118px; padding: 18px 22px; }
  .ovl-cd-big { font-size: 38px; }
}

/* ============================================================
   v25 · 叠卡：左右滑动 + 固定「收起」 + 球的手感 + 首页鼓励语
   ------------------------------------------------------------
   用户四点调整：
   1) 点球出卡片时**不再把球收走** —— 球留在原位、只高亮选中；收起交给最右边的「收起」键；
   2) 球多了球行能左右滑，「收起」键固定在右边、不跟着滚；
   3) 小球加交互（hover 浮起、按下回弹、选中描边），不然太单调；
   4) 首页底部"复习节奏"删掉，换成一句**首页专属**的鼓励语。

   注：v23 段用的是旧结构（.ovl-row），这里换成新结构（.ovl-head / .ovl-strip / .ovl-track）；
   --d / --fold / --open 现在挂在 .ovl-track 上（v23 里挂在 .ovl-row 上，已失效）。
   ============================================================ */

/* ---- 行：可滑动的球区 + 固定在右的「收起」 ---- */
.ovl-head { position: relative; display: flex; align-items: flex-start; gap: 8px; }
.ovl-strip {
  flex: 1 1 auto; min-width: 0;
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none; -ms-overflow-style: none;
  padding: 8px 0 26px;       /* 上：留给 hover 浮起；下：留给名称 */
  -webkit-overflow-scrolling: touch;
  scroll-behavior: smooth;
  outline: none;
  /* 右侧渐隐：提示"还能往左滑"（球多的时候第 6 颗会被收起键挡在外面） */
  mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 24px), transparent 100%);
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 24px), transparent 100%);
}
.ovl-strip::-webkit-scrollbar { display: none; }
.ovl-track {
  /* --d / --fold / --open 由 .ovl 提供（v26 起上提，好让兄弟节点 .ovl-fold 也能用） */
  position: relative; height: calc(var(--d) + 22px);
  width: calc(4 * var(--fold) + var(--d));
  transition: width .5s cubic-bezier(.22,.86,.28,1);
}
.ovl.open .ovl-track { width: calc((var(--n) - 1) * var(--open) + var(--d)); }
.ovl-fold {
  flex: 0 0 auto; align-self: flex-start; margin-top: 8px;
  height: 34px; padding: 0 14px; border-radius: 999px;
  font-size: 12px; line-height: 1; white-space: nowrap;
  color: var(--ink-soft); background: var(--glass, rgba(255,255,255,.7));
  border: 1px solid var(--line-strong, rgba(0,0,0,.12));
  transition: color .2s, border-color .2s, transform .16s, opacity .26s;
}
.ovl-fold:hover { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 46%, transparent); }
.ovl-fold:active { transform: scale(.95); }
.ovl:not(.open) .ovl-fold { opacity: 0; pointer-events: none; }

/* ---- 球的手感 ---- */
.ovl-c {
  transition: transform .22s cubic-bezier(.2,.9,.3,1), box-shadow .24s ease,
              border-color .24s ease, background .24s ease;
}
/* hover 那一圈高光太大了（用户反馈"取消掉"）—— 去掉抬升和光晕，
   只留一点点边框提亮，意思一下"这个可以点"。 */
.ovl-i:hover .ovl-c {
  transform: none;
  box-shadow: none;
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}
.ovl-i:active .ovl-c { transform: translateY(0) scale(.94); }
.ovl-i.is-active .ovl-c {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft, rgba(0,0,0,.06)), 0 12px 26px -16px var(--accent);
}
.ovl-i.is-active .ovl-n { color: var(--accent); }
.ovl-i:focus-visible .ovl-c {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft, rgba(0,0,0,.08));
}

/* ---- 卡片：改成文档流（跟在球行下面），从选中那颗球的 x 长出来 ---- */
.ovl-card {
  position: relative; inset: auto;
  margin-top: 2px; max-height: 0; min-height: 0; overflow: hidden;
  display: flex; align-items: center; gap: 15px;
  padding: 0 18px; border-radius: 22px;
  background: var(--glass, rgba(255,255,255,.8));
  border: 1px solid transparent; box-shadow: none;
  opacity: 0; pointer-events: none; transform: scale(.5);
  transform-origin: var(--ax, 26px) -62px;
  transition: max-height .46s cubic-bezier(.22,.86,.28,1), opacity .26s ease,
              transform .46s cubic-bezier(.22,.86,.28,1),
              padding .46s cubic-bezier(.22,.86,.28,1),
              border-color .3s ease, box-shadow .3s ease;
}
.ovl.has-card .ovl-card {
  max-height: 146px; padding: 16px 18px;
  opacity: 1; pointer-events: auto; transform: none;
  border-color: var(--line-strong, rgba(0,0,0,.12));
  box-shadow: var(--shadow-m, 0 10px 28px -14px rgba(0,0,0,.35));
}
@media (min-width: 720px) {
  .ovl.has-card .ovl-card { max-height: 164px; padding: 18px 22px; }
}

/* ---- 首页鼓励语（替代原来的「复习节奏」） ---- */
.home-cheer {
  margin: 16px 2px 6px; padding: 13px 16px;
  font-size: 13px; line-height: 1.85; letter-spacing: .01em;
  color: var(--ink-soft);
  border-left: 2px solid color-mix(in srgb, var(--accent) 46%, transparent);
  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 9%, transparent), transparent 80%);
  border-radius: 0 12px 12px 0;
}

/* ---- 窄屏 / 桌面：尺寸只在图标与字号上微调（--d 等已统一在 .ovl 上）---- */
@media (max-width: 380px) {
  .ovl-ico { width: 17px; height: 17px; }
  .ovl-v { font-size: 11px; }
  .ovl-n { font-size: 10px; }
}
@media (min-width: 720px) {
  .ovl-ico { width: 21px; height: 21px; }
  .ovl-v { font-size: 13px; }
  .ovl-n { font-size: 11.5px; }
}

/* ============================================================
   v26 · 卡片放大 + 内容填满 + 修「收起」对齐
   ------------------------------------------------------------
   用户反馈：
   1) 卡片太小，放不下内容 —— 好书只有一个书名、天气也没几条信息；
      "能放内容就放内容，空的地方空着就空着"；
   2) 刚展开时最后一个小球和「收起」按钮偏上。
   所以：尺寸变量从 .ovl-track **上提到 .ovl**（这样兄弟节点 .ovl-fold 也能用），
   收起键按球心对齐；卡片改成纵向排版并把高度放开到 ~250。
   ============================================================ */

/* 1) 变量统一挂在 .ovl 上（track 与 fold 都是它的后代，都能取到） */
.ovl { --d: 52px; --fold: 35px; --open: 60px; }
@media (max-width: 380px) { .ovl { --d: 46px; --fold: 31px; --open: 53px; } }
@media (min-width: 720px) { .ovl { --d: 58px; --fold: 39px; --open: 74px; } }

/* 2) 「收起」按**球的中心**对齐：球顶在 strip 的 8px 内边距上，球心 = 8 + d/2。
      加了 fallback —— 万一 --d 取不到，calc 会整条失效、退回 8px（实测踩过一次）。 */
.ovl-fold {
  align-self: flex-start;
  margin-top: calc(8px + (var(--d, 52px) - 34px) / 2);
}
/* 球本身也钉死在轨道顶部，避免任何纵向漂移 */
.ovl-i { top: 0; }

/* 3) 卡片：纵向排版、放开高度 */
.ovl-card {
  flex-direction: column; align-items: stretch; gap: 0;
  padding: 0 18px;
}
.ovl.has-card .ovl-card {
  /* 好书推荐要放下「书名 + 作者 + 一句推荐语」，原来 300px 会把推荐语截掉一半。
     这里放开到 380px —— 内容短的卡片高度是自适应的，不会被撑大。 */
  max-height: 380px;
  padding: 16px 18px 17px;
}
.ovl-cd-head { display: flex; align-items: center; gap: 10px; }
.ovl-cd-body { display: flex; flex-direction: column; gap: 5px; margin-top: 11px; }
.ovl-cd-k { font-size: 10.5px; letter-spacing: .16em; color: var(--ink-faint); }
.ovl-cd-tail {
  margin-left: auto; align-self: center;
  font-size: 11px; color: var(--ink-faint); white-space: nowrap;
}
.ovl-cd-big {
  font-family: var(--font-display, Georgia, serif);
  font-size: 31px; line-height: 1.15; color: var(--ink); letter-spacing: .01em;
}
.ovl-cd-sub { font-size: 12.5px; line-height: 1.6; color: var(--ink-soft); }
.ovl-cd-note {
  font-size: 12.5px; line-height: 1.8; color: var(--ink-soft);
  padding-top: 7px; margin-top: 3px;
  border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent);
}
.ovl-cd-foot { font-size: 11px; color: var(--ink-faint); }
@media (min-width: 720px) {
  .ovl.has-card .ovl-card { max-height: 400px; padding: 20px 22px 20px; }
  .ovl-cd-big { font-size: 36px; }
  .ovl-cd-note { font-size: 13px; }
}

/* ============================================================
   v29 · 全屏模式
   ------------------------------------------------------------
   按钮在顶栏右侧 `.nav-tail` 里（手机在 `.page-head` 那组、带 .m-only）——
   两处各自跟着原有的响应式规则显示/隐藏，不用额外处理。
   这里只管：① 按钮里的 SVG 尺寸；② 全屏之后的收尾适配。

   为什么"适配"其实不多：安全区（env(safe-area-inset-*)）和 100svh 原来就处理过，
   全屏后这些值会自动变小、fixed 元素自然贴到屏幕边缘 —— 这正是想要的行为。
   需要手工改的只有"视觉呼吸"：原来间距是按"上面还有地址栏"调的，
   全屏后显得顶得太紧，所以把顶部间距收一收。
   ============================================================ */
.nav-icon-btn svg { width: 17px; height: 17px; display: block; }
.page-head .nav-icon-btn svg { width: 16px; height: 16px; }
@media (max-width: 719px) {
  .page-head .nav-icon-btn svg { width: 17px; height: 17px; }
}

/* 全屏（Fullscreen API）下的收尾。data-fs 由 app.js 在 fullscreenchange 里同步。
   ⚠️ 全屏时**绝对不要动 .content 的 padding-top**：桌面端它承担着给 fixed 顶栏让位的职责
   （实测 96px）。v29 曾在这里（含 :fullscreen 伪类兜底）把它一刀切到 14px，
   结果全屏后所有内容"挤上去"贴着顶栏（用户截图反馈）——那几条已全部删除。
   顶栏/底栏自身的小微调保留，页面内容间距一律不动。 */
:root[data-fs="1"] .topnav { top: calc(12px + env(safe-area-inset-top, 0px)); }
:root[data-fs="1"] .tabbar { bottom: calc(10px + env(safe-area-inset-bottom, 0px)); }

/* ============================================================
   v30 · 亮色重做 + 设置页收成手风琴 + 板块"全在涨"的说明
   ------------------------------------------------------------
   三件事：
   1) 亮色画作换成 AI 修复版（用户给的参考图：竹林平江一叶小舟 / 枫林晚马车）；
   2) 设置页从"一长条平铺"改成一条条手风琴（DOM 包装见 app.js 的 wrapSettingsSections）；
   3) 行业板块"今天全在涨"时把话说透（用户问过"为什么没有跌的"）。
   ============================================================ */

/* ---- 1) 亮色画作 ---- */
:root[data-theme="light"] {
  --art-hero:  url('/theme-art/day-hero-hd.webp?v=30');
  --art-intel: url('/theme-art/day-intel-hd.webp?v=30');
}
/* 亮色情报站卡头用它 —— 与 --art-page 解耦（跟暗色 v22 的处理一致） */
:root[data-theme="light"] .intel-hero {
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--paper) 30%, transparent) 0%,
      transparent 40%,
      color-mix(in srgb, var(--paper) 62%, transparent) 100%),
    var(--art-intel);
  background-size: cover, cover;
  background-position: center, center 32%;
}

/* ============================================================
   v36 · 折叠态的球改成实心底（不再"透出底下那颗"）
   ------------------------------------------------------------
   用户反馈：「小球重叠之后被盖住的那部分不要显现，有点难看」。
   原因：`.ovl-c` 用的是半透明玻璃（`--glass`，亮色 .68 / 暗色 .66），
        折叠时球一颗压一颗，下面的球会**透过上面的球显出来**，边界糊成一团。
   做法：只在**折叠态**（球是叠着的）换成实心底；
        展开后球不再重叠，还原成玻璃质感 —— 那层毛玻璃的观感不用丢。
   ============================================================ */
:root { --ovl-solid: #fbfcf9; }
:root[data-theme="dark"] { --ovl-solid: #1b232e; }
.ovl:not(.open) .ovl-c,
.ovl:not(.open) .ovl-more { background: var(--ovl-solid); }

/* ---- 2) 设置页：分组卡片 + 列表行（iOS / Linear 那种做法） ---- */
.set-group { margin: 0 0 20px; }
.set-group-t {
  margin: 0 0 9px 4px;
  font-size: 11px; font-weight: 640; letter-spacing: .18em;
  color: var(--ink-faint);
}
.set-list {
  border-radius: var(--r-xl, 20px);
  background: var(--card, rgba(255,255,255,.74));
  border: 1px solid var(--line);
  box-shadow: var(--shadow-s, 0 1px 2px rgba(0,0,0,.06));
  overflow: hidden;
}
.set-row { display: block; }
.set-row + .set-row { border-top: 1px solid color-mix(in srgb, var(--line) 78%, transparent); }
.set-row[open] { background: color-mix(in srgb, var(--accent) 5%, transparent); }
.set-head {
  display: flex; align-items: center; gap: 12px;
  padding: 13px 15px; cursor: pointer; list-style: none;
  -webkit-tap-highlight-color: transparent;
  transition: background .16s;
}
.set-head::-webkit-details-marker { display: none; }
.set-head:hover { background: var(--sunken); }
.set-ico {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 10px;
  display: grid; place-items: center;
  font-size: 15px; line-height: 1;
  background: var(--accent-soft, rgba(0,0,0,.05));
}
.set-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.set-txt b { font-size: 13.5px; font-weight: 640; color: var(--ink); letter-spacing: .01em; }
.set-txt i { font-size: 11.5px; font-style: normal; color: var(--ink-faint); }
.set-arrow {
  flex: 0 0 auto; margin-left: auto; width: 16px; height: 16px;
  color: var(--ink-faint);
  transition: transform .26s cubic-bezier(.2,.8,.3,1);
}
.set-row[open] .set-arrow { transform: rotate(90deg); }
.set-body { padding: 0 15px 16px; }
/* 卡片在这一层里取消自己的"卡片感"，避免卡片里套卡片 */
.set-body .card {
  border: 0; box-shadow: none; background: transparent;
  padding: 0; margin: 0; border-radius: 0;
}
:root[data-theme="dark"] .set-list { background: var(--glass-strong, rgba(20,27,36,.9)); }

/* ============================================================
   v37 · 五个新增模块的样式（**只新增规则，不改任何既有规则**）
   ------------------------------------------------------------
   ④ 十二时辰徽章   ① 节气印章   ② 留白呼吸带
   ③ 打卡印章墙     ⑤ 藏书票墙
   朱红统一用中国印泥色 #b23a2e（暗色下提亮成 #c2493a，避免在深色背景上发闷）。
   ============================================================ */

/* ④ 十二时辰：页头那枚小漆牌 */
.sc-badge {
  display: inline-block; margin-right: 8px; padding: 2px 9px;
  border-radius: 7px; vertical-align: 1px;
  font-size: 11.5px; font-weight: 640; letter-spacing: .08em;
  color: var(--paper); background: var(--ink);
}
:root[data-theme="dark"] .sc-badge {
  background: color-mix(in srgb, var(--ink) 45%, var(--accent) 35%);
  color: #f2ece0;
}

/* ① 节气印章 */
.term-seal {
  display: inline-flex; align-items: center; gap: 11px;
  margin-top: 16px; padding: 9px 15px 9px 11px;
  border-radius: 13px;
  background: color-mix(in srgb, var(--paper) 58%, transparent);
  border: 1px solid color-mix(in srgb, #b23a2e 26%, transparent);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.ts-face {
  flex: 0 0 auto; width: 42px; height: 42px; border-radius: 9px;
  display: grid; place-items: center;
  writing-mode: vertical-rl; text-orientation: upright;   /* 印章竖排 */
  font-size: 14px; font-weight: 700; letter-spacing: .02em;
  color: #fff8f2; background: #b23a2e;
  box-shadow: 0 3px 10px -4px rgba(178,58,46,.75);
}
.ts-line { font-size: 12.5px; color: var(--ink-soft); letter-spacing: .04em; }
:root[data-theme="dark"] .term-seal { background: rgba(20,27,36,.5); }
:root[data-theme="dark"] .ts-face { background: #c2493a; }

/* ② 留白呼吸带：故意不放内容，留白本身也是内容 */
.breath-band {
  position: relative; margin: 30px 0 26px;
  padding: 34px 18px 40px; text-align: center;
}
.bb-line {
  display: block;
  font-family: var(--font-display, Georgia, serif);
  font-size: 15px; letter-spacing: .16em; line-height: 1.9;
  color: var(--ink-faint);
}
.bb-ridge {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: block; width: 100%; height: 26px;
  fill: color-mix(in srgb, var(--ink-faint) 16%, transparent);
}
:root[data-theme="dark"] .bb-ridge { fill: rgba(210,222,235,.10); }

/* ③ 打卡印章墙（不用进度条 / 图表） */
.seal-wall {
  margin: 26px 0 6px; padding: 20px 18px;
  border-radius: var(--r-xl, 20px);
  background: var(--glass, rgba(255,255,255,.7));
  border: 1px solid var(--line);
}
.seal-cap { margin-bottom: 16px; font-size: 11.5px; letter-spacing: .18em; color: var(--ink-faint); }
.seal-row { display: flex; gap: 18px; justify-content: center; flex-wrap: wrap; }
.seal { width: 84px; text-align: center; opacity: .72; }
.seal-face {
  width: 62px; height: 62px; margin: 0 auto 8px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 15px; font-weight: 700; color: var(--ink-faint);
  border: 2px dashed color-mix(in srgb, var(--ink-faint) 55%, transparent);
  background: transparent;
  transition: transform .3s, opacity .3s;
}
.seal.got { opacity: 1; }
.seal.got .seal-face {
  color: #fff8f2; background: #b23a2e; border: 2px solid #b23a2e;
  box-shadow: 0 6px 16px -8px rgba(178,58,46,.8);
}
.seal-tip { font-size: 11px; color: var(--ink-faint); }
.seal.got .seal-tip { color: var(--accent); }
:root[data-theme="dark"] .seal.got .seal-face { background: #c2493a; border-color: #c2493a; }

/* ⑤ 藏书票墙 */
.page-note {
  margin: 0 0 18px; padding: 11px 14px;
  font-size: 12.5px; line-height: 1.75; color: var(--ink-soft);
  background: var(--sunken); border-radius: 12px;
}
.shelf { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.ticket {
  position: relative; padding: 16px 14px 14px;
  border-radius: 4px 4px 10px 10px;
  background: color-mix(in srgb, var(--paper) 88%, #fff);
  border: 1px solid var(--line);
  box-shadow: 0 6px 16px -12px rgba(0,0,0,.5);
}
.tk-day { font-size: 10.5px; letter-spacing: .08em; color: var(--ink-faint); }
.tk-title {
  margin: 7px 0 3px;
  font-family: var(--font-display, Georgia, serif);
  font-size: 15px; line-height: 1.45; color: var(--ink);
}
.tk-author { font-size: 11px; color: var(--ink-faint); }
.tk-line {
  margin: 10px 0 0; padding-top: 9px;
  border-top: 1px dashed var(--line);
  font-size: 11.5px; line-height: 1.7; color: var(--ink-soft);
}
.tk-seal {
  position: absolute; right: 10px; top: 10px;
  width: 26px; height: 26px; border-radius: 6px;
  display: grid; place-items: center;
  font-size: 12px; font-weight: 700; color: #fff8f2;
  background: #b23a2e; opacity: .9;
}
:root[data-theme="dark"] .ticket { background: rgba(24,32,42,.72); }
:root[data-theme="dark"] .tk-seal { background: #c2493a; }

/* 藏书票：张数 + 删除按钮 */
.shelf-count { margin: 0 0 12px 2px; font-size: 11.5px; letter-spacing: .12em; color: var(--ink-faint); }
.tk-del {
  position: absolute; left: 10px; bottom: 8px;
  width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 15px; line-height: 1; color: var(--ink-faint);
  background: transparent; border: 1px solid var(--line);
  cursor: pointer; opacity: 0; transition: opacity .18s, color .18s, border-color .18s;
}
.ticket:hover .tk-del { opacity: 1; }          /* 鼠标移上去才出现，平时不吵 */
.tk-del:hover { color: var(--accent); border-color: var(--accent); }
:root[data-theme="dark"] .tk-seal { background: #c2493a; }

/* 收起小球时"+2"不要提前冒出来：球要 .58s 才叠好，
   "+2" 原本 .3s 就淡入，看着像先冒出来再收拢 —— 让它等球叠完再出现。
   展开时反过来：要**立刻**淡出，所以 .open 下把延迟清成 0。 */
.ovl-more { transition: opacity .3s ease, transform .3s ease; transition-delay: .34s; }
.ovl.open .ovl-more { transition-delay: 0s; }

/* ============================================================
   v40 · 情报站：实时最前沿 + 我的就业
   ------------------------------------------------------------
   · .live-zone  —— AI 简讯顶部的实时抓取区（抓取要 1~3 秒，先给骨架屏）
   · .live-card  —— 实时条目的左侧强调边（和内置内容区分开）
   · career 栏目复用 .intel-card，不用新样式
   ============================================================ */
.live-zone {
  position: relative;
  margin: 0 0 18px; padding: 14px 15px 4px;
  border-radius: var(--r-l, 16px);
  background: var(--glass, rgba(255,255,255,.7));
  border: 1px solid var(--line);
}
.lz-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.lz-title { font-size: 13px; font-weight: 660; color: var(--ink); letter-spacing: .02em; }
.lz-meta { margin-left: auto; font-size: 11px; color: var(--ink-faint); white-space: nowrap; }
.lz-skeleton { display: flex; flex-direction: column; gap: 9px; padding: 2px 0 12px; }
.lz-skeleton i {
  display: block; height: 13px; border-radius: 6px;
  background: linear-gradient(90deg,
    var(--sunken) 25%, color-mix(in srgb, var(--sunken) 30%, transparent) 50%, var(--sunken) 75%);
  background-size: 220% 100%;
  animation: lz-shimmer 1.5s ease-in-out infinite;
}
.lz-skeleton i:nth-child(1) { width: 80%; }
.lz-skeleton i:nth-child(2) { width: 63%; }
.lz-skeleton i:nth-child(3) { width: 71%; }
@keyframes lz-shimmer { 0% { background-position: 120% 0; } 100% { background-position: -20% 0; } }
@media (prefers-reduced-motion: reduce) { .lz-skeleton i { animation: none; } }

.live-list { margin-top: 6px; }
.live-card { border-left: 2px solid color-mix(in srgb, var(--accent) 52%, transparent); }
.live-tag {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}

/* ============================================================
   v43 · 借鉴 Dashy：信源状态指示器 + 轻量模式
   ============================================================ */
.lz-dots { display: inline-flex; gap: 4px; align-items: center; }
.lz-dot {
  display: block; width: 7px; height: 7px; border-radius: 50%;
  background: color-mix(in srgb, var(--ink-faint) 45%, transparent);
}
.lz-dot.ok  { background: #4c9a6a; box-shadow: 0 0 0 2px color-mix(in srgb, #4c9a6a 20%, transparent); }
.lz-dot.bad { background: #b23a2e; box-shadow: 0 0 0 2px color-mix(in srgb, #b23a2e 18%, transparent); }

/* 轻量模式：省掉最重的东西 —— 全屏画作背景（249KB / 265KB）。
   手机上过 Tailscale 时这两张图就是"加载慢"的主因之一。
   ⚠️ 只点名画作那几个层，**不要写 [class*="-hd"] 这种宽匹配** ——
      它会连卡片里的其它元素一起藏掉，之前就是它把图片弄没的。 */
body.lite .hero4 .h4-sky,
body.lite .art-layer,
body.lite .scene-layer { display: none !important; }
body.lite .hero4 { min-height: 200px; }

/* 轻量模式提示条：开着时必须看得见，否则用户会以为网站坏了 */
#lite-bar {
  position: sticky; top: 0; z-index: 60;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 10px; padding: 9px 14px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 15%, var(--glass, #fff));
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  font-size: 12px; color: var(--ink);
}
#lite-bar span { flex: 1; min-width: 160px; line-height: 1.6; }
#lite-bar b { color: var(--accent); }

/* ============================================================
   v44 · 词条库（学习页第三个 tab）—— 143 个词条终于有个门面了
   ============================================================ */
.kb-bar { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; }
.kb-bar .input { flex: 1; min-width: 0; }
.kb-count { font-size: 11.5px; color: var(--ink-faint); white-space: nowrap; }
.kb-count b { color: var(--ink); }
.kb-list { display: flex; flex-direction: column; gap: 8px; }
.kb-item {
  border-radius: 12px; border: 1px solid var(--line); overflow: hidden;
  background: var(--glass, rgba(255,255,255,.7));
}
.kb-item > summary {
  display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap;
  padding: 12px 14px; cursor: pointer; list-style: none;
}
.kb-item > summary::-webkit-details-marker { display: none; }
.kb-item[open] > summary { border-bottom: 1px solid var(--line); }
.kb-cat {
  flex: none; padding: 2px 7px; border-radius: 6px;
  font-size: 10.5px; background: var(--sunken); color: var(--ink-faint);
}
.kb-term { font-size: 14px; color: var(--ink); }
.kb-brief { flex: 1; min-width: 120px; font-size: 12px; color: var(--ink-soft); }
.kb-body { padding: 11px 14px 13px; font-size: 12.5px; line-height: 1.8; color: var(--ink-soft); }
.kb-body p { margin: 0 0 7px; }
.kb-body p:last-child { margin-bottom: 0; }
.kb-ex { padding-left: 9px; border-left: 2px solid var(--line); }
.kb-alias, .kb-src { font-size: 11px; color: var(--ink-faint); }
.kb-tags { display: flex; flex-wrap: wrap; gap: 5px; }
.kb-tags span { padding: 2px 6px; border-radius: 5px; font-size: 10.5px; background: var(--sunken); color: var(--ink-faint); }
body.lite .hero4::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(160deg,
    color-mix(in srgb, var(--accent) 12%, transparent),
    transparent 70%);
}

/* ---- 3) 板块：今天全在涨时的说明 ---- */
.sec-note {
  margin: 7px 0 11px;
  padding: 9px 12px;
  font-size: 12px; line-height: 1.75;
  color: var(--ink-soft);
  background: var(--sunken, rgba(0,0,0,.04));
  border-left: 2px solid color-mix(in srgb, var(--accent) 50%, transparent);
  border-radius: 0 10px 10px 0;
}
.sec-note b { color: var(--ink); }

/* ============================================================
   v31 · 亮色：整站背景统一到那张画（不要竹子了）+ 提高画质
   ------------------------------------------------------------
   用户反馈："亮色的整个背景可以换成我给你的那第一张图片了，不要是那个竹子"、
   "背景就直接暗色模式怎么做现在亮色也就怎么做"、"不够清晰，色彩又不够浓郁"。
   所以照暗色那套来 —— 同一张画的三个版本：
     · 首页 hero  → 高清原图（保住原图的绿和水，只提技术质量，不重绘构图）
     · 内页背景   → **淡化派生版**（模糊 + 提亮 + 降饱和），只统一氛围、不抢内容
     · 股票页     → 再模糊一点、再降饱和（与暗色一样略有区分）
   另外把输出质量提上去：hero / 情报站卡头 webp 0.78 → 0.88
   （"色彩不浓郁/不够清晰"有一部分就是压缩质量偏低造成的）。
   ============================================================ */
:root[data-theme="light"] {
  /* ⚠️ 默认给**小图**（jpg）。手机屏幕小、还常走 Tailscale，250KB 的首屏画是
     "手机进不去/太卡"的最大单项（实测占总下载 38%）。
     默认值就是小屏走的那条，宽屏才在下面换成高清 WebP。
     这套 hd/jpg 的体积对比（浅色）：
       hero  hd.webp 249.7 KB  →  jpg 107.8 KB     省 142 KB
       page  hd.webp  14.4 KB  →  jpg  87.9 KB     （page 反过来是 jpg 更大，所以只降 hero/stock）
       stock hd.webp  13.5 KB  →  jpg  95.2 KB     （同上，保留 webp）
     intel 只有 hd 版（265 KB），且只在情报站页才加载，不影响首屏，暂不动。 */
  --art-hero:  url('/theme-art/day-hero.jpg?v=31');
  --art-page:  url('/theme-art/day-page-hd.webp?v=31');
  --art-stock: url('/theme-art/day-stock-hd.webp?v=31');
  --art-intel: url('/theme-art/day-intel-hd.webp?v=31');
}

/* 宽屏（电脑）带宽和设备都扛得住，才上那张 250KB 的高清 hero */
@media (min-width: 821px) {
  :root[data-theme="light"] {
    --art-hero: url('/theme-art/day-hero-hd.webp?v=31');
  }
}

/* 换画之后文字要重新"立住"：原来是淡竹子，标题渐变的末段（--tt-4/5）本来就浅，
   压在那张浓郁的森林画上几乎看不见。这里把整条渐变加深，并给文字补一层白晕。 */
:root[data-theme="light"] {
  --tt-1: #13221a;  --tt-2: #1c3126;  --tt-3: #294535;  --tt-4: #365945;  --tt-5: #446d57;
}
/* ① 干掉那条"波浪"：早期"整页用 CSS 画水墨"方案留下的两层坡地 SVG
   （app.js 的 sceneLayers() → SCENE_FAR / SCENE_NEAR）。画作换成真图之后它们纯属多余，
   亮色下就是用户看到的那"一条白一条绿"。暗色在 v20 已经收了，这里把亮色也收掉。 */
:root[data-theme="light"] .hero4 .scene-layer { display: none; }
/* ② 卡片别发灰：上一版两条纸色遮罩叠得太厚（78% + 28%/32%/56%），整个画面被洗淡了。
   现在只在左侧文字区保留必要的一层，右半边尽量让画作透出来。 */
:root[data-theme="light"] .hero4 {
  background-image:
    linear-gradient(96deg,
      color-mix(in srgb, var(--paper) 62%, transparent) 0%,
      color-mix(in srgb, var(--paper) 30%, transparent) 34%,
      color-mix(in srgb, var(--paper) 6%, transparent) 58%,
      transparent 74%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--paper) 16%, transparent) 0%,
      transparent 22%,
      color-mix(in srgb, var(--paper) 18%, transparent) 88%,
      color-mix(in srgb, var(--paper) 34%, transparent) 100%),
    var(--art-hero);
  background-size: cover, cover, cover;
  background-position: center, center, center 52%;
  background-repeat: no-repeat;
}
@media (max-width: 719px) {
  :root[data-theme="light"] .hero4 { background-position: center, center, center 46%; }
}
/* 白晕：让深色文字在画作上不糊在一起（只加阴影，不改颜色） */
:root[data-theme="light"] .hero4 .h4-quote .q,
:root[data-theme="light"] .hero4 .h4-quote .a,
:root[data-theme="light"] .hero4 .h4-date {
  text-shadow: 0 1px 10px color-mix(in srgb, var(--paper) 84%, transparent),
               0 0 3px color-mix(in srgb, var(--paper) 60%, transparent);
}
:root[data-theme="light"] .hero4 .h4-title {
  filter: drop-shadow(0 1px 10px color-mix(in srgb, var(--paper) 72%, transparent));
}
