fix(ui): Atlas header gets its implant panel scrim — legible on any terrain (T-1197)
Root cause was not the suspected fade race — no animation exists anywhere under client/ui/implant (grep-proven, and settle+2 vs settle+90 captures were byte-identical). _build_screen_header() was the single ImplantHeader call site in the codebase that added the header bare instead of through ImplantPanel.add_component(), so its fixed light-gray text washed out against pale terrain (Quarter upland scatter, District olive) while reading fine on dark ocean. Wrapped in an ImplantPanel like every sibling — the theme's panel_bg scrim makes it legible everywhere. One committed golden (atlas_GJ820Bc_District) already carried the ghosting baked in, confirming the bug was static; all 13 goldens regenerated per the header change, two independent live-server runs byte-identical (T-1157 stability discipline). Verified live at the original evidence center: header crisp at settle+2/+30/+90. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 218 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 487 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 658 KiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 56 KiB |
@@ -145,6 +145,7 @@ var _canvas: Node2D = null
|
||||
var _terrain_layer: StepCanvasTerrainLayer = null
|
||||
var _annotation_layer: StepCanvasAnnotationLayer = null
|
||||
var _screen_header: ImplantHeader = null
|
||||
var _screen_header_panel = null # ImplantPanel — T-1197 backing scrim (untyped: no class_name cycle needed)
|
||||
var _overlay_bar = null
|
||||
var _legend_panel = null
|
||||
var _request = null # StepCanvasRequest
|
||||
@@ -691,14 +692,42 @@ func _apply_transform() -> void:
|
||||
# =============================================================================
|
||||
|
||||
|
||||
## T-1197: the header used to be a bare ImplantHeader added straight to this
|
||||
## Control, drawn directly over the terrain canvas with no backing — every
|
||||
## OTHER implant chrome element (the legend below it) gets its scrim from
|
||||
## ImplantPanel's `panel_bg` StyleBoxFlat, but a lone ImplantHeader has no
|
||||
## panel of its own (see implant_header.gd — just two Labels). Its fixed
|
||||
## opaque text color reads fine against the near-black viewer background or
|
||||
## dark ocean terrain (the common case at rung 0's letterboxed corner and most
|
||||
## fixed-rung captures), but against pale/light terrain — Quarter's white
|
||||
## upland scatter, District's olive/tan dry terrain — the contrast collapses
|
||||
## to the point of unreadability (Araminta's T-1196 observation,
|
||||
## scratchpad t1196/gj1002b_quarter.png; reproduced baked into the committed
|
||||
## golden atlas_GJ820Bc_District.png). This is a static contrast defect, not a
|
||||
## timing race — there is no fade/tween anywhere in this cluster (confirmed by
|
||||
## reading every script under client/ui/implant), so no harness settle change
|
||||
## could fix it. Wrapping in an ImplantPanel (same component every other
|
||||
## header-bearing screen in the implant UI already uses — index_screen.gd,
|
||||
## planet_screen.gd, system_screen.gd, reach_screen.gd, kind_menu_screen.gd,
|
||||
## detail_screen.gd, overview_screen.gd, character_creation.gd, and the
|
||||
## legend right below THIS header — step_canvas_viewer.gd's bare add_child()
|
||||
## was the only outlier) gives the header the same opaque scrim as every
|
||||
## sibling chrome element, guaranteeing contrast regardless of what terrain
|
||||
## renders underneath.
|
||||
func _build_screen_header() -> void:
|
||||
var PanelScript := load("res://ui/implant/implant_panel.gd")
|
||||
_screen_header_panel = PanelScript.new()
|
||||
_screen_header_panel.name = "ScreenHeaderPanel"
|
||||
_screen_header_panel.position = Vector2(PANEL_MARGIN, 16.0)
|
||||
_screen_header_panel.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
_screen_header_panel.custom_minimum_size.x = 320.0
|
||||
_screen_header_panel.theme_resource = _implant_theme # set BEFORE add_child(), matching _build_legend_panel()'s own ordering
|
||||
add_child(_screen_header_panel)
|
||||
|
||||
_screen_header = ImplantHeader.new()
|
||||
_screen_header.position = Vector2(PANEL_MARGIN, 16.0)
|
||||
_screen_header.custom_minimum_size.x = 320.0
|
||||
_screen_header.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
add_child(_screen_header)
|
||||
if _implant_theme:
|
||||
_screen_header.apply_implant_theme(_implant_theme)
|
||||
_screen_header_panel.add_component(_screen_header)
|
||||
|
||||
|
||||
func _refresh_screen_header() -> void:
|
||||
|
||||