diff --git a/docs/en/mental-models/ch-01-orthogonality/01-the-forces.md b/docs/en/mental-models/ch-01-orthogonality/01-the-forces.md index d591c59..7cf7ee8 100644 --- a/docs/en/mental-models/ch-01-orthogonality/01-the-forces.md +++ b/docs/en/mental-models/ch-01-orthogonality/01-the-forces.md @@ -6,6 +6,8 @@ You learned this in high school physics: an object's motion is never determined How fast a car goes is not just about the engine. Road friction, air resistance, tire grip, transmission efficiency — they all shape the outcome. A powerful engine on bald tires is just noise and heat. +![The resultant](assets/the-forces.png) + Agentic systems work the same way. When you plug an LLM into tools, feed it context, wrap it in a runtime framework, and deploy it inside a sandbox, the system's final performance — how complex a problem it solves, how reliably it finishes a task, how autonomously it operates — is the resultant of all these forces, not the solo act of any one. diff --git a/docs/en/mental-models/ch-01-orthogonality/assets/the-forces.dark.png b/docs/en/mental-models/ch-01-orthogonality/assets/the-forces.dark.png new file mode 100644 index 0000000..b734856 Binary files /dev/null and b/docs/en/mental-models/ch-01-orthogonality/assets/the-forces.dark.png differ diff --git a/docs/en/mental-models/ch-01-orthogonality/assets/the-forces.png b/docs/en/mental-models/ch-01-orthogonality/assets/the-forces.png index c9d0ef8..385fb22 100644 Binary files a/docs/en/mental-models/ch-01-orthogonality/assets/the-forces.png and b/docs/en/mental-models/ch-01-orthogonality/assets/the-forces.png differ diff --git a/docs/en/mental-models/ch-02-cybernetics/01-helmsman.md b/docs/en/mental-models/ch-02-cybernetics/01-helmsman.md index 928d8d5..00b9718 100644 --- a/docs/en/mental-models/ch-02-cybernetics/01-helmsman.md +++ b/docs/en/mental-models/ch-02-cybernetics/01-helmsman.md @@ -8,6 +8,8 @@ In 1948, a mathematician gave that work a name. The word *cybernetics* comes from the Greek κυβερνήτης — helmsman. Not a philosopher, not an architect. A helmsman. Someone adjusting course in real time, against wind and current. +![the helmsman](assets/helmsman.png) + Norbert Wiener used this word to name a discipline: the study of how systems achieve control through feedback — whether the system is a steam engine, a cat, or a social organization. ???+ quote "Wiener's core insight (paraphrased)" diff --git a/docs/en/mental-models/ch-02-cybernetics/06-second-order.md b/docs/en/mental-models/ch-02-cybernetics/06-second-order.md index 5d641fb..28eebfa 100644 --- a/docs/en/mental-models/ch-02-cybernetics/06-second-order.md +++ b/docs/en/mental-models/ch-02-cybernetics/06-second-order.md @@ -8,6 +8,8 @@ Observing the model's output, judging how far it lands from where you want it, m But you are also part of the system. Your design decisions shape the system's behavior, and the system's behavior shapes your next design decision. You are inside. +![observer within](assets/second-order.png) + In 1974, Heinz von Foerster drew a line through this phenomenon. ## First order and second order diff --git a/docs/en/mental-models/ch-02-cybernetics/assets/helmsman.dark.png b/docs/en/mental-models/ch-02-cybernetics/assets/helmsman.dark.png new file mode 100644 index 0000000..1205193 Binary files /dev/null and b/docs/en/mental-models/ch-02-cybernetics/assets/helmsman.dark.png differ diff --git a/docs/en/mental-models/ch-02-cybernetics/assets/helmsman.png b/docs/en/mental-models/ch-02-cybernetics/assets/helmsman.png new file mode 100644 index 0000000..d841e7e Binary files /dev/null and b/docs/en/mental-models/ch-02-cybernetics/assets/helmsman.png differ diff --git a/docs/en/mental-models/ch-02-cybernetics/assets/second-order.dark.png b/docs/en/mental-models/ch-02-cybernetics/assets/second-order.dark.png new file mode 100644 index 0000000..b783111 Binary files /dev/null and b/docs/en/mental-models/ch-02-cybernetics/assets/second-order.dark.png differ diff --git a/docs/en/mental-models/ch-02-cybernetics/assets/second-order.png b/docs/en/mental-models/ch-02-cybernetics/assets/second-order.png index 5fd546f..db244dc 100644 Binary files a/docs/en/mental-models/ch-02-cybernetics/assets/second-order.png and b/docs/en/mental-models/ch-02-cybernetics/assets/second-order.png differ diff --git a/docs/en/mental-models/ch-03-entropy/01-what-is-entropy.md b/docs/en/mental-models/ch-03-entropy/01-what-is-entropy.md index c24410c..a43d646 100644 --- a/docs/en/mental-models/ch-03-entropy/01-what-is-entropy.md +++ b/docs/en/mental-models/ch-03-entropy/01-what-is-entropy.md @@ -6,6 +6,8 @@ What does your desk look like right now? If you are like most people, the honest answer is "worse than last week." Not because you trashed it on purpose. Quite the opposite, you have been tidying up. But disorder is the default direction. Left alone, things drift toward mess. +![disorder is the default](assets/what-is-entropy.png) + That intuition is more precise than it feels. Behind it sits a mathematical structure that spans thermodynamics and information theory, and that structure is directly connected to a parameter you adjust every time you call an LLM. ## Boltzmann's desk diff --git a/docs/en/mental-models/ch-03-entropy/05-maxwells-demon.md b/docs/en/mental-models/ch-03-entropy/05-maxwells-demon.md index da6337f..2156d37 100644 --- a/docs/en/mental-models/ch-03-entropy/05-maxwells-demon.md +++ b/docs/en/mental-models/ch-03-entropy/05-maxwells-demon.md @@ -18,6 +18,8 @@ The setup, stated precisely. An insulated container. A partition in the middle. A door in the partition. Gas molecules bounce around on both sides. The Demon watches each molecule that approaches the door. Slow molecule on the left side? Open the door, let it through to the right. Fast molecule on the right? Open the door, let it through to the left. Otherwise, keep the door shut. +![Maxwell's demon at the door](assets/maxwells-demon.png) + After enough rounds, the left side holds only fast molecules (high temperature), the right side only slow ones (low temperature). A uniform-temperature system has been sorted into a hot half and a cold half. Entropy has decreased. No work was done. The door is massless; opening and closing it costs effectively nothing. The second law says entropy in an isolated system can only increase or stay the same. The Demon appears to violate it. diff --git a/docs/en/mental-models/ch-03-entropy/assets/maxwells-demon.dark.png b/docs/en/mental-models/ch-03-entropy/assets/maxwells-demon.dark.png new file mode 100644 index 0000000..aed12f0 Binary files /dev/null and b/docs/en/mental-models/ch-03-entropy/assets/maxwells-demon.dark.png differ diff --git a/docs/en/mental-models/ch-03-entropy/assets/maxwells-demon.png b/docs/en/mental-models/ch-03-entropy/assets/maxwells-demon.png index 5c9081f..469f8b4 100644 Binary files a/docs/en/mental-models/ch-03-entropy/assets/maxwells-demon.png and b/docs/en/mental-models/ch-03-entropy/assets/maxwells-demon.png differ diff --git a/docs/en/mental-models/ch-03-entropy/assets/what-is-entropy.dark.png b/docs/en/mental-models/ch-03-entropy/assets/what-is-entropy.dark.png new file mode 100644 index 0000000..21121f9 Binary files /dev/null and b/docs/en/mental-models/ch-03-entropy/assets/what-is-entropy.dark.png differ diff --git a/docs/en/mental-models/ch-03-entropy/assets/what-is-entropy.png b/docs/en/mental-models/ch-03-entropy/assets/what-is-entropy.png index e8138da..61fae32 100644 Binary files a/docs/en/mental-models/ch-03-entropy/assets/what-is-entropy.png and b/docs/en/mental-models/ch-03-entropy/assets/what-is-entropy.png differ diff --git a/docs/en/mental-models/ch-04-operating-system/01-from-demon-to-os.md b/docs/en/mental-models/ch-04-operating-system/01-from-demon-to-os.md index 283b29f..aa1ff06 100644 --- a/docs/en/mental-models/ch-04-operating-system/01-from-demon-to-os.md +++ b/docs/en/mental-models/ch-04-operating-system/01-from-demon-to-os.md @@ -10,6 +10,8 @@ One Demon, one judgment at a time. No rules, no fallback when it is absent, no a Write the sorting rules down as policy, and you have an operating system. +![from demon to institution](assets/from-demon-to-os.png) + ## Karpathy's three-year refinement In 2023, Andrej Karpathy described LLMs as "the kernel process of an emerging operating system." The phrase stuck. It captured something intuitively right about the relationship between language models and the broader computational infrastructure forming around them. diff --git a/docs/en/mental-models/ch-04-operating-system/assets/from-demon-to-os.dark.png b/docs/en/mental-models/ch-04-operating-system/assets/from-demon-to-os.dark.png new file mode 100644 index 0000000..25a8c77 Binary files /dev/null and b/docs/en/mental-models/ch-04-operating-system/assets/from-demon-to-os.dark.png differ diff --git a/docs/en/mental-models/ch-04-operating-system/assets/from-demon-to-os.png b/docs/en/mental-models/ch-04-operating-system/assets/from-demon-to-os.png index fc9902b..d100a70 100644 Binary files a/docs/en/mental-models/ch-04-operating-system/assets/from-demon-to-os.png and b/docs/en/mental-models/ch-04-operating-system/assets/from-demon-to-os.png differ diff --git a/docs/en/mental-models/ch-05-fractal/01-sumeru-in-a-mustard-seed.md b/docs/en/mental-models/ch-05-fractal/01-sumeru-in-a-mustard-seed.md index f6902d6..282e9c5 100644 --- a/docs/en/mental-models/ch-05-fractal/01-sumeru-in-a-mustard-seed.md +++ b/docs/en/mental-models/ch-05-fractal/01-sumeru-in-a-mustard-seed.md @@ -14,6 +14,8 @@ A different sutra pushes the same intuition further. Mount Sumeru is the axis of the Buddhist cosmos — the largest thing conceivable. A mustard seed is smaller than a sesame seed. Sumeru enters the seed without distortion: scale changes, structure stays intact. +![sumeru within the seed](assets/sumeru-in-a-mustard-seed.png) + These two passages come from different scriptures, but they share one structural intuition. Indra's Net says *every part mirrors the whole* — pick any jewel and you see the entire net. The Sumeru passage says *the largest structure fits inside the smallest container without loss* — the container's scale is irrelevant to the content's structure. One emphasizes the mapping relationship. The other emphasizes scale-invariance. Together, they outline something precise: the information of the whole is present in every part, and that presence survives changes in scale. diff --git a/docs/en/mental-models/ch-05-fractal/02-the-generator.md b/docs/en/mental-models/ch-05-fractal/02-the-generator.md index 5b82f04..7ec1970 100644 --- a/docs/en/mental-models/ch-05-fractal/02-the-generator.md +++ b/docs/en/mental-models/ch-05-fractal/02-the-generator.md @@ -59,6 +59,8 @@ One iteration rule. Different initial conditions. The result is a structure that L-systems and the Mandelbrot set come from completely different mathematical traditions — one from formal language theory, the other from complex dynamical systems. Yet they converge on the same conclusion: **simple rule + repeated iteration = emergent self-similarity.** +![the Koch snowflake](assets/the-generator.png) + There is an important distinction to be honest about here. L-systems produce **exact self-similarity** — every level of branching is a precise scaled-down copy of the level above, because the replacement rule is identical at every step. Natural plants exhibit **statistical self-similarity** — the branching angles, length ratios, and branch counts are consistent in their statistical properties across scales, but no two branches are ever identical. An L-system is a mathematical abstraction of plant growth, not a faithful reproduction of it. Real biological systems are buffeted by wind, uneven sunlight, soil nutrient gradients, and competition with neighboring plants — randomness that smears exact self-similarity into the statistical kind. The mathematical model reveals the underlying mechanism; nature adds noise on top. L-systems appeared in 1968. The Mandelbrot set was first rendered by computer in 1978. A decade apart, from different research traditions, both pointing at the same core mechanism. Mathematics has given its answer: iteration is the generator of self-similarity. diff --git a/docs/en/mental-models/ch-05-fractal/03-worlds-within-worlds.md b/docs/en/mental-models/ch-05-fractal/03-worlds-within-worlds.md index d7fd355..18fcfc8 100644 --- a/docs/en/mental-models/ch-05-fractal/03-worlds-within-worlds.md +++ b/docs/en/mental-models/ch-05-fractal/03-worlds-within-worlds.md @@ -32,6 +32,8 @@ In the seventh century, the Tang dynasty monk Fazang faced a pedagogical problem Gold, as a substance, has no fixed shape — it takes the form of a lion only because a craftsman made it so. The lion's shape is "empty," meaning not that it does not exist, but that it is not a separate entity independent of the gold. Form and substance are inseparable. Then the critical move: pick any single hair-pore on the lion's body, and that pore contains the entire lion. Every pore does. +![Indra's net](assets/worlds-within-worlds.png) + This is not a claim about visual resemblance — the pore does not *look like* a tiny lion. Fazang's point is that the gold in the pore and the gold of the whole lion are the same gold. Structure and substrate cannot be separated. The part does not "map to" the whole. The part **is** the whole, expressed at a different position and scale. Fazang was the third patriarch of the Huayan school, and his contribution was to take the poetic imagery of the Avatamsaka Sutra — Indra's Net, the interpenetration of all phenomena — and formalize it into a systematic philosophical framework. Francis Cook's *Hua-yen Buddhism* (1977) remains the standard English-language study of this tradition for readers who want the full philosophical architecture. diff --git a/docs/en/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.dark.png b/docs/en/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.dark.png new file mode 100644 index 0000000..8ceda79 Binary files /dev/null and b/docs/en/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.dark.png differ diff --git a/docs/en/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.png b/docs/en/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.png index c3dfbc4..13df50b 100644 Binary files a/docs/en/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.png and b/docs/en/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.png differ diff --git a/docs/en/mental-models/ch-05-fractal/assets/the-generator.dark.png b/docs/en/mental-models/ch-05-fractal/assets/the-generator.dark.png new file mode 100644 index 0000000..8debd77 Binary files /dev/null and b/docs/en/mental-models/ch-05-fractal/assets/the-generator.dark.png differ diff --git a/docs/en/mental-models/ch-05-fractal/assets/the-generator.png b/docs/en/mental-models/ch-05-fractal/assets/the-generator.png index 0ab6189..300950f 100644 Binary files a/docs/en/mental-models/ch-05-fractal/assets/the-generator.png and b/docs/en/mental-models/ch-05-fractal/assets/the-generator.png differ diff --git a/docs/en/mental-models/ch-05-fractal/assets/worlds-within-worlds.dark.png b/docs/en/mental-models/ch-05-fractal/assets/worlds-within-worlds.dark.png new file mode 100644 index 0000000..ce696c6 Binary files /dev/null and b/docs/en/mental-models/ch-05-fractal/assets/worlds-within-worlds.dark.png differ diff --git a/docs/en/mental-models/ch-05-fractal/assets/worlds-within-worlds.png b/docs/en/mental-models/ch-05-fractal/assets/worlds-within-worlds.png index 27f5fe2..78e0004 100644 Binary files a/docs/en/mental-models/ch-05-fractal/assets/worlds-within-worlds.png and b/docs/en/mental-models/ch-05-fractal/assets/worlds-within-worlds.png differ diff --git a/docs/en/mental-models/ch-06-causality/01-humes-fork.md b/docs/en/mental-models/ch-06-causality/01-humes-fork.md index af0701d..c23e556 100644 --- a/docs/en/mental-models/ch-06-causality/01-humes-fork.md +++ b/docs/en/mental-models/ch-06-causality/01-humes-fork.md @@ -20,6 +20,8 @@ Hume's answer: no. You witnessed two events in succession — Ball A moved, contact occurred, Ball B moved. But what did you observe *between* those events? Nothing. No force visibly flowing from A to B. No "causation" hanging in the air. You saw: A moved first, B moved second. Full stop. +![Hume's fork](assets/humes-fork.png) + What if you watch it a hundred times? A thousand? Each repetition increases your confidence that "when A hits B, B moves." But what accumulates is not observation of some hidden mechanism — it's statistical confidence in a pattern. What you observe is still *constant conjunction*: events of this type reliably follow events of that type. diff --git a/docs/en/mental-models/ch-06-causality/03-the-ladder.md b/docs/en/mental-models/ch-06-causality/03-the-ladder.md index 2306262..e5357b9 100644 --- a/docs/en/mental-models/ch-06-causality/03-the-ladder.md +++ b/docs/en/mental-models/ch-06-causality/03-the-ladder.md @@ -10,6 +10,8 @@ This question didn't get a precise answer until the 2000s. And the person who an Pearl divided causal reasoning into three levels. He called it the Ladder of Causation. +![the ladder of causation](assets/the-ladder.png) + A single scenario will make the structure clear. **Rung one: Association (Seeing).** "Among people who took this drug, 70% recovered." diff --git a/docs/en/mental-models/ch-06-causality/assets/humes-fork.dark.png b/docs/en/mental-models/ch-06-causality/assets/humes-fork.dark.png new file mode 100644 index 0000000..6ed18ca Binary files /dev/null and b/docs/en/mental-models/ch-06-causality/assets/humes-fork.dark.png differ diff --git a/docs/en/mental-models/ch-06-causality/assets/humes-fork.png b/docs/en/mental-models/ch-06-causality/assets/humes-fork.png index 74e5265..a5fd90c 100644 Binary files a/docs/en/mental-models/ch-06-causality/assets/humes-fork.png and b/docs/en/mental-models/ch-06-causality/assets/humes-fork.png differ diff --git a/docs/en/mental-models/ch-06-causality/assets/the-ladder.dark.png b/docs/en/mental-models/ch-06-causality/assets/the-ladder.dark.png new file mode 100644 index 0000000..c76f6f4 Binary files /dev/null and b/docs/en/mental-models/ch-06-causality/assets/the-ladder.dark.png differ diff --git a/docs/en/mental-models/ch-06-causality/assets/the-ladder.png b/docs/en/mental-models/ch-06-causality/assets/the-ladder.png index 3492197..eb3d520 100644 Binary files a/docs/en/mental-models/ch-06-causality/assets/the-ladder.png and b/docs/en/mental-models/ch-06-causality/assets/the-ladder.png differ diff --git a/docs/en/mental-models/ch-07-symbols-connectionism/01-two-roads.md b/docs/en/mental-models/ch-07-symbols-connectionism/01-two-roads.md index efcd164..d7a0337 100644 --- a/docs/en/mental-models/ch-07-symbols-connectionism/01-two-roads.md +++ b/docs/en/mental-models/ch-07-symbols-connectionism/01-two-roads.md @@ -8,6 +8,8 @@ One is good at structure but cannot discover. The other discovers but cannot str This impasse is not new. It is the oldest fork in artificial intelligence. +![two roads, irreducibly](assets/two-roads.png) + ## What symbols promised In 1975, Newell and Simon delivered their Turing Award lecture and articulated the Physical Symbol System Hypothesis: a physical symbol system has the necessary and sufficient means for general intelligent action. diff --git a/docs/en/mental-models/ch-07-symbols-connectionism/assets/two-roads.dark.png b/docs/en/mental-models/ch-07-symbols-connectionism/assets/two-roads.dark.png new file mode 100644 index 0000000..533c448 Binary files /dev/null and b/docs/en/mental-models/ch-07-symbols-connectionism/assets/two-roads.dark.png differ diff --git a/docs/en/mental-models/ch-07-symbols-connectionism/assets/two-roads.png b/docs/en/mental-models/ch-07-symbols-connectionism/assets/two-roads.png index badba00..a6c774b 100644 Binary files a/docs/en/mental-models/ch-07-symbols-connectionism/assets/two-roads.png and b/docs/en/mental-models/ch-07-symbols-connectionism/assets/two-roads.png differ diff --git a/docs/zh/mental-models/ch-01-orthogonality/01-the-forces.md b/docs/zh/mental-models/ch-01-orthogonality/01-the-forces.md index 018598d..e774d44 100644 --- a/docs/zh/mental-models/ch-01-orthogonality/01-the-forces.md +++ b/docs/zh/mental-models/ch-01-orthogonality/01-the-forces.md @@ -6,6 +6,8 @@ 一辆车能跑多快,不只取决于发动机输出了多少马力。路面摩擦力、空气阻力、轮胎抓地力、传动效率——每一股力都在影响最终结果。发动机再强,轮胎打滑的话,动力也只是在空转。 +![合力](assets/the-forces.png) + Agentic system 也是一样。 当你把一个大语言模型接入工具、喂进上下文、包裹进运行时框架、部署到沙箱里,最终系统的表现——它能解决多复杂的问题、能多可靠地完成任务、能在多大范围内自主行动——是所有这些力的合成结果,不是其中任何一股力的独角戏。 diff --git a/docs/zh/mental-models/ch-01-orthogonality/assets/the-forces.dark.png b/docs/zh/mental-models/ch-01-orthogonality/assets/the-forces.dark.png new file mode 100644 index 0000000..f0c054f Binary files /dev/null and b/docs/zh/mental-models/ch-01-orthogonality/assets/the-forces.dark.png differ diff --git a/docs/zh/mental-models/ch-01-orthogonality/assets/the-forces.png b/docs/zh/mental-models/ch-01-orthogonality/assets/the-forces.png index 46d195e..f525cba 100644 Binary files a/docs/zh/mental-models/ch-01-orthogonality/assets/the-forces.png and b/docs/zh/mental-models/ch-01-orthogonality/assets/the-forces.png differ diff --git a/docs/zh/mental-models/ch-02-cybernetics/01-helmsman.md b/docs/zh/mental-models/ch-02-cybernetics/01-helmsman.md index 7f17ece..e10d2bd 100644 --- a/docs/zh/mental-models/ch-02-cybernetics/01-helmsman.md +++ b/docs/zh/mental-models/ch-02-cybernetics/01-helmsman.md @@ -8,6 +8,8 @@ Agentic system 的输出是两股力的合成——模型能力和你在 harness Cybernetics 这个词来自希腊语 κυβερνήτης——舵手。不是哲学家,不是建筑师,是舵手。一个在风浪中实时调整航向的人。 +![舵手](assets/helmsman.png) + Norbert Wiener 用这个词命名了一个学科:研究系统如何通过反馈来实现控制——无论这个系统是一台蒸汽机、一只猫,还是一个社会组织。 ???+ quote "Wiener 的核心洞察(意译)" diff --git a/docs/zh/mental-models/ch-02-cybernetics/06-second-order.md b/docs/zh/mental-models/ch-02-cybernetics/06-second-order.md index db41988..d781d2a 100644 --- a/docs/zh/mental-models/ch-02-cybernetics/06-second-order.md +++ b/docs/zh/mental-models/ch-02-cybernetics/06-second-order.md @@ -8,6 +8,8 @@ 但同时,你也是系统的一部分。你的设计决策影响系统行为,系统行为影响你的下一个设计决策。你不是站在系统外面调参数的旁观者——你在里面。 +![观者即被观](assets/second-order.png) + 1974 年,Heinz von Foerster 给这个现象划了一条线。 ## 一阶与二阶 diff --git a/docs/zh/mental-models/ch-02-cybernetics/assets/helmsman.dark.png b/docs/zh/mental-models/ch-02-cybernetics/assets/helmsman.dark.png new file mode 100644 index 0000000..cd7a1ab Binary files /dev/null and b/docs/zh/mental-models/ch-02-cybernetics/assets/helmsman.dark.png differ diff --git a/docs/zh/mental-models/ch-02-cybernetics/assets/helmsman.png b/docs/zh/mental-models/ch-02-cybernetics/assets/helmsman.png new file mode 100644 index 0000000..c310201 Binary files /dev/null and b/docs/zh/mental-models/ch-02-cybernetics/assets/helmsman.png differ diff --git a/docs/zh/mental-models/ch-02-cybernetics/assets/second-order.dark.png b/docs/zh/mental-models/ch-02-cybernetics/assets/second-order.dark.png new file mode 100644 index 0000000..c98c451 Binary files /dev/null and b/docs/zh/mental-models/ch-02-cybernetics/assets/second-order.dark.png differ diff --git a/docs/zh/mental-models/ch-02-cybernetics/assets/second-order.png b/docs/zh/mental-models/ch-02-cybernetics/assets/second-order.png index 08f2ae7..96bafd2 100644 Binary files a/docs/zh/mental-models/ch-02-cybernetics/assets/second-order.png and b/docs/zh/mental-models/ch-02-cybernetics/assets/second-order.png differ diff --git a/docs/zh/mental-models/ch-03-entropy/01-what-is-entropy.md b/docs/zh/mental-models/ch-03-entropy/01-what-is-entropy.md index aaed128..57c989f 100644 --- a/docs/zh/mental-models/ch-03-entropy/01-what-is-entropy.md +++ b/docs/zh/mental-models/ch-03-entropy/01-what-is-entropy.md @@ -6,6 +6,8 @@ 如果你和大多数人一样,答案是"比上周更乱"。不是因为你故意弄乱它——恰恰相反,你一直在整理。但乱是默认方向。 +![乱是默认方向](assets/what-is-entropy.png) + 这个直觉比你以为的更精确。它背后有一个跨越物理学和信息论的数学结构,而这个结构和你每天在 LLM 系统里调的一个参数直接相关。 ## Boltzmann 的桌面 diff --git a/docs/zh/mental-models/ch-03-entropy/05-maxwells-demon.md b/docs/zh/mental-models/ch-03-entropy/05-maxwells-demon.md index 5c1bc23..2f41cda 100644 --- a/docs/zh/mental-models/ch-03-entropy/05-maxwells-demon.md +++ b/docs/zh/mental-models/ch-03-entropy/05-maxwells-demon.md @@ -18,6 +18,8 @@ 一个绝热容器,中间有一面隔板,隔板上有一扇门。气体分子在两侧随机运动。Demon 坐在门旁,观察每个接近门的分子。如果左侧来了一个慢分子,开门放到右侧;如果右侧来了一个快分子,开门放到左侧。其他时候,门关着。 +![门旁的 demon](assets/maxwells-demon.png) + 经过足够多的操作,左侧全是快分子(高温),右侧全是慢分子(低温)。一个均匀温度的系统被分成了冷热两半——熵降低了。 没有做功,没有消耗能量(门的质量忽略不计,开关门几乎不需要力)。第二定律说孤立系统的熵只能增加或不变。Demon 似乎违反了它。 diff --git a/docs/zh/mental-models/ch-03-entropy/assets/maxwells-demon.dark.png b/docs/zh/mental-models/ch-03-entropy/assets/maxwells-demon.dark.png new file mode 100644 index 0000000..47eac61 Binary files /dev/null and b/docs/zh/mental-models/ch-03-entropy/assets/maxwells-demon.dark.png differ diff --git a/docs/zh/mental-models/ch-03-entropy/assets/maxwells-demon.png b/docs/zh/mental-models/ch-03-entropy/assets/maxwells-demon.png index 1873cad..aa8b34d 100644 Binary files a/docs/zh/mental-models/ch-03-entropy/assets/maxwells-demon.png and b/docs/zh/mental-models/ch-03-entropy/assets/maxwells-demon.png differ diff --git a/docs/zh/mental-models/ch-03-entropy/assets/what-is-entropy.dark.png b/docs/zh/mental-models/ch-03-entropy/assets/what-is-entropy.dark.png new file mode 100644 index 0000000..0c0d239 Binary files /dev/null and b/docs/zh/mental-models/ch-03-entropy/assets/what-is-entropy.dark.png differ diff --git a/docs/zh/mental-models/ch-03-entropy/assets/what-is-entropy.png b/docs/zh/mental-models/ch-03-entropy/assets/what-is-entropy.png index 3843d12..8dc2bb2 100644 Binary files a/docs/zh/mental-models/ch-03-entropy/assets/what-is-entropy.png and b/docs/zh/mental-models/ch-03-entropy/assets/what-is-entropy.png differ diff --git a/docs/zh/mental-models/ch-04-operating-system/01-from-demon-to-os.md b/docs/zh/mental-models/ch-04-operating-system/01-from-demon-to-os.md index 6292960..f946142 100644 --- a/docs/zh/mental-models/ch-04-operating-system/01-from-demon-to-os.md +++ b/docs/zh/mental-models/ch-04-operating-system/01-from-demon-to-os.md @@ -10,6 +10,8 @@ Maxwell's Demon 做的事,和 harness 工程师做的事,结构上是同一 什么走哪个通道,什么触发什么操作,异常情况如何处理——这些本来在 Demon 脑子里的判断,一旦编码成规则,就可以复制、可以审计、可以在 Demon 不在时继续运行。从个案判断到制度化机制,这是一次跃迁。也是 harness 工程正在发生的事。 +![demon 退场,规则上台](assets/from-demon-to-os.png) + ## Karpathy 的直觉 2023 年 11 月,Andrej Karpathy 在一场 LLM 入门演讲里提出了一个框架: diff --git a/docs/zh/mental-models/ch-04-operating-system/assets/from-demon-to-os.dark.png b/docs/zh/mental-models/ch-04-operating-system/assets/from-demon-to-os.dark.png new file mode 100644 index 0000000..ae79497 Binary files /dev/null and b/docs/zh/mental-models/ch-04-operating-system/assets/from-demon-to-os.dark.png differ diff --git a/docs/zh/mental-models/ch-04-operating-system/assets/from-demon-to-os.png b/docs/zh/mental-models/ch-04-operating-system/assets/from-demon-to-os.png index 77ab185..613a96b 100644 Binary files a/docs/zh/mental-models/ch-04-operating-system/assets/from-demon-to-os.png and b/docs/zh/mental-models/ch-04-operating-system/assets/from-demon-to-os.png differ diff --git a/docs/zh/mental-models/ch-05-fractal/01-sumeru-in-a-mustard-seed.md b/docs/zh/mental-models/ch-05-fractal/01-sumeru-in-a-mustard-seed.md index 0b4a0ac..995880a 100644 --- a/docs/zh/mental-models/ch-05-fractal/01-sumeru-in-a-mustard-seed.md +++ b/docs/zh/mental-models/ch-05-fractal/01-sumeru-in-a-mustard-seed.md @@ -14,6 +14,8 @@ 须弥山是佛教宇宙观里最大的山。芥子是芥菜的种子,比芝麻还小。须弥山放入芥子,芥子不变大,须弥不变小——尺度变了,结构完整保留。 +![芥子纳须弥](assets/sumeru-in-a-mustard-seed.png) + 这两段经文出自不同的经典,表达同一个结构直觉。因陀罗网说"每个局部映射整体"——网中任取一珠,便可见全网。须弥芥子说"最大的东西能装进最小的容器而不失真"——容器的尺度与内容的结构无关。 两种说法,一个强调映射关系,一个强调尺度无关性。合在一起,它们勾勒出一种结构性质的轮廓:整体的信息存在于每一个局部之中,而这种存在不因尺度的缩放而损失。 diff --git a/docs/zh/mental-models/ch-05-fractal/02-the-generator.md b/docs/zh/mental-models/ch-05-fractal/02-the-generator.md index ab6d3e2..fa0cb7f 100644 --- a/docs/zh/mental-models/ch-05-fractal/02-the-generator.md +++ b/docs/zh/mental-models/ch-05-fractal/02-the-generator.md @@ -57,6 +57,8 @@ $$z_{n+1} = z_n^2 + c$$ L-system 和 Mandelbrot 集合来自完全不同的数学分支——一个是形式语言理论,一个是复动力系统。但它们指向同一个结论:**简单规则 + 重复迭代 = 自相似结构涌现。** +![Koch 雪花](assets/the-generator.png) + 不过这里有一个必须诚实面对的区分。L-system 生成的是**严格自相似**——每一级分支都是上一级的精确缩小复制,因为替换规则在每一步都完全相同。而自然界的植物是**统计自相似**——树枝的分叉角度、长度比例、分支数量在统计特征上跨尺度一致,但没有哪两根树枝完全相同。L-system 是对植物生长的数学抽象,不是精确描述。真实的生物系统有风力、光照角度、土壤中的营养分布、与邻近植物的竞争等随机因素介入,把严格自相似"打散"成了统计自相似。数学模型揭示了底层机制,但自然界在这个机制上叠加了噪声。 L-system 诞生于 1968 年,Mandelbrot 集合在 1978 年首次被计算机绘制出来。两者相隔十年,来自不同的研究传统,最终却指向了同一个核心机制。数学到此给出了它的回答:迭代是自相似的生成器。 diff --git a/docs/zh/mental-models/ch-05-fractal/03-worlds-within-worlds.md b/docs/zh/mental-models/ch-05-fractal/03-worlds-within-worlds.md index 3b5e21c..1d1be97 100644 --- a/docs/zh/mental-models/ch-05-fractal/03-worlds-within-worlds.md +++ b/docs/zh/mental-models/ch-05-fractal/03-worlds-within-worlds.md @@ -34,6 +34,8 @@ Koch 雪花的每一段边缘是整体的缩小版——没错,但那段边缘 金没有固定的形态,随工匠的手艺呈现为狮子。狮子的形状是"虚"的——不是说不存在,而是说它不是独立于金的另一种实体。形状和材质是一回事。然后关键的一步来了:取狮子身上任何一个毛孔——这个毛孔里就包含了整头狮子。每一个毛孔都是如此。 +![因陀罗网](assets/worlds-within-worlds.png) + 这不是"毛孔长得像狮子"的视觉相似。法藏说的是:毛孔中的金,和整头狮子的金,是同一种金。结构和基底不可分离。部分不是"映射"了整体——部分就**是**整体,只不过在不同的位置和尺度上表达。 "一即一切,一切即一"——华严经里这句话经常被当作禅宗式的玄谈。但在法藏的系统化阐释里,它是一个精确的结构描述:每一个局部都包含足够的信息来重建整体,而整体不过是所有局部的同时呈现。 diff --git a/docs/zh/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.dark.png b/docs/zh/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.dark.png new file mode 100644 index 0000000..1032ee3 Binary files /dev/null and b/docs/zh/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.dark.png differ diff --git a/docs/zh/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.png b/docs/zh/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.png index 987ebf7..bfbb104 100644 Binary files a/docs/zh/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.png and b/docs/zh/mental-models/ch-05-fractal/assets/sumeru-in-a-mustard-seed.png differ diff --git a/docs/zh/mental-models/ch-05-fractal/assets/the-generator.dark.png b/docs/zh/mental-models/ch-05-fractal/assets/the-generator.dark.png new file mode 100644 index 0000000..8bb43f0 Binary files /dev/null and b/docs/zh/mental-models/ch-05-fractal/assets/the-generator.dark.png differ diff --git a/docs/zh/mental-models/ch-05-fractal/assets/the-generator.png b/docs/zh/mental-models/ch-05-fractal/assets/the-generator.png index fb35b17..2187e74 100644 Binary files a/docs/zh/mental-models/ch-05-fractal/assets/the-generator.png and b/docs/zh/mental-models/ch-05-fractal/assets/the-generator.png differ diff --git a/docs/zh/mental-models/ch-05-fractal/assets/worlds-within-worlds.dark.png b/docs/zh/mental-models/ch-05-fractal/assets/worlds-within-worlds.dark.png new file mode 100644 index 0000000..4777665 Binary files /dev/null and b/docs/zh/mental-models/ch-05-fractal/assets/worlds-within-worlds.dark.png differ diff --git a/docs/zh/mental-models/ch-05-fractal/assets/worlds-within-worlds.png b/docs/zh/mental-models/ch-05-fractal/assets/worlds-within-worlds.png index e43b61a..e37fe05 100644 Binary files a/docs/zh/mental-models/ch-05-fractal/assets/worlds-within-worlds.png and b/docs/zh/mental-models/ch-05-fractal/assets/worlds-within-worlds.png differ diff --git a/docs/zh/mental-models/ch-06-causality/01-humes-fork.md b/docs/zh/mental-models/ch-06-causality/01-humes-fork.md index 977c7de..5b62ff0 100644 --- a/docs/zh/mental-models/ch-06-causality/01-humes-fork.md +++ b/docs/zh/mental-models/ch-06-causality/01-humes-fork.md @@ -20,6 +20,8 @@ 你看到了两个事件的先后相继——球 A 运动,接触,球 B 运动。但你在事件之间看到了什么?什么也没有。你没有看到一股"力量"从 A 传递到 B。你没有看到"导致"这个关系本身。你看到的是:A 先动,B 后动。仅此而已。 +![休谟的叉子](assets/humes-fork.png) + 那如果你看了一百次呢?一千次呢? 每多看一次,你对"A 撞 B,B 就会动"的信心增加了。但你增加的不是对某种隐藏机制的观察——你增加的只是对一种经验规律的统计信心。你观察到的仍然是恒常连结(constant conjunction):这类事件总是一前一后出现。 diff --git a/docs/zh/mental-models/ch-06-causality/03-the-ladder.md b/docs/zh/mental-models/ch-06-causality/03-the-ladder.md index c65215a..33d7bb9 100644 --- a/docs/zh/mental-models/ch-06-causality/03-the-ladder.md +++ b/docs/zh/mental-models/ch-06-causality/03-the-ladder.md @@ -10,6 +10,8 @@ Pearl 把因果推理分成三层。他管这叫因果阶梯(Ladder of Causation)。 +![Pearl 的因果阶梯](assets/the-ladder.png) + 用一个统一的场景来理解它。 **第一层:观察(Association)。** "在吃了这种药的人中,70% 病好了。" diff --git a/docs/zh/mental-models/ch-06-causality/assets/humes-fork.dark.png b/docs/zh/mental-models/ch-06-causality/assets/humes-fork.dark.png new file mode 100644 index 0000000..e330236 Binary files /dev/null and b/docs/zh/mental-models/ch-06-causality/assets/humes-fork.dark.png differ diff --git a/docs/zh/mental-models/ch-06-causality/assets/humes-fork.png b/docs/zh/mental-models/ch-06-causality/assets/humes-fork.png index ceeb256..ed4f955 100644 Binary files a/docs/zh/mental-models/ch-06-causality/assets/humes-fork.png and b/docs/zh/mental-models/ch-06-causality/assets/humes-fork.png differ diff --git a/docs/zh/mental-models/ch-06-causality/assets/the-ladder.dark.png b/docs/zh/mental-models/ch-06-causality/assets/the-ladder.dark.png new file mode 100644 index 0000000..cb68e35 Binary files /dev/null and b/docs/zh/mental-models/ch-06-causality/assets/the-ladder.dark.png differ diff --git a/docs/zh/mental-models/ch-06-causality/assets/the-ladder.png b/docs/zh/mental-models/ch-06-causality/assets/the-ladder.png index 335f7da..a227fde 100644 Binary files a/docs/zh/mental-models/ch-06-causality/assets/the-ladder.png and b/docs/zh/mental-models/ch-06-causality/assets/the-ladder.png differ diff --git a/docs/zh/mental-models/ch-07-symbols-connectionism/01-two-roads.md b/docs/zh/mental-models/ch-07-symbols-connectionism/01-two-roads.md index 774e125..f070967 100644 --- a/docs/zh/mental-models/ch-07-symbols-connectionism/01-two-roads.md +++ b/docs/zh/mental-models/ch-07-symbols-connectionism/01-two-roads.md @@ -8,6 +8,8 @@ 这个困境不新。它是人工智能领域最古老的路线分歧。 +![两条路,不可互还](assets/two-roads.png) + ## 符号的承诺 1975 年,Newell 和 Simon 在图灵奖演讲中提出了物理符号系统假说(Physical Symbol System Hypothesis):一个物理符号系统拥有智能行动的充分必要手段。 diff --git a/docs/zh/mental-models/ch-07-symbols-connectionism/assets/two-roads.dark.png b/docs/zh/mental-models/ch-07-symbols-connectionism/assets/two-roads.dark.png new file mode 100644 index 0000000..789d5c2 Binary files /dev/null and b/docs/zh/mental-models/ch-07-symbols-connectionism/assets/two-roads.dark.png differ diff --git a/docs/zh/mental-models/ch-07-symbols-connectionism/assets/two-roads.png b/docs/zh/mental-models/ch-07-symbols-connectionism/assets/two-roads.png index ff6899f..8307dc5 100644 Binary files a/docs/zh/mental-models/ch-07-symbols-connectionism/assets/two-roads.png and b/docs/zh/mental-models/ch-07-symbols-connectionism/assets/two-roads.png differ diff --git a/site/scripts/sync-content.mjs b/site/scripts/sync-content.mjs index abc8c4c..22dbe70 100644 Binary files a/site/scripts/sync-content.mjs and b/site/scripts/sync-content.mjs differ diff --git a/site/scripts/tests/sync-transforms.test.mjs b/site/scripts/tests/sync-transforms.test.mjs index f663e58..e7049ab 100644 --- a/site/scripts/tests/sync-transforms.test.mjs +++ b/site/scripts/tests/sync-transforms.test.mjs @@ -106,7 +106,11 @@ function testCardAttributesAnyOrder() { "After.", ].join("\n"); const out = transformCards(input, "en", "ch-02-cybernetics"); - assert.match(out, /!\[A\]\(\/mm\/en\/ch-02-cybernetics\/x\.png\)/, "image emitted from any-order attrs"); + // Info-cards retired: the data-card image is NO LONGER emitted. + // The wrapper body unwraps; the card PNG gets re-introduced only as + // a deliberate 配图 where the illustration bible says it should exist. + assert.doesNotMatch(out, /!\[A\]\(/, "card image NOT emitted"); + assert.doesNotMatch(out, /x\.png/, "card PNG reference NOT emitted"); assert.match(out, /Body prose\./, "body preserved"); assert.doesNotMatch(out, /<\/div>/, "matching stripped"); assert.match(out, /After\./, "subsequent prose preserved"); diff --git a/site/src/components/Topbar.astro b/site/src/components/Topbar.astro index 5066651..1948fb4 100644 --- a/site/src/components/Topbar.astro +++ b/site/src/components/Topbar.astro @@ -79,3 +79,152 @@ const isActive = (href: string) => [data-theme="dark"] .theme-icon-light { display: none !important; } [data-theme="dark"] .theme-icon-dark { display: block !important; } + + diff --git a/site/src/scripts/mermaid-loader.ts b/site/src/scripts/mermaid-loader.ts index e823955..cba4bbe 100644 --- a/site/src/scripts/mermaid-loader.ts +++ b/site/src/scripts/mermaid-loader.ts @@ -3,45 +3,140 @@ * Because we tell Shiki to excludeLangs:['mermaid'], fenced ```mermaid blocks * come through as
SRC
. * We convert each to
SRC
and run mermaid.run(). - * Re-hook on every Astro view-transition navigation. + * Re-hook on every Astro view-transition navigation AND on site theme flip. + * + * Palette is pulled from the site design tokens (`tokens.css`) so the graph + * lives in the same warm-paper / warm-dark world as the rest of the page — + * no pink/yellow mermaid defaults. */ let mermaidPromise: Promise | null = null; +let lastTheme: string | null = null; -async function getMermaid() { +function siteTokens() { + const cs = getComputedStyle(document.documentElement); + const v = (k: string) => cs.getPropertyValue(k).trim(); + return { + paper: v("--paper"), + paperRaised: v("--paper-raised"), + paperSunk: v("--paper-sunk"), + ink: v("--ink"), + inkSoft: v("--ink-soft"), + inkFaint: v("--ink-faint"), + rule: v("--rule"), + vermilion: v("--vermilion"), + gold: v("--gold"), + celadon: v("--celadon"), + }; +} + +function mermaidConfig() { + const t = siteTokens(); + return { + startOnLoad: false, + theme: "base" as const, + // Dual-script font stack so Latin stays monospaced (Plex) but the + // occasional CJK label (稀释信号 / 放大噪声) rides on the body Han serif + // and doesn't fall through to a generic system font. + fontFamily: + '"IBM Plex Mono", ui-monospace, "SF Mono", "LXGW WenKai", "Noto Serif SC", monospace', + themeVariables: { + background: t.paperRaised, + primaryColor: t.paperSunk, + primaryTextColor: t.ink, + primaryBorderColor: t.rule, + secondaryColor: t.paperRaised, + secondaryTextColor: t.ink, + secondaryBorderColor: t.rule, + tertiaryColor: t.paperRaised, + tertiaryTextColor: t.ink, + tertiaryBorderColor: t.rule, + lineColor: t.inkFaint, + textColor: t.ink, + mainBkg: t.paperSunk, + nodeBorder: t.rule, + edgeLabelBackground: t.paperRaised, + clusterBkg: t.paperSunk, + clusterBorder: t.rule, + titleColor: t.ink, + // Flowchart specifics + nodeTextColor: t.ink, + // Note / highlight blocks + noteBkgColor: t.paperRaised, + noteTextColor: t.ink, + noteBorderColor: t.rule, + // Accents — used by default style classes if any diagram opts in + labelBackground: t.paperRaised, + errorBkgColor: t.vermilion, + errorTextColor: t.paper, + }, + securityLevel: "strict" as const, + }; +} + +async function getMermaid(force = false) { + if (force) mermaidPromise = null; if (!mermaidPromise) { - mermaidPromise = import("https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs" as string) - .then((m: any) => { - const isDark = document.documentElement.getAttribute("data-theme") === "dark"; - m.default.initialize({ - startOnLoad: false, - theme: isDark ? "dark" : "neutral", - fontFamily: 'var(--font-mono), "IBM Plex Mono", monospace', - securityLevel: "strict", - }); - return m.default; - }); + mermaidPromise = import( + "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs" as string + ).then((m: any) => { + m.default.initialize(mermaidConfig()); + return m.default; + }); } return mermaidPromise; } -async function renderMermaid() { +// Strip author-supplied `style X fill:#f9f` lines. Those inline mermaid +// style directives hard-code the pink/yellow defaults and survive any theme +// we configure, so we drop them and rely on the token-driven themeVariables. +function cleanSource(src: string): string { + return src + .split("\n") + .filter((line) => !/^\s*style\s+\w[\w-]*\s+/i.test(line)) + .join("\n"); +} + +async function renderMermaid(force = false) { // Astro's shiki `excludeLangs: ['mermaid']` marks mermaid fences with // `data-language="mermaid"` on the
 (no language-* class on ).
+  // On theme flips we need to re-render existing diagrams too.
+  if (force) {
+    document
+      .querySelectorAll(".mermaid-diagram")
+      .forEach((el) => {
+        const src = el.dataset.mermaidSrc;
+        if (src) {
+          el.innerHTML = "";
+          el.removeAttribute("data-processed");
+          el.textContent = src;
+        }
+      });
+  }
+
   const preList = document.querySelectorAll(
     'pre[data-language="mermaid"], pre > code.language-mermaid',
   );
-  if (preList.length === 0) return;
-  const mermaid = await getMermaid();
+  const freshDiagrams: HTMLElement[] = [];
   for (const node of preList) {
     const pre = node.tagName === "PRE" ? node : node.parentElement!;
     if (!pre || pre.dataset.mermaidProcessed === "true") continue;
-    const src = pre.textContent ?? "";
+    const src = cleanSource(pre.textContent ?? "");
     const wrapper = document.createElement("div");
     wrapper.className = "mermaid-diagram";
+    wrapper.dataset.mermaidSrc = src;
     wrapper.textContent = src;
     pre.replaceWith(wrapper);
+    freshDiagrams.push(wrapper);
   }
+
+  const needsRun =
+    force
+      ? document.querySelectorAll(".mermaid-diagram").length > 0
+      : freshDiagrams.length > 0;
+  if (!needsRun) return;
+
+  const mermaid = await getMermaid(force);
   try {
     await mermaid.run({ querySelector: ".mermaid-diagram" });
   } catch (err) {
@@ -49,5 +144,24 @@ async function renderMermaid() {
   }
 }
 
-document.addEventListener("astro:page-load", renderMermaid);
+function onThemeMaybeChanged() {
+  const theme = document.documentElement.getAttribute("data-theme");
+  if (theme === lastTheme) return;
+  lastTheme = theme;
+  // Re-init with fresh token values and re-render existing diagrams.
+  renderMermaid(true);
+}
+
+// Initial render.
+lastTheme = document.documentElement.getAttribute("data-theme");
+document.addEventListener("astro:page-load", () => {
+  lastTheme = document.documentElement.getAttribute("data-theme");
+  renderMermaid();
+});
 renderMermaid();
+
+// Watch the theme attribute so mermaid flips when the user toggles day/night.
+new MutationObserver(onThemeMaybeChanged).observe(document.documentElement, {
+  attributes: true,
+  attributeFilter: ["data-theme"],
+});
diff --git a/site/src/styles/reader-site.css b/site/src/styles/reader-site.css
index 3d72a0d..d81967c 100644
--- a/site/src/styles/reader-site.css
+++ b/site/src/styles/reader-site.css
@@ -186,6 +186,19 @@
   font-size: inherit;
 }
 
+/* Shiki dual-theme activation.
+   Astro emits `color:{light}` + `--shiki-dark:{dark}` inline for every
+   token (and the outer 
), expecting a `prefers-color-scheme: dark`
+   media query to swap them.  Our theme is controlled via
+   ``, not the OS preference — so without this
+   override every token keeps its light-theme color, which on our
+   `--paper-sunk` dark background is near-black on near-black. */
+[data-theme="dark"] .reader__body .astro-code,
+[data-theme="dark"] .reader__body .astro-code code,
+[data-theme="dark"] .reader__body .astro-code span {
+  color: var(--shiki-dark) !important;
+}
+
 /* Images */
 .reader__body img {
   display: block;
@@ -197,6 +210,15 @@
   border-radius: 2px;
 }
 
+/* Themed specimen plate — pair of light/dark PNGs rendered by sync-content.mjs
+   whenever a `.dark.` sibling exists in docs/.../assets/.  Theme
+   switches via `[data-theme="dark"]` on . */
+.reader__body .themed-plate { display: contents; }
+.reader__body .themed-plate__dark { display: none; }
+[data-theme="dark"] .reader__body .themed-plate__light { display: none; }
+[data-theme="dark"] .reader__body .themed-plate__dark { display: block; }
+
+
 /* Tables — museum展签 style.
    display:block + overflow-x:auto so a genuinely wide table can scroll
    horizontally inside the content column instead of blowing the layout. */