Two-layer defense for the recurring "black screen during playback"
bug class (5+ occurrences in 24h per doc 26/28/30):
L1 (prevention): scope every black-bg rule with
:not(:has(.htmlVideoPlayer)):not(:has(#videoOsdPage)) so the rules
self-disable while a player is in the DOM. Covers body,
#reactRoot, .skinBody, .backgroundContainer, .mainAnimatedPage,
.mainAnimatedPages, .pageContainer.
L2 (override): when JS-toggled body.arrflix-video-active is set,
high-specificity (0,3,2 + tag) transparent rule wins against any
ancestor opaque-bg rule (including future regressions someone adds
without scoping). Covers all known wrappers, the
videoPlayerContainer + videoPlayerContainer-onTop, #videoOsdPage,
.libraryPage, .htmlVideoPlayer.
L3 (z-index lift): force .htmlVideoPlayer + child <video> to
z-index:9999 + isolation:isolate during playback so it floats above
any opaque ancestor that still leaks through.
Verified in playwright: with arrflix-video-active + .htmlVideoPlayer
mounted, all 7 ancestors return rgba(0,0,0,0). Without — all 7
return rgb(0,0,0). Self-disabling works.
Lesson reinforced (doc 30 roadmap open): add darkPct assertion to
bin/headless-test-v2.py + xmllint CI gate. Five recurrences without
those gates says we keep relearning this. TODO next.
Grey #101010 stripe at bottom of pages: jellyfin-web theme.css:44-50
sets .backgroundContainer + html to #101010, neither Cineplex nor
prior overlay overrode it. Added rule forcing #000 across html, body,
.backgroundContainer, .skinBody, .mainAnimatedPages, .pageContainer,
#reactRoot under body.arrflix-themed.
Search input: stock cyan focus ring (#00a4dc, theme.css:262-272)
swapped for borderless slab + 2px red bottom on focus + soft red
box-shadow halo. Cineplex/Netflix-faithful.
Movies/Series nav: variant E "cinematic glow" picked from preview.
Active state = red text + text-shadow halo + font-weight 700. JS
hash matcher toggles .arrflix-nav.active when location.hash matches
#/movies.html or #/tv.html (and short forms). hashchange listener +
existing setInterval keep state in sync.
My Media row: .homePage .homeSectionsContainer .verticalSection.section0
hidden — matches prod which had it hidden via different mechanism.
Snapshot at snapshots/2026-05-09-v6-stable/index.html bumped to
md5 2c8f5d5f7c99611fa93d15c34fbe35d1; same as prod and dev.
Stock Jellyfin shows .headerBackButton on library pages
(Movies/Series). With our nav links already in headerLeft, the back
arrow is redundant clutter and confuses the home button intent.
Add .headerBackButton to the existing display:none rule under
body.arrflix-themed. Verified visually on dev (md5 c99aca0f), then
shipped to prod with overlay swap (md5 364cc890 -> c99aca0f). Both
sides byte-identical.
Snapshot at snapshots/2026-05-09-v6-stable/index.html updated.
Owner pronounced "near perfect". Save current state as the rollback
target. Replace older 2026-05-08-pre-elegantfin snapshot.
Snapshot md5 364cc890c58f02d07cf50b43b31a48f0 — matches both prod
and dev deployed overlay.
Doc 30 lists every file/path-of-record + rollback procedure +
remaining roadmap items.
Tag this commit v6-stable-2026-05-09 after push.