' + title + "
" + description + '
diff --git a/docs/release-control/v6/internal/subsystems/api-contracts.md b/docs/release-control/v6/internal/subsystems/api-contracts.md
index 9c39035fe..b79bcd460 100644
--- a/docs/release-control/v6/internal/subsystems/api-contracts.md
+++ b/docs/release-control/v6/internal/subsystems/api-contracts.md
@@ -183,6 +183,12 @@ Own canonical runtime payload shapes between backend and frontend.
26. Keep storage chart identity canonical on that same shared API surface: the shared storage charts endpoint must key pool and physical-disk series by the resolved unified-resource `MetricsTarget.ResourceID`, not by canonical resource IDs or page-local aliases, so storage rows, focused summary cards, sticky summary shells, and detail charts all address the same history series in live and mock mode.
27. Keep synthetic summary-chart fallback identity canonical on that same shared API surface: when `internal/api/router.go` has to synthesize mock summary history for infrastructure, workloads, or storage cards, it must derive the fallback from canonical `resourceType`, `resourceID`, and `metricType` ownership instead of raw min/max seed-prefix helpers, so range changes and runtime mock updates stay on one governed timeline.
28. Keep workload-chart response identity canonical on that same shared API surface: `internal/api/router.go`, `internal/api/contract_test.go`, and workload summary consumers must emit provider-backed VM and system-container series under the same canonical workload IDs that workloads page rows use, while resolving history through the unified `MetricsTarget.ResourceID`, so hover and focus selection do not fall off for provider-backed rows.
+29. Keep the hosted account portal bootstrap intelligible without duplicate
+ chrome. `internal/cloudcp/portal/page.go`, the maintained portal frontend
+ bundle, and the shared portal styles may refine layout density, but the
+ account/billing shell must remain understandable from the primary header,
+ section title, and factual body content alone instead of depending on a
+ second context-chip strip to restate the same scope.
## Forbidden Paths
diff --git a/docs/release-control/v6/internal/subsystems/cloud-paid.md b/docs/release-control/v6/internal/subsystems/cloud-paid.md
index d0aa33ed9..b9f55d2a4 100644
--- a/docs/release-control/v6/internal/subsystems/cloud-paid.md
+++ b/docs/release-control/v6/internal/subsystems/cloud-paid.md
@@ -110,6 +110,11 @@ agreement, and cloud-specific enforcement rules.
19. Add or change cloud plan presentation through `frontend-modern/src/pages/CloudPricing.tsx`
20. Add contract tests where runtime and pricing need to stay aligned
21. Add or change hosted browser org-context bootstrap through `frontend-modern/src/App.tsx`, `frontend-modern/src/AppLayout.tsx`, `frontend-modern/src/useAppRuntimeState.ts`, and `frontend-modern/src/utils/apiClient.ts`
+22. Keep the hosted account portal shell task-first and compact. Section
+ headers, billing action rows, and the maintained portal bundle under
+ `internal/cloudcp/portal/` may surface the facts an operator needs, but the
+ shell should not spend vertical space on duplicate context-chip strips when
+ the page header and section body already communicate that scope.
## Forbidden Paths
diff --git a/internal/cloudcp/portal/dist/build_manifest.json b/internal/cloudcp/portal/dist/build_manifest.json
index f93305f4d..3b7df84d5 100644
--- a/internal/cloudcp/portal/dist/build_manifest.json
+++ b/internal/cloudcp/portal/dist/build_manifest.json
@@ -1,5 +1,5 @@
{
- "source_hash": "dee5325d02ca13ee1eb3b4ff7d09478406bbd5805999ced971f4b7f62700d7f0",
+ "source_hash": "8cda796f9a573443304df3d61c11f26041c8cd7f050fc737b67e3c056cd09b6c",
"build_inputs": [
"package.json",
"tsconfig.json",
diff --git a/internal/cloudcp/portal/dist/portal_app.css b/internal/cloudcp/portal/dist/portal_app.css
index 3122a8054..74d82df2e 100644
--- a/internal/cloudcp/portal/dist/portal_app.css
+++ b/internal/cloudcp/portal/dist/portal_app.css
@@ -81,6 +81,7 @@
--warn: #9a6700;
--warn-subtle: #fff8c5;
--radius: 6px;
+ --header-height: 49px;
}
*,
*::before,
@@ -89,6 +90,7 @@
}
html {
scroll-behavior: smooth;
+ background: var(--bg);
}
body {
margin: 0;
@@ -118,15 +120,16 @@ header {
align-items: center;
justify-content: space-between;
gap: 12px;
- height: 48px;
- padding: 0 16px;
+ height: var(--header-height);
+ padding: 0 24px;
border-bottom: 1px solid var(--border);
- background: var(--bg);
+ background: var(--bg-subtle);
}
header .brand {
font-size: 14px;
font-weight: 600;
color: var(--ink);
+ white-space: nowrap;
}
.header-account-chip {
display: inline-flex;
@@ -204,9 +207,9 @@ header .logout-btn:hover,
font-size: 12px;
}
.main {
- max-width: 800px;
+ max-width: 960px;
margin: 0 auto;
- padding: 0 24px 64px;
+ padding: 0 32px 64px;
}
.portal-shell {
display: flex;
@@ -217,13 +220,13 @@ header .logout-btn:hover,
display: flex;
align-items: baseline;
gap: 8px;
- padding: 16px 0 12px;
+ padding: 16px 0 0;
font-size: 13px;
color: var(--ink-secondary);
}
.portal-identity-bar h2 {
margin: 0;
- font-size: 20px;
+ font-size: 18px;
font-weight: 600;
color: var(--ink);
}
@@ -234,7 +237,8 @@ header .logout-btn:hover,
display: flex;
align-items: stretch;
gap: 0;
- border-bottom: 1px solid var(--border);
+ border-bottom: 1px solid var(--border-muted);
+ margin-top: 8px;
margin-bottom: 0;
}
.portal-tab {
@@ -293,7 +297,7 @@ header .logout-btn:hover,
display: none !important;
}
.portal-content-panel {
- padding: 20px 0 0;
+ padding: 16px 0 0;
}
.portal-section-header {
display: flex;
@@ -1591,6 +1595,9 @@ header .logout-btn:hover,
background: #82181a;
}
@media (max-width: 768px) {
+ header {
+ padding: 0 16px;
+ }
.main {
padding: 0 16px 48px;
}
diff --git a/internal/cloudcp/portal/dist/portal_app.js b/internal/cloudcp/portal/dist/portal_app.js
index 3694bf991..9cf73140f 100644
--- a/internal/cloudcp/portal/dist/portal_app.js
+++ b/internal/cloudcp/portal/dist/portal_app.js
@@ -2062,10 +2062,7 @@
return ' " + description + '' + title + "