/* ============================================================================
   skin.css —— 北极光站「全站皮肤层」(2026-09-11)

   做两件事:
     ① 把 fatfish.ca 那套「加个类就换肤」的机制搬过来 —— 全站只有两个颜色变量:
          --color_text / --color_bg
          默认 = 白底黑字; 给任意一节加 class="skin-dark" → 该节变 #222 底白字。
          (fatfish 原式: :root{--color_text:#222;--color_bg:#fff}
                         .skin-dark-mode{--color_text:#fff;--color_bg:#222})
     ② 承载全站共用的皮肤与构件: 字体 / 顶栏 / 汉堡浮层 / 隐私条 / 胶囊按钮 /
          章节头 / 漫画风点缀。

   加载顺序: 每个页面 <link> 一律放在 m.css **之后**、head 最末。
     本文件所有规则都带 html.fh 前缀 → 特异性稳压各页 inline <style>,
     与 apeTop.js 运行时注入的 <style>(它晚于本文件, 但特异性只有 (0,1,0))。
     **这是唯一的"最终裁决层"** —— 全站配色出问题只看这一个文件。

   与 f.css 的分工:
     f.css   = 首页第 1 屏(#fHero 三行大字)的专属样式, 只在 index.html 生效
     skin.css = 其余一切(皮肤 / 顶栏 / 构件)。f.css 里原 §1/§2/§8-§11 已搬到这里。

   数字一律 px, **禁用 rem**: fatfish 根字号 14px、本站 16px, 照抄它的 rem 会整体放大 14%。
   ========================================================================== */

/* ==========================================================================
   §1 字体(自托管; Archivo=SIL OFL 1.1, Roboto Slab=Apache-2.0)
   unicode-range 只声明 latin → 中文自动落 PingFang SC / Microsoft YaHei
   ========================================================================== */
@font-face{
  font-family:"ArchivoVar";
  src:url('/fonts/archivo/ArchivoVar-latin.woff2') format('woff2');
  font-weight:100 900; font-stretch:62% 125%; font-style:normal; font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Roboto Slab";
  src:url('/fonts/robotoslab/RobotoSlab-latin.woff2') format('woff2');
  font-weight:100 900; font-style:normal; font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* 中文：思源黑体 / Noto Sans SC（SIL OFL 1.1，免费可商用），自托管子集。
   为什么要自托管: 中文字体**没有可抄的对象** —— fatfish 那三个字体(IntegralCF /
   GuthenBoots / Roboto Slab)**一个汉字都没有**。原来全站中文写的是系统字体名
   (PingFang SC / Microsoft YaHei)，于是同一个页面 Win 看雅黑、Mac 看苹方，
   站点自己都做不到"同一个字"。自托管才能保证所有访客看到同一张脸。
   子集 = GB2312 全集 6763 字 + ASCII + 常用标点(实测 6908 字)，保留 wght 100–900
   变量轴 → **1.75MB**。
   ⚠ 别把这里和"首屏三行大字的方正牛黑简"搞混: 那三条用户指定用 FZNiuHJW-EB
   (f.css §1 的 "FZHero")，那份 /FZNiuHJW-EB.ttf **保留不删**。
   超出子集范围的字(生僻字/用户发的内容)自动落 `--ff-cjk` 后面的系统字体。 */
@font-face{
  font-family:"Noto Sans SC";
  src:url('/fonts/notosc/NotoSansSC-GB2312.woff2') format('woff2');
  font-weight:100 900; font-style:normal; font-display:swap;
  /* 只声明 CJK 段 → 纯拉丁文本永不下这个文件(拉丁走 Roboto Slab / Archivo) */
  unicode-range:U+2E80-2EFF,U+3000-303F,U+31C0-31EF,U+3200-32FF,U+3400-4DBF,
                U+4E00-9FFF,U+F900-FAFF,U+FE30-FE4F,U+FF00-FFEF;
}

/* 漫画风中文: 站酷快乐体(SIL OFL 1.1, 免费可商用)。
   用户 2026-09-12「这个太板正了…字体你照样有没有漫画风的字体」—— Noto 是中性的,
   正文想有手写/漫画味就得换一张脸。**只给首页第 2 屏正文用**(副标题与邮箱按钮用户明确
   说了不换), 见 §7 的那条 .fh-about .body-lg。
   子集 = GB2312 一级字(3755)+ASCII+常用标点 → 450KB(比全站每页都下的 Noto 还小 4 倍)。
   ⚠ 只有 400 这一档, 没有粗体/细体; 消费规则别写 font-weight:200(会白等一场, 无合成)。
   ⚠ 故意**不写 unicode-range**: 它只被一个元素族用到, 写了反而要多维护一份区间。
     子集外的字(生僻字/用户以后自己改文案打出来的字)自动落后面的 var(--ff-nav)。
   复现方式 / 为什么不是别的字体 → fonts/zcoolkuaile/SOURCE.txt */
@font-face{
  font-family:"ZCOOLKuaiLe";
  src:url('/fonts/zcoolkuaile/ZCOOLKuaiLe-GB2312L1.woff2') format('woff2');
  font-weight:400; font-style:normal; font-display:swap;
}

/* ==========================================================================
   §2 变量(≡ 后面的数字是 fatfish 14px 根字号下的原值)
   ========================================================================== */
html.fh{
  /* —— 换肤的两个总开关(fatfish 原式) —— */
  --color_text:#222;          /* ≡ :root{--color_text} */
  --color_bg:#fff;            /* ≡ :root{--color_bg}   */

  /* —— 品牌色(fatfish 全站配色就这两个, 2026-09-11 从它 :root 挖出) —— */
  --c-red:#cb413f;            /* ≡ --text_color_hover / --header_underline_color */
  --c-gold:#cab99a;           /* ≡ --tag_color */
  /* 金色有两种用途, 2026-09-11 拆开:
     --c-gold     装饰用(下划线/边框/跑马灯填色/彩色块底) —— 永远是这个浅金, 它不承担可读性;
     --c-gold-ink **文字**用 —— 白底上 #cab99a 只有 1.92:1(巡检实测), 读不了, 所以白底走深金
                  #8a6a1f(5.04:1), 深皮上再翻回浅金(见下面的 .skin-dark)。
     两处值必须成对改: 换了一个不换另一个, 就会出现"白底浅金 / 深底深金"这种两头都读不了的状态。 */
  --c-gold-ink:#8a6a1f;
  /* 描边水印色: 白底用浅灰、深皮用中灰(≡ .skin-dark-mode .expertises-marquees{--stroke_color:#434343}) */
  --stroke-light:#f2f2f0;
  --stroke-dark:#434343;

  /* —— 首页第 2/3 屏「背景渐暗」用的两档墨色(白底档) ——
     深皮档在 §6c 的 .fh-dark 里翻成白色系。做成变量是因为白/深两套的 rgba **不是一个色值**,
     逐条写死会让"翻皮"变成两份要同步维护的规则。 */
  --sk-line:rgba(34,34,34,.16);   /* 卡边框 / 分割线 */
  --sk-dim:rgba(34,34,34,.55);    /* 次要文字(作者/时间/空态) */
  --sk-hi:rgba(34,34,34,.8);      /* 作者名 */
  --sk-water:rgba(34,34,34,.24);  /* 跑马灯描边水印 */

  /* —— 换肤过渡(≡ fatfish --skin_transition_duration / --skin_transition_ease) ——
     2026-09-11 实测 fatfish.ca(越中线起每 60ms 采一次变量): 越过中线那一刻
     --color_bg/--color_text 是**瞬切**的, 真正"渐暗"的是两层 475ms 过渡 ——
     body 里那张 .page-background 遮罩淡入(opacity 0→1) 与
     .u-title-multiline__line 自己的 transition:color 475ms。
     两者同一条曲线, 所以观感是"底色变暗"与"字变白"同步走完 475ms。
     我们不用遮罩层: body/两屏各写 background:var(--color_bg), 变量一翻它们自己就过渡。 */
  --skin-dur:475ms;
  --skin-ease:cubic-bezier(.455,.03,.515,.955);   /* ≡ fatfish 原值 */

  /* —— 文字错开用的缓动(≡ GSAP custom_gsap_eases.expo_out_default) ——
     fatfish 那条是 CustomEase 两段贝塞尔 "M0,0 C0.084,0.61 0.214,0.802 0.28,0.856
     C0.356,0.918 0.374,1 1,1", 单个 cubic-bezier 表达不了。下面 §6c 里按 22 点采样写成
     CSS linear()(Chrome 113+/Safari 17.2+), 老浏览器落到这条 cubic-bezier 兜底。
     采样校验: y(0.14)=0.619 y(0.28)=0.856 y(0.5)=0.968 —— 与 GSAP 逐点吻合。 */
  --fx-ease:cubic-bezier(.19,1,.22,1);
  --fx-rise-dur:.7s;              /* ≡ 文字逐行上升的 duration:.7 */
  --fx-pop-dur:.6s;               /* ≡ 手写体逐字弹入的 duration:.6 */

  /* —— 字体栈 ——
     中文**只认这一条**(2026-09-12 收口): --ff-cjk 是全站唯一的中文字体链,
     以后要换中文字体只改这一行, 别在各处再写 PingFang / YaHei。

     为什么收: 原来 --ff-nav = `"Roboto Slab","PingFang SC",...`(--ff-display 才带
     "Noto Sans SC") → 实测同一页 **三种汉字**: 三条大字落 Noto Sans SC、说明段落落
     微软雅黑 Light、按钮落微软雅黑。fatfish 那三个字体(IntegralCF / GuthenBoots /
     Roboto Slab)**一个汉字都没有**, 所以"照抄原站"对中文不成立 —— 能对齐的只有
     拉丁文(已对齐: Roboto Slab 与原站同一个字、大标题 Archivo 顶它的商业 IntegralCF)。 */
  --ff-cjk:"Noto Sans SC","PingFang SC","Microsoft YaHei",sans-serif;
  --ff-nav:"Roboto Slab",var(--ff-cjk);
  --ff-display:"ArchivoVar","Archivo Black","Anton",var(--ff-cjk);

  /* —— 顶栏整体缩放(2026-09-12 用户:「顶栏和顶栏的文字都整体缩小一点」) ——
     条高 / 导航字号 / 胶囊字号+内边距 / logo / 左右留白 **全部**乘这一个系数,
     所以调大小只改这一个数, 不会出现"字小了条没小"的错位。
     ⚠ 它只作用于**顶栏本身**(§5 桌面 + §8 三档窄屏), **不动 `--fh-top`** ——
     `--fh-top` 是**未缩放的基数**, 条高是 `--fh-top × --top-k`; 两个一起改等于乘两遍。
     它现在只剩三个消费者: 条高(f.css §8 / §5)、chat.html 的 `.ch-page{top}` 兜底。
     (原来还喂着那个已删除的全屏菜单的关闭 × —— 2026-09-12 删菜单后没了。)
     ⚠ 同一个系数在**三个文件**里各引用一次(skin.css §5/§8 + f.css §8/§9 + m.css 窄屏两块):
     首页与窄屏首页是 f.css / m.css 那份赢, 内页才是本文件。只改一处 = "条缩小了字没缩"。
     真踩过: skin.css 里 8 处全改了, 首页只有 padding 生效(那是 f.css 唯一没重复的一条)。

     **2026-09-12 第二轮 —— 用户:「现在把电脑端的顶栏再整体缩小一倍」**:
       · 桌面(≥961): 0.88 → **0.44**(再砍一半)。1440 实测: 条高 162→71.3px、
         导航字 42.44→18.7px、logo 84→37px、胶囊 44→19.4px、左右留白同步减半。
       · **窄屏(≤960) 一个字都不动, 仍是 0.88** —— 用户说的是「电脑端」; 而且窄屏那 12 处
         正文补位(m.css:38-45 / 111-118 / 187-191)与 §10 抽屉里浮 logo 的定位, 全是按
         62/56/52 × 0.88 = 54.56/49.28/45.76 算好的, 跟着改会把手机端整片正文顶歪。
     做法: **只改这一个变量**, 按视口分两档(见本块下面那条 @media)。
     所有消费者(条高/字号/logo/间距/胶囊的十几处 `calc(… * var(--top-k))`)一行都不用动 ——
     它们本来就各自被媒体查询或特异性锁死在单一档里, 拿到哪一档的值都是对的。 */
  --top-k:0.44;   /* **桌面档(≥961)**。0.88(第一轮「缩小一点」)再砍一半 */

  /* —— 排版尺度(≡ fatfish 的 u-* 工具类) —— */
  --fs-body-lg:28px;          /* ≡ .u-body-lg{font-size:2rem;font-weight:200} */
  --fs-cursive:49.8px;        /* ≡ .u-subtitle-cursive{font-size:3.5555rem} */

  /* —— 栅格(≡ fatfish .wrapper: 12 栏, 左右外边距 35px, 沟槽 21px) —— */
  --g-pad:35px;               /* ≡ --wrapper_margin (2.5rem@14) */
  --g-gutter:21px;            /* ≡ --grid-gutter (1.5rem@14) */
  --g-col:calc((100vw - var(--g-pad) * 2 - 11 * var(--g-gutter)) / 12);

  /* —— ⚠ 首页第 1 屏的**布局变量**一律不在这里声明 ——
     --fh-pad / --fh-pad-top / --fh-handoff / --fh-gutter / --fh-col / --fh-inset /
     --fh-shift / --fh-desc-gap / --fh-fs / --fh-stroke / --fh-word-gap / --fh-icon /
     --fh-top 这一批的所有者是 **f.css §2(桌面值) + m.css 三档(960/560/400 的窄屏值)**。

     2026-09-11 踩过的坑: 曾经在这里照抄过一份。本文件晚于 m.css 加载, 两条规则又同为
     `html.fh` 特异性, 而 **@media 不增加特异性** → 桌面值反压了 m.css 的窄屏值。
     实测 360px: --fh-top 恒为 clamp 下限 92px(该 52)、--fh-inset 恒为 150.5px(该 16),
     大字被 f-home.js 的 fitLines 一路压到 3.63px, 顶栏也高出 40px。
     → 别再搬回来; 本文件只声明 f.css / m.css 都没有的变量。 —— */

  /* —— 顶栏用到的别名(与 f.css §2 同值; 内页不加载 f.css, 靠这里兜底) —— */
  --fh-txt:#222;
  --fh-red:#cb413f;
  --fh-gold:#cab99a;
  --fh-display:"ArchivoVar","Archivo Black","Anton",var(--ff-cjk);
}

/* 窄屏(≤960)把顶栏缩放退回第一轮的 0.88。
   ⚠ 这条必须在 §2 那个 `html.fh{}` **之后**(同特异性, 靠后赢); 也必须在 §8/§10 的
   媒体查询之外独立成立 —— 它们里面那十几处 `calc(… * var(--top-k))` 吃的就是这里的值。
   ⚠ 别把它并进 §10: §10 整块是侧边抽屉的皮, 顶栏缩放不是抽屉的一部分, 混在一起
   下次改顶栏时没人会想到来抽屉那节找。 */
@media (max-width:960px){ html.fh{--top-k:0.88} }

/* ==========================================================================
   §3 全局(底 / 字 / 链接 / 选中 / 滚动条 / 表单 / 表格)
   每一节只需写 background:var(--color_bg);color:var(--color_text) 就能换肤。
   ========================================================================== */
html.fh body{
  background:var(--color_bg);
  color:var(--color_text);
  font-family:var(--ff-nav);
  font-weight:300;
  -webkit-font-smoothing:antialiased;
  /* 首页第 3 屏越中线时 --color_bg/--color_text 会翻, 这条让整页底色与继承色**渐**过去
     (≡ fatfish 的 475ms)。其余页面这两个变量不变, 这条规则对它们等于不存在。 */
  transition:background-color var(--skin-dur) var(--skin-ease),
             color var(--skin-dur) var(--skin-ease);
}

/* 链接: fatfish 的默认链接是继承色 + 细下划线, 悬停转品牌红。
   ⚠ 只作用于**没有 class 的裸链接**。早先写成 `html.fh a`, 特异性(0,1,2)压过页面自己的
   `.ai-btn{color:#fff}`(0,1,0) —— 于是 chat.html 红底胶囊上的白字被 inherit 成 #222,
   肉眼看就是"红底黑字", 巡检算出来 3.31:1。带 class 的 <a> 是**组件**, 颜色归组件自己定。
   (悬停那条同理: 不跟着限定的话, 悬停时白字会被刷成红字 = 红底红字, 直接看不见。) */
html.fh a:not([class]){color:inherit}
html.fh a:not([class]):hover{color:var(--c-red)}

html.fh ::selection{background:var(--c-red);color:#fff}

/* 滚动条: 深色页面时代的浅色滚动条在白底上会"消失", 统一成中性灰 */
html.fh{scrollbar-color:rgba(0,0,0,.28) transparent;scrollbar-width:thin}
html.fh ::-webkit-scrollbar{width:10px;height:10px}
html.fh ::-webkit-scrollbar-track{background:transparent}
html.fh ::-webkit-scrollbar-thumb{background:rgba(0,0,0,.22);border-radius:999px}
html.fh ::-webkit-scrollbar-thumb:hover{background:rgba(0,0,0,.38)}

/* 表单: 白底时代统一成"下划线式"输入(≡ fatfish 的表单观感) —— 无框、无填充、
   只留一条底线, 聚焦时底线转品牌红。圆角/阴影一律去掉。 */
html.fh input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
html.fh textarea,
html.fh select{
  font-family:var(--ff-nav);
  background:transparent;
  color:var(--color_text);
  border:0;border-bottom:1px solid rgba(0,0,0,.18);
  border-radius:0;outline:none;
  transition:border-color .2s ease;
}
html.fh input:focus,html.fh textarea:focus,html.fh select:focus{border-bottom-color:var(--c-red)}
html.fh input::placeholder,html.fh textarea::placeholder{color:rgba(0,0,0,.34)}

/* 表格: 去框线, 只留行间细分隔线(= 极简无卡片) */
html.fh table{border-collapse:collapse}
html.fh th,html.fh td{border:0;border-bottom:1px solid var(--stroke-light)}

/* 分割线 */
html.fh hr{border:0;border-top:1px solid var(--stroke-light)}

/* 「极简无卡片」(2026-09-11 用户选定): 去掉卡片/面板的底色、描边与圆角,
   只留留白。**排除**对话气泡(.ch-msg 一族)与明确的功能性色块 —— 见 §6 说明。 */
html.fh .card,html.fh .panel,html.fh .box,
html.fh [class$="-card"]:not(.cm-card),html.fh [class$="-panel"]{
  background:transparent;border:0;border-radius:0;box-shadow:none;
}

/* 「返回」浮标: account.html / publish.html 各有一个 .bk(position:fixed;top:16px;left:16px;
   z-index:130), 2026-09-11 顶栏全站统一后它正好压在 logo 上。两处都是 body 的直接子元素,
   链接目标也都是 '/' —— 顶栏的 logo 干的是同一件事, 所以隐掉。
   ⚠ 用 `body > .bk` 比裸 `.bk` 稳: 这两页的 .bk 确实都在 body 层, 而 .bk 这名字太通用,
   万一以后内容区里也用, 裸选择器会一起误伤(同 §9 那个 .tl-no 一名两用的坑)。 */
html.fh body > .bk{display:none}

/* ==========================================================================
   §4 深色皮 —— 一个类换一整节
   用法: <section class="skin-dark"> … </section>
   游戏实况整页 / 首页第 3 屏都是它。
   ========================================================================== */
html.fh .skin-dark,
html.fh.skin-dark,
/* `.fh-dark` 是**运行时开关**(首页第 3 屏越中线时 home-fx.js 挂到 <html> 上, 见 §6c)。
   它跟 .skin-dark 走同一套变量, 差别只有"会不会过渡": .skin-dark 是静态的(游戏实况整页),
   .fh-dark 是来回切的, 所以它参与的每个能变的属性都配了 --skin-dur/--skin-ease。 */
html.fh.fh-dark{
  --color_text:#fff;          /* ≡ .skin-dark-mode{--color_text:#fff;--color_bg:#222} */
  --color_bg:#222;
  --stroke-light:var(--stroke-dark);
  /* 金色文字在深皮上翻回浅金 —— 与 :root 的 --c-gold-ink(#8a6a1f) 是一对, 缺一个就两头都读不了 */
  --c-gold-ink:var(--c-gold);
  /* 白底档的同名墨色(见 §2) —— 翻皮时这四条要跟着翻, 否则白字配浅色边框 */
  --sk-line:rgba(255,255,255,.16);
  --sk-dim:rgba(255,255,255,.55);
  --sk-hi:rgba(255,255,255,.8);
  --sk-water:rgba(255,255,255,.24);
  background:var(--color_bg);
  color:var(--color_text);
  transition:background-color var(--skin-dur) var(--skin-ease),
             color var(--skin-dur) var(--skin-ease);
}
/* ⚠ --fh-txt 是**顶栏专用**的墨色, 只在「整页深皮」时才翻白, **不跟着 .fh-dark 翻**。
   为什么: 顶栏底色被 f.css 硬钉成白(html.fh #apeTop.lv-top{background:#fff}, (1,2,1),
   稳压本文件的 html.fh .lv-top{background:var(--color_bg)} (0,2,1))。首页第 3 屏越中线时
   只是**局部**渐暗、顶栏仍是白条 —— 这时若把 --fh-txt 也翻白, 就是白底白字,
   首页/AI/游戏实况/桌宠 四个导航项直接消失。
   真踩过: 线上推完 4-dark 截图里那四个字整片没了。所以从 §4 的共用块里摘出来,
   只留给 .skin-dark(游戏实况整页深皮, 那时顶栏底也真的翻了)。
   顶栏维持用户 09-11 定的「恒定收口」深字白话。 */
html.fh .skin-dark,
html.fh.skin-dark{
  --fh-txt:#fff;
}
/* 深皮里的表单/表格/分割线要跟着翻过来(否则黑底线黑字看不见)。
   ⚠ 每条都写了**两种形态**: `.skin-dark` 在某个 <section> 上(首页第 3 屏)与
   在 <html> 上(游戏实况整页) —— 后者的选择器必须用 `html.fh.skin-dark X` 复合写法,
   `html.fh .skin-dark X`(带空格)只匹配后代, 类落在 <html> 自己身上时一条都不命中。 */
html.fh .skin-dark input,html.fh .skin-dark textarea,html.fh .skin-dark select,
html.fh.skin-dark input,html.fh.skin-dark textarea,html.fh.skin-dark select{
  color:#fff;border-bottom-color:rgba(255,255,255,.24);
}
html.fh .skin-dark input::placeholder,html.fh .skin-dark textarea::placeholder,
html.fh.skin-dark input::placeholder,html.fh.skin-dark textarea::placeholder{color:rgba(255,255,255,.4)}
html.fh .skin-dark th,html.fh .skin-dark td,
html.fh.skin-dark th,html.fh.skin-dark td{border-bottom-color:rgba(255,255,255,.12)}
html.fh .skin-dark hr,html.fh.skin-dark hr{border-top-color:rgba(255,255,255,.12)}
html.fh .skin-dark ::-webkit-scrollbar-thumb,
html.fh.skin-dark ::-webkit-scrollbar-thumb,
html.fh.skin-dark::-webkit-scrollbar-thumb{background:rgba(255,255,255,.24)}
/* 根滚动条: §3 那条是黑拇指(白底时代的), 深皮上等于隐形 —— 用上面这条盖掉。
   scrollbar-color 是根元素属性, 后代选择器对它无效, 必须写在 html 自己身上。 */
html.fh.skin-dark{scrollbar-color:rgba(255,255,255,.24) transparent}

/* ==========================================================================
   §5 顶栏白底皮肤(原 f.css §8, 选择器由 #apeTop 泛化成 .lv-top)
   为什么泛化: 首页顶栏是 apeTop.js 注入的 <header id="apeTop" class="lv-top">,
   8 个内页各自有一份 **静态** <header class="lv-top">(无 id)。
   两边都有 .lv-top 类 → 一条规则同时覆盖两套, 全站顶栏从此只有一处定义。
   特异性 (0,3,1) 稳压 apeTop.js 运行时注入的 (0,1,0) 与 m.css 的 (0,1,0),
   与加载顺序无关(它注入得晚, 但特异性更低)。
   实测值来源: fatfish.ca 1440×900 计算样式(它根字号 14px, 这里已换算成 px)。
   ========================================================================== */
html.fh .lv-top{
  /* --fh-top 由 f.css(桌面) / m.css(窄屏三档) 提供; 内页不加载 f.css →
     这里给一份**与 f.css §2 同值**的 fallback。
     ⚠ 2026-09-11 巡检抓到的真 bug: fallback 原来写 88px(深色时代的老高度), 但同一节里
     logo 是 clamp(60px,8.125vw,117px)、导航是 clamp(22px,2.95vw,42.44px) —— 1440 宽下
     两者都取到满值(117 / 42.44), 塞进 88px 的条里直接**溢出**。
     不能改成在 §2 里声明 --fh-top: 本文件晚于 m.css 加载、两条又同为 `html.fh` 特异性,
     而 @media 不加特异性 → 桌面值会反压 m.css 的窄屏档(§2 那段注释记的就是这个坑)。
     所以走 var() 的 fallback: 窄屏时 m.css 已把 --fh-top 定义成 62/56/52, 走不到这里。 */
  height:calc(var(--fh-top,clamp(92px,11.25vw,162px)) * var(--top-k));
  background:var(--color_bg);
  box-shadow:0 1px 0 rgba(0,0,0,.06);
  position:fixed;top:0;left:0;right:0;z-index:120;
  display:flex;align-items:center;justify-content:space-between;
  padding:0 calc(clamp(24px,5vw,64px) * var(--top-k)) 0 calc(40px * var(--top-k));box-sizing:border-box;
}
html.fh .lv-top::after{background:none}   /* 干掉深色底时代那条白色细线 */

/* nav 间距: 原站 li{margin-left:3.4rem}@14 = 47.6px(配 12.44px 的字)。字号放大后按视口等比。 */
html.fh .lv-top .lv-nav{gap:calc(clamp(20px,2.6vw,40px) * var(--top-k))}
html.fh .lv-top .apc-slot{display:flex;align-items:center}

/* 导航: fatfish 实测 "Roboto Slab" 300 / 12.44px / #222。
   2026-09-11 用户要「字大 30px」→ 12.44 + 30 = 42.44px(1440 及以上满值)。 */
html.fh .lv-top .lv-li{
  font-family:var(--ff-nav);
  font-weight:300;font-size:calc(clamp(22px,2.95vw,42.44px) * var(--top-k));line-height:1;letter-spacing:.04em;
  color:var(--fh-txt);text-decoration:none;cursor:pointer;position:relative;
}
/* 原站导航**悬停不改文字色**, 只出一条红色下划线(≡ .header__main-nav .menu>li>a::after
   的 background-color:#cb413f + scaleX(0), 从右往左拉开)。 */
html.fh .lv-top .lv-li::after{
  content:"";position:absolute;left:0;right:0;bottom:-12px;height:1px;
  background:var(--c-red);background-image:none;
  transform:scaleX(0);transform-origin:right;
  transition:transform .5s cubic-bezier(.83,0,.17,1);
}
html.fh .lv-top .lv-li:hover::after{transform:scaleX(1)}
html.fh .lv-top .lv-on{color:var(--fh-txt)}
html.fh .lv-top .lv-on::after{
  transform:scaleX(1);background:var(--fh-txt);   /* 当前页: 黑色常驻 */
  transition:none;
}

/* 认证位(#apcAcc 里 authnav.js 挂的 .lv-li: 未登录=登录 / 已登录=主页) → fatfish 胶囊 CTA
   ≡ .cta: 本底品牌红, 悬停时金色从左侧滑入盖住它(0.4s cubic-bezier(.76,0,.24,1))。
   金色层用 ::before 做(用两层 background-image + background-position 会因 background-size
   与容器同宽导致百分比定位退化成 0, 金层根本藏不住 —— 实测过)。 */
html.fh .lv-top #apcAcc .lv-li{
  position:relative;z-index:0;overflow:hidden;
  font-family:var(--ff-display);font-weight:900;letter-spacing:.04em;
  font-size:calc(clamp(22px,3.06vw,44px) * var(--top-k));
  color:#fff;border:0;border-radius:999px;
  padding:calc(clamp(9px,1.25vw,18px) * var(--top-k)) calc(clamp(20px,3.75vw,54px) * var(--top-k)) calc(clamp(12px,1.67vw,24px) * var(--top-k));
  background:var(--c-red);
}
html.fh .lv-top #apcAcc .lv-li::before{
  content:"";position:absolute;inset:0;z-index:-1;
  background:var(--c-gold);
  transform:translateX(-101%);
  transition:transform .4s cubic-bezier(.76,0,.24,1);
}
html.fh .lv-top #apcAcc .lv-li:hover::before{transform:translateX(0)}
html.fh .lv-top #apcAcc .lv-li::after{display:none}   /* 胶囊不要下划线 */
html.fh .lv-top #apcAcc .lv-li:hover{color:#fff}

/* logo: 2026-09-12 换成 /img/logo.png(从用户给的「桌宠界面UI设计.png」紧裁到墨迹边 + 白底抠透明)。
   新图字标本就是黑的 → **删掉旧的 filter:brightness(0)**(那是给纯白 aurora.png 用的,
   留着会把整张图连猫一起糊成实心黑块), 负左边距同样归零(新图没有内边距)。
   高度: 旧值 117 是整张画布高(可见字标仅 49px); 新图整张都是墨迹 → 按可见字标 ≈63px 反推 84px。
   完整推导见 f.css 同名段落。 */
html.fh .lv-top .lv-logo{display:block;text-decoration:none;margin-left:0}
html.fh .lv-top .lv-logo img{
  display:block;width:auto;object-fit:contain;
  height:calc(clamp(44px,5.85vw,84px) * var(--top-k));
}

/* ==========================================================================
   §5b 全站红幕转场(≡ fatfish .transition-overlay)
   —— 用户 2026-09-11: 「也要他一样的切换效果」。

   机制(照 fatfish, 但驱动方式换了):
     红横条 = 138vh × 100vh(靠 .tr-inner::before 的 padding-top:72% 撑出 138:100),
     从中心 scale(.04) 铺满 → 漫画贴纸从屏幕外飞入 → 跳转 → 落地首帧幕已满 → 揭开。
     fatfish 用 GSAP + ScrollTrigger 推; 我们**不引 GSAP**, 全部 CSS transition + 两个类。

   三个类:
     .tr-live 帘子在台上(visibility:visible) —— 与「满不满」解耦, 否则揭开时幕会瞬没
     .is-on   帘子铺满 / 贴纸到位
     .no-anim 关掉过渡(落地首帧用: 幕必须一上来就是满的, 不能看到"铺开")

   首帧防闪: html.transit-on 由 chrome.js 在 <head> 同步段加上, 配下面这条 ::before
   红幕 —— 与 intro.js 的开屏白幕同一套路(那条在 index.html 的 head 里)。
   转场落地时 intro.js **必须让路**, 否则「红幕揭开 → 又一张白幕开屏」, 见 intro.js。
   ========================================================================== */
html.fh.transit-on::before{
  content:"";position:fixed;inset:0;z-index:1999;background:var(--c-red);
}
html.fh #ffTransit{
  position:fixed;inset:0;z-index:2000;pointer-events:none;overflow:hidden;
  visibility:hidden;
}
html.fh #ffTransit.tr-live{visibility:visible}
html.fh #ffTransit .tr-inner{
  position:absolute;top:50%;left:50%;
  min-width:138vh;background:var(--c-red);
  transform:translate(-50%,-50%) scale(.04);
  transition:transform .46s cubic-bezier(.76,0,.24,1);
}
html.fh #ffTransit .tr-inner::before{content:"";display:block;padding-top:72%}
html.fh #ffTransit.is-on .tr-inner{transform:translate(-50%,-50%) scale(1)}
/* 贴纸: 5 列网格(≡ fatfish 每行 5 个), 每格从屏幕外飞入。方向/距离/延迟由 chrome.js
   按行列算好写进 --fx/--fy/--fr/--fd, 这里只管过渡。 */
html.fh #ffTransit .tr-imgs{
  position:absolute;left:50%;top:0;transform:translateX(-50%);
  width:106%;height:106%;display:flex;flex-wrap:wrap;justify-content:space-between;
}
html.fh #ffTransit .tr-cell{
  width:18%;margin:1%;display:flex;align-items:center;justify-content:center;
  transform:translate(var(--fx,0),var(--fy,0)) rotate(var(--fr,0deg));
  opacity:0;
  transition:transform .5s cubic-bezier(.19,1,.22,1),opacity .26s ease;
  transition-delay:var(--fd,0s);
}
html.fh #ffTransit.is-on .tr-cell{transform:translate(0,0) rotate(var(--fr,0deg));opacity:1}
html.fh #ffTransit .tr-cell img{width:100%;height:auto;display:block}
/* src 留空的槽位: 虚线框 + 「空槽」标记(与首屏 ?fstickers=1 的做法一致) */
html.fh #ffTransit .tr-cell.is-empty{
  border:2px dashed rgba(255,255,255,.45);border-radius:4px;aspect-ratio:1;
}
html.fh #ffTransit .tr-cell.is-empty::after{
  content:"空槽";color:rgba(255,255,255,.62);font-size:11px;letter-spacing:.1em;
}
html.fh #ffTransit.no-anim .tr-inner,
html.fh #ffTransit.no-anim .tr-cell{transition:none}
/* 用户系统开了「减少动态效果」→ 整场转场关掉, 直接跳(见 chrome.js) */
@media (prefers-reduced-motion:reduce){
  /* 原来这条是 content:none —— 结果连"首帧幕布"一起没了, 落地页第一帧直接是**裸 SSR**
     (旧深色顶栏 + 空 body), 用户报的「一帧之前网页的样子」在这一档最明显(2026-09-12)。
     现在不演红幕, 但改用开屏同色 #222 盖住, 等 .ready(新版首屏就位)再摘。 */
  html.fh.transit-on::before{background:#222}
  html.fh #ffTransit .tr-inner,
  html.fh #ffTransit .tr-cell{transition:none}
}

/* ==========================================================================
   §5c 汉堡按钮 + 全屏浮层 —— **2026-09-12 已整体删除**
   --------------------------------------------------------------------------
   这里原来有两块: `.fh-burger`(原 f.css §9 的泛化副本) 与 `#fhMenu`(全屏白浮层,
   原 f.css §10 的泛化副本), 2026-09-11 tier6「顶栏全站统一」时搬进来的。
   用户 2026-09-12:「汉堡全屏菜单整个删掉, 桌面和手机都不要」→ 连同 f.css §9/§10、
   apeTop.js 里的 HTML 与交互一起删干净了。**别加回来。**

   窄屏的导航现在在**侧边抽屉 `#fhDrawer`** 里, 皮在本文件末尾 §10;
   桌面顶栏只剩「logo + 四个导航 + 胶囊」。

   ⚠ 留一条**还有用的旧账**, 下次动顶栏还会撞上:
   选择器带不带 id 是生死问题。当年 `html.fh #apeTop .fh-burger` 是 (1,2,1),
   压过本文件的 `html.fh .lv-top .fh-burger` (0,3,1) —— **@media 不增加特异性**,
   所以"窄屏那条隐藏"形同虚设。同一笔账今天仍然成立: §8 三档那份 `html.fh .lv-top{…}`
   只有 (0,3,1), 压不过 f.css §8 的 `html.fh #apeTop.lv-top` (1,2,1)
   —— 这就是 §10 的窄屏覆盖一律写成 `html.fh header#apeTop.lv-top` (1,2,2) 的原因。
   ========================================================================== */

/* ==========================================================================
   §6 通用构件
   ========================================================================== */

/* 胶囊 CTA(≡ .cta{--cta_padding:.5rem 1.5rem .7rem;font-size:1rem;color:#fff}) */
html.fh .cta-pill,html.fh .fh-cta{
  display:inline-block;font-family:var(--ff-display);font-weight:900;
  font-size:14px;line-height:1.2em;letter-spacing:.04em;
  padding:7px 21px 10px;border-radius:98px;
  color:#fff;background:var(--c-red);text-decoration:none;
  transition:background-color .25s ease;
}
html.fh .cta-pill:hover,html.fh .fh-cta:hover{background:#b83836;color:#fff}

/* 大段文字(≡ .u-body-lg{font-size:2rem;font-weight:200}) */
html.fh .body-lg{font-family:var(--ff-nav);font-size:var(--fs-body-lg);font-weight:200;line-height:1.5}

/* 手写金色副标题(≡ .u-subtitle-cursive{font-size:3.5555rem;color:#cab99a})
   fatfish 原用 GuthenBoots 商业花体 → 系统手写体兜底(中文落黑体栈)。
   ⚠ 用 --c-gold-ink 不是 --c-gold: 这是**文字**, 白底上浅金 1.92:1 读不了(巡检实测),
   而这条规则同时被首页第 2 屏(白底)和第 3 屏(深皮)用到 —— 只有会跟皮翻的 ink 两头都对。 */
html.fh .cursive{
  font-family:"Segoe Script","Bradley Hand","Comic Sans MS",cursive,var(--ff-cjk);
  font-size:var(--fs-cursive);color:var(--c-gold-ink);line-height:1.3;
  /* 自带 color → 翻皮不会自动过渡(自定义属性赋值是瞬时的)。补一条, 与 §6c 的 .fh-dark 配套。 */
  transition:color var(--skin-dur) var(--skin-ease);
}

/* 章节头(≡ fatfish .section-header): 大标题居中 + 手写副标题在下方右侧 */
html.fh .section-head{text-align:center;padding:0 0 56px}
html.fh .section-head__title{
  margin:0 auto;width:max-content;max-width:100%;
  font-family:var(--ff-display);font-weight:900;line-height:1.06;
  font-size:clamp(34px,6.2vw,88px);letter-spacing:.01em;text-transform:uppercase;
}
html.fh .section-head__title strong{font-weight:900;text-decoration:underline;
  text-decoration-thickness:4px;text-underline-offset:6px;text-decoration-color:var(--c-gold)}
html.fh .section-head__sub{margin:14px 0 0;font-weight:400}

/* 长句标题档(.is-prose, 由 f-home.js 的 projTitle(lines, prose) 挂上):
   当章节标题是一整句长文而不是 3 行短横排时用。**只改"能不能折行"和行错落,
   字体/字号/颜色一个字不动** —— 见 f-home.js 里 FH.projects.titleProse 的注释。
   两条都必须写, 缺一条就出事:
     · 第 1、2 条 缺了就横向溢出: §6c ④ 的 `html.fh .fx-tl{white-space:nowrap}`(≥750px)
       会把 39 字撑成 ~3467px 的单行; 同处 `:nth-child(1){margin-left:-10%}` 的错落是给
       5~7 字短行配的, 压到长句上会把首行顶出 .fh-projects 的 overflow:hidden 左边缘。
   选择器特异性都比被覆盖的那两条高(5 类 > 4 类), 放这儿不依赖源序。 */
html.fh .section-head__title.is-prose{width:auto;max-width:100%}
html.fh .section-head__title.is-prose .fx-tl{white-space:normal}
html.fh .section-head__title.is-prose .fx-tl:nth-child(1),
html.fh .section-head__title.is-prose .fx-tl:nth-child(2){margin-left:0;text-align:center}
/* 第 3 条: 关掉 home-fx.js ④ 的**逐行横向错落**。
   那个 scrub 写的是 `translateX(±%)`, **百分比按元素自身宽度算** —— 标题窄(≈704px)时
   ±25~35% 才 ±176~246px, 好看着; 满宽(1376px)之后同样的百分比变成 ±482px, 直接把标题
   顶出 .fh-projects 的 overflow:hidden。而且它本来就是**给多行错落配的**(TX 表 5 档),
   prose 标题只有一行, 没有任何一行可以"错"。
   用 !important 是因为位移是 home-fx.js 每帧写的**内联** transform —— 不写就压不住。
   (这样 home-fx.js 一个字不用动, 也就不会碰到它给首屏三行写的那条 scrub。) */
html.fh .section-head__title.is-prose .fx-tl{transform:none!important}
/* 窄屏再让一档**字号**(字体族不动): 基础 clamp 的 34px 下, 10 字一行要 343px, 而 390px
   屏里只有 342px —— 差 1px 就掉一个「议，」到下一行, 360px 屏更糟。降到 28px 后 10 字
   = 284px, 两种窄屏都稳。**只影响 .is-prose 这一档**, 别的章节标题一个字不动。 */
@media (max-width:749px){
  html.fh .section-head__title.is-prose{font-size:clamp(22px,7.2vw,34px)}
}

/* ==========================================================================
   §6b 首页第 2 / 3 屏(≡ fatfish.ca 首页往下滚的第 2、3 段)
   —— 用户 2026-09-11: 「第二页和第三页, 你自己模仿着做一下, 差不多的,
      然后也要他一样的切换效果」。这里做的是「排版」; 「切换效果」在 chrome.js §5。

   两屏都由 f-home.js 挂到 <html> 层(与 #fHero 同一套路 —— 躲 React 水合)。
   纵向落点不用算: body 里那个 .SectionHomepageHero 空壳本身就占满 0..100svh,
   所以挂在 <html> 上的静态节点天然从 100svh 起排队, 正好接在第 1 屏下面。

   旧内容流退役: .SectionGridCarousel 只 **CSS 隐、标记不删** —— 它是 React SSR
   渲染出来的, 删节点会让水合对不上(#418)。它的数据源(/api/posts)改由第 3 屏
   自己拉, 见 f-home.js buildProjects()。
   ========================================================================== */
html.fh .SectionGridCarousel,
html.fh .SectionDiscoverApps,
html.fh footer.MainFooter{display:none!important}
/* main 自带 bg-new-ape-dark-navy(#030a21): 第 1 屏底下那片深藏青。新设计里
   第 1 屏要直接淡进第 2 屏的白底, 所以把它拿掉(留着会让 hero 的渐变尾露一条深色)。 */
html.fh main{background:transparent!important}

/* —— 第 2 屏: 白底居中自述(≡ fatfish .home-intro 下面那段 u-body-lg) —— */
html.fh .fh-about{
  /* **第 2 屏专属的字号旋钮**(2026-09-12 用户「第二页字体变大」)。
     只作用于本屏三块字: 手写副标题 / 正文 / 邮箱按钮 —— 见下面三条 .fh-about 后代规则。
     ⚠ 为什么必须写成本屏局部变量而不是直接改 --fs-body-lg / --fs-cursive:
       `--fs-cursive` 还被**第 3 屏**的章节副标题(.section-head__sub, f-home.js:469)共用,
       直接改会连带把第 3 屏的「真的。」一起放大。
     改大小 = 改这一个数(窄屏档在 §7 末尾的 @media 里另有更小一档, 防止副标题折行)。 */
  --about-k:1.3;
  background:var(--color_bg);color:var(--color_text);
  /* ⚠ 2026-09-13 晚 用户「第一页第二页第三页第四页分开大一点，现在距离太近了」
     → 本屏上下留白一起抬（原 `clamp(72px,9vw,150px)` / `clamp(64px,7.5vw,120px)`）。
     1440 实测：上 129.6→216（+86），下 108→201.6（+94）。
     上边这块推开的是**首屏底缘 → 本屏第一行字**，下边这块推开的是**本屏邮箱按钮 → 第 3 屏标题**，
     两屏各推各的、中间的空隙是两者相加 —— 要调"两页离多远"就调这两个数。 */
  padding:clamp(120px,15vw,240px) 24px clamp(110px,14vw,220px);
  text-align:center;position:relative;
  /* ⚠ 两屏都必须自己写 transition: .fh-dark 翻的是 --color_bg, 没有这条的屏会**瞬切**,
     于是"一页白一页黑"的老毛病会从"分屏"变成"分屏+硬切", 比原来还难看。
     子元素里凡是自带 color 的(.cursive/.p2-meta/…)也各自要一条, 见下。 */
  transition:background-color var(--skin-dur) var(--skin-ease),
             color var(--skin-dur) var(--skin-ease);
}
/* 900 → 1240(2026-09-12): 用户要"一句话一行"。原来 900px 装不下目前最长的那句
   (33 字 × 36.4px ≈ 1090px), 它会折成"…非常欢迎 / 你的加入哦~"这种五行两截的孤字行。
   副标题与邮箱按钮都是居中短文本, 放宽**看不出区别** —— 受影响的只有正文的折行位置。
   (1024 及以下仍会折行, 那是视口宽度决定的, 不是这条。) */
html.fh .fh-about__wrap{width:min(1240px,100%);margin:0 auto}
/* 正文: 漫画体 + **一句话一行**(2026-09-12 用户「可以长短不一, 可以一句话一行」)。
   ⚠ 四行仍然是**同一个元素**里用 <br> 硬换行, 不是四个 <p> ——
     home-fx.js 的逐行升起只 `querySelector('.body-lg')` 抓**第一个**, 拆成四个 <p> 的话
     后三行永远不动(且各自 26~38px 的下外边距会把行距撑成两倍)。
   ⚠ line-height 1.6(原 1.5): 快乐体字面小、笔画蓬, 1.5 会显得挤。
   ⚠ font-weight 400(原 200): 这字体只有一档, 写 200 不会变细也不会报错, 只是没意义。 */
html.fh .fh-about .body-lg{
  font-family:"ZCOOLKuaiLe",var(--ff-nav);font-weight:400;line-height:1.6;
  font-size:calc(var(--fs-body-lg) * var(--about-k));margin:0 0 clamp(26px,3vw,38px)}
html.fh .fh-about .cursive{
  display:block;font-size:calc(var(--fs-cursive) * var(--about-k));margin:0 0 6px}
html.fh .fh-about__cta{margin:0}
/* 邮箱按钮: 字号与内边距一起按 --about-k 走, 只放大字不放大壳会让胶囊变成"紧箍咒"。
   14px 基准 = §5 那条 .fh-cta 的原始值; 内边距比例(7/21/10)照抄, 不碰共用那条规则
   (`.cta-pill` 顶部登录钮也在用它的 padding)。 */
html.fh .fh-about .fh-cta{
  font-size:calc(14px * var(--about-k));
  padding:calc(7px * var(--about-k)) calc(21px * var(--about-k)) calc(10px * var(--about-k));
}
/* 漫画风章节角标(§7 .cm-burst 的爆炸框 + 编号) —— 点缀位, 不碰正文 */
html.fh .fh-about__badge{
  width:66px;height:66px;margin:0 auto clamp(20px,2.6vw,30px);
  display:flex;align-items:center;justify-content:center;
  background:var(--c-gold);color:#1a1a1a;
  font-family:var(--ff-display);font-weight:900;font-size:22px;letter-spacing:.02em;
}

/* —— 第 3 屏: 章节头 + 项目卡 + 超大描边跑马灯 ——
   底色**不再固定深皮**: 它跟着 .fh-dark 走 —— 未越中线时是白底(与第 2 屏连着的一片白),
   越中线后 475ms 渐成 #222。这正是用户 2026-09-11 要的「背景再变暗, 不是一页一个颜色」。 */
html.fh .fh-projects{
  background:var(--color_bg);color:var(--color_text);
  /* 上留白 150→240 上限（1440 实测 129.6→216）：和上面 .fh-about 的下留白一起，
     把**第 2 屏的邮箱按钮**和**第 3 屏的标题**拉开。底部仍是 0 —— 跑马灯就该贴到页脚。 */
  padding:clamp(120px,15vw,240px) 0 0;position:relative;overflow:hidden;
  transition:background-color var(--skin-dur) var(--skin-ease),
             color var(--skin-dur) var(--skin-ease);
}
/* 章节头与项目卡之间（= 用户说的"第 3 页"与"第 4 页"之间）的留白：
   2026-09-13 晚 第一轮 72→130 上限（1440 实测 72→129.6）；
   同晚第二轮 用户「最下边的图文是投稿的地方，这是第四页，和第三页的文字分开一点」
   → 再看一段：72/9vw/130 → **110/13vw/200**（1440 实测 129.6→187.2，+57.6px）。
   ⚠ 用户眼里的「第四页」= 文档流里的图文卡（#fhProjGrid），**不是** <section>
     —— 全站只有 3 个 section，第 3/4 屏都在 #homeProjects 里（量法见 `_secgeo.js`）。 */
html.fh .fh-projects .section-head{padding:0 24px clamp(110px,13vw,200px)}
html.fh .fh-proj-grid{
  width:min(1400px,86vw);margin:0 auto;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));
  gap:clamp(16px,2vw,28px);
}
html.fh .fh-proj-state{
  grid-column:1/-1;margin:0;padding:48px 0;text-align:center;
  color:var(--sk-dim);font-size:14px;letter-spacing:.2em;
}
/* 卡: 收回「极简无卡片」(§3 那条已把 .p2-post 的底/圆角去掉), 改用
   一条 1px 细线 + 悬停转品牌红 —— 与 fatfish 的卡观感一致。
   ⚠ border-color 这里**故意不跟 --skin-dur**: 同一条 transition 悬停变红也要用,
   拉到 475ms 会让 hover 变迟钝。代价是翻皮那一下 1px 细线的墨色是瞬切的 ——
   白 16% ↔ 黑 16% 在渐暗的底色上都近乎不可见, 不值得为它牺牲 hover。 */
html.fh .fh-projects .p2-post{
  border:1px solid var(--sk-line);border-radius:0;
  background:transparent;color:var(--color_text);
  transition:border-color .25s ease,transform .25s ease,
             color var(--skin-dur) var(--skin-ease);
}
html.fh .fh-projects .p2-post:hover{
  border-color:var(--c-red);transform:translateY(-3px);box-shadow:none;
}
html.fh .fh-projects .p2-shot{aspect-ratio:4/3}
html.fh .fh-projects .p2-kb{
  background:var(--c-red);border:0;border-radius:0;color:#fff;
  font-family:var(--ff-display);font-weight:900;
  font-size:11px;letter-spacing:.12em;text-transform:uppercase;padding:4px 10px 5px;
}
html.fh .fh-projects .p2-tt{
  font-family:var(--ff-nav);font-weight:400;font-size:17px;line-height:1.45;min-height:0;
}
/* 这两条自带 color(不继承 .fh-projects), 所以翻皮时不会跟着过渡 —— 各补一条。
   ≡ fatfish 给 .u-title-multiline__line 单写 transition:color 475ms 的同一手法。 */
html.fh .fh-projects .p2-meta{color:var(--sk-dim);
  transition:color var(--skin-dur) var(--skin-ease)}
html.fh .fh-projects .p2-auth{color:var(--sk-hi);
  transition:color var(--skin-dur) var(--skin-ease)}

/* 超大描边跑马灯(≡ fatfish .home-projects__marquee-title + :hover 填色)。
   纯 CSS 位移, **不引 GSAP**; 轨道放两遍词 → 位移 -50% 正好无缝接上。 */
html.fh .fh-marquee{
  /* 2026-09-13 晚 用户：「和最下边的 warframe stea 也分开一点」——
     "warframe stea" = 这条跑马灯的头两个词（WARFRAME / STEAM，见 f-home.js 的 FH.marquee），
     它是文档最底下那块。56/7vw/110 → **80/10vw/160**（1440 实测 100.8→144，+43.2px）。
     ⚠ 这里动的是 marquee 的 margin-top，所以它那条 `border-top` 细线跟着一起下来 ——
       拉开的是「图文卡 ↔ 细线」的距离；要让"线不动、只把字挤下去"得改内层 padding。 */
  margin-top:clamp(80px,10vw,160px);padding:clamp(18px,2.6vw,40px) 0;
  border-top:1px solid var(--sk-line);overflow:hidden;
}
html.fh .fh-marquee__track{display:flex;width:max-content;animation:fh-marquee 26s linear infinite}
html.fh .fh-marquee__item{
  font-family:var(--ff-display);font-weight:900;text-transform:uppercase;
  font-size:clamp(64px,13vw,190px);line-height:1;letter-spacing:.01em;
  padding:0 .16em;color:transparent;cursor:default;
  /* 描边态。fatfish 深皮用 #434343, 但那是叠在它自己的 #222 上、字又极大;
     实测照抄到我们这边太糊(≈1.4:1), 提一档到 24% —— 仍是"描边字"观感。 */
  -webkit-text-stroke:1px var(--sk-water);
  transition:color .35s ease,-webkit-text-stroke-color .35s ease;
}
html.fh .fh-marquee__item:hover{color:var(--c-red);-webkit-text-stroke-color:var(--c-red)}
@keyframes fh-marquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){html.fh .fh-marquee__track{animation:none}}

/* 窄屏: 第 2 屏缩字号(§8 已给 --fs-body-lg), 第 3 屏改单列、跑马灯降速 */
@media (max-width:960px){
  html.fh .fh-proj-grid{width:auto;padding:0 20px;grid-template-columns:repeat(auto-fill,minmax(210px,1fr))}
  /* 窄屏的 --about-k 单独一档: 基础字号本来就被 §8 压小过, 再乘 1.3 会让副标题在 390px 上
     折成两行(26px × 12 字 ≈ 312px 刚好一行, ×1.3 = 405px 就漏了)。1.15 仍是一行(≈299px)。 */
  html.fh .fh-about{padding-left:20px;padding-right:20px;--about-k:1.15}
}
@media (max-width:560px){
  html.fh .fh-proj-grid{grid-template-columns:1fr 1fr;gap:12px}
  html.fh .fh-projects .p2-tt{font-size:15px}
  html.fh .fh-about__badge{width:54px;height:54px;font-size:18px}
}

/* ==========================================================================
   §6c 首页第 2/3 屏的「切换效果」 —— 文字错开 + 背景渐暗
   用户 2026-09-11: 「第二页到第三页的时候文字会错开, 背景再变暗, 不是现在一页一个颜色」
                   「首页到第二页也是文字会错开」

   —— 对照 fatfish.ca 挖出来的三件事(全部逐字读过它的 fe.js/fe.css) ——
   ① 背景渐暗: 见 §2 的 --skin-dur/--skin-ease 与 §4 的 .fh-dark。
   ② 第 2 屏正文错开上升(ff_register_scroll_trigger_animation(".home-about .wysiwyg")):
        把正文切成 words+lines, 每个**行**外壳 overflow:hidden, 然后
        `from({y:"100%", rotate:±5deg, stagger:±0.06})`, duration .7, ease expo_out_default,
        **偶数行 +5° / 奇数行 -5°**, 且奇数行的 stagger 取负(= 从最后一个词先动)。
        行与行之间 `"<+=0.02"` —— 后一行比前一行晚 20ms 起跑, 所以是"错开"而不是齐动。
        播完 `revert()` —— 拆开的 DOM 还原成原样(所以选中/复制不受影响)。
   ③ 手写副标题逐字弹入(`.u-ff-cursive, .u-text-cursive, .u-subtitle-cursive`):
        `fromTo(chars,{scale:0},{scale:1,duration:.6,ease:"Power4.easeOut",stagger:.05})`,
        字多(>40)时压到 .5s / stagger .022。
   ④ 第 3 屏大标题横向错开(`.u-title-multiline`): 桌面档不是入场动画, 而是
        **scrub 驱动的逐行横向位移** —— 行的 x 随滚动从 i 走到 o, 每行数值都不同:
          第1行 -25%→35%  第2行 30%→-30%  第3行 -30%→5%  第4行 10%→-5%  第5行 0→10%
        (所以"错开"是**一直在动**的, 不是播一次就停)。另有静态偏移
        `:nth-child(1){margin-left:-10%}` `:nth-child(2){text-align:right;margin-left:10%}`。
   ⑤ 首屏三行大字在第 1 屏→第 2 屏时左右错开滑出(用户 2026-09-11「第一个翻到第二页的时候
        第一页文字也有变化呀」)。≡ fatfish ScrollTrigger[1]: start=0 end=569 scrub:.2 ease:none,
        行1 x:0→-14rem / 行2 x:0→0 / 行3 x:0→+14rem —— 又是 scrub, 也跟手。见下面的 ⑤ 小节。

   —— 为什么这里全是 CSS transition 而不是引 GSAP ——
     GSAP 只在这几处出场, 为它引 70KB 不值当。逐行/逐字错开本来就能拆成
     "每个元素一条 transform + 各自的 transition-delay", 与 GSAP 的时间轴等价;
     scrub 那条用一条 200ms linear 的 transform transition 近似(每帧改目标值 =
     一阶滞后, 与 GSAP scrub:.2 的手感一致)。**不引 GSAP 是本节的硬约定。**
   ========================================================================== */

/* —— ④ 大标题: 一行的包裹层(由 f-home.js 的 projTitle() 生成, 替掉原来的 <br>) —— */
html.fh .fx-tl{
  display:block;
  /* scrub 的滞后。roll 起来 = 每帧改目标值, 过渡从当前插值处续上 → 一阶低通, ≡ scrub:.2 */
  transition:transform .2s linear;
}
@media (min-width:750px){
  /* 桌面才做横向错开: 窄屏上 nowrap 会把大标题顶出屏外(§8 三档的版式会被压坏)。
     fatfish 在窄屏走的是另一套(逐行从左右 ±120% 滑入), 我们**不做** —— 手机档保持静止。 */
  html.fh .fx-tl{white-space:nowrap}
  html.fh .section-head__title .fx-tl:nth-child(1){margin-left:-10%}      /* ≡ fatfish 原值 */
  html.fh .section-head__title .fx-tl:nth-child(2){text-align:right;margin-left:10%}
}

/* —— ⑥ 第 3 屏大标题: 两行**从左右两边推进**(≡ ribbit.dk 的 Curious / Fullservice) ——
   用户 2026-09-13 晚:「第三页的 如果对我们有什么反馈或者建议，可以在下边投稿哦~ 这句话
   加一个翻到这一页的效果，可以看 ribbit.dk 这个网页的 Curious 和 Fullservice 这两个词,
   一个一行，从左右两边推进了，咱们可以不做人物推，只要文字这样进场就行」。
   第 1 行从左、第 2 行从右，同时(差 90ms)推进到中间，**只做位移不做透明度**——
   ribbit 就是纯推，没有淡入，别"顺手加个 fade"。
   ⚠⚠ 这里**必须用独立的 `translate` 属性，不能用 `transform`**：本标题是 .is-prose，
     上面那条 `html.fh .section-head__title.is-prose .fx-tl{transform:none!important}`
     把 transform 打死了；何况 home-fx.js ④ 的 titleTick() 每帧还在往 .fx-tl 写内联 transform。
     `translate` 与 `transform` 是两个独立属性，`transform:none` 管不着它 —— 这正是能共存的原因。
   ⚠⚠⚠ **`transition` 只准写在 `.fx-sl-in` 这条上，绝不能写在基础规则上** ——
     这是 2026-09-13 上线后用户回「翻到第三页的时候没有看到文字的动效」的真因。
     写在基础规则上时，`fx-sl` 推出去这一步**自己也被过渡**；home-fx.js 是**同一拍**
     加完两个类（中间只隔一次 `void offsetHeight`），于是 `fx-sl-in` 把**还在第 0 帧**的
     那条过渡直接改靶到 0 —— 净位移恒为 0，**从头到尾一动不动**（实测每拍 `translate=0px`）。
     挪到 `.fx-sl-in` 上之后：加 `fx-sl` 时**没有过渡声明 → 瞬移到界外**（此刻标题刚露头
     1px，看不见），隔一次回流再加 `fx-sl-in` → 目标态那条**自带过渡** → 正常推进。
     ⭐ 一般规律：**"瞬移到起点 + 过渡回终点"必须让起点那一步没有过渡**，
     否则两步在同一帧内被合并。⚠ 别用"在两次加类之间 setTimeout"来绕 ——
     那样动画每次都在滚到位之后**再等一会儿**才开始，正确的做法是让起点态无过渡。
   ⚠ 起始位移只写在 `.fx-sl`(已武装)且**还没** `.fx-sl-in` 时；两条对 .fx-tl 的特异性同分
     (1,5,1)，**靠源序分胜负 → `.fx-sl-in` 那条必须在最后**(同 §6c ② `.fx-w` 的坑，别调顺序)。
   ⚠ **不移除这两个 class**(演完就留着)：本动画不拆 DOM、终点即默认态，留着可保证
     不会有"摘 class 那一帧位移回跳"；别的入场动画要摘是因为它们把 DOM 换成行/字了。
   ⚠ 距离上限 620px 不是随手写的：`.fh-projects` 是 `overflow:hidden`，位移太大整行会被裁到
     屏外，观感就从"推进来"变成"凭空出现"。下限 220px 是给 390 窄屏留的可见位移。 */
html.fh #homeProjects .section-head__title .fx-tl{
  --fx-slide:clamp(220px,42vw,620px);
}
html.fh #homeProjects .section-head__title.fx-sl .fx-tl:nth-child(1){translate:calc(-1 * var(--fx-slide)) 0}
html.fh #homeProjects .section-head__title.fx-sl .fx-tl:nth-child(2){translate:var(--fx-slide) 0}
html.fh #homeProjects .section-head__title.fx-sl.fx-sl-in .fx-tl{
  translate:0 0;
  transition:translate 1s var(--fx-ease) var(--fx-d,0ms);
}

/* —— ⑤ 第 1 屏三行大字: 往下滚时左右错开滑出 ——
   ≡ fatfish ScrollTrigger[1]: trigger=<body> start=0 end=569 scrub:.2 ease:none,
   三条补间 x: 0→-14rem / 0→0 / 0→+14rem; 569 = 它 .expertises-marquees 的绝对底边。
   数值与判定全在 home-fx.js 的 heroTick(); 这里只给那条 scrub 的一阶滞后。
   行元素本身没有任何 transform(f.css:116 只有 display:flex), 所以内联位移不会打架。 */
html.fh #fHero .expertises-marquees__expertise{
  transition:transform .2s linear;      /* ≡ scrub:.2, 与 ④ 的 .fx-tl 同一手法 */
}

/* —— ② 正文逐行错开上升 —— */
html.fh .fx-l{display:block;overflow:hidden}      /* 行外壳: 裁掉还没升上来的词 */
html.fh .fx-w{display:inline-block}               /* transform 对非替换 inline 无效, 必须 inline-block */
html.fh .fx-run .fx-w{
  transform:translateY(110%) rotate(5deg);        /* 偶数行(1-indexed) +5° */
  transition:transform var(--fx-rise-dur) var(--fx-ease) var(--fx-d,0ms);
}
html.fh .fx-l.fx-alt .fx-w{transform:translateY(110%) rotate(-5deg)}   /* 奇数行 -5° */
/* ⚠ 这三条必须**按此顺序**写: 前两条特异性都是 (0,4,1), 靠源序分胜负, .fx-in 必须在最后。 */
html.fh .fx-run.fx-in .fx-w{transform:none}

/* —— ③ 手写副标题逐字弹入 —— */
html.fh .fx-c{display:inline-block}
html.fh .fx-run .fx-c{
  transform:scale(0);
  transition:transform var(--fx-pop-dur) cubic-bezier(.165,.84,.44,1) var(--fx-d,0ms);  /* ≡ Power4.easeOut */
}
html.fh .fx-run.fx-in .fx-c{transform:none}

/* 精确的 expo_out_default(§2 说明)。不支持的浏览器忽略整条 @supports, 落到 --fx-ease 的兜底。 */
@supports (transition-timing-function:linear(0,1)){
  html.fh{--fx-ease:linear(0.000,0.272,0.465,0.609,0.717,0.796,0.850,0.890,0.922,0.943,0.957,
          0.968,0.975,0.982,0.986,0.990,0.993,0.996,0.997,0.999,0.999,1.000,1.000)}
}

/* ⚠ 这里**故意没有** prefers-reduced-motion 分支(2026-09-11 用户「还是直接变色的」后删掉)。
   原来那一版写成「减动效时把过渡全掐掉、只留翻皮」, 结果是: 背景从白**瞬切**成 #222,
   第 3 屏大标题 transform:none 一动不动 —— 用户在自己的机器上(Windows 关掉了
   「动画效果」→ Chrome 报 prefers-reduced-motion:reduce)看到的就是这一版, 于是报
   「还是直接变色、文字没有左右错位」。
   判据: **原站 fatfish.ca 压根不认这个开关** —— 它的 GSAP 时间轴与 .page-background 的
   475ms 过渡对 reduce 用户照跑不误。用户要的是「和他一样的切换效果」, 所以这里对齐原站,
   动作对所有人生效。真机实测: no-preference 下我们 x=[-171,168,-187] vs 原站 [-183,198,-220],
   同形同相(视口 1440、标题宽 622 vs 732, 折算后 -27% vs -25%)。
   (唯一的例外留给了 §6 的跑马灯那条无限循环 —— 那不是"跟手"的动效, 是真·自走动画。) */

/* ==========================================================================
   §7 漫画风点缀(用户 2026-09-11: 「也可以在他的基础上加一点漫画风」)
   ⚠ 红线: 只用在**点缀位** —— 转场贴纸 / 跑马灯 / 章节标题 / 卡片角标。
     正文、表格、表单一律干净, 否则整站会变成廉价手绘风。
   ========================================================================== */

/* 粗描边字(漫画标题感)。paint-order 让描边落在填充之下, 笔画才不会被吃掉。 */
html.fh .cm-ink{
  -webkit-text-stroke:3px #111;
  paint-order:stroke fill;
}
html.fh .cm-ink--light{-webkit-text-stroke-color:#fff}

/* 网点(halftone): 漫画背景最典型的质感 */
html.fh .cm-dot{
  background-image:radial-gradient(currentColor 1.2px,transparent 1.3px);
  background-size:8px 8px;
}

/* 爆炸框 / 吼叫框轮廓 */
html.fh .cm-burst{
  clip-path:polygon(50% 0,61% 34%,97% 22%,79% 51%,100% 68%,68% 69%,72% 100%,
                    50% 78%,28% 100%,32% 69%,0 68%,21% 51%,3% 22%,39% 34%);
}

/* 贴纸通用手感: 白描边外圈 + 轻微投影, 让它"贴"在底上 */
html.fh .cm-sticker{
  filter:drop-shadow(2px 2px 0 #fff) drop-shadow(2px -2px 0 #fff)
         drop-shadow(-2px 2px 0 #fff) drop-shadow(-2px -2px 0 #fff)
         drop-shadow(0 4px 10px rgba(0,0,0,.22));
}

/* 拟声词(漫画里那种手写爆音字) */
html.fh .cm-boom{
  font-family:var(--ff-display);font-weight:900;text-transform:uppercase;
  color:var(--c-gold);-webkit-text-stroke:3px #111;paint-order:stroke fill;
  transform:rotate(-8deg);display:inline-block;
}

/* ==========================================================================
   §8 窄屏三档(960 / 560 / 400)
   必须与 m.css 的 .lv-top 高度(62/56/52)与字号(16/14/13)保持**同一组数值** ——
   本文件晚于 m.css 加载且特异性更高, 谁赢都该是同一个值。
   改这里务必顺手改 m.css, 反之亦然。
   ========================================================================== */
@media (max-width:960px){
  html.fh .lv-top{height:calc(62px * var(--top-k));padding:0 calc(12px * var(--top-k)) 0 calc(16px * var(--top-k))}
  html.fh .lv-top .lv-logo{margin-left:0}
  html.fh .lv-top .lv-logo img{height:calc(44px * var(--top-k))}
  html.fh .lv-top .lv-nav{gap:calc(16px * var(--top-k))}
  html.fh .lv-top .lv-li{font-size:calc(16px * var(--top-k));letter-spacing:.04em}
  html.fh .lv-top #apcAcc .lv-li{font-size:calc(16px * var(--top-k));padding:calc(7px * var(--top-k)) calc(15px * var(--top-k)) calc(8px * var(--top-k))}
  html.fh{--fs-body-lg:20px;--fs-cursive:32px;--g-pad:20px}
}
@media (max-width:560px){
  html.fh .lv-top{height:calc(56px * var(--top-k));padding:0 calc(10px * var(--top-k)) 0 calc(12px * var(--top-k))}
  html.fh .lv-top .lv-logo img{height:calc(38px * var(--top-k))}
  html.fh .lv-top .lv-nav{gap:calc(12px * var(--top-k))}
  html.fh .lv-top .lv-li{font-size:calc(14px * var(--top-k));letter-spacing:.02em}
  html.fh .lv-top #apcAcc .lv-li{font-size:calc(14px * var(--top-k));padding:calc(6px * var(--top-k)) calc(13px * var(--top-k)) calc(7px * var(--top-k))}
  html.fh{--fs-body-lg:18px;--fs-cursive:26px}
}
@media (max-width:400px){
  html.fh .lv-top{height:calc(52px * var(--top-k));padding:0 calc(8px * var(--top-k))}
  html.fh .lv-top .lv-logo img{height:calc(32px * var(--top-k))}
  html.fh .lv-top .lv-nav{gap:calc(10px * var(--top-k))}
  html.fh .lv-top .lv-li{font-size:calc(13px * var(--top-k));letter-spacing:0}
  html.fh .lv-top #apcAcc .lv-li{font-size:calc(13px * var(--top-k));padding:calc(5px * var(--top-k)) calc(11px * var(--top-k)) calc(6px * var(--top-k))}
}

/* ==========================================================================
   §9 游戏实况深皮(用户 2026-09-11: 「咱们的游戏实况做这种灰色, 排版变成和
      原网站一样的排版」)

   live.html 有 **自己一整套 850 行 inline <style>**(深空蓝 #080b14 + 冷蓝强调),
   不是"改个变量就换肤"的结构。本节的策略是**只覆写可见骨架**, 不重写数据区:

     · 底色 / 背景层 / 烟雾   → 中性 #222, 去掉冷蓝
     · 页头(fatfish section-header) → 大标题 + 金色手写副标题
     · 章节头 / Tab / 卡片 / 表格 / 查询行 → 「极简无卡片」在深皮上的落地
     · 冷蓝强调色 → 品牌红 / 金(fatfish 全站只有这两个色)

   ⚠ **不动语义色**: 遗物纪元(.e-lith/.e-meso/.e-neo/.e-axi)、紫卡评级(.g-S..g-D)、
     元素标签(.el-*)、执刑官碎片(.shard-dot)、日历类型(.t-do/.t-big/.t-ovr)、
     冷/暖状态(.cyc-state.cold/.warm) —— 那些颜色是**游戏含义**, 不是装饰。

   ⚠ 全部规则带 `.live` 前缀, 只作用于本页; 首页第 1 屏有 306 项验收兜底, 不受影响。
   ========================================================================== */

/* —— 根与背景 —— */
html.fh.live{background:#222}
html.fh.live body{background:#222;color:#fff}
/* 原来那个 .bg 是深空渐变(#080b14 + 上下纯黑)。fatfish 的区块是**平涂**的,
   所以压成一层很淡的暗角(只保住顶/底的层次), 不再给页面染藏青。 */
html.fh.live .bg{
  background-color:transparent;
  background-image:linear-gradient(to bottom,
      rgba(0,0,0,.45) 0%, rgba(0,0,0,.16) 10%, rgba(0,0,0,0) 26%,
      rgba(0,0,0,0) 74%, rgba(0,0,0,.16) 90%, rgba(0,0,0,.45) 100%);
}
/* 烟雾层(#smoke, nova-fluid 建的 canvas): 保留"按住出烟"的手感, 但**压到 35%**。
   满强度时在 #222 上是一团团灰斑, 像没擦干净的污渍 —— 平涂是 fatfish 的底子,
   这点氛围只该"若有若无"。值由 _shots/ab-smoke-{on,low,off}.png 目检定(35% 最舒服)。 */
html.fh.live #smoke{opacity:.35}

/* —— 顶栏: 深皮上要"浮"起来, 靠一条底部细线而不是黑渐变 —— */
html.fh.live .lv-top{
  background:rgba(34,34,34,.88);
  -webkit-backdrop-filter:saturate(1.4) blur(10px);backdrop-filter:saturate(1.4) blur(10px);
  box-shadow:0 1px 0 rgba(255,255,255,.10);
}
/* ⚠ 关键: /img/logo.png 是**黑字标 + 浅灰线稿猫**(用户 2026-09-12 给的那张),
   在 #222 上几乎看不见 → 本页(深皮顶栏)整块翻成纯白:
   brightness(0) 把所有有色像素压成黑(alpha 保留 → 透明处仍透明), invert(1) 再翻成白。
   猫的线稿跟着变白, 正好是深底上最清楚的形态。 */
html.fh.live .lv-top .lv-logo img{filter:brightness(0) invert(1)}

/* —— 页头: ≡ fatfish .section-header(大标题 + 金色手写副标题) —— */
html.fh.live .lv-eyebrow{
  font-family:var(--ff-nav);font-weight:300;
  font-size:13px;letter-spacing:.42em;color:var(--c-gold);
  text-transform:uppercase;margin-bottom:14px;
}
html.fh.live .lv-title{
  font-family:var(--ff-display);font-weight:900;text-transform:uppercase;
  font-size:clamp(46px,8vw,88px);line-height:1.02;letter-spacing:.01em;color:#fff;
  text-shadow:none;        /* 干掉那条冷蓝光晕(深空时代唯一的冷光) */
}
html.fh.live .lv-sub{
  font-family:"Segoe Script","Bradley Hand","Comic Sans MS",cursive,var(--ff-cjk);
  font-size:clamp(22px,3.46vw,49.8px);   /* ≡ fatfish .u-subtitle-cursive @14px */
  color:var(--c-gold);line-height:1.3;
  letter-spacing:0;text-transform:none;text-indent:0;margin-top:4px;
}

/* —— 实时状态条 —— */
html.fh.live .lv-meta{
  color:rgba(255,255,255,.6);
  border-color:rgba(255,255,255,.14);background:transparent;
}
html.fh.live .live-dot.on{background:var(--c-red);box-shadow:0 0 10px rgba(203,65,63,.9)}
html.fh.live .live-dot.off{background:rgba(255,255,255,.4)}

/* —— Tab: 换成 fatfish 导航的语言(平涂 + 红色下划线), 不要蓝渐变胶囊 —— */
html.fh.live .lv-tabs{gap:28px;border-bottom:1px solid rgba(255,255,255,.12)}
html.fh.live .lv-tab{
  font-family:var(--ff-nav);font-weight:300;
  font-size:17px;letter-spacing:.08em;
  color:rgba(255,255,255,.5);background:transparent;
  border:0;border-radius:0;padding:10px 2px 14px;
}
html.fh.live .lv-tab:hover{color:#fff;background:transparent;border-color:transparent}
html.fh.live .lv-tab.on{
  color:#fff;background:transparent;border-color:transparent;box-shadow:none;
  position:relative;
}
html.fh.live .lv-tab.on::after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;background:var(--c-red);
}

/* —— 章节头(01 官方公告 / 02 商人 …) —— */
html.fh.live .sec-t{
  font-family:var(--ff-display);font-weight:900;
  font-size:22px;letter-spacing:.02em;text-transform:uppercase;
}
html.fh.live .sec-no{
  font-family:var(--ff-nav);font-weight:400;
  color:var(--c-gold);border-color:rgba(202,185,154,.45);border-radius:0;
}
html.fh.live .sec-en{color:rgba(255,255,255,.35)}

/* —— 卡片: 「极简无卡片」在深皮上的落地 ——
   去掉填充与 20px 圆角, 只留一条 1px 细线。⚠ 深皮上**不能连边框也去掉**:
   透明的卡在 #222 上会完全看不见边界(白底上才不会)。 */
html.fh.live .blk{
  border:1px solid rgba(255,255,255,.14);border-radius:0;background:transparent;
}
html.fh.live .blk::before{display:none}      /* 去掉冰蓝内阴影 */
html.fh.live .blk--hl{border-color:rgba(203,65,63,.5);background:transparent}
html.fh.live .blk--dim{border-color:rgba(255,255,255,.07)}
html.fh.live .blk-hd i{background:radial-gradient(circle,#cab99a 10%,#8a7a5c 60%,transparent 70%);
  box-shadow:0 0 8px rgba(202,185,154,.7)}
html.fh.live .blk-hd b{font-family:var(--ff-display);font-weight:900}
html.fh.live .blk-foot{border-top:1px solid rgba(255,255,255,.12)}
/* 卡内的次级容器: 比外层再淡一档, 保住"卡里有块"的层次 */
html.fh.live .tier-card,
html.fh.live .ev-card,
html.fh.live .nw-col,
html.fh.live .fis-col,
html.fh.live .cal-day,
html.fh.live .arch-item,
html.fh.live .arch-panel,
html.fh.live .ph-item,
html.fh.live .tl-item{
  border:1px solid rgba(255,255,255,.10);border-radius:0;background:transparent;
}
html.fh.live .tl-item:hover{background:rgba(255,255,255,.04);border-color:rgba(255,255,255,.24)}
html.fh.live .ph-item{border-color:rgba(255,255,255,.10)}

/* —— 冷蓝 → 金 / 白 —— fatfish 全站没有蓝; 这是"排版和原站一样"最显眼的一半 —— */
html.fh.live .hi,
html.fh.live .sortie-info b,
html.fh.live .sp-current b,
html.fh.live .nw-head b,
html.fh.live .ckt-now,
html.fh.live .ckt-now b,
html.fh.live .zn-cn,
html.fh.live .zn-name,
html.fh.live .tl-mid b,
html.fh.live .q-detail h3,
html.fh.live .nm,
html.fh.live .an-num b{color:#fff}
html.fh.live .hi{text-shadow:none}          /* 去掉冰蓝发光 */
html.fh.live .cd{color:#fff}

html.fh.live .arb-day,
html.fh.live .zn-lab,
html.fh.live .ckt-lab,
html.fh.live .arch-hd b,
html.fh.live .blk-foot .rw-lab,
html.fh.live .q-meta b,
html.fh.live .an-meta b,
html.fh.live .mod-eff.en,
html.fh.live .tag,
html.fh.live .dt-desc.cn,
html.fh.live .cal-date,
html.fh.live .tl-item:hover .tl-go,
html.fh.live .tl-tbl th:hover{color:var(--c-gold)}
html.fh.live .zn-lab::after{background:rgba(202,185,154,.28)}

/* 蓝色描边/发光 → 金或中性白 */
html.fh.live .sp-current,
html.fh.live .arb-rem,
html.fh.live .tl-refresh,
html.fh.live .q-search input:focus,
html.fh.live .an-weapon input:focus,
html.fh.live .an-stat select:focus,
html.fh.live .an-stat input[type=number]:focus{border-color:rgba(202,185,154,.42)!important}
html.fh.live .sp-current{background:rgba(202,185,154,.06)}
html.fh.live .arb-rem{background:rgba(202,185,154,.06)}
html.fh.live .tl-refresh{background:transparent;color:var(--c-gold)}
html.fh.live .tl-refresh:hover{background:rgba(202,185,154,.12)}
html.fh.live .ck{box-shadow:none}

/* 冰蓝渐变(#dbe9ff→#8fb6ff)的 5 个用点 → 品牌红 */
html.fh.live .lv-tab.on,
html.fh.live .tl-no,
html.fh.live .q-cat.on,
html.fh.live .an-go,
html.fh.live .sortie-no{
  background:var(--c-red);color:#fff;box-shadow:none;border-color:transparent;
}
html.fh.live .an-go:hover{background:#b83836}
html.fh.live .q-cat.on:hover{background:#b83836}
/* ⚠ .tl-no 一名两用(实测抓出来的坑):
     span.tl-no = 工具条上的编号徽章(live.html 静态写在红底上) → 必须纯白;
     div.tl-no  = "该类别暂无武器"的空态文案(tools.js 填进 .tl-tblwrap) → 走深底灰字。
   白 45% 压在 #cb413f 上只有 2.08:1 —— 低于 3:1 硬地板, 所以按标签分开写。 */
html.fh.live span.tl-no{color:#fff}
html.fh.live div.tl-no{color:rgba(255,255,255,.55);background:transparent}
html.fh.live .cyc-bar span{background:linear-gradient(90deg,#8a7a5c,#cab99a)}
html.fh.live .cyc-bar.warm span{background:linear-gradient(90deg,#b8763c,#ffcf9e)}

/* —— 表格 / 列表: 去填充, 只留行间细线 —— */
html.fh.live .tl-tblwrap{background:transparent;border-color:rgba(255,255,255,.12);border-radius:0}
html.fh.live .tl-tbl th{background:transparent;color:rgba(255,255,255,.5);
  border-bottom-color:rgba(255,255,255,.16)}
html.fh.live .tl-tbl td{border-bottom-color:rgba(255,255,255,.09)}
html.fh.live .tl-tbl tbody tr:nth-child(odd){background:transparent}
html.fh.live .tl-tbl tbody tr:hover{background:rgba(255,255,255,.05)}
html.fh.live .tl-fchip.on{background:var(--c-red);color:#fff}
html.fh.live .q-row{background:transparent;border-color:rgba(255,255,255,.10);border-radius:0}
html.fh.live .q-row:hover{background:rgba(255,255,255,.04);border-color:rgba(255,255,255,.24)}
html.fh.live .q-detail{background:#1b1b1b;border-color:rgba(255,255,255,.14);border-radius:0}
html.fh.live .q-cat{color:rgba(255,255,255,.55);background:transparent;
  border-color:rgba(255,255,255,.14);border-radius:0}
html.fh.live .q-cat:hover{color:#fff;border-color:rgba(255,255,255,.34)}
html.fh.live .q-search input::placeholder{color:rgba(255,255,255,.4)}
html.fh.live .an-st{background:transparent;border-color:rgba(255,255,255,.10);border-radius:0}

/* —— 对比度兜底: 一批 9~11px 的小号标签原色是 .26~.35 的白 ——
   #222 上 .32 只有 2.89:1(实测 _live_verify.js E 组抓出来的), 低于 3:1 硬地板。
   统一提到 .45(=4.33:1)。顺带也根治了"灰字糊成一片"的观感, 与 fatfish 的干脆留白一致。
   ⚠ 只收**文字色**; 同名的 border/background 不动(那些是分隔线, 本来就要淡)。 */
html.fh.live .zn-hint,html.fh.live .zn-en,html.fh.live .zn-empty,
html.fh.live .tl-hint,html.fh.live .tl-tt em,html.fh.live .tl-go,
html.fh.live .nm .en,html.fh.live .px::after,
html.fh.live .an-hint,html.fh.live .an-st .st-range,
html.fh.live .fis-none,html.fh.live .fis-sub,
html.fh.live .tier-none,html.fh.live .cyc-en,
html.fh.live .cal-day-h .dow,
html.fh.live .ev-reward .lvl,html.fh.live .hunt-rem .lab,
html.fh.live .news-eta,html.fh.live .q-count,html.fh.live .q-row .q-nm .en,
html.fh.live .ph-head em,html.fh.live .ph-sub,html.fh.live .ph-nm,
html.fh.live .empty,html.fh.live .lv-foot,
html.fh.live .blk-hd em,html.fh.live .blk-hd .tag,
html.fh.live .sec-en,html.fh.live .sp-rotno,html.fh.live .lv-back{color:rgba(255,255,255,.55)}
html.fh.live .dim{color:rgba(255,255,255,.5)}
html.fh.live .lv-back:hover{color:#fff}
html.fh.live .blk-hd .tag{border-color:rgba(255,255,255,.22);border-radius:0}
/* 输入框 placeholder 同理(.28 → .45) */
html.fh.live .an-weapon input::placeholder,
html.fh.live .q-search input::placeholder,
html.fh.live .an-stat input::placeholder{color:rgba(255,255,255,.55)}

/* —— 页脚 —— */
html.fh.live .lv-foot{border-top:1px solid rgba(255,255,255,.10);padding-top:16px;
  width:min(1240px,100%);margin:42px auto 0}

/* —— 窄屏: 页头别把标题顶出屏 + 内容区收内边距 —— */
@media (max-width:960px){
  html.fh.live .lv-main{padding:104px 20px 80px}
  html.fh.live .lv-sub{font-size:30px}
  html.fh.live .sec-t{font-size:19px}
  html.fh.live .lv-tabs{gap:20px}
}
@media (max-width:560px){
  html.fh.live .lv-main{padding:84px 14px 64px}
  html.fh.live .lv-eyebrow{font-size:11px;letter-spacing:.3em}
  html.fh.live .lv-sub{font-size:24px}
  html.fh.live .lv-title{font-size:clamp(34px,11vw,52px)}
  html.fh.live .lv-tab{font-size:15px;padding:8px 2px 12px}
  html.fh.live .lv-tabs{gap:16px}
  html.fh.live .sec-t{font-size:17px}
  html.fh.live .sec-en{display:none}       /* 窄屏放不下中英两行: fatfish 也是只留主标题 */
  html.fh.live .blk-hd{padding:13px 14px 4px}
  html.fh.live .blk-bd{padding:4px 14px 14px}
  html.fh.live .blk-foot{padding:10px 14px 12px}
  html.fh.live .lv-foot{margin-top:32px}
}

/* ==========================================================================
   §10 窄屏侧边抽屉(2026-09-12)
   --------------------------------------------------------------------------
   用户原话:「手机端可以用侧边栏，点击logo出现侧边栏，把内容放到那里边，顶栏就不要了」。
   形态(用户逐条选定, 见 remembered 计划):
     · 顶栏只剩**左上角一枚浮 logo**(无底条), 它同时是抽屉的开关;
     · 点它从**左侧滑出抽屉**(78vw / 最多 340px)+ 右侧半透明黑遮罩, 点遮罩关闭;
     · 抽屉里三组: 「四个主导航」+「登录·账号胶囊」+「更多」(代码站/关注/投稿);
     · 滚动超过 24px 时 logo 背后**淡出一个半透明白底衬**(顶部是裸 logo)。
   桌面(≥961)一行都不命中 —— 汉堡与全屏菜单 2026-09-12 已整体删除(墓碑见 §5c),
   桌面顶栏只剩「logo + 四个导航 + 胶囊」, 与改动前逐像素相同。

   ⚠ 为什么写在本文件(skin.css)而不是 m.css / f.css:
     m.css 加载在 skin.css **前面**, 同特异性的规则会被本文件压掉 —— 抽屉不能写那里。
     窄屏覆盖一律写成 `html.fh header#apeTop.lv-top` = (1,2,2), 靠"带 id + 加载最后"
     赢过 f.css §8 的 `html.fh #apeTop.lv-top` (1,2,1)、skin.css §8 自己的
     `html.fh .lv-top` (0,3,1) 与 m.css §"首页 #apeTop 覆盖"的 `header#apeTop.lv-top` (1,1,1)。
     ⚠ 顺带记一笔旧账: **@media 不增加特异性**。§5c 的汉堡当年就是栽在这条上
       (m.css 的窄屏值反压 skin.css 的桌面值), 所以这次的覆盖必须**带 id**, 不靠"在媒体查询里"。

   ⚠⚠ **顶栏条盒子的高度 / 内边距 / 位置刻意一个字节都不改**, 只让它变透明。
     窄屏正文那批补位值(m.css:38-45 / 111-118 / 187-191 与 §9 的 live 两条)是按
     「条高 + 空隙」算出来的, 不是随手写的数:
       ≤960: .p-wrap{padding-top:102px} − 条高 54.56px = **47.44px 空隙**,
             而浮 logo 最高档才 44×0.88 = 38.72px, 完整落在条盒子内部(条高 54.56) —— 正文永不撞 logo。
       所以"顺手把补位改小"是错的: 补位一改小 = 正文直接顶到 logo 底下。
     留着条盒子 = 11 个页面的补位与 `_fhero_verify.js` 的 `topH` 断言**全部不用动**。
   ========================================================================== */

/* 抽屉视图: 桌面档完全不存在(apeTop.js 也不会在桌面建它); 万一从窄屏拉宽后残留, 这里兜底藏掉 */
#fhDrawer{display:none}

@media (max-width:960px){

  /* —— 10.1 顶栏 → 左上角一枚浮 logo —— */
  html.fh header#apeTop.lv-top{
    background:none;                                        /* 简写: 顺手清掉 f.css §8 的 #fff 与 apeTop.js 的渐变 */
    box-shadow:none;
    -webkit-backdrop-filter:none; backdrop-filter:none;     /* 游戏实况深皮那条 (0,3,1) 只声明了它, 必须单独清 */
    pointer-events:none;                                    /* 条本身不吃点击; 否则屏幕顶部一条 54px 隐形死区 */
  }
  html.fh header#apeTop.lv-top::after{background:none}      /* 那条 1px 白色渐变细线 */
  html.fh header#apeTop .lv-nav{display:none}               /* 四个导航 + 胶囊一起退场(抽屉里各有一份) */
  html.fh header#apeTop .lv-logo{
    pointer-events:auto;                                    /* 只有 logo 可点 */
    display:flex; align-items:center;
    /* 触摸热区做到 ≥44px; 负边距 + 等量左内边距把**图**的左缘拉回原处(与今天逐像素相同)。
       box-sizing:border-box 让 min-height 把内边距算进去 —— ≤400 档图只有 32×.88=28px,
       加上下 12px 内边距才 40px, 不够指头; 补到 44 后仍然塞得进 45.76px 的条盒子。 */
    box-sizing:border-box; min-height:44px;
    margin-left:-6px; padding:6px 10px 6px 6px;
    border-radius:999px;
    transition:background-color .2s ease, box-shadow .2s ease;
  }
  /* 滚动底衬(用户 2026-09-12 选定「滚动时浮出白底衬」)。类由 apeTop.js 的 syncScrolled() 挂在 <html> 上。
     ⚠ 排掉 .live: 游戏实况深皮上 logo 是 brightness(0) invert(1) 的**白**剪影,
       铺白底衬等于白字白底 → 互相吃掉。深皮上裸 logo 压在深空蓝上本来就够清楚。 */
  html.fh.fh-scrolled:not(.live) header#apeTop .lv-logo{
    background:rgba(255,255,255,.86);
    box-shadow:0 2px 10px rgba(0,0,0,.10);
    -webkit-backdrop-filter:saturate(1.2) blur(6px); backdrop-filter:saturate(1.2) blur(6px);
  }

  /* —— 10.2 抽屉外壳与遮罩 —— */
  #fhDrawer{
    display:block;
    position:fixed; inset:0; z-index:130;                   /* > 顶栏 120; 但 < #fhPrivacy 1020(那条隐私告知必须可读) */
    visibility:hidden;                                      /* 关闭态: 天然不参与命中测试, 也不进 Tab 序列 */
    transition:visibility .3s;
  }
  #fhDrawer.on{visibility:visible}
  /* ⚠ 关闭态为什么用 visibility 而不是 opacity:
       visibility 的过渡语义是「0<t<1 视为 visible」→ **关的时候照样看得见面板滑出去**,
       滑完(300ms)才整体隐藏。改用 opacity:0 会把"滑出动画"整段吃掉
       —— 那正是被删掉的 #fhMenu 的做法, 别再犯。 */
  #fhDrawer::before{
    content:""; position:absolute; inset:0;
    background:rgba(0,0,0,.45);
    opacity:0; transition:opacity .28s ease;
  }
  #fhDrawer.on::before{opacity:1}
  /* 开抽屉时锁背景滚动。类挂 <html>, 规则只包在本媒体查询里 → 桌面维持今天"不锁"的行为。 */
  html.fh-d-open,html.fh-d-open body{overflow:hidden}

  /* —— 10.3 抽屉面板 —— */
  #fhDrawer .fh-d-panel{
    display:flex; flex-direction:column;
    position:absolute; top:0; left:0; bottom:0;
    width:78vw; max-width:340px; box-sizing:border-box;
    background:#fff; box-shadow:4px 0 40px rgba(0,0,0,.22);
    padding:16px 20px calc(24px + env(safe-area-inset-bottom,0px));
    overflow-y:auto; -webkit-overflow-scrolling:touch;
    transform:translateX(-100%);
    transition:transform .3s cubic-bezier(.19,1,.22,1);     /* 快速滑出 + 轻微过冲收尾 */
  }
  #fhDrawer.on .fh-d-panel{transform:translateX(0)}

  /* 头部: 左 logo(纯装饰, 不是 <a> —— 见 apeTop.js buildDrawer 的注释)、右关闭 × */
  #fhDrawer .fh-d-head{
    display:flex; align-items:center; justify-content:space-between;
    padding-bottom:14px; border-bottom:1px solid rgba(34,34,34,.10);
  }
  #fhDrawer .fh-d-brand img{display:block;height:26px;width:auto}
  #fhDrawer .fh-d-x{
    width:44px; height:44px; margin-right:-10px; padding:0;
    background:none; border:0; cursor:pointer;
    font-family:var(--ff-nav,serif); font-weight:300; font-size:26px; line-height:1;
    color:#222;
  }

  /* —— 10.4 三组内容 —— */
  #fhDrawer .fh-d-sec{margin-top:22px}
  #fhDrawer .fh-d-cap{
    font-family:var(--ff-nav,serif); font-weight:300; font-size:11px;
    letter-spacing:.22em; text-transform:uppercase;
    color:rgba(34,34,34,.45); margin-bottom:10px;
  }
  #fhDrawer .fh-d-list{list-style:none;margin:0;padding:0}
  #fhDrawer .fh-d-row{margin:0 0 14px}
  #fhDrawer .fh-d-row:last-child{margin-bottom:0}
  /* ⚠ 抽屉行一律 .fh-d-link, **绝不用 .lv-li**: apeTop.js 无条件注入
     `.lv-li{color:rgba(255,255,255,.55)}` (0,1,0), 白底抽屉上就是白字隐形。
     当前页高亮同理只用 .fh-d-on, 不用 .lv-on(#fff)。 */
  #fhDrawer .fh-d-link{
    display:inline-block; text-decoration:none; cursor:pointer;
    font-family:var(--ff-display,sans-serif); font-weight:900;
    font-size:clamp(24px,7.6vw,32px); line-height:1.12; letter-spacing:.01em;
    color:#222;
  }
  #fhDrawer .fh-d-link:active{opacity:.6}
  #fhDrawer .fh-d-more .fh-d-link{
    font-family:var(--ff-nav,serif); font-weight:300;
    font-size:clamp(15px,4.1vw,17px); letter-spacing:.06em;
    color:rgba(34,34,34,.72);
  }
  #fhDrawer .fh-d-link.fh-d-on{color:var(--c-red,#cb413f)}

  /* —— 10.5 登录 / 账号胶囊 ——
     ⚠ 抽屉在 #apeTop 之外, 拿不到 `html.fh #apeTop #apcAcc .lv-li` 那套红底金字,
       会掉回 apeTop.js 注入的白色 .lv-li → **白底白字**。所以这里必须自带一份。
       (authnav.js 造的胶囊类名写死 lv-li, 改不了, 只能从这边压。) */
  #fhDrawer .fh-d-auth .lv-li{
    display:inline-flex; align-items:center; justify-content:center;
    font-family:var(--ff-display,sans-serif); font-weight:900;
    font-size:16px; letter-spacing:.04em; line-height:1;
    color:#fff; background:var(--c-red,#cb413f);
    border-radius:999px; padding:13px 28px 15px;
    text-decoration:none; cursor:pointer;
  }
  #fhDrawer .fh-d-auth .apc-acc{position:relative; display:block}
  /* 已登录态的下拉: 基类是 `position:absolute;right:0;min-width:212px`(authnav.js 注入),
     在最多 340px 的抽屉里会往左越出面板被裁掉。抽屉里改成**文档流内、由 .apc-open 显隐**
     (authnav.js 的触屏路径本来就是点一下加 .apc-open) —— 不能用 opacity:0 留在流里,
     那会凭空撑出一块 212px 高的空洞。 */
  #fhDrawer .fh-d-auth .apc-drop{
    display:none;
    position:static; top:auto; right:auto; min-width:0; width:100%;
    margin-top:10px; opacity:1; visibility:visible; transform:none;
  }
  #fhDrawer .fh-d-auth .apc-acc.apc-open .apc-drop{display:block}
  #fhDrawer .fh-d-auth .apc-drop::before{display:none}   /* 那条 14px 的悬停缝隙补白在文档流里不需要 */
}
