The per-app Updates tab rendered a bare version/badge bar + detail with no
title, no dividers and no recessed container — unlike the Config / Backups /
Tasks tabs.
- Add a .updater-title block (⬆️ Updates + description, Check/Update actions,
bottom-border divider) mirroring .backup-title.
- Wrap the body in a .updater-detail-container recessed dark panel (same recipe
as .backup-snapshots-container / .tasks-container).
- Separate the Version/Security/Recovery/History sections with divider lines
(scoped to the container; fleet row-details keep their gap-only spacing).
- renderAppDetail() gains an opt-in Version section so the version/badge reads
as a section in the panel; fleet rows omit it (the row head shows it already).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Migrate and Backups detached their sub-tab strip from the content (16px gap)
and Backups had no top-level header and a transparent (card-less) body — so
both read as different from the per-app Config sub-tabs.
- Migrate: nest .tabs-content inside the same .tabs-wrapper as .tabs-list (the
canonical app-detail structure) and drop the gap, so the strip joins the
content card with no space and clean corners.
- Backups: inject the shared "Backups" .config-title header above the embedded
BackupPage; drop the sub-tab strip's bottom gap; give the content (.main) the
connected .tabs-content surface (card bg + rounded bottom) and round the
strip's outer top corners — so it reads as one tabs-within-tabs unit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the floating fleet header; every Overview tab now renders its heading
inside the pane, under the tab strip, in the per-app detail .config-title
format (emoji + title + description) — matching the Migrate tab.
Introduces a small modular system so the area can't drift:
- OV_TAB_META is the single source of truth for each tab's icon/title/blurb.
- renderHeader(id) is the only thing that turns it into markup; renderTab()
prepends it for the string tabs and mountMigrate() injects it once for the
static Migrate pane. Body renderers now only ever produce the body.
Retires the now-dead floating-header plumbing: updateHeader(), the
ov-backups-active/ov-migrate-active hide toggles + CSS, and the .overview-header
rules. The tabbed interface owns the top padding the header used to provide.
Backups is the documented exception — it embeds the full BackupPage, which
supplies its own header.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Give the fleet Overview › Migrate tab the same in-content header + sub-tab
styling the per-app detail tabs use:
- Add a .config-title header (icon + title + description) inside the Migrate
pane, above the Restore/Peers sub-tabs, and hide the generic floating fleet
header for Migrate (mirrors how Backups already supplies its own heading).
- Make the .tab-button icon↔label gap explicit (flex + 6px gap) so sub-tabs
render identically whether or not the markup has whitespace between the
emoji and name spans; align the Backups sub-tab strip gap to match.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Remove the Admin sidebar Peers entry; /peers and /admin/tools/peers now
redirect to /overview/migrate/peers (its new home next to cross-host Restore).
- Re-skin the embedded Backups center's sub-tab strip from pills to the per-app
Config .tabs-list/.tab-button segmented look (full-width bar, accent underline)
so every nested sub-tab row is consistent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New 5th Overview tab 'Migrate' with a nested segmented sub-tab row reusing the
per-app Config-tab .tabs-list/.tab-button design:
- Restore: a standalone MigratePage (cross-host migrate moved out of BackupPage
into its own controller + fragment + modal; own data fetch + task dispatch).
- Peers: reuses the existing PeersPage (container-parameterized) + its template.
Both lazy-loaded on first open and disposed on apps-feature unmount. Additive —
migrate is still in the backup center and Peers still in Admin until the next
commits remove the duplicates.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Instead of a glance + 'Open backup center' button, the Backups tab now mounts
the real BackupPage (dashboard/snapshots/locations/migrate/configuration) inline,
with its sidebar restyled as a nested tab strip and its own header taking over.
- BackupPage gains an embedded mode (opts.embedded): no /backup URL coupling, so
sub-tabs switch in-page under /overview/backups. Backward compatible.
- OverviewManager lazy-loads the backup bundle + fragment on first open, news a
BackupPage({embedded:true}), and disposes it on apps-feature unmount. Colliding
ids (#sidebar/#mobile-overlay) are stripped on inject.
- Revert the Admin backup-config surface — the embedded center (incl.
Configuration) is now the single home for backup settings.
- The updater needs no equivalent: its sections were already unpacked into the
Overview/Updates/Improvements tabs + the per-row expander.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New 'Updates' tab in the app detail page, beside Backups. Reuses the headless
UpdaterPage + renderAppDetail() scoped to the single app, so the per-app and
fleet views share one data/render path. UpdaterPage is added to the apps script
bundle so it's available on app pages; the tab is disabled while a task runs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduce a per-fleet Overview area inside the apps shell, reachable from a new
'Overview' entry pinned above the apps sidebar search. Selecting it renders a
top-tabbed view in the main pane — Overview · Updates · Improvements · Backups —
mirroring the per-app tabbed layout, with the apps sidebar persistent.
- TabController: generic root-scoped show/hide tab host (core/ui-state).
- OverviewManager: drives the 4 tabs. Reuses a headless UpdaterPage for all
update/CVE/improvement data + rendering (its renderX() are pure HTML
producers) and reads backup/dashboard.json directly for backup health.
- Overview tab: combined update + backup health cards.
- Updates tab: per-app expander table (CVEs/recovery/history inline via the new
UpdaterPage.renderAppDetail) + All/Updates/Security filter chips.
- Improvements tab: reuses the updater's signed-hotfix renderer.
- Backups tab: fleet backup-health tiles; actions deep-link per app.
- Additive only: /overview* routes on the apps feature; old /updater and
/backup pages untouched. Cleanup (redirects, nav, Admin config move) is next.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>