@oh-story/dsh 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/README.md +17 -11
  2. package/lib/client.js +85 -35
  3. package/lib/client.js.map +3 -3
  4. package/lib/drama/manifest.json +41 -36
  5. package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +340 -13
  6. package/lib/drama/skills/short-drama-assets/references/voice-direction.md +4 -2
  7. package/lib/drama/skills/short-drama-edit/SKILL.md +32 -12
  8. package/lib/drama/skills/short-drama-edit/references/still-cuts.md +90 -0
  9. package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1035 -145
  10. package/lib/drama/skills/short-drama-edit/scripts/selftest.py +48 -0
  11. package/lib/drama/skills/short-drama-produce/SKILL.md +6 -1
  12. package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +12 -0
  13. package/lib/drama/skills/short-drama-produce/scripts/production_tool.py +138 -9
  14. package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +6 -0
  15. package/lib/drama/skills/short-drama-storyboard/SKILL.md +2 -0
  16. package/lib/drama/skills/short-drama-storyboard/references/production-shot-grammar.md +3 -1
  17. package/lib/drama/skills/short-drama-video-prompts/SKILL.md +7 -0
  18. package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +14 -0
  19. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +19 -6
  20. package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +1 -0
  21. package/lib/drama/skills/short-drama-video-prompts/references/target-model-profile.md +5 -0
  22. package/lib/drama/skills/short-drama-video-prompts/references/wan-3.0.md +4 -1
  23. package/lib/index.js +16 -7
  24. package/lib/index.js.map +2 -2
  25. package/lib/novel-to-game/README.md +98 -44
  26. package/lib/novel-to-game/README_ZH.md +100 -46
  27. package/lib/novel-to-game/VERSION +1 -1
  28. package/lib/novel-to-game/examples/jin-ping-mei/build/BUILD_BRIEF.md +27 -202
  29. package/lib/novel-to-game/examples/jin-ping-mei/build/app/RUN.md +23 -115
  30. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/chamber.webp +0 -0
  31. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/court_night.webp +0 -0
  32. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/court_rain.webp +0 -0
  33. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/garden.webp +0 -0
  34. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/hall.webp +0 -0
  35. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/kitchen.webp +0 -0
  36. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/street.webp +0 -0
  37. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/street_dawn.webp +0 -0
  38. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/bg/temple.webp +0 -0
  39. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/yue/moon.webp +0 -0
  40. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/meng/angry.webp +0 -0
  41. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/meng/blush.webp +0 -0
  42. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/meng/neutral.webp +0 -0
  43. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/meng/sad.webp +0 -0
  44. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/meng/smile.webp +0 -0
  45. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/meng/surprised.webp +0 -0
  46. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pan/angry.webp +0 -0
  47. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pan/blush.webp +0 -0
  48. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pan/neutral.webp +0 -0
  49. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pan/sad.webp +0 -0
  50. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pan/smile.webp +0 -0
  51. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pan/surprised.webp +0 -0
  52. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pinger/angry.webp +0 -0
  53. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pinger/blush.webp +0 -0
  54. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pinger/neutral.webp +0 -0
  55. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pinger/sad.webp +0 -0
  56. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pinger/smile.webp +0 -0
  57. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/pinger/surprised.webp +0 -0
  58. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/xuee/angry.webp +0 -0
  59. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/xuee/blush.webp +0 -0
  60. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/xuee/neutral.webp +0 -0
  61. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/xuee/sad.webp +0 -0
  62. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/xuee/smile.webp +0 -0
  63. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/xuee/surprised.webp +0 -0
  64. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/yue/angry.webp +0 -0
  65. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/yue/blush.webp +0 -0
  66. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/yue/neutral.webp +0 -0
  67. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/yue/sad.webp +0 -0
  68. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/yue/smile.webp +0 -0
  69. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/sprite/yue/surprised.webp +0 -0
  70. package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/style.css +326 -2503
  71. package/lib/novel-to-game/examples/jin-ping-mei/build/app/index.html +71 -4
  72. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/adv.js +221 -0
  73. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/audio.js +113 -257
  74. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/main.js +511 -3026
  75. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/menus.js +277 -0
  76. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/petals.js +67 -0
  77. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/stage.js +180 -0
  78. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/store.js +70 -0
  79. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/common.js +198 -0
  80. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/common2.js +204 -0
  81. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/common3.js +198 -0
  82. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/dates.js +186 -0
  83. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/index.js +122 -0
  84. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/meng.js +190 -0
  85. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/pan.js +212 -0
  86. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/pinger.js +198 -0
  87. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/xuee.js +199 -0
  88. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/story/yue.js +214 -0
  89. package/lib/novel-to-game/examples/jin-ping-mei/build/app/package.json +2 -2
  90. package/lib/novel-to-game/examples/jin-ping-mei/build/art/generated-art.json +182 -45
  91. package/lib/novel-to-game/examples/jin-ping-mei/qa/README.md +7 -17
  92. package/lib/novel-to-game/examples/jin-ping-mei/qa/verification.json +9 -9
  93. package/lib/novel-to-game/manifest.json +303 -78
  94. package/lib/novel-to-game/skills/game-art-direction/references/art-direction-method.md +7 -2
  95. package/lib/novel-to-game/skills/game-concept/references/concept-method.md +2 -0
  96. package/lib/novel-to-game/skills/game-world-design/references/narrative-design-method.md +2 -0
  97. package/lib/novel-to-game/skills/game-world-design/references/world-design-method.md +9 -0
  98. package/lib/types/client/drama-production-view.d.ts +11 -0
  99. package/lib/types/client/drama-production-view.d.ts.map +1 -1
  100. package/lib/types/client/file-activity.d.ts +1 -1
  101. package/lib/types/client/file-activity.d.ts.map +1 -1
  102. package/lib/types/client/production-prompts.d.ts +7 -1
  103. package/lib/types/client/production-prompts.d.ts.map +1 -1
  104. package/lib/types/client/production-runtime.d.ts +7 -2
  105. package/lib/types/client/production-runtime.d.ts.map +1 -1
  106. package/lib/types/drama-adapters.d.ts.map +1 -1
  107. package/lib/types/skill-provider.d.ts.map +1 -1
  108. package/lib/types/video-project.d.ts.map +1 -1
  109. package/lib/video-recap/CHANGELOG.md +108 -1
  110. package/lib/video-recap/README.en.md +18 -14
  111. package/lib/video-recap/README.md +18 -14
  112. package/lib/video-recap/manifest.json +297 -321
  113. package/lib/video-recap/skills/video-assemble/SKILL.md +18 -16
  114. package/lib/video-recap/skills/video-assemble/references/explicit-audio-mix.md +3 -1
  115. package/lib/video-recap/skills/video-assemble/references/jianying/SOURCE.md +5 -5
  116. package/lib/video-recap/skills/video-assemble/references/packaging.md +4 -4
  117. package/lib/video-recap/skills/video-assemble/references/subtitle-track.md +10 -10
  118. package/lib/video-recap/skills/video-assemble/scripts/adoption/audio_mix_binding.py +13 -2
  119. package/lib/video-recap/skills/video-assemble/scripts/adoption/av_clock.py +109 -0
  120. package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_publish.py +4 -1
  121. package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +2 -9
  122. package/lib/video-recap/skills/video-assemble/scripts/assemble.py +188 -51
  123. package/lib/video-recap/skills/video-assemble/scripts/assemble_constants.py +0 -1
  124. package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +32 -75
  125. package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +8 -15
  126. package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +202 -161
  127. package/lib/video-recap/skills/video-assemble/scripts/codec_peak.py +112 -0
  128. package/lib/video-recap/skills/video-assemble/scripts/export_jianying.py +10 -101
  129. package/lib/video-recap/skills/video-assemble/scripts/jianying/builders.py +44 -475
  130. package/lib/video-recap/skills/video-assemble/scripts/jianying/model.py +1 -22
  131. package/lib/video-recap/skills/video-assemble/scripts/jianying/templates.py +0 -3
  132. package/lib/video-recap/skills/video-assemble/scripts/jianying/timeline_contract.py +36 -103
  133. package/lib/video-recap/skills/video-assemble/scripts/jianying/tracks.py +0 -8
  134. package/lib/video-recap/skills/video-assemble/scripts/jianying/writer.py +28 -203
  135. package/lib/video-recap/skills/video-assemble/scripts/lib.py +20 -34
  136. package/lib/video-recap/skills/video-assemble/scripts/loudness.py +332 -0
  137. package/lib/video-recap/skills/video-assemble/scripts/media.py +158 -38
  138. package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +30 -16
  139. package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +49 -8
  140. package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +17 -6
  141. package/lib/video-recap/skills/video-assemble/scripts/subtitles/core.py +24 -2
  142. package/lib/video-recap/skills/video-assemble/scripts/subtitles/track.py +2 -5
  143. package/lib/video-recap/skills/video-assemble/scripts/subtitles/track_binding.py +2 -9
  144. package/lib/video-recap/skills/video-assemble/scripts/timeline.py +12 -34
  145. package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +3 -4
  146. package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +28 -2
  147. package/lib/video-recap/skills/video-cut/SKILL.md +37 -11
  148. package/lib/video-recap/skills/video-cut/references/shot-review.md +1 -1
  149. package/lib/video-recap/skills/video-cut/scripts/cut.py +2 -34
  150. package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +96 -124
  151. package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +97 -182
  152. package/lib/video-recap/skills/video-cut/scripts/cut_render.py +177 -166
  153. package/lib/video-recap/skills/video-cut/scripts/frame_grid.py +249 -0
  154. package/lib/video-recap/skills/video-cut/scripts/lib.py +0 -3
  155. package/lib/video-recap/skills/video-cut/scripts/media_geometry.py +173 -7
  156. package/lib/video-recap/skills/video-cut/scripts/sentence_boundaries.py +234 -151
  157. package/lib/video-recap/skills/video-cut/scripts/sentence_gate.py +189 -0
  158. package/lib/video-recap/skills/video-cut/scripts/shot_review.py +2 -6
  159. package/lib/video-recap/skills/video-recap/SKILL.md +24 -27
  160. package/lib/video-recap/skills/video-recap/references/audio-routing.md +8 -6
  161. package/lib/video-recap/skills/video-recap/references/config-playbook.md +8 -11
  162. package/lib/video-recap/skills/video-recap/references/data-schema.md +131 -74
  163. package/lib/video-recap/skills/video-recap/references/resource-library.md +17 -1
  164. package/lib/video-recap/skills/video-recap/scripts/doctor.py +51 -268
  165. package/lib/video-recap/skills/video-recap/scripts/final_qc.py +89 -254
  166. package/lib/video-recap/skills/video-recap/scripts/lib.py +81 -70
  167. package/lib/video-recap/skills/video-recap/scripts/library.py +40 -4
  168. package/lib/video-recap/skills/video-recap/scripts/materials.py +13 -80
  169. package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +49 -17
  170. package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +1 -3
  171. package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +86 -116
  172. package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +87 -23
  173. package/lib/video-recap/skills/video-recap/scripts/recap_source.py +0 -39
  174. package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +37 -135
  175. package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +118 -127
  176. package/lib/video-recap/skills/video-recap/scripts/resources/__init__.py +4 -0
  177. package/lib/video-recap/skills/video-recap/scripts/{resource_lock.py → resources/lock.py} +1 -1
  178. package/lib/video-recap/skills/video-recap/scripts/{project_binding.py → resources/project_binding.py} +78 -17
  179. package/lib/video-recap/skills/video-reference/SKILL.md +108 -0
  180. package/lib/video-recap/skills/video-reference/references/reference-schema.md +139 -0
  181. package/lib/video-recap/skills/video-reference/scripts/lib.py +85 -0
  182. package/lib/video-recap/skills/video-reference/scripts/reference.py +96 -0
  183. package/lib/video-recap/skills/video-reference/scripts/reference_check.py +553 -0
  184. package/lib/video-recap/skills/video-reference/scripts/reference_frames.py +122 -0
  185. package/lib/video-recap/skills/video-reference/scripts/reference_measure.py +253 -0
  186. package/lib/video-recap/skills/video-reference/scripts/reference_profile.py +271 -0
  187. package/lib/video-recap/skills/video-script/SKILL.md +9 -7
  188. package/lib/video-recap/skills/video-script/scripts/agent_text.py +18 -267
  189. package/lib/video-recap/skills/video-script/scripts/deslop_qc.py +12 -30
  190. package/lib/video-recap/skills/video-script/scripts/entry_suggestion.py +125 -0
  191. package/lib/video-recap/skills/video-script/scripts/evidence_bundle.py +2 -26
  192. package/lib/video-recap/skills/video-script/scripts/lib.py +5 -15
  193. package/lib/video-recap/skills/video-script/scripts/lint_summary.py +184 -0
  194. package/lib/video-recap/skills/video-script/scripts/narration_lint.py +120 -100
  195. package/lib/video-recap/skills/video-script/scripts/review.py +3 -34
  196. package/lib/video-recap/skills/video-script/scripts/review_grounding.py +20 -46
  197. package/lib/video-recap/skills/video-script/scripts/review_response.py +120 -258
  198. package/lib/video-recap/skills/video-script/scripts/review_runner.py +2 -10
  199. package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +89 -5
  200. package/lib/video-recap/skills/video-script/scripts/validate.py +26 -34
  201. package/lib/video-recap/skills/video-understanding/SKILL.md +29 -4
  202. package/lib/video-recap/skills/video-understanding/references/data-schema.md +5 -22
  203. package/lib/video-recap/skills/video-understanding/scripts/agent_text.py +24 -121
  204. package/lib/video-recap/skills/video-understanding/scripts/asr.py +11 -5
  205. package/lib/video-recap/skills/video-understanding/scripts/asr_timing_evidence.py +15 -24
  206. package/lib/video-recap/skills/video-understanding/scripts/briefing/builder.py +59 -25
  207. package/lib/video-recap/skills/video-understanding/scripts/briefing/context.py +39 -3
  208. package/lib/video-recap/skills/video-understanding/scripts/briefing/inputs.py +15 -27
  209. package/lib/video-recap/skills/video-understanding/scripts/briefing/timeline.py +136 -37
  210. package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +121 -37
  211. package/lib/video-recap/skills/video-understanding/scripts/detect.py +118 -16
  212. package/lib/video-recap/skills/video-understanding/scripts/index_normalize.py +359 -0
  213. package/lib/video-recap/skills/video-understanding/scripts/lib.py +62 -21
  214. package/lib/video-recap/skills/video-understanding/scripts/storyboard.py +181 -51
  215. package/lib/video-recap/skills/video-understanding/scripts/timeline_fusion.py +0 -26
  216. package/lib/video-recap/skills/video-understanding/scripts/understanding_brief.py +37 -14
  217. package/lib/video-recap/skills/video-understanding/scripts/understanding_cache.py +40 -32
  218. package/lib/video-recap/skills/video-understanding/scripts/understanding_runner.py +100 -127
  219. package/lib/video-recap/skills/video-understanding/scripts/understanding_storyboard.py +182 -30
  220. package/lib/video-recap/skills/video-understanding/scripts/vlm.py +30 -27
  221. package/lib/video-recap/skills/video-voiceover/SKILL.md +19 -12
  222. package/lib/video-recap/skills/video-voiceover/references/index-tts.md +3 -3
  223. package/lib/video-recap/skills/video-voiceover/scripts/approved_text_policy.py +3 -1
  224. package/lib/video-recap/skills/video-voiceover/scripts/dub.py +60 -135
  225. package/lib/video-recap/skills/video-voiceover/scripts/lib.py +9 -34
  226. package/lib/video-recap/skills/video-voiceover/scripts/providers/fish_audio.py +6 -1
  227. package/lib/video-recap/skills/video-voiceover/scripts/tts_audio.py +64 -1
  228. package/lib/video-recap/skills/video-voiceover/scripts/tts_cache.py +99 -0
  229. package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +177 -200
  230. package/package.json +45 -45
  231. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/inner_court_accord_five.webp +0 -0
  232. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/cg/group/public_day15.webp +0 -0
  233. package/lib/novel-to-game/examples/jin-ping-mei/build/app/assets/household/li_jiaoer.webp +0 -0
  234. package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/new-guofeng.css +0 -1494
  235. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/assets.js +0 -147
  236. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/data.js +0 -7470
  237. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/engine.js +0 -13066
  238. package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/text.js +0 -32
  239. package/lib/novel-to-game/examples/jin-ping-mei/qa/playable-model.json +0 -99
  240. package/lib/novel-to-game/examples/jin-ping-mei/qa/verify_playable_model.mjs +0 -152
  241. package/lib/video-recap/skills/video-assemble/references/foreground-compose.md +0 -118
  242. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_combination_segment.json +0 -84
  243. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_combination_video_material.json +0 -98
  244. package/lib/video-recap/skills/video-assemble/references/jianying/empty_jy_draft.json +0 -204
  245. package/lib/video-recap/skills/video-assemble/references/pair-media.md +0 -74
  246. package/lib/video-recap/skills/video-assemble/scripts/compose_foreground.py +0 -293
  247. package/lib/video-recap/skills/video-assemble/scripts/pair_media.py +0 -216
  248. package/lib/video-recap/skills/video-recap/references/shift-left-qc-schema.md +0 -23
  249. package/lib/video-recap/skills/video-recap/scripts/mimo_qc.py +0 -33
  250. package/lib/video-recap/skills/video-recap/scripts/qc/__init__.py +0 -1
  251. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_client.py +0 -13
  252. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_contract.py +0 -9
  253. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_evidence.py +0 -287
  254. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_observations.py +0 -175
  255. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_payload.py +0 -206
  256. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_report.py +0 -318
  257. package/lib/video-recap/skills/video-recap/scripts/qc/mimo_runner.py +0 -130
  258. package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +0 -320
  259. package/lib/video-recap/skills/video-script/scripts/timeline_fusion.py +0 -108
  260. package/lib/video-recap/skills/video-understanding/scripts/brief.py +0 -9
  261. package/lib/video-recap/skills/video-understanding/scripts/deslop_qc.py +0 -211
  262. package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +0 -707
  263. package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +0 -143
  264. /package/lib/video-recap/skills/video-cut/scripts/{narration_mapping.py → cut_qc.py} +0 -0
@@ -1,1494 +0,0 @@
1
- /*
2
- * 新国风叙事 CG 主题(2026-08)
3
- *
4
- * 目标不是复刻古画,也不是把古装人物放进现代时尚棚拍。完整保留晚明世界,
5
- * 以当代文字游戏常见的二维人物审美、通透光色、情绪化镜头和丝绸层次重塑界面。
6
- * 白日保持春庭高明度;夜景用蓝紫月光与暖灯形成可读层次,不允许全屏压黑。
7
- */
8
-
9
- :root {
10
- --paper: #fff7ed;
11
- --paper-light: #fffdf8;
12
- --paper-dark: #e7d6c7;
13
- --ink: #292d3b;
14
- --ink-soft: #646676;
15
- --night: #e8edf8;
16
- --night-soft: #d8dfef;
17
- --gold: #b98642;
18
- --gold-bright: #d2a15b;
19
- --cinnabar: #c84f5c;
20
- --jade: #3f8f83;
21
- --honey: #d39847;
22
- --azurite: #355f98;
23
- --lilac: #8c79ad;
24
- --line: rgba(72, 75, 96, .2);
25
- --silk: rgba(255, 250, 245, .9);
26
- --silk-strong: rgba(255, 253, 249, .975);
27
- --cg-shadow: 0 22px 64px rgba(79, 63, 74, .16);
28
- }
29
-
30
- html,
31
- body {
32
- color: var(--ink);
33
- background:
34
- radial-gradient(circle at 14% 10%, rgba(242, 180, 188, .2), transparent 28%),
35
- radial-gradient(circle at 86% 86%, rgba(91, 146, 170, .15), transparent 30%),
36
- #f3e9df;
37
- }
38
-
39
- #app::after {
40
- opacity: .34;
41
- mix-blend-mode: soft-light;
42
- background-image:
43
- radial-gradient(ellipse at 12% 18%, rgba(255,255,255,.9) 0 1px, transparent 2px),
44
- radial-gradient(ellipse at 74% 12%, rgba(229,137,154,.34) 0 1px, transparent 2px),
45
- radial-gradient(circle at 48% 82%, rgba(82,128,152,.22) 0 1px, transparent 2px);
46
- background-size: 31px 37px, 43px 49px, 53px 61px;
47
- }
48
-
49
- .loading,
50
- .fatal-card {
51
- color: var(--ink);
52
- background: linear-gradient(145deg, #fffdf8, #f3e4dd);
53
- }
54
-
55
- .eyebrow { color: var(--cinnabar); }
56
-
57
- /* 年龄门:从明亮宅门进入,而不是穿过一堵黑墙。 */
58
- .age-gate {
59
- color: var(--ink);
60
- background:
61
- linear-gradient(90deg, rgba(255,250,244,.96) 0%, rgba(255,250,244,.86) 45%, rgba(255,250,244,.25) 76%),
62
- url('../assets/bg/compound_new_guofeng.webp') center / cover;
63
- }
64
-
65
- .age-gate::before {
66
- border: 1px solid rgba(185, 127, 92, .26);
67
- background: rgba(255, 248, 242, .12);
68
- box-shadow:
69
- inset 0 0 0 8px rgba(255, 253, 249, .42),
70
- inset 0 0 0 9px rgba(200, 79, 92, .12),
71
- 0 26px 90px rgba(75, 65, 82, .13);
72
- }
73
-
74
- .age-gate p:not(.eyebrow) { color: #5d6070; }
75
-
76
- .age-seal {
77
- color: var(--cinnabar);
78
- border-color: var(--cinnabar);
79
- background: rgba(255, 250, 245, .76);
80
- box-shadow: 0 10px 28px rgba(152, 63, 79, .14);
81
- }
82
-
83
- /* 按钮是剧情签,不是黑色系统框。 */
84
- .ink-button,
85
- .plain-button {
86
- border-color: rgba(80, 91, 120, .28);
87
- color: #343745;
88
- background: rgba(255, 252, 248, .84);
89
- box-shadow: 0 9px 25px rgba(61, 69, 91, .08);
90
- backdrop-filter: blur(8px);
91
- }
92
-
93
- .ink-button:hover:not(:disabled),
94
- .plain-button:hover {
95
- color: #a93345;
96
- border-color: rgba(200, 79, 92, .58);
97
- background: #fffaf7;
98
- }
99
-
100
- .ink-button.primary {
101
- color: #fffaf7;
102
- border-color: #b94050;
103
- background: linear-gradient(145deg, #d96370, #b83f50);
104
- box-shadow: 0 13px 32px rgba(177, 56, 73, .24);
105
- }
106
-
107
- .ink-button.primary:hover:not(:disabled),
108
- .ink-button.primary:focus-visible {
109
- color: #fff;
110
- border-color: #a83546;
111
- background: linear-gradient(145deg, #e06d79, #aa3547);
112
- }
113
-
114
- .ink-button.story-continue {
115
- color: #406d91;
116
- background: transparent;
117
- box-shadow: none;
118
- }
119
-
120
- .ink-button.story-continue:hover:not(:disabled) { color: var(--cinnabar); }
121
-
122
- /* 标题图自带左侧春庭留白,标题直接进入画面,不另做硬分栏。 */
123
- .title-screen {
124
- display: grid;
125
- grid-template-columns: minmax(19rem, 42%) 1fr;
126
- color: var(--ink);
127
- background: #f7e9e2;
128
- }
129
-
130
- .title-art {
131
- background-position: center;
132
- filter: saturate(1.04) contrast(1.01) brightness(1.02);
133
- }
134
-
135
- .title-art::after {
136
- background:
137
- linear-gradient(90deg, rgba(255,250,246,.96) 0%, rgba(255,250,246,.82) 22%, rgba(255,250,246,.18) 45%, transparent 66%),
138
- linear-gradient(0deg, rgba(92,65,83,.1), transparent 45%);
139
- }
140
-
141
- .title-copy {
142
- z-index: 2;
143
- grid-column: 1;
144
- padding: 8vh 2.2vw 7vh 5.3vw;
145
- background: radial-gradient(circle at 30% 48%, rgba(255,255,255,.62), transparent 54%);
146
- }
147
-
148
- .title-copy::before {
149
- right: auto;
150
- left: 2.1vw;
151
- top: 8vh;
152
- color: rgba(192, 66, 85, .08);
153
- }
154
-
155
- .title-copy::after {
156
- content: "";
157
- width: min(18rem, 76%);
158
- height: 3px;
159
- margin: .2rem 0 1.25rem;
160
- order: -1;
161
- background: linear-gradient(90deg, var(--azurite) 0 20%, var(--cinnabar) 20% 40%, #d5aa65 40% 60%, var(--lilac) 60% 80%, var(--jade) 80%);
162
- box-shadow: 0 1px rgba(255,255,255,.86);
163
- }
164
-
165
- .title-copy h1 {
166
- color: #2e3040;
167
- text-shadow: 0 2px rgba(255,255,255,.78);
168
- }
169
-
170
- .title-subtitle { color: #996334; }
171
- .identity-line { color: #545969; border-left-color: var(--cinnabar); }
172
- .rating-line { color: #a74d59; }
173
- .save-note { color: #767786; }
174
-
175
- /* 游戏框架像一层铺在 CG 上的轻绢,不再把画面装进暗木盒。 */
176
- .game-shell { background: #e8e5e7; }
177
-
178
- .topbar {
179
- color: #343846;
180
- border-bottom-color: rgba(64, 96, 135, .22);
181
- background:
182
- linear-gradient(90deg, rgba(255,253,249,.98), rgba(239,245,248,.95) 55%, rgba(255,241,238,.97));
183
- box-shadow: 0 8px 30px rgba(65, 71, 91, .12);
184
- }
185
-
186
- .day-mark { border-right-color: rgba(64, 96, 135, .18); }
187
- .day-mark b { color: #7a5a2e; }
188
- .day-mark span,
189
- .hud-notice { color: #707383; }
190
- .hud-notice.urgent { color: #a93647; background: rgba(200,79,92,.08); }
191
- .top-actions #btn-mute { color: #6e7180; }
192
-
193
- .phase-stage,
194
- .dialogue-stage,
195
- .night-talk-stage,
196
- .scene-view { background: #e7e4e7; }
197
-
198
- #app .visual-stage::before { filter: saturate(1.01) contrast(1.01) brightness(1.03); }
199
-
200
- #app .visual-stage::after {
201
- background:
202
- linear-gradient(180deg, rgba(255,248,244,.02), rgba(77,72,91,.08)),
203
- radial-gradient(120% 96% at 76% 36%, transparent 55%, rgba(70,64,89,.11) 100%);
204
- }
205
-
206
- /* 通用对话与账册面板。 */
207
- .decision-panel,
208
- .confirm-card,
209
- .gallery-book,
210
- .roster-sheet,
211
- .epilogue-copy,
212
- .fate-coda-copy {
213
- color: var(--ink);
214
- border-color: rgba(86, 92, 119, .22);
215
- background:
216
- linear-gradient(145deg, var(--silk-strong), rgba(245, 236, 236, .94));
217
- box-shadow: var(--cg-shadow);
218
- backdrop-filter: blur(16px) saturate(.9);
219
- }
220
-
221
- .decision-panel::before,
222
- .confirm-card::before {
223
- content: "";
224
- position: absolute;
225
- inset: 7px;
226
- pointer-events: none;
227
- border: 1px solid rgba(200, 79, 92, .09);
228
- }
229
-
230
- .phase-header h2,
231
- .decision-panel h2,
232
- .confirm-card h2,
233
- .gallery-book h2,
234
- .roster-sheet h2 { color: #303342; }
235
-
236
- .phase-header > p:last-child,
237
- .phase-lead,
238
- .speaker-line,
239
- .consent-note,
240
- .want-line { color: #626574; }
241
-
242
- .morning-note,
243
- .day-speaker,
244
- .want-line {
245
- border-left-color: rgba(200,79,92,.58);
246
- color: #575b69;
247
- background: rgba(217,99,112,.055);
248
- }
249
-
250
- .choice-button {
251
- color: #343745;
252
- border: 1px solid rgba(79, 91, 120, .18);
253
- border-left: 4px solid rgba(78, 125, 155, .58);
254
- background: rgba(255,253,249,.76);
255
- box-shadow: 0 7px 22px rgba(66,68,89,.06);
256
- }
257
-
258
- .choice-button span { color: #676a79; }
259
- .choice-button:hover:not(:disabled):not([aria-disabled="true"]),
260
- .choice-button:focus-visible {
261
- border-color: rgba(200,79,92,.5);
262
- border-left-color: var(--cinnabar);
263
- background: #fffaf7;
264
- box-shadow: 0 10px 27px rgba(141,65,81,.1);
265
- }
266
-
267
- .story-progress { color: #9b6d3a; }
268
- .story-progress b { color: #4c5060; }
269
-
270
- /* 五扇院门像角色卡面,但仍属于同一个古代庭院。 */
271
- .visit-prompt {
272
- color: #333746;
273
- border-left-color: var(--cinnabar);
274
- background: rgba(255,251,247,.9);
275
- box-shadow: 0 14px 40px rgba(72,67,88,.13);
276
- backdrop-filter: blur(14px);
277
- }
278
-
279
- .accord-panel { border-left-color: rgba(71,101,134,.24); }
280
- .accord-heading,
281
- .visit-prompt h2 { color: #353846; }
282
-
283
- .accord-seal {
284
- color: #707383;
285
- border-color: rgba(74,91,118,.2);
286
- background: rgba(255,253,249,.72);
287
- }
288
-
289
- .accord-seal.complete { color: #8d4450; background: rgba(200,79,92,.07); }
290
-
291
- .door-card {
292
- color: #303441;
293
- border: 1px solid rgba(87, 92, 119, .27);
294
- background: #fbf2ed;
295
- box-shadow: 0 16px 42px rgba(71,65,87,.15);
296
- }
297
-
298
- .door-card::before { border-color: rgba(200,79,92,.16); }
299
- .door-card > span { color: #4d5264; background: rgba(255,250,246,.88); }
300
- .door-card img { filter: saturate(1.03) brightness(1.05) contrast(.99); }
301
- .door-card > div { color: #323542; background: linear-gradient(transparent, rgba(251,242,237,.97) 58%); }
302
- .door-card small,
303
- .door-knock,
304
- .door-forecast dd { color: #666978; }
305
-
306
- #app .dialogue-stage::after,
307
- #app .morning-stage::after { background: linear-gradient(90deg, rgba(255,249,245,.34), transparent 60%); }
308
-
309
- .night-talk-cg,
310
- .close-cg,
311
- .close-cg.closer,
312
- #app .scene-view > img { filter: saturate(1.02) brightness(1.03) contrast(1.01); }
313
-
314
- .close-cg::after,
315
- .morning-cg::after {
316
- background:
317
- linear-gradient(96deg, rgba(244,240,244,.94) 0%, rgba(244,240,244,.8) 30%, rgba(244,240,244,.08) 58%, rgba(63,59,82,.08) 100%),
318
- radial-gradient(112% 88% at 72% 40%, transparent 52%, rgba(69,62,91,.13) 100%);
319
- }
320
-
321
- .close-cg.closer { filter: saturate(1.04) brightness(1.01) contrast(1.02); }
322
- .morning-cg { filter: saturate(1) brightness(1.08) contrast(1); }
323
-
324
- #app .night-talk-stage::after,
325
- #app .night-talk-result::after {
326
- background:
327
- linear-gradient(96deg, rgba(243,241,249,.96) 0%, rgba(243,241,249,.86) 42%, rgba(243,241,249,.1) 69%),
328
- linear-gradient(0deg, rgba(72,62,98,.08), transparent 62%);
329
- }
330
-
331
- .night-talk-voice,
332
- .night-talk-continuity,
333
- .night-talk-memory,
334
- .route-branch-memory,
335
- .day-consequence,
336
- .ledger-status {
337
- color: #515565;
338
- border-color: rgba(75, 91, 120, .22);
339
- background: rgba(255,253,250,.68);
340
- }
341
-
342
- .night-talk-voice b,
343
- .night-talk-continuity b,
344
- .route-branch-memory b,
345
- .day-consequence b { color: #3f4352; }
346
-
347
- .night-talk-voice p,
348
- .night-talk-memory p,
349
- .night-talk-continuity p,
350
- .route-branch-memory p { color: #626575; }
351
-
352
- .night-talk-prop {
353
- color: #7b5a2e;
354
- border-color: rgba(179, 130, 66, .35);
355
- background: radial-gradient(circle, rgba(255,253,249,.98), rgba(226,214,221,.94) 72%);
356
- box-shadow: 0 18px 46px rgba(74,65,91,.16), inset 0 0 0 8px rgba(255,255,255,.25);
357
- }
358
-
359
- /* 场景册与剧情结果让 CG 继续占主位。 */
360
- #app .scene-scrim {
361
- background: linear-gradient(90deg, rgba(247,243,246,.93) 0%, rgba(247,243,246,.67) 34%, transparent 66%);
362
- }
363
-
364
- #app .scene-caption,
365
- #app .scene-view:is([data-scene-tier="public"], [data-scene-tier="ensemble"]) .scene-caption {
366
- color: #303442;
367
- border: 1px solid rgba(77, 91, 119, .21);
368
- border-left: 4px solid var(--cinnabar);
369
- background: rgba(255,251,248,.88);
370
- box-shadow: 0 20px 52px rgba(67,63,84,.15);
371
- backdrop-filter: blur(14px);
372
- }
373
-
374
- #app .scene-caption h2,
375
- #app .scene-caption > p:not(.eyebrow) { color: #343746; }
376
- #app .scene-meta { color: #6a6d7c; }
377
- #app .scene-meta span { border-color: rgba(75,91,119,.22); }
378
-
379
- #app .scene-view:is([data-scene-tier="public"], [data-scene-tier="ensemble"]) .scene-scrim {
380
- background: linear-gradient(0deg, rgba(250,246,247,.72) 0%, rgba(250,246,247,0) 38%);
381
- }
382
-
383
- #app .scene-view:is([data-scene-tier="public"], [data-scene-tier="ensemble"]) .scene-caption {
384
- background: linear-gradient(0deg, rgba(255,251,248,.96) 0%, rgba(255,251,248,.84) 52%, rgba(255,251,248,0) 100%);
385
- backdrop-filter: none;
386
- }
387
-
388
- #app .scene-view:is([data-scene-tier="public"], [data-scene-tier="ensemble"]) > img {
389
- filter: saturate(1.03) brightness(1.03) contrast(1.01);
390
- }
391
-
392
- /* 旧结构里最暗的三张群像,强制回到新 CG 自己的曝光。 */
393
- .scene-view[data-scene-id="inner_court_alliance"] > img,
394
- .scene-view[data-scene-id="inner_court_accord"] > img,
395
- .scene-view[data-scene-id="inner_court_afterglow"] > img {
396
- filter: saturate(1.03) brightness(1.04) contrast(1.01);
397
- }
398
-
399
- .scene-view[data-scene-id="inner_court_alliance"] .scene-caption,
400
- .scene-view[data-scene-id="inner_court_afterglow"] .scene-caption {
401
- color: var(--ink);
402
- border-color: rgba(80,95,123,.22);
403
- border-left-color: var(--cinnabar);
404
- background: linear-gradient(145deg, rgba(255,253,249,.97), rgba(241,235,241,.92));
405
- }
406
-
407
- .shared-night-accord-overview,
408
- .shared-night-accord-entry,
409
- .alliance-tableau-overview,
410
- .alliance-tableau-entry,
411
- .shared-afterglow-tableau-overview,
412
- .shared-afterglow-tableau-entry {
413
- color: #4a4e5e;
414
- border-color: rgba(80,96,124,.2);
415
- background: rgba(255,252,249,.68);
416
- }
417
-
418
- .shared-night-accord-overview header,
419
- .shared-night-accord-entry > header,
420
- .alliance-tableau-overview > header,
421
- .alliance-tableau-entry > header,
422
- .shared-afterglow-tableau-overview header,
423
- .shared-afterglow-tableau-entry > header { color: #767887; }
424
-
425
- .shared-night-accord-overview header b,
426
- .shared-night-accord-entry > header b,
427
- .alliance-tableau-overview > header b,
428
- .alliance-tableau-entry > header b,
429
- .shared-afterglow-tableau-overview header b,
430
- .shared-afterglow-tableau-entry > header b { color: #8e6040; }
431
-
432
- .shared-night-accord-overview > div > span,
433
- .shared-night-accord-ledger article,
434
- .alliance-tableau-overview,
435
- .alliance-tableau-entry,
436
- .alliance-tableau-path > span,
437
- .alliance-tableau-actions article,
438
- .shared-afterglow-tableau-overview > div > span,
439
- .shared-afterglow-tableau-actions article {
440
- border-color: rgba(91,111,140,.18);
441
- background: rgba(247,244,247,.68);
442
- }
443
-
444
- .shared-night-accord-overview b,
445
- .shared-night-accord-ledger b,
446
- .alliance-tableau-members b,
447
- .alliance-tableau-path b,
448
- .alliance-tableau-actions b,
449
- .shared-afterglow-tableau-overview b,
450
- .shared-afterglow-tableau-actions b { color: #805a42; }
451
-
452
- .shared-night-accord-overview em,
453
- .shared-night-accord-overview small,
454
- .shared-night-accord-ledger p,
455
- .shared-night-accord-conclusion,
456
- .alliance-tableau-overview > p,
457
- .alliance-tableau-entry > p,
458
- .alliance-tableau-members span,
459
- .alliance-tableau-path small,
460
- .alliance-tableau-path em,
461
- .alliance-tableau-actions p,
462
- .shared-afterglow-tableau-overview small,
463
- .shared-afterglow-tableau-overview em,
464
- .shared-afterglow-tableau-entry > p,
465
- .shared-afterglow-tableau-actions p { color: #666a79; }
466
-
467
- .alliance-tableau-members figure { background: rgba(231,226,232,.72); }
468
- .alliance-tableau-members img,
469
- .alliance-tableau-actions img { filter: saturate(1) brightness(1.03); }
470
- .alliance-tableau-members figcaption { background: linear-gradient(90deg, transparent, rgba(251,247,245,.94) 42%); }
471
-
472
- .shared-night-accord-ledger blockquote,
473
- .alliance-tableau-entry > blockquote,
474
- .shared-afterglow-tableau-entry > blockquote {
475
- color: #4b655f;
476
- border-left-color: rgba(63,143,131,.54);
477
- background: rgba(63,143,131,.07);
478
- }
479
-
480
- .gallery-overlay,
481
- .confirm-overlay,
482
- .roster-overlay,
483
- .epilogue-overlay,
484
- .fate-coda-overlay {
485
- background: rgba(224, 220, 226, .62);
486
- backdrop-filter: blur(14px) saturate(.82);
487
- }
488
-
489
- .gallery-book > header,
490
- .roster-sheet > header,
491
- .epilogue-copy > header,
492
- .fate-coda-copy > header { border-color: rgba(79,94,122,.19); }
493
-
494
- .roster-sheet,
495
- .gallery-book { color: #383c4a; }
496
-
497
- /* 压力与成功只改变局部色,不改变整场曝光。 */
498
- .day-consequence.resolved {
499
- border-color: rgba(63,143,131,.4);
500
- background: rgba(63,143,131,.07);
501
- }
502
-
503
- .day-consequence.missed,
504
- .hud-notice.urgent {
505
- border-color: rgba(200,79,92,.44);
506
- background: rgba(200,79,92,.075);
507
- }
508
-
509
- .fast .scene-view > img { animation: none; filter: saturate(1.02) brightness(1.03); }
510
-
511
- /*
512
- * 复合叙事页不能继续沿用旧主题的“黑底上叠半透明卡”结构。新插画本身已经
513
- * 承担场景气氛;面板、旁听者和多人回应要成为彼此分开的纸面层,不能互相透图。
514
- */
515
- #app :is(.opening-aftermath-stage, .day-aftermath-stage, .aftermath-stage, [class*="-aftermath-stage"]) {
516
- background: #e8e4e7;
517
- }
518
-
519
- #app :is(
520
- .day-aftermath-lead,
521
- .aftermath-main,
522
- .personal-afterglow-aftermath-close
523
- ) {
524
- filter: saturate(1.02) brightness(1.04) contrast(1.01);
525
- }
526
-
527
- #app .decision-panel :is(p:not(.eyebrow), li, dd, small, em) { color: #626574; }
528
- #app .decision-panel :is(h2, h3, h4, b, strong, dt) { color: #343746; }
529
-
530
- #app .decision-panel :is(
531
- blockquote,
532
- [class*="-origin"],
533
- [class*="-echo"],
534
- [class*="-memory"],
535
- [class*="-stake"],
536
- [class*="-ledger"],
537
- [class*="-rule"],
538
- [class*="-voice"],
539
- [class*="-note"]
540
- ) {
541
- color: #515565;
542
- border-color: rgba(75, 91, 120, .22);
543
- background: rgba(255, 253, 250, .72);
544
- }
545
-
546
- #app .decision-panel :is(
547
- [class*="-transcript"],
548
- [class*="-archive"]
549
- ) li,
550
- #app .supporting-context > summary,
551
- #app .supporting-context-pages > * {
552
- color: #5f6271;
553
- border-color: rgba(75, 91, 120, .18);
554
- background: rgba(244, 240, 241, .82);
555
- }
556
-
557
- #app .decision-panel :is(
558
- blockquote,
559
- [class*="-origin"],
560
- [class*="-echo"],
561
- [class*="-memory"],
562
- [class*="-stake"],
563
- [class*="-ledger"],
564
- [class*="-rule"],
565
- [class*="-voice"],
566
- [class*="-note"],
567
- [class*="-transcript"] li,
568
- [class*="-archive"] li
569
- ) :is(p, small, em) { color: #626574; }
570
-
571
- #app .decision-panel :is(
572
- blockquote,
573
- [class*="-origin"],
574
- [class*="-echo"],
575
- [class*="-memory"],
576
- [class*="-stake"],
577
- [class*="-ledger"],
578
- [class*="-rule"],
579
- [class*="-voice"],
580
- [class*="-note"],
581
- [class*="-transcript"] li,
582
- [class*="-archive"] li
583
- ) :is(b, strong) { color: #3f4352; }
584
-
585
- #app .decision-panel :is(
586
- blockquote,
587
- [class*="-origin"],
588
- [class*="-echo"],
589
- [class*="-memory"],
590
- [class*="-stake"],
591
- [class*="-ledger"],
592
- [class*="-rule"],
593
- [class*="-voice"],
594
- [class*="-note"],
595
- [class*="-transcript"] li,
596
- [class*="-archive"] li
597
- ) > span { color: #91623f; }
598
-
599
- /* 多人卡不再悬浮在同一张人物图上:给卡组一张不透底的薄绢托纸。 */
600
- #app :is(
601
- .opening-aftermath-cast,
602
- .crisis-cast,
603
- .crisis-aftermath-cast,
604
- .pair-portraits,
605
- .pair-aftermath-cast,
606
- .jiaoer-aftermath-cast,
607
- .invitation-aftermath-cast,
608
- .council-resolution-cast,
609
- .public-aftermath-cast,
610
- .act-aftermath-cast,
611
- .final-aftermath-cast,
612
- .alliance-assembly-cast,
613
- .alliance-result-cast,
614
- .collapse-cast,
615
- .collapse-result-cast,
616
- .shared-result-cast,
617
- .shared-dawn-result-cast
618
- ) {
619
- padding: .45rem;
620
- border: 1px solid rgba(80, 95, 123, .18);
621
- background: rgba(249, 246, 246, .94);
622
- box-shadow: 0 18px 52px rgba(67, 63, 84, .14);
623
- backdrop-filter: blur(12px) saturate(.9);
624
- }
625
-
626
- #app :is(
627
- .opening-aftermath-cast,
628
- .day-aftermath-reactions,
629
- .crisis-cast,
630
- .crisis-aftermath-cast,
631
- .pair-portraits,
632
- .pair-aftermath-cast,
633
- .jiaoer-aftermath-cast,
634
- .invitation-aftermath-cast,
635
- .council-resolution-cast,
636
- .public-aftermath-cast,
637
- .act-aftermath-cast,
638
- .final-aftermath-cast,
639
- .alliance-assembly-cast,
640
- .alliance-result-cast,
641
- .collapse-cast,
642
- .collapse-result-cast,
643
- .shared-result-cast,
644
- .shared-dawn-result-cast
645
- ) figure {
646
- border-color: rgba(80, 95, 123, .2);
647
- background: #eee7e6;
648
- filter: none;
649
- transform: none;
650
- }
651
-
652
- #app :is(
653
- .opening-aftermath-cast,
654
- .day-aftermath-reactions,
655
- .crisis-cast,
656
- .crisis-aftermath-cast,
657
- .pair-portraits,
658
- .pair-aftermath-cast,
659
- .jiaoer-aftermath-cast,
660
- .invitation-aftermath-cast,
661
- .council-resolution-cast,
662
- .public-aftermath-cast,
663
- .act-aftermath-cast,
664
- .final-aftermath-cast,
665
- .alliance-assembly-cast,
666
- .alliance-result-cast,
667
- .collapse-cast,
668
- .collapse-result-cast,
669
- .shared-result-cast,
670
- .shared-dawn-result-cast
671
- ) figure:not(.speaking):not(.is-responding) { opacity: .8; }
672
-
673
- #app :is(
674
- .opening-aftermath-cast,
675
- .day-aftermath-reactions,
676
- .crisis-cast,
677
- .crisis-aftermath-cast,
678
- .pair-portraits,
679
- .pair-aftermath-cast,
680
- .jiaoer-aftermath-cast,
681
- .invitation-aftermath-cast,
682
- .council-resolution-cast,
683
- .public-aftermath-cast,
684
- .act-aftermath-cast,
685
- .final-aftermath-cast,
686
- .alliance-assembly-cast,
687
- .alliance-result-cast,
688
- .collapse-cast,
689
- .collapse-result-cast,
690
- .shared-result-cast,
691
- .shared-dawn-result-cast
692
- ) figure:is(.speaking, .is-responding) {
693
- opacity: 1;
694
- border-color: rgba(200, 79, 92, .54);
695
- box-shadow: 0 10px 28px rgba(130, 66, 82, .14);
696
- }
697
-
698
- #app :is(
699
- .opening-aftermath-cast,
700
- .day-aftermath-reactions,
701
- .crisis-cast,
702
- .crisis-aftermath-cast,
703
- .pair-portraits,
704
- .pair-aftermath-cast,
705
- .jiaoer-aftermath-cast,
706
- .invitation-aftermath-cast,
707
- .council-resolution-cast,
708
- .public-aftermath-cast,
709
- .act-aftermath-cast,
710
- .final-aftermath-cast,
711
- .alliance-assembly-cast,
712
- .alliance-result-cast,
713
- .collapse-cast,
714
- .collapse-result-cast,
715
- .shared-result-cast,
716
- .shared-dawn-result-cast
717
- ) img { filter: saturate(1.02) brightness(1.04) contrast(1.01); }
718
-
719
- #app :is(
720
- .opening-aftermath-cast,
721
- .day-aftermath-reactions,
722
- .crisis-cast,
723
- .crisis-aftermath-cast,
724
- .pair-portraits,
725
- .pair-aftermath-cast,
726
- .jiaoer-aftermath-cast,
727
- .invitation-aftermath-cast,
728
- .council-resolution-cast,
729
- .public-aftermath-cast,
730
- .act-aftermath-cast,
731
- .final-aftermath-cast,
732
- .alliance-assembly-cast,
733
- .alliance-result-cast,
734
- .collapse-cast,
735
- .collapse-result-cast,
736
- .shared-result-cast,
737
- .shared-dawn-result-cast
738
- ) figcaption {
739
- color: #444856;
740
- background: linear-gradient(transparent, rgba(252, 248, 246, .98) 48%);
741
- }
742
-
743
- #app :is(
744
- .opening-aftermath-cast,
745
- .day-aftermath-reactions,
746
- .crisis-cast,
747
- .crisis-aftermath-cast,
748
- .pair-portraits,
749
- .pair-aftermath-cast,
750
- .jiaoer-aftermath-cast,
751
- .invitation-aftermath-cast,
752
- .council-resolution-cast,
753
- .public-aftermath-cast,
754
- .act-aftermath-cast,
755
- .final-aftermath-cast,
756
- .alliance-assembly-cast,
757
- .alliance-result-cast,
758
- .collapse-cast,
759
- .collapse-result-cast,
760
- .shared-result-cast,
761
- .shared-dawn-result-cast
762
- ) figcaption :is(b, strong) { color: #353846; }
763
-
764
- #app :is(
765
- .opening-aftermath-cast,
766
- .day-aftermath-reactions,
767
- .crisis-cast,
768
- .crisis-aftermath-cast,
769
- .pair-portraits,
770
- .pair-aftermath-cast,
771
- .jiaoer-aftermath-cast,
772
- .invitation-aftermath-cast,
773
- .council-resolution-cast,
774
- .public-aftermath-cast,
775
- .act-aftermath-cast,
776
- .final-aftermath-cast,
777
- .alliance-assembly-cast,
778
- .alliance-result-cast,
779
- .collapse-cast,
780
- .collapse-result-cast,
781
- .shared-result-cast,
782
- .shared-dawn-result-cast
783
- ) figcaption :is(span, small, em, p) { color: #666978; }
784
-
785
- .day-aftermath-reactions figure:only-child {
786
- width: min(250px, 100%);
787
- height: min(520px, 72%);
788
- align-self: center;
789
- }
790
-
791
- .aftermath-observer {
792
- padding: .38rem;
793
- color: #3f4352;
794
- border: 1px solid rgba(80, 95, 123, .2);
795
- background: rgba(252, 248, 246, .94);
796
- box-shadow: 0 14px 38px rgba(67, 63, 84, .14);
797
- opacity: 1;
798
- }
799
-
800
- .aftermath-observer img {
801
- mask-image: none;
802
- filter: saturate(1.02) brightness(1.04) contrast(1.01);
803
- }
804
-
805
- .aftermath-observer figcaption span { color: #91623f; }
806
- .aftermath-observer figcaption b { color: #353846; }
807
-
808
- /* 单人抉择按内容收高,避免短段落被一整块空白纸面包到屏幕底。 */
809
- .dialogue-panel,
810
- .night-talk-panel {
811
- top: 50%;
812
- bottom: auto;
813
- max-height: 88%;
814
- overflow-y: auto;
815
- transform: translateY(-50%);
816
- }
817
-
818
- /* 结局与后日谈也必须延续亮色叙事,不在最后一屏突然回到旧黑金主题。 */
819
- .ending-view {
820
- color: var(--ink);
821
- background: #eee7e6;
822
- }
823
-
824
- .ending-art,
825
- .ending-view[data-ending="exclusive"] .ending-art,
826
- .ending-view[data-ending="intrigue"] .ending-art,
827
- .ending-view[data-ending="unstable"] .ending-art {
828
- filter: saturate(1.01) brightness(1.03) contrast(1.01);
829
- background-blend-mode: screen;
830
- }
831
-
832
- .ending-copy {
833
- border-left: 1px solid rgba(80, 95, 123, .16);
834
- background:
835
- radial-gradient(circle at 18% 12%, rgba(218, 113, 126, .08), transparent 35%),
836
- linear-gradient(145deg, rgba(255, 253, 249, .985), rgba(240, 237, 243, .97));
837
- box-shadow: -20px 0 54px rgba(67, 63, 84, .12);
838
- }
839
-
840
- .ending-copy h1 { color: #303342; }
841
- .ending-copy h1:focus-visible {
842
- outline: 2px solid rgba(200, 79, 92, .54);
843
- outline-offset: .3rem;
844
- }
845
- .ending-tag { color: #9a6834; }
846
- .ending-copy > p:not(.eyebrow):not(.ending-tag):not(.ending-note) { color: #5f6372; }
847
- .ending-note { color: #737584; }
848
-
849
- /* 长结局总账允许读者翻动正文,但结果动作始终像书页脚签一样留在视口内。 */
850
- .ending-copy > .button-row {
851
- position: sticky;
852
- z-index: 4;
853
- bottom: -4vh;
854
- margin: auto -1.2vw -4vh;
855
- padding: .7rem 1.2vw .8rem;
856
- border-top: 1px solid rgba(80, 95, 123, .16);
857
- background: linear-gradient(0deg, rgba(250,248,247,.995), rgba(250,248,247,.96));
858
- box-shadow: 0 -12px 28px rgba(67,63,84,.08);
859
- }
860
-
861
- .ending-copy > .button-row .ink-button {
862
- flex: 1 1 7.5rem;
863
- min-width: 0;
864
- padding: .58rem .7rem;
865
- font-size: .7rem;
866
- }
867
-
868
- .ending-ledger span,
869
- .ending-habits,
870
- .ending-habits article,
871
- .household-ending span {
872
- color: #626574;
873
- border-color: rgba(80, 95, 123, .18);
874
- background: rgba(255, 253, 250, .64);
875
- }
876
-
877
- .ending-ledger b,
878
- .ending-habits > header b,
879
- .ending-habits article b,
880
- .household-ending b { color: #454958; }
881
-
882
- .ending-habits > header,
883
- .ending-habits article span,
884
- .ending-habits article small,
885
- .household-ending small { color: #737584; }
886
-
887
- .epilogue-book,
888
- .fate-coda-book {
889
- color: var(--ink);
890
- border-color: rgba(80, 95, 123, .24);
891
- background: #eee7e8;
892
- box-shadow: 0 32px 90px rgba(67, 63, 84, .28);
893
- }
894
-
895
- .epilogue-art { background: #e8e2e3; }
896
- .epilogue-art::after { background: linear-gradient(90deg, transparent 62%, rgba(244, 239, 240, .9)); }
897
- .epilogue-art img { filter: saturate(1.02) brightness(1.03) contrast(1.01); }
898
- .epilogue-art > span { color: rgba(154, 104, 52, .22); }
899
-
900
- .epilogue-copy h2,
901
- .epilogue-body,
902
- .epilogue-progress,
903
- .epilogue-relations b,
904
- .epilogue-route-note,
905
- .epilogue-habit b,
906
- .epilogue-habit p,
907
- .epilogue-night-conversations header b,
908
- .epilogue-night-conversations li b,
909
- .epilogue-night-conversations li p { color: #4e5261; }
910
-
911
- .epilogue-relations span,
912
- .epilogue-route-note,
913
- .epilogue-habit,
914
- .epilogue-night-conversations,
915
- .epilogue-night-conversations li {
916
- color: #666978;
917
- border-color: rgba(80, 95, 123, .18);
918
- background: rgba(255, 253, 250, .64);
919
- }
920
-
921
- .fate-coda-art { filter: saturate(1.01) brightness(1.03) contrast(1.01); }
922
- .fate-coda-art::after {
923
- background: linear-gradient(90deg, rgba(242, 241, 246, .98) 0%, rgba(242, 241, 246, .9) 31%, rgba(242, 241, 246, .2) 55%, transparent 76%);
924
- }
925
-
926
- .fate-coda-copy {
927
- color: #4e5261;
928
- background: linear-gradient(90deg, rgba(248, 250, 252, .99), rgba(248, 250, 252, .9) 72%, transparent);
929
- }
930
-
931
- .fate-coda-copy > header p,
932
- .fate-coda-copy > header .eyebrow,
933
- .fate-coda-progress i,
934
- .fate-coda-variants > span { color: #6d7180; }
935
-
936
- .fate-coda-variants,
937
- .fate-coda-variants button {
938
- color: #555968;
939
- border-color: rgba(80, 95, 123, .2);
940
- background: rgba(255, 253, 250, .7);
941
- }
942
-
943
- .fate-coda-variants button.current {
944
- color: #8d4450;
945
- border-color: rgba(200, 79, 92, .48);
946
- background: rgba(200, 79, 92, .07);
947
- }
948
-
949
- .fate-coda-copy h2 { color: #303442; }
950
- .fate-coda-body,
951
- .fate-coda-decision > p,
952
- .fate-coda-result p,
953
- .fate-coda-combination > p { color: #5f6372; }
954
-
955
- .fate-coda-ledger-section,
956
- .fate-coda-ledger-section article,
957
- .fate-coda-result {
958
- color: #555968;
959
- border-color: rgba(80, 95, 123, .2);
960
- background: rgba(255, 253, 250, .7);
961
- }
962
-
963
- .fate-coda-ledger-section > header span,
964
- .fate-coda-ledger-section article > span,
965
- .fate-coda-result span,
966
- .fate-coda-combination > span { color: #737786; }
967
-
968
- .fate-coda-ledger-section > header h3,
969
- .fate-coda-ledger-section article > b,
970
- .fate-coda-result b,
971
- .fate-coda-combination > b { color: #454958; }
972
-
973
- .fate-coda-ledger-section article > p { color: #626574; }
974
-
975
- .fate-coda-decision .choice-button {
976
- color: #343745;
977
- border-color: rgba(79, 91, 120, .2);
978
- background: rgba(255, 253, 249, .82);
979
- }
980
-
981
- .fate-coda-decision .choice-button:hover,
982
- .fate-coda-decision .choice-button:focus-visible {
983
- border-color: rgba(200, 79, 92, .5);
984
- background: #fffaf7;
985
- }
986
-
987
- .fate-coda-copy > footer > span { color: #707483; }
988
-
989
- @media (max-width: 900px) {
990
- .age-gate {
991
- background:
992
- linear-gradient(0deg, rgba(255,250,245,.98) 0%, rgba(255,250,245,.87) 56%, rgba(255,250,245,.22) 100%),
993
- url('../assets/bg/compound_new_guofeng.webp') center / cover;
994
- }
995
-
996
- .title-art {
997
- inset: 0 0 auto;
998
- height: 52%;
999
- background-color: #f8e8e2;
1000
- background-position: 63% top;
1001
- background-size: auto 100%;
1002
- background-repeat: no-repeat;
1003
- }
1004
-
1005
- .title-art::after {
1006
- background: linear-gradient(0deg, #f7e8e2 0%, rgba(247,232,226,.86) 36%, rgba(247,232,226,.04) 72%);
1007
- }
1008
-
1009
- .title-copy {
1010
- justify-content: flex-start;
1011
- padding: 42vh 1.2rem 1.25rem;
1012
- background: linear-gradient(0deg, rgba(247,232,226,.99), rgba(247,232,226,.8) 68%, transparent);
1013
- }
1014
-
1015
- .title-copy h1 {
1016
- white-space: nowrap;
1017
- font-size: clamp(2rem, 8.7vw, 2.45rem);
1018
- }
1019
-
1020
- .title-copy::after { width: 13rem; margin-bottom: .65rem; }
1021
- .visit-prompt { background: rgba(255,251,248,.94); }
1022
-
1023
- /* 窄屏只保留一张主图;重复的人物卡会把画面和正文同时吃掉。 */
1024
- .opening-aftermath-cast,
1025
- .day-aftermath-reactions,
1026
- .aftermath-observer { display: none; }
1027
-
1028
- .opening-aftermath-panel,
1029
- .aftermath-panel { max-height: 76%; overflow-y: auto; }
1030
-
1031
- .dialogue-panel,
1032
- .night-talk-panel {
1033
- top: auto;
1034
- bottom: 2%;
1035
- max-height: 76%;
1036
- transform: none;
1037
- }
1038
-
1039
- #app :is(
1040
- .crisis-cast,
1041
- .crisis-aftermath-cast,
1042
- .pair-portraits,
1043
- .pair-aftermath-cast,
1044
- .jiaoer-aftermath-cast,
1045
- .invitation-aftermath-cast,
1046
- .council-resolution-cast,
1047
- .public-aftermath-cast,
1048
- .act-aftermath-cast,
1049
- .final-aftermath-cast,
1050
- .alliance-assembly-cast,
1051
- .alliance-result-cast,
1052
- .collapse-cast,
1053
- .collapse-result-cast,
1054
- .shared-result-cast,
1055
- .shared-dawn-result-cast
1056
- ) {
1057
- top: 1.5%;
1058
- bottom: auto;
1059
- height: 22%;
1060
- padding: .2rem;
1061
- }
1062
-
1063
- #app :is(
1064
- .crisis-cast,
1065
- .crisis-aftermath-cast,
1066
- .pair-portraits,
1067
- .pair-aftermath-cast,
1068
- .jiaoer-aftermath-cast,
1069
- .invitation-aftermath-cast,
1070
- .council-resolution-cast,
1071
- .public-aftermath-cast,
1072
- .act-aftermath-cast,
1073
- .final-aftermath-cast,
1074
- .alliance-assembly-cast,
1075
- .alliance-result-cast,
1076
- .collapse-cast,
1077
- .collapse-result-cast,
1078
- .shared-result-cast,
1079
- .shared-dawn-result-cast
1080
- ) figcaption :is(p, small, em) { display: none; }
1081
-
1082
- #app .scene-scrim {
1083
- background: linear-gradient(0deg, rgba(246,242,246,.96), rgba(246,242,246,.16) 74%);
1084
- }
1085
-
1086
- .close-cg::after,
1087
- .morning-cg::after {
1088
- background: linear-gradient(0deg, rgba(243,240,245,.98) 0%, rgba(243,240,245,.83) 47%, rgba(243,240,245,.05) 78%);
1089
- }
1090
-
1091
- .fate-coda-art::after {
1092
- background: linear-gradient(0deg, rgba(240,244,248,.99) 0%, rgba(240,244,248,.9) 62%, rgba(240,244,248,.06) 91%);
1093
- }
1094
-
1095
- .fate-coda-copy {
1096
- background: linear-gradient(0deg, rgba(248,250,252,.995), rgba(248,250,252,.91) 78%, transparent);
1097
- }
1098
-
1099
- .ending-art { opacity: .76; }
1100
- .ending-copy {
1101
- background: linear-gradient(0deg, rgba(250, 247, 245, .995) 0%, rgba(250, 247, 245, .95) 64%, rgba(250, 247, 245, .88) 100%);
1102
- }
1103
-
1104
- .epilogue-art::after { background: linear-gradient(0deg, rgba(244, 239, 240, .94), transparent 62%); }
1105
- }
1106
-
1107
- @media (prefers-reduced-motion: reduce) {
1108
- .title-art,
1109
- .door-card img,
1110
- .night-talk-cg,
1111
- .close-portrait,
1112
- .scene-view > img {
1113
- transition: none !important;
1114
- animation: none !important;
1115
- }
1116
- }
1117
-
1118
- /* 2026-09 画面重构:把标题做成一张可读的“人物权力总账”,而不是文案压在 CG 上。 */
1119
- .title-folio {
1120
- position: absolute;
1121
- z-index: 3;
1122
- top: 4.5vh;
1123
- left: 2.2vw;
1124
- display: grid;
1125
- gap: .3rem;
1126
- padding-left: .75rem;
1127
- border-left: 2px solid rgba(200, 79, 92, .54);
1128
- color: #3d4251;
1129
- writing-mode: vertical-rl;
1130
- }
1131
-
1132
- .title-folio b {
1133
- font-size: .78rem;
1134
- font-weight: 600;
1135
- letter-spacing: .24em;
1136
- }
1137
-
1138
- .title-folio span {
1139
- color: #8c6670;
1140
- font: .62rem var(--sans);
1141
- letter-spacing: .14em;
1142
- }
1143
-
1144
- .title-cast {
1145
- position: absolute;
1146
- z-index: 4;
1147
- right: 2.2vw;
1148
- bottom: 2.4vh;
1149
- width: min(50rem, 55vw);
1150
- display: grid;
1151
- grid-template-columns: repeat(5, minmax(0, 1fr));
1152
- gap: 1px;
1153
- margin: 0;
1154
- padding: 0;
1155
- list-style: none;
1156
- border: 1px solid rgba(255,255,255,.62);
1157
- background: rgba(76, 78, 99, .12);
1158
- box-shadow: 0 16px 40px rgba(65, 56, 74, .16);
1159
- backdrop-filter: blur(18px) saturate(.86);
1160
- }
1161
-
1162
- .title-cast li {
1163
- position: relative;
1164
- min-width: 0;
1165
- display: grid;
1166
- grid-template-columns: auto 1fr;
1167
- grid-template-rows: auto auto;
1168
- column-gap: .65rem;
1169
- padding: .72rem .8rem .66rem;
1170
- color: #353947;
1171
- background: rgba(255, 251, 247, .78);
1172
- }
1173
-
1174
- .title-cast li::after {
1175
- content: "";
1176
- position: absolute;
1177
- inset: auto .8rem 0;
1178
- height: 2px;
1179
- background: var(--cast-color, var(--cinnabar));
1180
- }
1181
-
1182
- .title-cast li:nth-child(1) { --cast-color: var(--azurite); }
1183
- .title-cast li:nth-child(2) { --cast-color: var(--cinnabar); }
1184
- .title-cast li:nth-child(3) { --cast-color: #d5aa65; }
1185
- .title-cast li:nth-child(4) { --cast-color: var(--lilac); }
1186
- .title-cast li:nth-child(5) { --cast-color: var(--jade); }
1187
- .title-cast i {
1188
- grid-row: 1 / 3;
1189
- align-self: center;
1190
- color: var(--cast-color);
1191
- font: 500 .62rem/1 var(--sans);
1192
- }
1193
- .title-cast span { font-size: .84rem; letter-spacing: .12em; }
1194
- .title-cast b { color: #777987; font: 500 .6rem/1.4 var(--sans); letter-spacing: .1em; }
1195
-
1196
- /* 开局把抉择变成一张靠左的案件封套,留出右侧五人的完整表情和器物。 */
1197
- .opening-scene::after {
1198
- background:
1199
- linear-gradient(90deg, rgba(250,246,244,.96) 0%, rgba(250,246,244,.76) 38%, rgba(250,246,244,.08) 64%, transparent 78%),
1200
- linear-gradient(0deg, rgba(69,61,79,.12), transparent 58%);
1201
- }
1202
-
1203
- .opening-panel {
1204
- left: 4vw;
1205
- top: 50%;
1206
- bottom: auto;
1207
- width: min(38rem, 44vw);
1208
- display: grid;
1209
- grid-template-columns: 4.2rem minmax(0, 1fr);
1210
- column-gap: 1.15rem;
1211
- padding: 1.5rem 1.5rem 1.35rem 1.2rem;
1212
- transform: translateY(-50%);
1213
- }
1214
-
1215
- .opening-panel::before {
1216
- inset: 8px;
1217
- border-color: rgba(53,95,152,.1);
1218
- }
1219
-
1220
- .opening-panel > :not(.opening-case) { grid-column: 2; }
1221
- .opening-case {
1222
- grid-column: 1;
1223
- grid-row: 1 / 4;
1224
- min-height: 100%;
1225
- display: flex;
1226
- flex-direction: column;
1227
- align-items: center;
1228
- padding-right: 1rem;
1229
- border-right: 1px solid rgba(76, 92, 119, .18);
1230
- }
1231
- .opening-case span { color: #aa5260; font: 700 .52rem/1 var(--sans); letter-spacing: .18em; }
1232
- .opening-case b { margin: .35rem 0; color: #343846; font: 300 2.8rem/1 var(--serif); }
1233
- .opening-case i { color: #8b6a47; font: 500 .65rem/1.6 var(--sans); letter-spacing: .12em; writing-mode: vertical-rl; }
1234
- .opening-panel .phase-header h2 { font-size: clamp(1.85rem, 2.55vw, 2.8rem); }
1235
- .opening-panel .speaker-line {
1236
- margin: .9rem 0 1rem;
1237
- padding: .65rem .75rem;
1238
- border-left: 2px solid rgba(200,79,92,.48);
1239
- }
1240
- .opening-panel .choice-grid { gap: .55rem; }
1241
- .opening-panel .choice-button { min-height: 4.2rem; }
1242
-
1243
- @media (max-width: 900px) {
1244
- .title-folio { display: none; }
1245
- .title-cast {
1246
- top: 35.5%;
1247
- right: 1rem;
1248
- bottom: auto;
1249
- left: 1rem;
1250
- width: auto;
1251
- box-shadow: 0 10px 30px rgba(65,56,74,.12);
1252
- }
1253
- .title-cast li {
1254
- display: grid;
1255
- grid-template-columns: 1fr;
1256
- justify-items: center;
1257
- gap: .18rem;
1258
- padding: .48rem .2rem .45rem;
1259
- }
1260
- .title-cast i { display: none; }
1261
- .title-cast span { font-size: .72rem; letter-spacing: .08em; }
1262
- .title-cast b { font-size: .48rem; }
1263
- .title-copy { padding-top: 46vh; }
1264
-
1265
- .opening-scene::after {
1266
- background: linear-gradient(0deg, rgba(247,243,245,.99) 0%, rgba(247,243,245,.92) 42%, rgba(247,243,245,.04) 76%);
1267
- }
1268
- .opening-panel {
1269
- left: 3%;
1270
- right: 3%;
1271
- top: auto;
1272
- bottom: 2%;
1273
- width: auto;
1274
- max-height: 74%;
1275
- grid-template-columns: 1fr;
1276
- gap: 0;
1277
- padding: 1rem;
1278
- transform: none;
1279
- }
1280
- .opening-panel > :not(.opening-case) { grid-column: 1; }
1281
- .opening-case {
1282
- grid-column: 1;
1283
- grid-row: auto;
1284
- min-height: 0;
1285
- flex-direction: row;
1286
- justify-content: flex-start;
1287
- gap: .4rem;
1288
- margin-bottom: .35rem;
1289
- padding: 0 0 .4rem;
1290
- border-right: 0;
1291
- border-bottom: 1px solid rgba(76,92,119,.16);
1292
- }
1293
- .opening-case b { margin: 0; font-size: 1.2rem; }
1294
- .opening-case i { writing-mode: horizontal-tb; }
1295
- .opening-panel .phase-header h2 { font-size: clamp(1.65rem, 7vw, 2rem); }
1296
- .opening-panel .phase-header > p:last-child { line-height: 1.65; }
1297
- .opening-panel .speaker-line { margin: .55rem 0 .7rem; padding: .45rem .55rem; }
1298
- }
1299
-
1300
- @media (max-width: 460px) {
1301
- .title-copy h1 { font-size: 1.9rem; }
1302
- .title-subtitle { margin-bottom: .7rem; font-size: .88rem; }
1303
- .identity-line { margin-bottom: .8rem; font-size: .78rem; line-height: 1.65; }
1304
- .title-actions { gap: .45rem; margin-bottom: .65rem; }
1305
- .title-actions .ink-button { flex: 1 1 calc(50% - .45rem); min-width: 0; padding: .65rem .7rem; }
1306
- .title-actions #btn-gallery { flex-basis: 100%; }
1307
- .rating-line, .save-note { margin-block: .3rem; font-size: .62rem; }
1308
- .opening-panel { max-height: 78%; }
1309
- .opening-panel .choice-grid { grid-template-columns: 1fr; gap: .4rem; }
1310
- .opening-panel .choice-button { min-height: 3.6rem; }
1311
- }
1312
-
1313
- /* 2026-09 第二轮整体重设:正戏不再是一组等重的审计卡,而是一桌、一物、一人。 */
1314
- :root {
1315
- --scene-ink: #171d29;
1316
- --scene-paper: #f2eadc;
1317
- --scene-red: #9f2630;
1318
- --scene-gold: #c5a264;
1319
- }
1320
-
1321
- /* 标题页不再套用第二轮的深色覆盖:那组规则是为已撤回的暗色群像配的,会把原版明亮封面压暗。
1322
- * 标题沿用上方 08-25 的亮底规则;下方白日、路线与夜谈的重设保留。 */
1323
-
1324
- /* 白日:一张掀起的宣纸靠左,院落与人物行动留出大面积呼吸。 */
1325
- #app .hub-stage:not(.evening)::after {
1326
- background:
1327
- linear-gradient(90deg, rgba(20,28,36,.24) 0%, rgba(21,28,36,.04) 58%),
1328
- linear-gradient(0deg, rgba(19,27,34,.24), transparent 52%);
1329
- }
1330
- #app .day-panel {
1331
- left: clamp(1.2rem,5vw,5.5rem);
1332
- right: auto;
1333
- top: 50%;
1334
- bottom: auto;
1335
- width: min(42rem,48vw);
1336
- max-height: 88%;
1337
- padding: clamp(1.3rem,2.3vw,2.4rem) clamp(1.2rem,2.5vw,2.7rem) clamp(1.2rem,2.2vw,2.2rem) 6.1rem;
1338
- transform: translateY(-50%) rotate(-.22deg);
1339
- border: 0;
1340
- border-radius: 0 1.4rem 1.4rem 0;
1341
- background:
1342
- linear-gradient(96deg, rgba(229,217,197,.98), rgba(250,244,232,.94) 78%, rgba(248,241,228,.88));
1343
- box-shadow: 20px 28px 70px rgba(20,26,32,.3), inset 1px 0 rgba(255,255,255,.9);
1344
- backdrop-filter: blur(7px);
1345
- }
1346
- #app .day-panel::before { inset: .65rem; border: 0; border-left: 1px solid rgba(144,73,54,.22); }
1347
- .day-scene-mark {
1348
- position: absolute;
1349
- left: 1rem;
1350
- top: 1.35rem;
1351
- bottom: 1.35rem;
1352
- width: 3.8rem;
1353
- display: flex;
1354
- flex-direction: column;
1355
- align-items: center;
1356
- gap: .35rem;
1357
- padding-right: .8rem;
1358
- border-right: 1px solid rgba(91,79,64,.2);
1359
- }
1360
- .day-scene-mark span { color: #a0443e; font: 700 .55rem var(--sans); letter-spacing: .24em; }
1361
- .day-scene-mark b { color: #252a31; font: 300 2.5rem/1 var(--serif); }
1362
- .day-scene-mark i { color: #72604c; font: 500 .66rem/1.5 var(--sans); letter-spacing: .14em; writing-mode: vertical-rl; }
1363
- .day-panel .phase-header .eyebrow { color: #9e413d; letter-spacing: .19em; }
1364
- .day-panel .phase-header h2 { color: #222833; font-size: clamp(2rem,3vw,3.25rem); line-height: 1.04; }
1365
- .day-panel .phase-header > p:last-child { color: #574f45; max-width: 34rem; font-size: .95rem; line-height: 1.78; }
1366
- .day-actions { counter-reset: day-choice; gap: .6rem; }
1367
- .day-actions .choice-button { counter-increment: day-choice; position: relative; padding-left: 3.25rem; border: 0; border-bottom: 1px solid rgba(91,73,55,.2); border-radius: .2rem; background: rgba(255,252,244,.6); box-shadow: none; }
1368
- .day-actions .choice-button::before { content: counter(day-choice, cjk-ideographic); position:absolute; left:.9rem; top:50%; translate:0 -50%; color:#a02d35; font: 500 1.2rem var(--serif); }
1369
- .day-actions .choice-button:hover:not(:disabled) { transform: translateX(.35rem); background: #fffaf0; box-shadow: -4px 0 #9f2630; }
1370
-
1371
- /* 人物路线与普通夜晚:近景占右,左侧窄绢只承载她此刻的一句话。 */
1372
- #app :is(.dialogue-stage, .night-talk-stage)::after {
1373
- background:
1374
- linear-gradient(90deg, rgba(13,18,28,.96) 0%, rgba(19,24,36,.91) 38%, rgba(18,23,34,.28) 61%, rgba(12,17,26,.08) 100%),
1375
- linear-gradient(0deg, rgba(7,12,21,.45), transparent 62%);
1376
- }
1377
- #app :is(.dialogue-stage, .night-talk-stage) .close-cg { filter: saturate(.92) brightness(.86) contrast(1.08); }
1378
- #app :is(.dialogue-panel, .night-talk-panel) {
1379
- left: clamp(1.15rem,4.5vw,5rem);
1380
- right: auto;
1381
- top: 50%;
1382
- bottom: auto;
1383
- width: min(35rem,41vw);
1384
- max-height: 88%;
1385
- padding: 2rem 2rem 1.7rem 4.4rem;
1386
- transform: translateY(-50%);
1387
- color: #ede1cf;
1388
- border: 0;
1389
- border-left: 1px solid rgba(198,162,99,.56);
1390
- border-radius: 0;
1391
- background: linear-gradient(90deg, rgba(16,21,31,.93), rgba(24,29,41,.78));
1392
- box-shadow: 30px 0 70px rgba(5,8,14,.22);
1393
- backdrop-filter: blur(10px);
1394
- }
1395
- #app :is(.dialogue-panel, .night-talk-panel)::before { display: none; }
1396
- #app :is(.dialogue-panel, .night-talk-panel) .phase-header .eyebrow { color: #c7a46c; letter-spacing: .2em; }
1397
- #app :is(.dialogue-panel, .night-talk-panel) .phase-header h2 { color: #fff2da; font-size: clamp(2.4rem,4vw,4.5rem); line-height: .96; }
1398
- #app :is(.dialogue-panel, .night-talk-panel) .phase-header > p:last-child { color: #e1d2bd; font-size: 1rem; line-height: 1.8; }
1399
- .character-seal { position:absolute; left:.8rem; top:2rem; display:grid; justify-items:center; gap:.5rem; }
1400
- .character-seal i { display:grid; place-items:center; width:2.25rem; aspect-ratio:1; color:#ffe8bd; border:1px solid rgba(202,161,95,.65); border-radius:50%; font:500 1rem var(--serif); }
1401
- .character-seal span { color:rgba(231,211,178,.62); font:600 .55rem var(--sans); letter-spacing:.16em; writing-mode:vertical-rl; }
1402
- #app .dialogue-panel p.want-line { margin:.85rem 0 1rem; padding:.8rem 0 .8rem 1rem; color:#d8c8b2; border:0; border-left:2px solid #8f2832; background:rgba(255,255,255,.035); }
1403
- #app .dialogue-panel .want-line > b { display:block; margin-bottom:.3rem; color:#c9a568; font:600 .58rem var(--sans); letter-spacing:.14em; }
1404
- #app .dialogue-panel .want-line span { color:#bdad97; }
1405
- #app .dialogue-panel .want-line small { color:rgba(218,204,184,.64); }
1406
- #app :is(.dialogue-panel, .night-talk-panel) :is(.choice-stack,.choice-grid) { counter-reset: night-choice; gap:.55rem; }
1407
- #app :is(.dialogue-panel, .night-talk-panel) .choice-button { counter-increment:night-choice; position:relative; min-height:3.6rem; padding:.7rem .9rem .7rem 3.2rem; color:#f1e5d2; border:1px solid rgba(209,178,125,.2); border-left:0; background:rgba(239,223,194,.055); box-shadow:none; }
1408
- #app :is(.dialogue-panel, .night-talk-panel) .choice-button::before { content:counter(night-choice, cjk-ideographic); position:absolute; left:1rem; top:50%; translate:0 -50%; color:#c5a264; font:500 1rem var(--serif); }
1409
- #app :is(.dialogue-panel, .night-talk-panel) .choice-button span { color:rgba(224,208,184,.62); }
1410
- #app :is(.dialogue-panel, .night-talk-panel) .choice-button:hover:not(:disabled) { color:#fff8eb; border-color:rgba(184,54,65,.68); background:rgba(151,35,45,.42); transform:translateX(.3rem); }
1411
- #app :is(.dialogue-panel, .night-talk-panel) .consent-note { color:rgba(231,215,192,.65); }
1412
-
1413
- @media (max-width: 900px) {
1414
- #app .day-panel { left:3%; right:3%; top:auto; bottom:2%; width:auto; max-height:77%; padding:1rem 1rem 1rem 4.4rem; transform:none; }
1415
- .day-scene-mark { left:.65rem; top:1rem; bottom:1rem; width:3rem; }
1416
- .day-scene-mark b { font-size:1.8rem; }
1417
- #app :is(.dialogue-panel, .night-talk-panel) { left:3%; right:3%; top:auto; bottom:2%; width:auto; max-height:74%; padding:1.1rem 1rem 1rem 3.5rem; transform:none; background:linear-gradient(90deg, rgba(16,21,31,.97),rgba(24,29,41,.92)); }
1418
- .character-seal { left:.55rem; top:1.2rem; }
1419
- }
1420
-
1421
- /* 第二轮文字可读性复核:纹理退到空气层,必要事实不能靠低对比度降级。 */
1422
- #app::after {
1423
- opacity: .08;
1424
- mix-blend-mode: soft-light;
1425
- background-image: linear-gradient(115deg, rgba(255,255,255,.05), transparent 42%, rgba(111,58,68,.035));
1426
- background-size: auto;
1427
- }
1428
- #app :is(.dialogue-stage, .night-talk-stage)::after {
1429
- background:
1430
- linear-gradient(90deg, rgba(16,22,32,.88) 0%, rgba(19,26,37,.72) 39%, rgba(19,25,36,.16) 61%, transparent 100%),
1431
- linear-gradient(0deg, rgba(21,27,38,.14), transparent 58%);
1432
- }
1433
- #app :is(.dialogue-panel, .night-talk-panel) {
1434
- background: linear-gradient(100deg, rgba(25,33,45,.96), rgba(32,40,53,.91));
1435
- }
1436
- #app :is(.dialogue-panel, .night-talk-panel) .phase-header > p:last-child {
1437
- color: #f0e3d0;
1438
- font-size: 1.04rem;
1439
- line-height: 1.82;
1440
- }
1441
- #app .dialogue-panel p.want-line {
1442
- color: #eadbc5;
1443
- background: #303a49;
1444
- font-size: .9rem;
1445
- line-height: 1.68;
1446
- }
1447
- #app .dialogue-panel .want-line > b { color: #e2bd78; font-size: .75rem; }
1448
- #app .dialogue-panel .want-line span { color: #dbc8ab; font-size: .86rem; }
1449
- #app .dialogue-panel .want-line small { color: #cfc0aa; font-size: .76rem; line-height: 1.65; }
1450
- #app :is(.dialogue-panel, .night-talk-panel) .choice-button b {
1451
- color: #fff1da;
1452
- font-size: .93rem;
1453
- line-height: 1.38;
1454
- }
1455
- #app :is(.dialogue-panel, .night-talk-panel) .choice-button span {
1456
- color: #d7c5a9;
1457
- font-size: .76rem;
1458
- line-height: 1.5;
1459
- }
1460
- #app :is(.dialogue-panel, .night-talk-panel) .choice-button {
1461
- border-color: rgba(224,193,140,.3);
1462
- background: rgba(249,231,201,.085);
1463
- }
1464
- #app :is(.dialogue-panel, .night-talk-panel) .choice-button:focus-visible {
1465
- outline: 2px solid #e2bd78;
1466
- outline-offset: 3px;
1467
- }
1468
- .ending-old-account {
1469
- margin: .8rem 0 1rem;
1470
- color: #5f5860;
1471
- border-top: 1px solid rgba(114,82,72,.18);
1472
- border-bottom: 1px solid rgba(114,82,72,.18);
1473
- }
1474
- .ending-old-account summary {
1475
- padding: .65rem 0;
1476
- color: #8d514a;
1477
- cursor: pointer;
1478
- font: 600 .76rem var(--sans);
1479
- letter-spacing: .08em;
1480
- }
1481
- .ending-old-account p { margin: 0 0 .8rem; }
1482
- @media (max-width: 900px) {
1483
- #app :is(.dialogue-panel, .night-talk-panel) { max-height: 82%; }
1484
- }
1485
- @media (max-width: 460px) {
1486
- #app :is(.dialogue-panel, .night-talk-panel) { padding-top: .9rem; padding-bottom: .8rem; }
1487
- #app :is(.dialogue-panel, .night-talk-panel) .phase-header h2 { font-size: 2.1rem; }
1488
- #app :is(.dialogue-panel, .night-talk-panel) .phase-header > p:last-child { font-size: .92rem; line-height: 1.66; }
1489
- #app .dialogue-panel p.want-line { margin: .55rem 0 .65rem; padding-block: .5rem; font-size: .84rem; }
1490
- #app .dialogue-panel .want-line span { font-size: .79rem; }
1491
- #app .dialogue-panel .want-line small { font-size: .75rem; }
1492
- #app .dialogue-panel .choice-stack { grid-template-columns: 1fr; gap: .4rem; }
1493
- #app :is(.dialogue-panel, .night-talk-panel) .choice-button { min-height: 3.15rem; padding-block: .55rem; }
1494
- }