- Settings tab renamed Edit; embeds config_form_body (.ConfigForm via the
builder) + Controller Update + Geo + a new Danger zone card holding the
relocated Block/Unblock/Delete forms (endpoints + confirm() unchanged).
All cards are SIBLINGS after </form> — never nested in the config form.
- Customer Info header loses the Edit link and Block/Delete forms; only the
config-less Create Config action stays.
- GET /configs/{id}/edit is a 302 to /customers/{id}#tab=edit; tabs JS gains
the settings→edit legacy-hash alias.
- Post-action redirects land back on their tab: update/block/unblock/
offsite-reissue/offsite-freeze/pbsdr-reissue → #tab=edit, regen-password
→ #tab=setup; delete unchanged (/configs).
- handleConfigUpdate gains the server-side twin of the form's required
fields; the error path re-renders the STANDALONE page with the SUBMITTED
overrides (B3 red-proof: nil overrides → typed values reset → test FAILS;
header red-proof: restored header buttons → count=2 → test FAILS; both run).
- Tests: Group A (panel surface, sibling forms, header cleaned by COUNT),
Group B (B1 302, B2 create unchanged, B3 typed-values, B4/B5 anchor table).
Amended pins: customer_tabs_test settings→edit; pbsdr_test postUpdate now
supplies the required fields + FormRendersState asserts the embedded render.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TZc5w5jDhFLv6qDC32KN5v
- host_detail_body.html: {{define}}'d body sections extracted from
host_detail.html; the standalone page is now chrome + the sub-template
- hosts.go: hostDetailData(host, r) view-model builder extracted from
handleHostDetail (reused by both surfaces)
- store: ListHostsByCustomer (host_id order; the Host tab is a list by
design - N hosts for a future HA cluster)
- customer Host tab renders one host_detail_body per host + cross-link;
empty state when no host is enrolled
- tests: TestTemplates_CustomerHostTab(+_Empty), TestListHostsByCustomer
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vvz1NCu22p8dGkRCpeX9re
- style.css: .data-table td a -> :not(.btn) so <a class=btn> keeps the .btn
palette (View/Download buttons were blue-on-blue invisible)
- customer_unified.html: 8 client-side hash tabs (#tab=...) + sticky summary
strip; all sections preserved in DOM, hiding is a JS-added body class only
(no-JS = everything visible); Events tab gets a red error-count badge
- new render tests: TestTemplates_CustomerTabs (+_NoReports)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vvz1NCu22p8dGkRCpeX9re