/* ============================================================
   《有间推理馆2：雾山档案》 视觉系统
   ------------------------------------------------------------
   设计原则（血泪教训）：
   1. 基础渲染只用 CSS 滤镜（grayscale/contrast/sepia/brightness/blur）
      —— 这些在任何浏览器上都不可能黑屏
   2. SVG 滤镜只做「毛边/洇染」这类增强，且必须可关
      —— 上次黑屏就是 feComposite 读 alpha 通道写错了
   3. 动效全部是叠加层（渐变 + CSS 动画），不依赖滤镜
      —— 所以动效和风格可以任意组合

   风格（mood）× 动效（anim）可以任意穿插搭配。
   ============================================================ */

:root{
  /* 纸与墨 —— 全套视觉的基准色 */
  --paper:      #d8ccae;
  --paper-hi:   #ece2c8;
  --paper-lo:   #b9ac8b;
  --ink:        #26201a;
  --ink-soft:   #574c3d;
  --fox:        #a8845a;   /* 霉斑 */
  --rust:       #8a5a3a;   /* 锈 */
  --seal:       #9c3b2e;   /* 印泥 */
  --blue:       #7d95a3;   /* 雨夜的冷色 */

  --serif: "Songti SC","SimSun","Noto Serif CJK SC",serif;
  --sans:  "PingFang SC","Microsoft YaHei",sans-serif;
  --mono:  "Cascadia Mono","Consolas","SFMono-Regular",ui-monospace,monospace;
}

/* ============================================================
   场景容器
   ============================================================ */
.sc{
  position:relative;overflow:hidden;background:#0a0908;
  isolation:isolate;               /* 锁住混合模式，不污染外层 */
}
.sc img.base{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  will-change:transform,filter;
}

/* 叠加层通用：不吃点击、不占位 */
.sc > .L{position:absolute;inset:0;pointer-events:none}

/* ============================================================
   风格 preset —— 只改 base 图的 CSS 滤镜链
   ============================================================ */

/* ① 旧档扫描件：泛黄、低对比、发脆 */
.sc.m-dossier img.base{
  filter:sepia(.62) saturate(.72) contrast(.92) brightness(.94);
}
/* ② 水墨洇染：去色、灰度拉满、柔化 */
.sc.m-ink img.base{
  filter:grayscale(1) contrast(1.22) brightness(1.06);
}
/* ③ 高清对比：高反差、留一点色、压迫 */
.sc.m-hard img.base{
  filter:contrast(1.62) saturate(.82) brightness(.9);
}
/* ④ 雨夜冷调 */
.sc.m-night img.base{
  filter:sepia(.2) hue-rotate(170deg) saturate(.62) contrast(1.24) brightness(.82);
}
/* ⑤ 回忆（暖、褪色、软） */
.sc.m-memory img.base{
  filter:sepia(.78) saturate(.55) contrast(.9) brightness(1.02) blur(.4px);
}
/* ⑥ 干扰/故障（高反差 + 硬） */
.sc.m-static img.base{
  filter:grayscale(1) contrast(1.9) brightness(.86);
}

/* 风格层的对应色调 */
.sc.m-dossier .tint{background:linear-gradient(168deg,rgba(216,204,174,.30),rgba(150,125,88,.34));mix-blend-mode:multiply}
.sc.m-ink     .tint{background:linear-gradient(168deg,rgba(250,248,240,.32),rgba(180,175,160,.20));mix-blend-mode:screen}
.sc.m-hard    .tint{background:radial-gradient(ellipse at 50% 45%,transparent 30%,rgba(0,0,0,.62) 100%);mix-blend-mode:multiply}
.sc.m-night   .tint{background:linear-gradient(180deg,rgba(20,36,48,.42),rgba(8,16,22,.55));mix-blend-mode:multiply}
.sc.m-memory  .tint{background:linear-gradient(168deg,rgba(230,205,160,.34),rgba(160,120,70,.30));mix-blend-mode:multiply}
.sc.m-static  .tint{background:linear-gradient(180deg,rgba(0,0,0,.35),rgba(0,0,0,.5));mix-blend-mode:multiply}

/* ============================================================
   材质层（可叠加在任意风格上）
   ============================================================ */

/* 纸纤维 */
.sc .fiber{
  position:absolute;inset:0;pointer-events:none;opacity:.42;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.88' numOctaves='4'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23f)'/%3E%3C/svg%3E");
  animation:fiberBreathe 12s ease-in-out infinite alternate;
}
@keyframes fiberBreathe{0%{opacity:.38;transform:scale(1)}100%{opacity:.52;transform:scale(1.012)}}

/* 霉斑：会缓慢扩散 */
.sc .fox{
  position:absolute;inset:0;pointer-events:none;mix-blend-mode:multiply;
  background-image:
    radial-gradient(circle 34px at 14% 22%,rgba(168,132,90,.34),transparent 70%),
    radial-gradient(circle 22px at 79% 16%,rgba(168,132,90,.26),transparent 70%),
    radial-gradient(circle 46px at 64% 78%,rgba(150,116,78,.30),transparent 72%),
    radial-gradient(circle 18px at 28% 86%,rgba(168,132,90,.28),transparent 70%);
  animation:foxGrow 40s ease-in-out infinite alternate;
}
@keyframes foxGrow{0%{opacity:.58;transform:scale(1)}100%{opacity:.94;transform:scale(1.05)}}

/* 扫描线（细密横纹） */
.sc .scanline{
  position:absolute;inset:0;pointer-events:none;opacity:.30;mix-blend-mode:multiply;
  background:repeating-linear-gradient(0deg,rgba(60,45,28,.55) 0 1px,transparent 1px 3px);
}

/* 颗粒（随机噪点） */
.sc .grain{
  position:absolute;inset:-20%;pointer-events:none;opacity:.16;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.95' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  animation:grainJit 1.1s steps(3) infinite;
}
@keyframes grainJit{
  0%{transform:translate(0,0)}33%{transform:translate(-8px,6px)}
  66%{transform:translate(6px,-9px)}100%{transform:translate(0,0)}
}

/* 暗角 */
.sc .vig{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse at center,transparent 42%,rgba(0,0,0,.62) 100%);
}

/* ============================================================
   动效层（任意风格可叠加）
   ============================================================ */

/* ① 扫描光条 —— 一道柔光从上扫到下 */
.sc .beam{
  position:absolute;left:-8%;right:-8%;height:15%;top:-22%;pointer-events:none;
  mix-blend-mode:screen;z-index:6;filter:blur(2px);
  background:linear-gradient(180deg,transparent,rgba(255,252,242,.40) 44%,
    rgba(255,255,252,.66) 50%,rgba(255,252,242,.40) 56%,transparent);
  animation:beamPass var(--beamDur,7.5s) cubic-bezier(.45,0,.55,1) infinite;
}
.sc .beam::after{
  content:"";position:absolute;left:0;right:0;top:100%;height:22%;
  background:linear-gradient(180deg,rgba(255,252,242,.18),transparent);
}
@keyframes beamPass{0%{top:-22%}60%{top:112%}100%{top:112%}}

/* ② 水墨洇染 —— 墨从四周往内渗（用径向遮罩动画做） */
.sc .bleed{
  position:absolute;inset:-4%;pointer-events:none;z-index:5;mix-blend-mode:multiply;
  background:radial-gradient(ellipse 120% 110% at 50% 50%,
    transparent 34%, rgba(38,32,26,.28) 68%, rgba(38,32,26,.72) 100%);
  animation:inkBleed var(--bleedDur,9s) ease-in-out infinite alternate;
}
@keyframes inkBleed{
  0%{transform:scale(.86);opacity:.5}
  100%{transform:scale(1.1);opacity:1}
}
/* 洇染的"水痕"：几条不规则的边 */
.sc .bleed::after{
  content:"";position:absolute;inset:0;
  background:
    radial-gradient(ellipse 40% 26% at 18% 30%,rgba(38,32,26,.36),transparent 70%),
    radial-gradient(ellipse 34% 22% at 82% 66%,rgba(38,32,26,.32),transparent 70%),
    radial-gradient(ellipse 30% 30% at 62% 14%,rgba(38,32,26,.24),transparent 72%);
  animation:bleedShift 14s ease-in-out infinite alternate;
}
@keyframes bleedShift{
  0%{transform:translate(0,0) scale(1);opacity:.7}
  100%{transform:translate(2%,-1.4%) scale(1.08);opacity:1}
}

/* ③ 旧档抖动 —— 老胶片跳帧 */
.sc.jitter{animation:frameJit var(--jitDur,7s) steps(1) infinite}
@keyframes frameJit{
  0%,88%{transform:translate(0,0)}
  89%{transform:translate(-2.5px,1px)}
  90.5%{transform:translate(2px,-1.5px)}
  92%{transform:translate(-1px,.5px)}
  93%,100%{transform:translate(0,0)}
}

/* ④ 交叉淡入 —— 多帧轮流，做"录像感" */
.sc .frame{
  position:absolute;inset:0;opacity:0;
  animation:frameFade var(--fadeDur,18s) linear infinite;
}
.sc .frame img{width:100%;height:100%;object-fit:cover;display:block}
@keyframes frameFade{
  0%,26%{opacity:1}
  33%,100%{opacity:0}
}
/* 帧间黑闪 */
.sc .blackflash{
  position:absolute;inset:0;pointer-events:none;z-index:8;background:#000;opacity:0;
  animation:bf var(--fadeDur,18s) linear infinite;
}
@keyframes bf{
  0%,25%{opacity:0}
  28%{opacity:.72}
  31%{opacity:0}
  100%{opacity:0}
}

/* ⑤ 雨 */
.sc .rain{
  position:absolute;inset:-30% -10%;pointer-events:none;z-index:7;opacity:.5;
  background:
    repeating-linear-gradient(76deg,rgba(200,215,225,.34) 0 1px,transparent 1px 7px),
    repeating-linear-gradient(74deg,rgba(200,215,225,.18) 0 1px,transparent 1px 13px);
  background-size:120% 240%,160% 320%;
  animation:rainFall .5s linear infinite;
}
@keyframes rainFall{
  0%{background-position:0 -240%,0 -320%}
  100%{background-position:-16% 0,-22% 0}
}

/* ⑥ 雾 */
.sc .fog{
  position:absolute;inset:-14% -22%;pointer-events:none;z-index:6;mix-blend-mode:screen;
  background:
    radial-gradient(ellipse 62% 34% at 22% 62%,rgba(196,210,214,.22),transparent 62%),
    radial-gradient(ellipse 48% 30% at 74% 52%,rgba(196,210,214,.16),transparent 62%);
  animation:fogDrift var(--fogDur,30s) ease-in-out infinite alternate;
}
@keyframes fogDrift{
  0%{transform:translate3d(-3%,1%,0) scale(1.04)}
  100%{transform:translate3d(4%,-2%,0) scale(1.14)}
}

/* ⑦ 心跳暗角 —— 关键抉择 */
.sc .pulse{
  position:absolute;inset:0;pointer-events:none;z-index:7;
  background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,.9) 100%);
  animation:heartBeat 1.6s ease-in-out infinite;
}
@keyframes heartBeat{
  0%,100%{transform:scale(1);opacity:.78}
  8%{transform:scale(.93);opacity:.96}
  16%{transform:scale(1.03);opacity:.74}
  24%{transform:scale(.96);opacity:.9}
  32%{transform:scale(1);opacity:.78}
}

/* ⑧ 浮尘 */
.sc .dust{position:absolute;inset:0;pointer-events:none;z-index:7;opacity:.42}
.sc .dust i{
  position:absolute;border-radius:50%;background:rgba(255,250,235,.85);
  box-shadow:0 0 4px rgba(255,245,220,.7);
  animation:dustFloat 15s ease-in-out infinite;
}
@keyframes dustFloat{
  0%{transform:translate(0,0);opacity:0}
  14%{opacity:.92}
  86%{opacity:.62}
  100%{transform:translate(15px,-72px);opacity:0}
}

/* ⑨ 缓慢推近 */
.sc .dolly img.base{animation:dollyIn var(--dollyDur,22s) ease-in-out infinite alternate}
@keyframes dollyIn{
  0%{transform:scale(1) translate(0,0)}
  100%{transform:scale(1.14) translate(-1.2%,-1%)}
}

/* ⑩ 电视雪花干扰 */
.sc .snow{
  position:absolute;inset:0;pointer-events:none;z-index:8;opacity:0;
  mix-blend-mode:screen;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='s'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.99' numOctaves='1'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23s)'/%3E%3C/svg%3E");
  animation:snowGlitch 6s steps(1) infinite;
}
@keyframes snowGlitch{
  0%,91%{opacity:0}
  92%{opacity:.42}
  93.5%{opacity:.08}
  95%{opacity:.34}
  96.5%,100%{opacity:0}
}

/* ⑫ 大气系统 v2（atmos.js 生成）
   ------------------------------------------------------------------
   ★ 上一版最致命的错误：雨画满了整个画面，包括方向盘和仪表盘。
     雨不可能落在车里。
     → 用 .glass-win 容器 + clip-path 把雨裁进挡风玻璃区域。
   ★ 第二：雨在所有深度亮度相同。真实雨夜只有灯照到的雨才看得见。
     → .rainbow-lit 是受光雨，用径向遮罩限在灯锥里。            */

/* --- 雨 --- */
.sc .glass-win{                    /* 挡风玻璃窗口：雨只能出现在这里面 */
  position:absolute;z-index:7;pointer-events:none;overflow:hidden;
  /* 默认裁成整幅；具体场景会覆盖 left/top/width/height 与 clip-path */
}
.sc .rain-svg{
  position:absolute;left:0;right:0;width:100%;
  /* 高度 200%、上移 50% —— 配合只位移 50% 的动画，循环无缝 */
  height:200%;top:-50%;
  pointer-events:none;
}
/* 6 组雨丝，各自不同时长（时长由行内 style 单独覆盖） */
.sc .rain-svg .rls{animation-name:rf0;animation-timing-function:linear;animation-iteration-count:infinite}
@keyframes rf0{
  0%{transform:translate3d(0,0,0)}
  100%{transform:translate3d(-2.4%,50%,0)}
}
.sc .rain-svg .rls:nth-child(odd){opacity:.84}

/* 风：整幅缓慢左右摆动，阵性 */
.sc .glass-win.windy{animation:gust 7.5s ease-in-out infinite alternate}
@keyframes gust{
  0%{transform:translateX(-0.7%)}
  100%{transform:translateX(0.9%)}
}

/* 受光雨：只在灯锥内可见 —— 这是「雨夜真实感」的关键 */
.sc .rainbow-lit{
  -webkit-mask-image:radial-gradient(ellipse 34% 46% at 46% 62%,
    rgba(0,0,0,.95) 0%, rgba(0,0,0,.55) 42%, transparent 76%);
  mask-image:radial-gradient(ellipse 34% 46% at 46% 62%,
    rgba(0,0,0,.95) 0%, rgba(0,0,0,.55) 42%, transparent 76%);
  filter:brightness(1.5) saturate(1.1);
}

/* --- 玻璃上的水珠 --- */
.sc .rain-drops{position:absolute;inset:0;pointer-events:none;z-index:9}
.sc .rain-drops i{
  position:absolute;border-radius:50%;
  /* 折射质感：暗环包亮心 —— 单色圆点会像噪点，这是关键差别 */
  background:
    radial-gradient(circle at 34% 30%, rgba(255,255,255,.9) 0 15%, rgba(255,255,255,.28) 21%, transparent 33%),
    radial-gradient(circle at 64% 72%, rgba(186,212,226,.5) 0 25%, transparent 39%),
    radial-gradient(circle, rgba(255,255,255,.14) 40%, rgba(8,16,22,.44) 74%, rgba(255,255,255,.22) 100%);
  box-shadow:inset 0 0 2px rgba(255,255,255,.45), 0 1px 2px rgba(0,0,0,.5);
  animation:dropBreathe 5.5s ease-in-out infinite alternate;
  animation-delay:var(--d,0s);
}
@keyframes dropBreathe{0%{transform:scale(.94)}100%{transform:scale(1.05)}}
.sc .rain-drops i.slide::after{
  content:"";position:absolute;left:50%;top:100%;width:1px;height:var(--trail,0);
  transform:translateX(-50%);
  background:linear-gradient(180deg,rgba(255,255,255,.4),transparent);
}

/* --- 流水 --- */
.sc .rain-riv{position:absolute;inset:0;pointer-events:none;z-index:10}
.sc .rain-riv i{
  position:absolute;top:-24%;height:var(--h,40%);border-radius:2px;
  background:linear-gradient(180deg,transparent,rgba(255,255,255,.5) 22%,
    rgba(255,255,255,.2) 70%,transparent);
  filter:blur(.4px);
  animation:rivFlow var(--dur,14s) linear infinite;
  animation-delay:var(--delay,0s);
}
@keyframes rivFlow{
  0%{transform:translateY(0);opacity:0}
  8%{opacity:1}
  88%{opacity:.85}
  100%{transform:translateY(150%);opacity:0}
}

/* --- 雨滴溅射 --- */
.sc .rain-splash{position:absolute;inset:0;pointer-events:none;z-index:9}
.sc .rain-splash i{
  position:absolute;width:9px;height:9px;border-radius:50%;
  border:1px solid rgba(220,236,246,.7);
  animation:splashPop var(--dur,4s) ease-out infinite;
  animation-delay:var(--delay,0s);
}
@keyframes splashPop{
  0%{transform:scale(.2);opacity:0}
  6%{opacity:.85}
  26%{transform:scale(1.5);opacity:0}
  100%{transform:scale(1.5);opacity:0}
}

/* --- 雾 --- */
.sc .atmos-fog{position:absolute;inset:0;pointer-events:none;z-index:6;mix-blend-mode:screen}
.sc .atmos-fog i{
  position:absolute;border-radius:50%;
  background:radial-gradient(ellipse at center, rgba(198,212,218,.9), rgba(198,212,218,.28) 52%, transparent 72%);
  filter:blur(26px);
  animation:fogSway var(--dur,34s) ease-in-out infinite alternate;
  animation-delay:var(--delay,0s);
}
@keyframes fogSway{
  0%{transform:translate3d(-6%,2%,0) scale(1)}
  100%{transform:translate3d(7%,-3%,0) scale(1.22)}
}

/* --- 浮尘 --- */
.sc .atmos-dust{position:absolute;inset:0;pointer-events:none;z-index:7}
.sc .atmos-dust i{
  position:absolute;border-radius:50%;background:rgba(255,250,235,.9);
  box-shadow:0 0 3px rgba(255,245,220,.7);
  animation:dustUp var(--dur,18s) linear infinite;
  animation-delay:var(--delay,0s);
}
@keyframes dustUp{
  0%{transform:translate(0,0);opacity:0}
  12%{opacity:1}
  85%{opacity:.6}
  100%{transform:translate(17px,-84px);opacity:0}
}

/* --- 场景字幕条 */
.sc .capwrap{
  position:absolute;left:0;right:0;bottom:0;z-index:12;pointer-events:none;
  padding:8% 7% 5%;
  background:linear-gradient(0deg,rgba(0,0,0,.72),transparent);
}
.sc .cap{
  font-family:var(--serif);font-size:clamp(13px,1.6vw,17px);line-height:1.9;
  color:#e6dcc6;letter-spacing:.5px;text-shadow:0 1px 6px rgba(0,0,0,.9);
}
.sc .cap b{color:#fff}

/* ============================================================
   可选增强：SVG 毛边滤镜
   —— 默认关闭。开启时若浏览器不支持/出错，视觉上只是"少了点毛边"，
      绝不会黑屏（因为 base 图始终有 CSS 滤镜兜底）
   ============================================================ */
.sc.rough img.base{filter:var(--roughFilter)}

/* ============================================================
   无障碍：尊重「减少动效」系统偏好
   ============================================================ */
@media (prefers-reduced-motion: reduce){
  .sc *{animation-duration:.001s !important;animation-iteration-count:1 !important}
}

/* 手动暂停（给用户一个开关） */
body.still .sc *{animation-play-state:paused !important}

/* ═══ 手机端：负 inset/偏移会撑破屏幕，这里全部归零（电脑端保持原特效）═══ */
@media (max-width:640px){
  .fog{inset:0}
  .grain{inset:0}
  .rain{inset:0}
  .bleed{inset:0}
  .beam{left:0;right:0;top:0}
}
