From 972d18d26f130ab170fc72d3c376af8204448f46 Mon Sep 17 00:00:00 2001 From: Test Date: Sat, 25 Apr 2026 22:37:48 -0700 Subject: [PATCH 1/2] fix(hillshade): revert per-tile blend; use isolation: isolate on #map instead MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #169 moved mix-blend-mode from .hillshade-blend (the layer container) to .hillshade-blend img.leaflet-tile (individual tile images). I had the stacking-context reasoning backwards: applying the blend AT the tile image places it INSIDE the transformed .leaflet-tile-container's stacking context. That context contains only the hillshade tiles — nothing to multiply against — so the blend has no backdrop and renders source pixels opaque, hiding the base map entirely. Correct placement is at .hillshade-blend, which is a peer of the base-layer container under .leaflet-tile-pane. There the multiply blend has the base map as the sibling backdrop. To address the original "sometimes not applied" symptom from #168, add isolation: isolate to #map. This makes the map a clean stacking- context root so the blend can reliably composite against base-layer tiles without ancestor compositing layers isolating it from the intended backdrop. Closes #171 Re-opens #168 conceptually but the new fix targets the actual root cause. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/style.css | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/style.css b/src/style.css index 8493d94..753161c 100644 --- a/src/style.css +++ b/src/style.css @@ -6,10 +6,16 @@ html { height: 100%; width: 100%; padding: 0; margin: 0; } body { height: 100%; width: 100%; padding: 0; margin: 0; } -#map { position: absolute; top: 0; bottom: 0; right: 0; left: 0; } - -/* Per-tile multiply — a container-level blend can isolate under .leaflet-tile-container's translate3d. */ -.hillshade-blend img.leaflet-tile { mix-blend-mode: multiply; } +/* isolation: isolate establishes a clean stacking context root for the map so .hillshade-blend's + mix-blend-mode reliably composites against the base-layer tiles below it (without this the blend + can sometimes leak out to the page-level backdrop or be isolated by ancestor compositing layers). */ +#map { position: absolute; top: 0; bottom: 0; right: 0; left: 0; isolation: isolate; } + +/* Multiply at the Leaflet layer container — peer of the base-layer container in the tile pane, + so the blend has the base map below it as the backdrop. (Per-tile blending at img.leaflet-tile + was tried in PR #169 and reverted: it moves the blend INTO the transformed tile-container's + stacking context, where there is nothing behind to multiply against, so hillshade renders opaque.) */ +.hillshade-blend { mix-blend-mode: multiply; } /* Icon state classes for GPS accuracy filter visual feedback */ #disabled { From 80a73446f58f3357d06f16e4bdbd6983d116dbb4 Mon Sep 17 00:00:00 2001 From: Test Date: Sat, 25 Apr 2026 22:41:18 -0700 Subject: [PATCH 2/2] fix: trim hillshade comments per CLAUDE.md convention Single-line comments capturing only the non-obvious WHY; no PR refs that rot as the codebase evolves. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/style.css | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/style.css b/src/style.css index 753161c..ab86a87 100644 --- a/src/style.css +++ b/src/style.css @@ -6,15 +6,10 @@ html { height: 100%; width: 100%; padding: 0; margin: 0; } body { height: 100%; width: 100%; padding: 0; margin: 0; } -/* isolation: isolate establishes a clean stacking context root for the map so .hillshade-blend's - mix-blend-mode reliably composites against the base-layer tiles below it (without this the blend - can sometimes leak out to the page-level backdrop or be isolated by ancestor compositing layers). */ +/* isolation: isolate keeps mix-blend-mode contained to the map's own stacking context. */ #map { position: absolute; top: 0; bottom: 0; right: 0; left: 0; isolation: isolate; } -/* Multiply at the Leaflet layer container — peer of the base-layer container in the tile pane, - so the blend has the base map below it as the backdrop. (Per-tile blending at img.leaflet-tile - was tried in PR #169 and reverted: it moves the blend INTO the transformed tile-container's - stacking context, where there is nothing behind to multiply against, so hillshade renders opaque.) */ +/* Blend at the layer container so multiply composites against the base-layer sibling below. */ .hillshade-blend { mix-blend-mode: multiply; } /* Icon state classes for GPS accuracy filter visual feedback */