diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6e062ed..44800ef 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,8 @@
- 多语言第二轮审校(Claude 子代理逐语言通读 UI 与 16 章手册,交叉复审 Gemini 的修订):采用 de 39、fr 56、es 34、pl 37、ru 45、ja 142 条(ja 里约一半是全角标点、×、〜 等机械统一)。要点:天数不再缩写、Tumbler 称谓与 Key-Drive 统一、手册页签名对齐界面、ASIC 时代统一、修正数处误译(俄语手册首章“卖出”写成用交易币付款、永续/挖矿章、日语质押章“向池子付款”等)。
- 二手贩子的卡按卖家调整健康度:老实人 72–97、中间商 55–85、骗子 42–72,平均每张卡成色有问题的项(叶片、金手指、挡板、封条,共 4 项)约 0.5 / 1.5 / 2.5(原来三者都是 25–85,约 2.4)。范围进 `Tuning.UsedHealthMin/Max`。
-- 显卡鉴定手册改为阅读窗口(和 Web3 手册同一个窗口,共 8 页,8 种语言);外观折价六个数字进 `Tuning`(`CardFanDust` 等),手册用占位符取值。物品提示缩短为一句。
+- 显卡鉴定指南改为游戏原版的纸质指南样式(笔记本背景、委员会页眉、居中标题、插图加图注、“价格不变 / -n%”标注、末页鉴定示例,共 9 页,插图用检视台的大图),文案改成名词标题加陈述句,用词与原版鉴定指南一致(假冒、品相、价格不变)。
+- (已被上一条取代)显卡鉴定手册曾做成阅读窗口(和 Web3 手册同一个窗口,共 8 页,8 种语言);外观折价六个数字进 `Tuning`(`CardFanDust` 等),手册用占位符取值。物品提示缩短为一句。
- 鉴定样例测试按钮(`Showcase: next dealer / appraisal case`),展示页的显卡鉴定专页用它截图。
- 鉴定显卡的检视弹窗:第一行标签“型号真伪”改为“型号”(各语言同改),指出之前不再写“检查:供电口与风扇数、序列号、背面丝印”这行依据;指出之后仍在下方列出查到的问题。
- 带首尾空格的拼接文字(“ (seller said: {0})”等 10 条):英文原先有的没加引号,被游戏读表时吃掉;其余语言翻译时也丢了。已补引号、按英文补回空格,并加测试。
diff --git a/src/Decentralized/GpuGuide.cs b/src/Decentralized/GpuGuide.cs
new file mode 100644
index 0000000..fbfcf71
--- /dev/null
+++ b/src/Decentralized/GpuGuide.cs
@@ -0,0 +1,320 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Decentralized.Domain;
+using UnityEngine;
+
+namespace Decentralized
+{
+ ///
+ /// 显卡鉴定指南:游戏的纸质指南(PaperUI),版式和原版鉴定指南一致——笔记本背景、委员会页眉、居中标题、
+ /// 插图加图注、“价格不变 / -n%”的折价标注、末页的鉴定示例。第一次打开时按当前语言生成并登记,语言变了重新生成。
+ /// 坐标是设计单位(314×402,屏幕上放大 2 倍)。
+ ///
+ public static class GpuGuide
+ {
+ public const string BookId = "gpu_guide";
+ private const float X = 35f, W = 253f, Top = 80f, Bottom = 368f;
+ private const string Ink = "#221C1A", Good = "#3F7D4B", Bad = "#9E1F1A";
+
+ private static string _locale;
+ private static LoadedMod _mod;
+
+ public static void OnAssetsLoaded(LoadedMod mod)
+ {
+ if (mod?.Manifest?.ID == ModInfo.Id) _mod = mod;
+ }
+
+ /// 原版背景、按钮和页眉图按名字找不到时(纸张素材目录没打包),把内存里同名的原版精灵登记给本 mod。
+ private static void ProvideMissingPaperSprites()
+ {
+ if (_mod == null) return;
+ foreach (var sprite in Resources.FindObjectsOfTypeAll())
+ {
+ string n = sprite.name;
+ if (n != "notebook_manual" && n != "guide_logo" && !n.StartsWith("paper_buttons")) continue;
+ if (_mod.PaperSprites.ContainsKey(n) || PaperAssets.FindInCatalog(n) != null) continue;
+ _mod.PaperSprites[n] = sprite;
+ }
+ }
+
+ public static void Open(int page = 0)
+ {
+ try
+ {
+ if (_locale != L.Code || !ModHelper.GetPaperBookIds(ModInfo.Id).Contains(BookId)) Register();
+ var ui = ModHelper.OpenPaper(ModInfo.Id, BookId);
+ if (ui == null) { Log.Warn("[GpuGuide] 打不开鉴定指南"); return; }
+ ui.FlipTo(page);
+ RaiseAboveModWindows(ui);
+ }
+ catch (Exception ex) { Log.Error("[GpuGuide] " + ex); }
+ }
+
+ /// 纸质画布在 mod 窗口所在的层下面:从终端里打开时会被盖住,打开期间调到上面,关上时恢复。
+ private static void RaiseAboveModWindows(PaperUI ui)
+ {
+ var canvas = ui.Root != null ? ui.Root.GetComponentInParent