diff --git a/docs/ASSET_PIPELINE.md b/docs/ASSET_PIPELINE.md
index bafbf9ef..3e2ca2ff 100644
--- a/docs/ASSET_PIPELINE.md
+++ b/docs/ASSET_PIPELINE.md
@@ -16,9 +16,9 @@ All of it runs in `scripts/build_assets.mjs`, in the Docker builder stage, befor
2. The 38 JS modules (37 in the runtime import graph — `types.js` is JSDoc-only) get bundled into a single file with esbuild. `minify: true` handles identifier mangling, syntax compression, and whitespace removal, including collapsing the newlines in HTML template strings that esbuild normally leaves alone. Asset references get rewritten, then the whole thing gets content-hashed.
-3. The 14 CSS files get concatenated and run through esbuild's CSS transformer. Non-critical styles (everything except `critical.css`) merge into a single `app.css`. Both get content-hashed.
+3. The 14 CSS files get concatenated and run through esbuild's CSS transformer. Non-critical styles (everything except `critical.css`) merge into a single, content-hashed `app.css`. `critical.css` itself is minified but *not* fingerprinted as a file — it's inlined straight into `index.html` (step 4) so first paint (the inline `#loading` screen) doesn't wait on a second network round trip beyond the document itself. Its sha256 is written to `dist/csp.json`.
-4. `index.html` gets rewritten: the 13 non-critical `` tags collapse to one, the modulepreload graph (37 entries) drops, every URL swaps to its hashed equivalent, and the HTML gets stripped of comments and collapsed to a single line. The web-app manifest is fingerprinted the same pass (`manifest.webmanifest`, step 4b): its icon refs are rewritten to hashed paths and its `` href updated to match.
+4. `index.html` gets rewritten: the critical.css `` becomes an inline `\n`,
+);
// collapse the 9 non-critical stylesheet links into one bundled link
html = html.replace(
@@ -199,6 +224,11 @@ writeFileSync(join(DIST, 'index.html'), html);
writeFileSync(join(DIST, 'manifest.json'),
JSON.stringify(Object.fromEntries(manifest), null, 1));
+// ── 7b. CSP hash for the inlined critical.css ", html, re.S)
+ check(style_match is not None, "index.html has an inline