/poster.jpg present in sampled items
+/home/docker/jellyfin/cache = 59M
+ /images/resized-images/{0..f} = 16 hex subdirs, all populated with .webp tiles
+```
+
+Agent 7's earlier note "**only `resized-images` subdir present**" is **still true** — `/cache/images/` contains only `resized-images/`, no `original/` or `remote/`. That is the **expected** Jellyfin layout (originals live under `/config/metadata/library/`, only resizes live under `/cache/images/resized-images/`). Not a bug.
+
+API probe for item `7aa5add2c2d8575eda5280b9b9072071` (The Mike Nolan Show) via temp token (revoked after), all four image types via `https://arrflix.s8n.ru`:
+
+| Endpoint | Status | Content-Type | Notes |
+|---|---|---|---|
+| `/Items/{id}/Images/Backdrop` | **200** | image/jpeg | served, `age: 5400` (90min upstream cache) |
+| `/Items/{id}/Images/Primary` | **200** | image/jpeg | served |
+| `/Items/{id}/Images/Logo` | **200** | image/png | served |
+| `/Items/{id}/Images/Thumb` | **200** | image/jpeg | served |
+
+**Verdict:** Server-side images are healthy. Backdrop + Primary + Logo + Thumb all 200 with valid content-types for a real item the user is browsing. The "all backdrops black" symptom (Section D) is **NOT** a server-side image problem and **NOT** a SW-cache problem. Likely culprits remaining:
+- (a) CSS rule in deployed `index.html` overrides / theme overrides hiding `.itemBackdrop` or setting `opacity: 0`;
+- (b) browser HTTP cache holding stale 404s from earlier broken state — same Ctrl+Shift+R fix as Part 1;
+- (c) a custom-css.user.css backdrop opacity:0 / display:none rule.
+
+Recommend: in user's browser open one show page, DevTools → Network → filter Img → look for `/Items/{id}/Images/Backdrop` request. If 200 served but invisible → CSS theme leak. If never requested → SPA template not fetching it (theme-side bug).
+
+### Backdrop diagnosis
+
+Investigation 2026-05-09. User reported: detail-page backdrops are pure black on prod (`arrflix.s8n.ru`). Posters render fine. Used a temp ApiKey row (`Name='arrflix-backdrop-diag-2026-05-09'`, deleted after diag) on the live `jellyfin` container.
+
+**Layer A (server) — RULED OUT.**
+- Item `7aa5add2c2d8575eda5280b9b9072071` (The Dark Knight) JSON returns `BackdropImageTags: ['76cac7069dc988f7cd54e99b481db3fc']`. Tag exists.
+- `HEAD https://arrflix.s8n.ru/Items/.../Images/Backdrop` → `HTTP/2 200`, `content-type: image/jpeg`, `content-length: 560210`, `last-modified: 2026-05-08 22:11:50`.
+- Same call against `dev.arrflix.s8n.ru` → also 200 + image/jpeg. Both prod and dev serve backdrop bytes correctly.
+
+**Layer C (browser cache / SW) — RULED OUT.**
+- The stock SW (Section "SW source + image cache" above) does not intercept `/Items/*/Images/*`. Backdrop URL also returns fresh on direct curl (no SW in path).
+
+**Layer B (CSS) — CONFIRMED. The CustomCss `BLACK-PASS` block hides the image layer.**
+
+The Jellyfin DOM has two distinct elements (verified by reading `main.jellyfin.bundle.js` + `main.jellyfin.1ed46a7a22b550acaef3.css` inside the running container):
+1. `.backdropContainer` — stock CSS: `position:fixed; bottom:0; left:0; right:0; top:0; z-index:-1`. Holds a child `` whose `style.backgroundImage="url(/Items/.../Backdrop)"` is injected by JS (`r.style.backgroundImage="url('".concat(e,"')")` in the bundle). This is the IMAGE LAYER.
+2. `.backgroundContainer` (no `d`) — separate `position:fixed` overlay; gets the `withBackdrop` class toggled by JS. This is the OVERLAY LAYER. Stock CSS sets `body { background-color: transparent !important; }` precisely so the body never occludes the `z-index:-1` backdrop.
+
+Bug 1 — **`!important` blacks override stock body transparency.** CustomCss `BLACK-PASS 2026-05-08` block (lines ~110-202 of branding.xml CustomCss) sets `background-color: #000000 !important` on `html, body, #reactRoot, .skinBody, .preload, .mainAnimatedPages, .pageContainer, .libraryPage, .itemDetailPage, .padded-bottom-page, .layout-desktop, .layout-mobile, .layout-tv` etc. Since `.backdropContainer` is at `z-index:-1`, ANY ancestor with an opaque background paints on top of it, hiding the backdrop image entirely.
+
+Bug 2 — **The transparent-scope rule at lines 102-107 is incomplete.** It scopes to `body.itemDetailPage, body.itemDetailPage #reactRoot, body.itemDetailPage .mainAnimatedPages, body.itemDetailPage .skinBody`, but does NOT include `.layout-desktop` / `.itemDetailPage` itself / `.layout-tv` / `.pageContainer` / `.padded-bottom-page` — so those wrappers remain `#000` on detail pages and continue to occlude the `z-index:-1` layer.
+
+Bug 3 (cosmetic — not the cause of black) — line 89-101 sets `background-image: linear-gradient(...)` on `.layout-desktop .backgroundContainer.withBackdrop`. That's the OVERLAY layer, fine on its own. But because the actual backdrop image is hidden by Bug 1, the gradient now composites against pure black instead of the backdrop, so the user sees only the gradient (which fades from black to transparent) over a black backdrop = solid black with at most a faint gradient edge.
+
+**Cross-check:** dev (`dev.arrflix.s8n.ru`) does NOT mount the `BLACK-PASS` CustomCss block (Section B above confirms dev branding.xml is 4.5KB smaller and uses remote jsDelivr Cineplex without local overrides). Opening dev should show backdrops normally; if it does, that's a clean A/B confirmation that prod's CustomCss is the regression.
+
+**Fix recipe (smallest reversible change).**
+
+In `/home/docker/jellyfin/config/config/branding.xml` `` block, extend the `body.itemDetailPage` transparent-scope rule (currently lines 102-107) to also cancel the black backgrounds on every wrapper that the BLACK-PASS block paints:
+
+```css
+/* Replace existing block at lines 102-107 with: */
+body.itemDetailPage,
+body.itemDetailPage #reactRoot,
+body.itemDetailPage .mainAnimatedPages,
+body.itemDetailPage .skinBody,
+body.itemDetailPage .layout-desktop,
+body.itemDetailPage .layout-mobile,
+body.itemDetailPage .layout-tv,
+body.itemDetailPage .pageContainer,
+body.itemDetailPage .padded-bottom-page,
+body.itemDetailPage .itemDetailPage,
+body.itemDetailPage #mainPanel,
+body.itemDetailPage #mainDrawerPanel {
+ background-color: transparent !important;
+ background: transparent !important;
+}
+```
+
+This keeps `#000` everywhere else (library, search, dashboard) but reveals the `.backdropContainer > .backdropImage` layer on detail pages — which is what the gradient overlay (Bug 3) was originally designed to compose against.
+
+**Apply via Dashboard → Branding → Custom CSS** (no container restart needed; CSS reloads on next page render). Editing branding.xml directly works too but Jellyfin re-serializes on save, so use the Dashboard.
+
+**Verify after edit:** open a movie detail page in an incognito window (bypasses SW). Expected: full-bleed backdrop visible at right ~70% of viewport, gradient fade from black on the left. If still black: hard-refresh + DevTools → Elements → search `.backdropImage` and confirm its parent chain has no `background-color` other than transparent.
+
+**Recovery:** revert to the original 6-selector block.
+
+---
+
+### Playback diagnosis
+
+Investigation date 2026-05-09 ~00:30–00:45 UTC. Live transcode test against prod jellyfin via temp ApiKey `arrflix-playback-diag-2026-05-09` (deleted at end of session, verified empty SELECT after DELETE).
+
+**A) Source codec verdict — the ItemId is mis-attributed in this incident report.** ItemId `7aa5add2c2d8575eda5280b9b9072071` is **The Dark Knight (2008)**, NOT "The Mike Nolan Show". Confirmed via `/Users/{u}/Items?searchTerm=...`:
+- `7aa5add2...` → Movie / `/media/movies/The Dark Knight (2008)/The Dark Knight (2008).mkv` — **HEVC Main 10 / yuv420p10le, 1918x800, TrueHD 24-bit + AC3 + 2× PGS**.
+- The Mike Nolan Show series Id is `37cb910f507c4d1f9e365ef1954f99c2`. Episodes (e.g. S01E04 "Ding Dong Delli") are **AV1 Main / yuv420p / Opus**, ~412 kbps total.
+
+(So the prior Section D backdrop-probe line that labelled `7aa5add2...` as MNS is also wrong — those Backdrop/Primary/Logo/Thumb 200s were TDK images. Doesn't change Section D's conclusion that backdrops serve fine.)
+
+Chrome advertises `av1,h264,vp9` (NOT hevc, NOT vp8). So:
+- **TDK (HEVC 10-bit)**: must transcode → server picks libx264 High@4.0 yuv420p (8-bit) AAC LC stereo. Fully Chrome-decodable.
+- **MNS episodes (AV1+Opus)**: should DirectPlay/DirectStream — Chrome supports both natively.
+
+**B) HLS pipeline verdict — server-side fully working.** PlaybackInfo POST returned `TranscodingUrl=/videos/.../master.m3u8?VideoCodec=h264&...`, `SupportsTranscoding=True`, `TranscodingSubProtocol=hls`. Manual fetches on TDK:
+- master.m3u8 → HTTP 200, valid `#EXTM3U`, single variant `BANDWIDTH=13407532, RESOLUTION=1918x800, CODECS="avc1.424029,mp4a.40.2"` (the `424029` decodes to "Baseline 4.1" but actual stream below is High — known cosmetic Jellyfin mislabel, not a Chrome blocker).
+- main.m3u8 sub-playlist → HTTP 200, segments `hls1/main/0.ts` … `9.ts`, 3-second EXTINF.
+- segment 0.ts → HTTP 200, 269 KB. ffprobe verdict: `h264 High / yuv420p / level 4.0, 1918x800` + `aac LC`. Valid 8-bit H.264. Cache dir during playback contains 40+ valid `.ts` segments. No fmp4 init filename collision (mpegts segments in current run; the earlier fmp4 path's `-1.mp4` init pattern with `start_number=0` is also fine — `-1.mp4` literally has the `-1` infix in filename, while data segments are `0.mp4, 1.mp4...`; no actual name collision).
+
+**C) CSS verdict — video element NOT hidden.** Read `branding.xml` CustomCss + `cineplex.css` (full). All `display:none` / `visibility:hidden` / `opacity:0` / `transform:scale(0)` matches are on UI chrome (`#castCollapsible`, `#guestCastCollapsible`, `.btnQuick`, `.headerSyncButton`, `.headerCastButton`, `.headerUserButton`, MUI drawer items, `.countIndicator`, `#loginPage h1`, etc.). The only `video::*` / `:cue` rules touch subtitle font only. **No hide/scale rule hits `.htmlvideoplayer`, `.videoPlayerContainer`, or the `