Ask: Extract main.gd theme/style helpers (make_panel_style, make_empty_style, apply_theme, apply_button_theme) into a dedicated dock_theme.gd module so rendering concerns stop growing main.gd.
Expected files: scripts/main.gd, scripts/dock_theme.gd (new)
Problem: After the extraction work that produced TileRender, WorkerRenderer, LayoutMath, ColonyStance, MilestoneManager, GoalProgression, GoalReward, and RotatingGoal, the theme/style construction that styles every panel, button, slider, and option in the dock still lives in scripts/main.gd (functions make_panel_style, make_empty_style, apply_theme, apply_button_theme — ~118 lines from scripts/main.gd:145 to scripts/main.gd:263). Every menu variant, color tweak, or new themed control now lives in the same file as the simulation facade and the popup state machine, and the _button_styles member at scripts/main.gd:235 is the only styling piece that has been cached. main.gd is back down to 1994 lines from a peak of 2646, but it still owns more rendering code than any extracted renderer. The 2026-07-15 audit (#279 finding 1) flagged that 159 functions in main.gd is unsustainable; this finding narrows that to the styling subset that has no other extraction candidate.
Evidence:
scripts/main.gd:145 — func make_panel_style(bg: Color, border: Color, corner_radius: int = 12) -> StyleBoxFlat — only public StyleBox helper, called ~12 times across apply_theme and inline at startup/stance panel sites (e.g. scripts/main.gd:303, 1007)
scripts/main.gd:159 — func make_empty_style() -> StyleBoxEmpty
scripts/main.gd:165 — func apply_theme() — 90+ lines that iterates 8 panel names, 6 margin containers, 3 box containers, 16 themed buttons, a slider, and an option, calling make_panel_style(...) and section_style.duplicate() per node per call
scripts/main.gd:235 — var _button_styles: Dictionary = {} — only cached theme state; apply_button_theme() populates it once and reuses, but apply_theme() itself still creates + duplicates other styleboxes
grep -c "^func " scripts/main.gd = 139; the styling helpers above are the only ones not yet extracted alongside the scene-free renderers (TileRender, WorkerRenderer)
Acceptance:
- New module
scripts/dock_theme.gd (class_name DockTheme) owns make_panel_style, make_empty_style, apply_theme, apply_button_theme, and the cached _button_styles dict; pure (no scene references) so it can be tested in --script mode
- main.gd shrinks by at least 100 lines and removes all four stylebox helpers
apply_dock_position() and _on_startup_new_game() etc. continue to call the new module without behavioural change
- All existing test suites stay green:
tests/test_runner.gd, tests/test_dock_layout.gd, and tests/test_tile_render.gd exercise the docking/layout path that this style change touches
- New unit test
tests/test_dock_theme.gd covers at least: stylebox caching (same key returns same reference), panel/button theme application, and the _button_styles LRU-style re-use
Ask: Extract main.gd theme/style helpers (make_panel_style, make_empty_style, apply_theme, apply_button_theme) into a dedicated dock_theme.gd module so rendering concerns stop growing main.gd.
Expected files: scripts/main.gd, scripts/dock_theme.gd (new)
Problem: After the extraction work that produced TileRender, WorkerRenderer, LayoutMath, ColonyStance, MilestoneManager, GoalProgression, GoalReward, and RotatingGoal, the theme/style construction that styles every panel, button, slider, and option in the dock still lives in scripts/main.gd (functions make_panel_style, make_empty_style, apply_theme, apply_button_theme — ~118 lines from
scripts/main.gd:145toscripts/main.gd:263). Every menu variant, color tweak, or new themed control now lives in the same file as the simulation facade and the popup state machine, and the_button_stylesmember atscripts/main.gd:235is the only styling piece that has been cached. main.gd is back down to 1994 lines from a peak of 2646, but it still owns more rendering code than any extracted renderer. The 2026-07-15 audit (#279 finding 1) flagged that 159 functions in main.gd is unsustainable; this finding narrows that to the styling subset that has no other extraction candidate.Evidence:
scripts/main.gd:145—func make_panel_style(bg: Color, border: Color, corner_radius: int = 12) -> StyleBoxFlat— only public StyleBox helper, called ~12 times across apply_theme and inline at startup/stance panel sites (e.g.scripts/main.gd:303, 1007)scripts/main.gd:159—func make_empty_style() -> StyleBoxEmptyscripts/main.gd:165—func apply_theme()— 90+ lines that iterates 8 panel names, 6 margin containers, 3 box containers, 16 themed buttons, a slider, and an option, callingmake_panel_style(...)andsection_style.duplicate()per node per callscripts/main.gd:235—var _button_styles: Dictionary = {}— only cached theme state;apply_button_theme()populates it once and reuses, butapply_theme()itself still creates + duplicates other styleboxesgrep -c "^func " scripts/main.gd= 139; the styling helpers above are the only ones not yet extracted alongside the scene-free renderers (TileRender, WorkerRenderer)Acceptance:
scripts/dock_theme.gd(class_name DockTheme) ownsmake_panel_style,make_empty_style,apply_theme,apply_button_theme, and the cached_button_stylesdict; pure (no scene references) so it can be tested in--scriptmodeapply_dock_position()and_on_startup_new_game()etc. continue to call the new module without behavioural changetests/test_runner.gd,tests/test_dock_layout.gd, andtests/test_tile_render.gdexercise the docking/layout path that this style change touchestests/test_dock_theme.gdcovers at least: stylebox caching (same key returns same reference), panel/button theme application, and the_button_stylesLRU-style re-use