/* 演出模式（视觉小说，assets/js/vn.js）。2026-10-29 定调：画面铺满全屏；上下两道薄渐暗托住字幕，重要时刻（is-wide）退开、画面全开；
   叙述 = 下方电影字幕；对白浮在说话人身旁、名字是一笔签名；字像墨迹一个个写上去，先湿后干；每个人有自己的字。 */
@font-face { font-family: 'VNScript'; src: url(../fonts/script/LongCang.woff2) format('woff2'); font-display: block; } /* 开场雾上的花体（龙藏 Long Cang，只含开场要写的字；vn.js 再把笔画削细） */
.vn { position: fixed; inset: 0; z-index: 310; overflow: hidden; background: #050507; color: #ece4d4; font-family: var(--serif); user-select: none; }
.vn[hidden] { display: none; }
.vn button { font-family: var(--serif); }

/* ---------- 舞台 ---------- */
.vn-stage, .vn-bgs, .vn-bg, .vn-face { position: absolute; inset: 0; }
.vn-stage { z-index: 0; overflow: hidden; }
.vn-bg { width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: filter .9s; }
.vn-bg.is-on { opacity: 1; }
.vn-bgs { transform-origin: 0 0; transition: transform 9s cubic-bezier(.25, .1, .25, 1), filter 1.8s; will-change: transform; }
.vn[data-tone="cold"] .vn-bgs { filter: saturate(.8) brightness(.94) hue-rotate(-6deg); }
.vn[data-tone="thaw"] .vn-bgs { filter: saturate(.95) brightness(1.02) sepia(.12); }
.vn[data-tone="warm"] .vn-bgs { filter: saturate(1.05) brightness(1) sepia(.16); }
.vn.is-talk .vn-bg { filter: blur(2.2px); }           /* 对焦转移：有人说话时背景虚掉 */
.vn-flash, .vn-dark { position: absolute; inset: 0; opacity: 0; pointer-events: none; }
.vn-flash { background: #fff6e4; } .vn-dark { background: #000; }

/* 场景上的火光、钟表指针 */
.vn-glow { position: absolute; border-radius: 50%; pointer-events: none; mix-blend-mode: screen; background: radial-gradient(closest-side, rgba(255, 170, 80, .55), rgba(255, 120, 40, .18) 55%, transparent); animation: vnFlicker 1.8s ease-in-out infinite alternate; }
@keyframes vnFlicker { 0% { opacity: .55; transform: scale(.96); } 30% { opacity: .9; } 55% { opacity: .62; transform: scale(1.03); } 80% { opacity: 1; } 100% { opacity: .7; transform: scale(.99); } }
.vn-dial { position: absolute; pointer-events: none; }
.vn-dial svg { width: 100%; height: 100%; overflow: visible; filter: drop-shadow(2px 4px 3px rgba(0, 0, 0, .45)); }
.vn-dial g { transform-origin: 0 0; transition: transform .12s cubic-bezier(.3, 2.2, .5, 1); }
.vn-dial .h path, .vn-dial .m path { fill: #17120d; } .vn-dial .h circle { stroke: #17120d; }
.vn-dial .s path { stroke: #7a1c10; stroke-width: 1.3; } .vn-dial .s circle { fill: #7a1c10; }

/* 镜中的脸（镜前改容）：5 帧叠在一起 */
.vn-face { opacity: 0; pointer-events: none; perspective: 900px; }
.vn-face.is-on { opacity: 1; }
.vn-face img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vn-mote { position: absolute; width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px; border-radius: 50%; background: #ffe6a8; box-shadow: 0 0 8px 2px rgba(255, 214, 140, .8); pointer-events: none; }
.vn-glint { position: absolute; width: 46px; height: 46px; margin: -23px 0 0 -23px; pointer-events: none;
  background: radial-gradient(closest-side, rgba(255, 240, 200, .95), transparent), linear-gradient(transparent 47%, rgba(255, 240, 200, .9) 50%, transparent 53%), linear-gradient(90deg, transparent 47%, rgba(255, 240, 200, .9) 50%, transparent 53%); }

/* 立绘：站在画面里；说话的人亮起、往前一步；不说话的退暗、虚一点 */
.vn-cast { position: absolute; inset: 0; pointer-events: none; transition: opacity .6s; }
.vn-cast.is-away { opacity: 0; }
.vn-who { position: absolute; bottom: -4vh; height: 100vh; opacity: 0; transition: opacity .7s, transform .7s cubic-bezier(.2, .8, .2, 1), filter .5s; }
.vn-who img { height: 100%; width: auto; display: block; -webkit-mask: linear-gradient(#000 80%, transparent); mask: linear-gradient(#000 80%, transparent); }
.vn-who[data-side="left"] { left: max(2vw, calc(50vw - 760px)); transform: translateX(-50px); }
.vn-who[data-side="right"] { right: max(2vw, calc(50vw - 760px)); transform: translateX(50px); }
.vn-who.is-on { opacity: 1; transform: none; filter: brightness(.85); }
.vn-cast.has-say .vn-who.is-on:not(.is-say) { filter: brightness(.45) saturate(.6) blur(2px); }
.vn-who.is-on.is-say { filter: brightness(1.04); }
.vn-who.is-on.is-say[data-side="left"] { transform: translateX(18px); }
.vn-who.is-on.is-say[data-side="right"] { transform: translateX(-18px); }
.vn-who.is-on[data-mood="shy"] { transform: translateY(12px) scale(.985); filter: brightness(.8); }
.vn-who[data-who="nancy"].is-say img { animation: vnHop .5s cubic-bezier(.3, 1.8, .5, 1); }
@keyframes vnHop { 40% { transform: translateY(-14px); } }

/* 上下两道薄渐暗：重要时刻退开 */
.vn-bar { position: absolute; left: 0; right: 0; z-index: 2; pointer-events: none; transition: opacity 1.1s cubic-bezier(.6, 0, .2, 1); }
.vn-bar.is-top { top: 0; height: 9vh; background: linear-gradient(rgba(2, 2, 4, .7), transparent); }
.vn-bar.is-bot { bottom: 0; height: 30vh; background: linear-gradient(transparent, rgba(2, 2, 4, .5) 45%, rgba(2, 2, 4, .86)); }
.vn.is-wide .vn-bar, .vn.is-opening .vn-bar { opacity: 0; }
.vn.is-wide:not(.is-boxless) .vn-bar.is-bot { opacity: .55; }   /* 全开时字幕下仍留一点点托底 */
/* 暗影关掉（默认）：不压暗角，上下渐层只留字幕底下薄薄一层托字，画面回到原亮度 */
.vn:not(.is-shade) .vn-bar.is-top { background: linear-gradient(rgba(2, 2, 4, .32), transparent); height: 7vh; }
.vn:not(.is-shade) .vn-bar.is-bot { background: linear-gradient(transparent, rgba(2, 2, 4, .22) 50%, rgba(2, 2, 4, .5)); height: 24vh; }
.vn:not(.is-shade)[data-tone="cold"] .vn-bgs { filter: saturate(.85) brightness(1.04) hue-rotate(-6deg); }
.vn:not(.is-shade) .vn-who.is-on { filter: none; }
.vn:not(.is-shade) .vn-line, .vn:not(.is-shade) .vn-name { text-shadow: 0 1px 2px rgba(0, 0, 0, .9), 0 0 14px rgba(0, 0, 0, .55); }

/* 粒子、胶片颗粒、暗角 */
.vn-fx { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.vn-grain { position: absolute; inset: -50%; pointer-events: none; opacity: .09; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1.4 -.2'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: vnGrain .7s steps(6) infinite; }
@keyframes vnGrain { 0% { transform: translate(0, 0); } 20% { transform: translate(-3%, 2%); } 40% { transform: translate(2%, -3%); } 60% { transform: translate(-1%, 3%); } 80% { transform: translate(3%, 1%); } 100% { transform: translate(-2%, -2%); } }
.vn-vig { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity .8s; background: radial-gradient(ellipse 75% 70% at 50% 46%, transparent 55%, rgba(0, 0, 0, .55)); }
.vn.is-shade .vn-vig { opacity: 1; }

/* 开场：雾（canvas）与章号 */
.vn-fog { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 3; opacity: 0; pointer-events: none; }
/* 纸笔：开场写章名的档案纸、墨迹、墨晕的晕边、羽毛笔；结尾的“完”与按钮（vn.js 纸笔一节） */
.vn-paper { position: absolute; inset: 0; z-index: 5; pointer-events: none; transform-origin: 50% 50%; }
.vn-paper[hidden] { display: none; }
.vn-paper-c { position: absolute; inset: 0; width: 100%; height: 100%; }
.vn-ink { position: absolute; inset: 0; transition: opacity .3s; }
.vn-ink canvas { position: absolute; mix-blend-mode: multiply; }
.vn-fringe { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 6; pointer-events: none; filter: blur(9px); mix-blend-mode: multiply; }
.vn-pen { position: absolute; left: 0; top: 0; z-index: 7; height: 34vh; width: auto; opacity: 0; pointer-events: none; filter: drop-shadow(-10px 14px 10px rgba(30, 20, 10, .35)); will-change: transform; }
.vn.is-opening .vn-title { z-index: 8; }
.vn-seal.is-paper { z-index: 2; left: 50%; top: 47%; margin: -40px 0 0 11vh; width: 120px; height: 120px; rotate: 10deg; color: #a8231b; mix-blend-mode: multiply; }
.vn-paper-nav { position: absolute; left: 0; right: 0; bottom: 9vh; display: flex; gap: 14px; justify-content: center; pointer-events: auto; }
.vn-paper-nav[hidden] { display: none; }
.vn-paper-nav button { padding: 8px 20px; font-size: 13px; letter-spacing: .25em; color: #3a2c1e; background: rgba(250, 242, 226, .55); border: 1px solid rgba(58, 44, 30, .35); }
.vn-paper-nav button:hover:not(:disabled) { background: rgba(250, 242, 226, .9); border-color: rgba(58, 44, 30, .7); }
.vn-paper-nav button:disabled { opacity: .45; }
.vn.is-ending .vn-ctl button, .vn.is-ending .vn-time { opacity: 0; pointer-events: none; }
/* 雾散时切出来的几团云（vn.js fogOut），各自飘走 */
.vn-fogbits { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.vn-fogbits canvas { position: absolute; inset: 0; width: 100%; height: 100%; will-change: transform, opacity, filter; }
/* 雾面前两层一直在挪的薄云，让雾是活的；不盖住字太多 */
.vn-mist { position: absolute; inset: 0; z-index: 3; pointer-events: none; opacity: 0; overflow: hidden; }
.vn-mist canvas { position: absolute; left: -20%; top: -20%; width: 140%; height: 140%; opacity: .42; will-change: transform; }
.vn-mist canvas + canvas { opacity: .3; }
.vn-title { position: absolute; inset: 0; z-index: 4; pointer-events: none; text-align: center; }
.vn-title small { position: absolute; left: 0; right: 0; top: 24%; font-family: VNScript, var(--serif); font-size: clamp(22px, 2.2vw, 34px); letter-spacing: .5em; padding-left: .5em; color: rgba(70, 76, 90, .75); opacity: 0; }
.vn-hint { position: absolute; left: 0; right: 0; bottom: 7vh; font-size: 12px; letter-spacing: .6em; padding-left: .6em; color: rgba(60, 66, 80, .6); opacity: 0; transition: opacity 1.4s .6s; }
.vn-title.is-on .vn-hint { opacity: 1; animation: vnBreath 2.4s 2s ease-in-out infinite; }

/* ---------- 字幕与对白（电影式） ---------- */
.vn-box { position: absolute; z-index: 1; left: 50%; bottom: 5.5vh; translate: -50% 0; width: min(900px, 82vw); box-sizing: border-box; text-align: center; transition: opacity .35s, transform .35s; pointer-events: none; }
.vn-box.is-gone { opacity: 0; transform: translateY(14px); }
.vn-line { margin: 0; font-size: clamp(17px, 1.25vw, 20px); line-height: 1.95; letter-spacing: .08em; color: #e6ddcc; }
.vn-next { display: block; margin: 12px auto 0; width: 5px; height: 5px; border-radius: 50%; background: #c9a467; opacity: 0; }
.vn-box.is-done .vn-next { opacity: .8; animation: vnNext 1.1s ease-in-out infinite; }
@keyframes vnNext { 50% { translate: 0 4px; opacity: .4; } }
.vn-name { position: relative; display: inline-block; margin: 0 0 10px; padding: 0 0 6px; font-size: 14px; font-style: italic; font-weight: 600; letter-spacing: .55em; }
.vn-name[hidden] { display: none; }
.vn-name::after { content: ''; position: absolute; left: -4px; right: -10px; bottom: 0; height: 1.5px; background: linear-gradient(90deg, currentColor, transparent); transform-origin: left; animation: vnSwash .7s cubic-bezier(.3, .7, .2, 1) both; }
@keyframes vnSwash { from { transform: scaleX(0); } }
/* 对白：浮到说话人身旁，底下一团暗影 */
.vn-box[data-side] { bottom: 24vh; width: min(520px, 38vw); translate: none; text-align: left; }
.vn-box[data-side="left"] { left: calc(max(2vw, 50vw - 760px) + 60vh); }
.vn-box[data-side="right"] { left: auto; right: calc(max(2vw, 50vw - 760px) + 58vh); text-align: right; }
.vn-box[data-side]::before { content: ''; position: absolute; inset: -46px -70px; z-index: -1; background: radial-gradient(closest-side, rgba(3, 3, 5, .78), rgba(3, 3, 5, .45) 60%, transparent); }
.vn-box[data-side] .vn-next { margin: 10px 0 0; }
.vn-box[data-side="right"] .vn-next { margin-left: auto; }
.vn-box[data-side="right"] .vn-name::after { background: linear-gradient(270deg, currentColor, transparent); transform-origin: right; }
/* 各人的字 */
.vn-box[data-who="nancy"] { color: #f4c48a; }
.vn-box[data-who="nancy"] .vn-line { color: #f8dcb4; font-size: clamp(18.5px, 1.38vw, 22px); letter-spacing: .04em; }
.vn-box[data-who="nancy"] .k:not(.is-fast) { display: inline-block; animation: vnInk .8s ease-out both, vnHopK .45s cubic-bezier(.3, 1.9, .5, 1) both; }
@keyframes vnHopK { 40% { transform: translateY(-5px); } }
.vn-box[data-who="vera"][data-look="clerk"], .vn-box[data-who="vera"][data-look="shy"] { color: #9ea8b2; }
.vn-box[data-who="vera"][data-look="clerk"] .vn-line, .vn-box[data-who="vera"][data-look="shy"] .vn-line { color: #c3cad1; font-size: clamp(15.5px, 1.12vw, 18px); letter-spacing: .02em; }
.vn-box[data-who="vera"][data-look="home"] { color: #e9a36a; }
.vn-box[data-who="vera"][data-look="home"] .vn-line { color: #f5d6b4; font-weight: 600; letter-spacing: .07em; transform: rotate(-1.2deg); transform-origin: left; }
.vn-box[data-who="vera"][data-look="eleanor"] { color: #b9a6d8; }
.vn-box[data-who="vera"][data-look="eleanor"] .vn-line { color: #e2d8f0; letter-spacing: .1em; }
.vn-box.is-inner .vn-line { color: #d3cbe0; font-style: italic; letter-spacing: .14em; }
/* 墨迹：先湿亮、后收干 */
.vn .k { animation: vnInk .9s ease-out both; }
.vn .k.is-fast { animation-duration: .35s; }
@keyframes vnInk { 0% { opacity: 0; filter: blur(3px); text-shadow: 0 0 14px rgba(255, 236, 200, .9); } 35% { opacity: 1; filter: blur(.4px); text-shadow: 0 0 8px rgba(255, 236, 200, .5); } 100% { opacity: 1; filter: none; text-shadow: 0 1px 3px rgba(0, 0, 0, .8); } }

/* 自动段的大字（“当——”） */
.vn-big { position: absolute; z-index: 4; left: 0; right: 0; top: 40%; text-align: center; font-size: clamp(40px, 5vw, 76px); letter-spacing: .6em; color: #fff1d6; text-shadow: 0 0 40px rgba(255, 210, 150, .6), 0 2px 6px #000; pointer-events: none; opacity: 0; }

/* ---------- 动作拍 ---------- */
.vn-act { position: absolute; inset: 0; z-index: 5; display: none; }
.vn-act.is-on { display: block; }
.vn-cue { position: absolute; left: 0; right: 0; bottom: 7vh; margin: 0; text-align: center; font-size: 16px; letter-spacing: .5em; color: #f0dcb4; text-shadow: 0 2px 6px #000; animation: vnBreath 2.2s ease-in-out infinite; pointer-events: none; }
.vn-cue small { display: block; margin-top: 8px; font-size: 11px; letter-spacing: .35em; color: rgba(240, 220, 180, .6); }
@keyframes vnBreath { 50% { opacity: .5; } }
.vn-ta { position: absolute; top: 46%; font-size: 44px; font-weight: 900; color: #f5e6c8; text-shadow: 0 3px 8px #000; pointer-events: none; }
.vn-skipact { position: absolute; right: 22px; bottom: 22px; padding: 5px 14px; font-size: 12px; letter-spacing: .25em; color: rgba(241, 232, 220, .7); background: rgba(9, 9, 13, .5); border: 1px solid rgba(241, 232, 220, .22); }
/* 推以太：黄铜圆片上的一圈，按住慢慢填满 */
.vn-ring { position: absolute; width: 120px; height: 120px; margin: -60px 0 0 -60px; pointer-events: none; filter: drop-shadow(0 0 calc(6px + var(--p, 0) * 24px) rgba(255, 210, 120, .9)); }
.vn-ring svg { width: 100%; height: 100%; rotate: -90deg; }
.vn-ring circle { fill: none; stroke-width: 3; }
.vn-ring .bg { stroke: rgba(255, 230, 180, .25); }
.vn-ring .fg { stroke: #ffd890; stroke-linecap: round; }
/* 首饰箱里会发光的那一样 */
.vn-spot { position: absolute; width: 110px; height: 110px; margin: -55px 0 0 -55px; border-radius: 50%; border: 1px solid rgba(255, 220, 160, .7); background: radial-gradient(closest-side, rgba(255, 210, 150, .25), transparent); animation: vnSpot 1.6s ease-in-out infinite; }
@keyframes vnSpot { 50% { transform: scale(1.12); box-shadow: 0 0 24px rgba(255, 210, 150, .5); } }
/* 十二根拨针 */
.vn-pins { position: absolute; z-index: 4; left: 50%; top: 50%; width: 360px; height: 220px; margin: -110px 0 0 -180px; pointer-events: none; }
.vn-pins i { position: absolute; left: 50%; bottom: 20px; width: 1.5px; height: 150px; background: linear-gradient(transparent, rgba(220, 235, 255, .95)); box-shadow: 0 0 6px rgba(200, 225, 255, .8); transform-origin: bottom; transform: rotate(calc((var(--k) - 5.5) * 7deg)); }
.vn-pins b { position: absolute; left: 0; right: 0; bottom: -30px; text-align: center; font-size: 34px; font-weight: 400; letter-spacing: .2em; color: #dfe9ff; text-shadow: 0 0 12px rgba(200, 225, 255, .8); }
.vn-shade { position: absolute; width: 520px; height: 620px; margin: -310px 0 0 -260px; pointer-events: none; background: radial-gradient(closest-side, rgba(0, 0, 0, .55), transparent); }
/* 红印 */
.vn-seal { position: absolute; z-index: 4; width: 110px; height: 110px; color: #b3261e; mix-blend-mode: screen; pointer-events: none; }
.vn-seal.is-corner { right: 6vw; top: 12vh; rotate: -12deg; }
.vn-seal.is-end { z-index: 8; left: 50%; top: 50%; margin: -175px 0 0 150px; width: 140px; height: 140px; rotate: 9deg; }
.vn-seal svg { width: 100%; height: 100%; font-family: var(--serif); }

/* ---------- 上方的按钮、角落时间 ---------- */
.vn-top { position: absolute; z-index: 6; left: 0; right: 0; top: 0; display: flex; align-items: center; gap: 14px; padding: 14px 18px; transition: opacity .4s; }
.vn-top.is-gone { opacity: 0; pointer-events: none; }
.vn-back { padding: 6px 14px; font-size: 13px; letter-spacing: .2em; color: rgba(241, 232, 220, .85); background: rgba(9, 9, 13, .45); border: 1px solid rgba(241, 232, 220, .25); }
.vn-time { font-size: 13px; letter-spacing: .35em; color: rgba(240, 220, 180, .75); text-shadow: 0 1px 4px #000; }
.vn-ctl { margin-left: auto; display: flex; gap: 2px; }
.vn-ctl button { padding: 5px 10px; font-size: 12px; letter-spacing: .25em; color: rgba(241, 232, 220, .55); background: none; border: 0; }
.vn-ctl button:hover, .vn-ctl button.is-on { color: #f0dcb4; }
.vn-skipop { display: none; }
.vn.is-opening .vn-skipop { display: inline-block; color: rgba(241, 232, 220, .7); }
.vn.is-opening .vn-ctl button:not(.vn-skipop), .vn.is-opening .vn-time { opacity: 0; pointer-events: none; }

/* 回看 */
.vn-log { position: absolute; inset: 0; z-index: 8; background: rgba(6, 6, 9, .92); }
.vn-log[hidden] { display: none; }
.vn-log-in { position: absolute; inset: 70px 0 80px; width: min(760px, 90vw); margin: 0 auto; overflow-y: auto; scrollbar-width: thin; }
.vn-log p { margin: 0 0 18px; font-size: 16px; line-height: 1.9; color: rgba(236, 228, 212, .85); }
.vn-log p b { display: block; font-size: 12px; letter-spacing: .4em; color: #c9a467; }
.vn-log p[data-who="nancy"] b { color: #f2b874; }
.vn-log p.is-inner { font-style: italic; opacity: .75; }
.vn-log-x, .vn-end button { padding: 7px 18px; font-size: 13px; letter-spacing: .25em; color: #f1e8dc; background: rgba(11, 10, 10, .6); border: 1px solid rgba(241, 232, 220, .35); }
.vn-log-x { position: absolute; left: 50%; bottom: 26px; translate: -50% 0; }

/* 章末 */
.vn-end { position: absolute; inset: 0; z-index: 7; display: grid; place-content: center; text-align: center; background: radial-gradient(ellipse at 50% 50%, rgba(5, 5, 8, .35), rgba(5, 5, 8, .85)); }
.vn-end[hidden] { display: none; }
.vn-end p { margin: 0; font-size: clamp(22px, 2vw, 30px); letter-spacing: .8em; padding-left: .8em; color: #f0e4cc; }
.vn-end small { display: block; margin: 14px 0 34px; font-size: 12px; letter-spacing: .4em; color: rgba(240, 228, 204, .55); }
.vn-end div { display: flex; gap: 12px; justify-content: center; }

/* 直接打开链接时的“点一下开始” */
.vn-gate { position: absolute; inset: 0; z-index: 9; display: grid; place-items: center; background: rgba(4, 4, 7, .78); border: 0; }
.vn-gate[hidden] { display: none; }
.vn-gate span { font-size: 15px; letter-spacing: .6em; padding-left: .6em; color: #e9e1d3; animation: vnBreath 2.4s ease-in-out infinite; }

@media (max-width: 760px) {
  .vn-who { height: 74vh; } .vn-who.is-on:not(.is-say) { opacity: .4; }
  .vn-box[data-side] { width: 80vw; left: 10vw !important; right: auto !important; bottom: 22vh; text-align: left; }
  .vn-ctl button { padding: 5px 6px; letter-spacing: .1em; }
}
@media (prefers-reduced-motion: reduce) { .vn-grain, .vn-glow, .vn-spot { animation: none; } .vn-bgs { transition: none; } }

/* ===== 第二章（10-30）===== */
/* 心声（10-30 作者定）：世界退半步（变暗、虚焦），维拉本人的半身像从左下浮出；字在下方偏左、手写体、墨红 */
.vn.is-heart .vn-bgs { filter: brightness(.42) saturate(.6) blur(3px) !important; }
.vn-bgs { transition: filter .7s; }
.vn.is-heart .vn-who { filter: brightness(.45) saturate(.7) blur(2.5px) !important; }
.vn.is-heart .vn-box { opacity: 0; }
.vn-self { position: absolute; z-index: 3; left: max(1vw, 50vw - 800px); bottom: 0; height: 68vh; width: auto; opacity: 0; pointer-events: none; transform: translateY(24px) scale(.97); transform-origin: 50% 100%;
  transition: opacity .6s, transform .7s cubic-bezier(.2, .8, .2, 1), filter .6s; filter: drop-shadow(0 0 30px rgba(150, 30, 40, .45));
  -webkit-mask-image: linear-gradient(to top, transparent 0, #000 22%); mask-image: linear-gradient(to top, transparent 0, #000 22%); }
.vn-self.is-on { opacity: 1; transform: none; }
.vn-self.is-past { opacity: .22; filter: blur(2px) drop-shadow(0 0 30px rgba(150, 30, 40, .3)); }
.vn-heart { position: absolute; z-index: 4; left: calc(max(1vw, 50vw - 800px) + 70vh); right: max(4vw, 50vw - 700px); bottom: 7vh; max-width: 760px; opacity: 0; transform: translateY(8px); transition: opacity .5s, transform .5s; pointer-events: none; }
.vn-heart.is-on { opacity: 1; transform: none; }
.vn-heart.is-past { opacity: .35; }
.vn-heart::before { content: ''; position: absolute; inset: -34px -60px -30px -50px; z-index: -1; background: radial-gradient(closest-side, rgba(20, 4, 8, .6), rgba(20, 4, 8, .28) 60%, transparent); }
.vn-heart-line { margin: 0; font-family: 'Long Cang', VNScript, var(--serif); font-size: clamp(24px, 2vw, 33px); line-height: 1.6; letter-spacing: .04em; color: #f0a49b; text-shadow: 0 1px 2px rgba(0, 0, 0, .95), 0 0 16px rgba(60, 0, 10, .8); }
.vn-heart-line .k:not(.is-fast) { animation: vnInk .9s ease-out both; }

/* 登场卡：画面冻住、褪色，只留那个人亮着；左边落下一张档案卡 */
.vn.is-freeze .vn-bgs { filter: grayscale(.92) brightness(.42) contrast(1.15) !important; transition: filter .6s; }
.vn.is-freeze .vn-who:not(.is-card) { opacity: 0 !important; }
.vn.is-freeze .vn-who.is-card { filter: drop-shadow(0 0 40px rgba(170, 30, 24, .45)) contrast(1.08) !important; }
.vn-card { position: absolute; z-index: 4; left: max(5vw, 50vw - 720px); top: 20vh; width: 360px; padding: 26px 32px 28px; box-sizing: border-box; opacity: 0; pointer-events: none; color: #2a1c12;
  background: linear-gradient(rgba(250, 240, 220, .2), rgba(120, 90, 50, .18)), url(../img/ui/paper.jpg) center / cover; box-shadow: 0 18px 40px rgba(0, 0, 0, .65), inset 0 0 0 1px rgba(60, 40, 20, .35), inset 0 0 0 6px rgba(250, 240, 220, .3), inset 0 0 0 7px rgba(60, 40, 20, .25); }
.vn-card small { display: block; font-size: 12px; letter-spacing: .4em; color: #8a2a1e; margin-bottom: 8px; }
.vn-card em { display: block; font-style: normal; font-size: 17px; letter-spacing: .18em; color: #5a3a22; margin-bottom: 2px; }
.vn-card b { display: block; font-family: var(--serif); font-weight: 700; font-size: 36px; letter-spacing: .08em; line-height: 1.3; margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid rgba(60, 40, 20, .4); }
.vn-card span { display: block; font-size: 15px; line-height: 1.9; letter-spacing: .08em; opacity: 0; animation: vnCardLine .6s ease-out forwards; animation-delay: calc(.7s + var(--n) * .35s); }
@keyframes vnCardLine { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }

/* 罗盘的光：一道很淡、斜着的光带从左扫到右（盖在人身上也扫过去） */
.vn-sweep { position: absolute; z-index: 2; top: -10vh; bottom: -10vh; left: 0; width: 26vw; opacity: 0; pointer-events: none; mix-blend-mode: screen;
  background: linear-gradient(90deg, transparent, rgba(170, 210, 255, .12) 30%, rgba(225, 240, 255, .42) 49%, rgba(255, 255, 255, .6) 50%, rgba(225, 240, 255, .42) 51%, rgba(170, 210, 255, .12) 70%, transparent); }

/* 布防图：四个位置依次亮起 */
.vn.is-map .vn-bgs { filter: brightness(.55) saturate(.7) !important; transition: filter .8s; }
.vn-mark { position: absolute; z-index: 4; width: 0; height: 0; pointer-events: none; }
.vn-mark i { position: absolute; left: -22px; top: -22px; width: 44px; height: 44px; border-radius: 50%; border: 1.5px solid rgba(220, 70, 60, .9); box-shadow: 0 0 18px rgba(220, 60, 50, .6); animation: vnMark 1.6s ease-out infinite; }
.vn-mark span { position: absolute; left: 30px; top: -12px; white-space: nowrap; font-family: VNScript, var(--serif); font-size: 22px; color: #f3d9c8; text-shadow: 0 1px 3px #000, 0 0 12px rgba(0, 0, 0, .8); }
@keyframes vnMark { 0% { transform: scale(.7); opacity: 1; } 100% { transform: scale(1.5); opacity: 0; } }

/* 回忆：褪色、偏暖、四角压暗 */
.vn.is-memory .vn-bgs { filter: sepia(.55) saturate(.75) brightness(.92) contrast(.95) !important; }
.vn.is-memory .vn-vig { opacity: 1; }

/* 收卷：纸卷（纸的纹理 + 圆柱的明暗） */
.vn-roll { position: absolute; left: -1%; right: -1%; z-index: 9; border-radius: 12px / 50%; pointer-events: none;
  background: linear-gradient(rgba(60, 38, 18, .7), rgba(255, 244, 222, .1) 38%, rgba(255, 250, 235, .25) 48%, rgba(60, 38, 18, .75)), url(../img/ui/paper.jpg) center / 100% 900%;
  box-shadow: 0 8px 14px rgba(0, 0, 0, .45); }

/* 第二章说话的人 */
.vn-box[data-who="vera"][data-look="ball"] { color: #c3a6d6; }
.vn-box[data-who="vera"][data-look="ball"] .vn-line { color: #ece0f2; letter-spacing: .1em; }
.vn-box[data-who="merchant"] { color: #e7bd5a; }
.vn-box[data-who="merchant"] .vn-line { color: #f4dfa8; font-size: clamp(18px, 1.35vw, 21.5px); font-weight: 600; letter-spacing: .03em; }
.vn-box[data-who="baron"] { color: #d9cdb4; }
.vn-box[data-who="baron"] .vn-line { color: #ece4d2; letter-spacing: .12em; }
.vn-box[data-who="stern"] { color: #a9b7c6; }
.vn-box[data-who="stern"] .vn-line { color: #dfe6ee; letter-spacing: .02em; font-weight: 600; }
.vn-box[data-who="noble"], .vn-box[data-who="young"] { color: #c9c2b6; }
.vn-box[data-who="noble"] .vn-line { color: #ebe4d8; letter-spacing: .02em; }

/* ===== 第三章（10-30）===== */
/* 破译：拖着光扫过古卷，浮出的金色译字 */
.vn-decipher { position: absolute; inset: 0; width: 100%; height: 100%; cursor: none; }
/* 搭回路：淡金白色的以太线、双层钟表齿轮（照正本第 12 章） */
.vn-circuit { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 4; pointer-events: none; overflow: visible; filter: drop-shadow(0 0 6px rgba(255, 220, 150, .9)) drop-shadow(0 0 18px rgba(255, 190, 90, .45)); }
.vn-circuit path, .vn-circuit circle, .vn-circuit line { fill: none; stroke: rgba(255, 240, 210, .92); stroke-width: 1.4; }
.vn-circuit .c-guide { stroke: rgba(255, 230, 180, .45); stroke-dasharray: 6 8; animation: vnGuide 1.4s linear infinite; }
@keyframes vnGuide { to { stroke-dashoffset: -28; } }
.vn-circuit .c-draw { stroke-width: 2; }
.vn-circuit .c-arc { stroke-width: 1.1; transform-box: fill-box; transform-origin: center; }
.vn-circuit .c-tail { stroke-width: 1.8; }
.vn-circuit .c-start { stroke: rgba(255, 240, 210, .9); stroke-width: 2; animation: vnMark 1.4s ease-out infinite; transform-box: fill-box; transform-origin: center; }
.vn-circuit .c-end { fill: rgba(255, 236, 200, .95); stroke: none; filter: drop-shadow(0 0 10px #ffd27a); }
.vn-circuit.is-spinning .c-outer { animation: vnSpin 14s linear infinite; }
.vn-circuit.is-spinning .c-spin { animation: vnSpin 6s linear infinite reverse; }
.vn-circuit .c-outer, .vn-circuit .c-spin { transform-box: fill-box; transform-origin: center; }
@keyframes vnSpin { to { rotate: 360deg; } }
/* 头痛：重影（同一画面错开一层）、泛红、字幕抖 */
.vn-ghost { position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: .45; mix-blend-mode: screen; animation: vnGhost 1.6s ease-in-out infinite alternate; }
.vn-ghost .g-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vn-ghost .vn-who { opacity: 1 !important; transform: none; }
@keyframes vnGhost { from { transform: translate(14px, -6px); } to { transform: translate(-10px, 5px); } }
.vn.is-hurt .vn-stage::after { content: ''; position: absolute; inset: 0; z-index: 3; pointer-events: none; background: radial-gradient(ellipse at 50% 50%, transparent 35%, rgba(120, 0, 10, .55)); animation: vnPulse 1.5s ease-in-out infinite; }
@keyframes vnPulse { 0%, 100% { opacity: .55; } 12% { opacity: 1; } 30% { opacity: .7; } }
.vn.is-hurt .vn-bgs { filter: saturate(.7) contrast(1.1) blur(1.2px) !important; }
.vn.is-hurt .vn-line { animation: vnShake .18s steps(2) infinite; }
@keyframes vnShake { 0% { transform: translate(1px, 0); } 50% { transform: translate(-1px, 1px); } }
/* 单片镜：中间一个圆镜片，四周压暗；纯银滚花镜圈；以太痕迹在“以太残留”模式下亮起 */
.vn-lens { position: absolute; inset: 0; z-index: 3; pointer-events: none; opacity: 0; transition: opacity .6s; --lr: 34vh; }
.vn.is-lens .vn-lens { opacity: 1; }
.vn-lens::before { content: ''; position: absolute; inset: 0; background: radial-gradient(circle at 50% 46%, transparent calc(var(--lr) - 2px), rgba(4, 4, 8, .82) var(--lr)); }
.vn-traces { position: absolute; inset: 0; opacity: 0; transition: opacity 1.2s; }
.vn-lens.is-tuned .vn-traces { opacity: 1; }
.vn-trace { position: absolute; border-radius: 50%; background: radial-gradient(circle, rgba(170, 230, 255, .95), rgba(120, 190, 255, .45) 40%, transparent 70%); mix-blend-mode: screen; animation: vnTrace 2.6s ease-in-out infinite; }
.vn-lens.is-ping .vn-trace { filter: brightness(2.2); }
@keyframes vnTrace { 0%, 100% { opacity: .6; transform: scale(.92); } 50% { opacity: 1; transform: scale(1.08); } }
.vn-lens-ring { position: absolute; left: 50%; top: 46%; width: calc(var(--lr) * 2.2); height: calc(var(--lr) * 2.2); transform: translate(-50%, -50%); transition: transform .25s; overflow: visible; filter: drop-shadow(0 0 8px rgba(0, 0, 0, .8)); }
.vn-lens-ring circle { fill: none; stroke: #c9ced6; }
.vn-lens-ring .o { stroke-width: 5; stroke: #aab0b8; } .vn-lens-ring .i { stroke-width: 1.5; stroke: rgba(220, 225, 232, .7); }
.vn-lens-ring line { stroke: #e3e7ec; stroke-width: 1.2; }
.vn-lens-ring .knob circle { fill: #e8ecf0; stroke: none; }
.vn-lens-mode { position: absolute; left: 50%; top: calc(46% + var(--lr) * 1.16); transform: translateX(-50%); font-size: 14px; letter-spacing: .5em; padding-left: .5em; color: #dfe6ee; text-shadow: 0 1px 3px #000; opacity: 0; transition: opacity .4s; }
.vn.is-lens .vn-lens-mode { opacity: .85; }
/* 图纸路线：试过的（褪色墨线 + 红叉 + 理由）、找到的（金线一路亮到地下） */
.vn-routes { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; }
.vn-routes path { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.vn-routes .r-try { stroke: rgba(60, 35, 20, .85); stroke-width: 3; stroke-dasharray: 6 6; }
.vn-routes .r-ok { stroke: rgba(255, 210, 120, .95); stroke-width: 4; filter: drop-shadow(0 0 6px rgba(255, 200, 90, .9)); }
.vn-routes .r-ok.is-lit { animation: vnLit 1.6s ease-in-out infinite; }
@keyframes vnLit { 50% { filter: drop-shadow(0 0 16px rgba(255, 210, 110, 1)); } }
.vn-routes .r-x path { stroke: #b3261e; stroke-width: 5; }
.vn-routes .r-x text { fill: #8a1f17; font-family: 'Long Cang', VNScript, serif; font-size: 26px; }
/* 账目卡：不冻结画面的那种卡 */
.vn-card.is-plain { left: auto; right: max(5vw, 50vw - 720px); top: 16vh; width: 400px; }
/* 第三章说话的人 */
.vn-box[data-who="vera"][data-look="clerk-tea"] { color: #9ea8b2; }
.vn-box[data-who="vera"][data-look="clerk-tea"] .vn-line { color: #c3cad1; font-size: clamp(15.5px, 1.12vw, 18px); letter-spacing: .02em; }
.vn-box[data-who="vera"][data-look^="ball-"] { color: #c3a6d6; }
.vn-box[data-who="vera"][data-look^="ball-"] .vn-line { color: #ece0f2; letter-spacing: .1em; }
.vn-box[data-who="karl"] { color: #c8b48a; }
.vn-box[data-who="karl"] .vn-line { color: #efe3c6; letter-spacing: .01em; }
.vn-box[data-who="duke"] { color: #e8b04a; }
.vn-box[data-who="duke"] .vn-line { color: #f6dda2; font-size: clamp(19px, 1.45vw, 23px); font-weight: 700; letter-spacing: .04em; }
