diff --git a/internal/cloudcp/portal/dist/build_manifest.json b/internal/cloudcp/portal/dist/build_manifest.json
index 7b2181efb8..c6b39b5999 100644
--- a/internal/cloudcp/portal/dist/build_manifest.json
+++ b/internal/cloudcp/portal/dist/build_manifest.json
@@ -1,5 +1,5 @@
{
- "source_hash": "640380cc9fd2cd2036a3ac2a9f949e018d3adfb7a6953cc3aa46c8d799980740",
+ "source_hash": "4b50b53b4369c0b8f2a17ddf8868a1eb8739772cb7a500616a2ba36f1449199d",
"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 b62540a6d0..a79298257c 100644
--- a/internal/cloudcp/portal/dist/portal_app.css
+++ b/internal/cloudcp/portal/dist/portal_app.css
@@ -161,18 +161,14 @@ header .logout-btn:hover,
display: block;
}
.portal-shell-head {
- padding: 20px 22px 18px;
+ padding: 16px 22px 14px;
border-bottom: 1px solid var(--line);
- background:
- linear-gradient(
- 180deg,
- rgba(248, 250, 252, 0.98),
- rgba(245, 248, 250, 0.96));
+ background: rgba(246, 248, 251, 0.96);
}
.portal-shell-head-main {
display: flex;
flex-direction: column;
- gap: 10px;
+ gap: 8px;
}
.portal-shell-head-kicker,
.account-panel-kicker,
@@ -195,24 +191,20 @@ header .logout-btn:hover,
.intro-card p {
margin: 0;
font-size: 12px;
- line-height: 1.45;
+ line-height: 1.5;
color: var(--ink-soft);
}
-.portal-shell-head p strong {
- color: var(--ink);
- font-weight: 700;
-}
.portal-shell-head-row {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
- gap: 16px;
- align-items: end;
+ gap: 14px;
+ align-items: center;
}
.portal-shell-head-copy {
display: flex;
flex-direction: column;
- gap: 6px;
- max-width: 860px;
+ gap: 4px;
+ max-width: 760px;
}
.portal-shell-head-brand-row {
display: flex;
@@ -222,8 +214,8 @@ header .logout-btn:hover,
}
.portal-shell-head-title {
margin: 0;
- font-size: 32px;
- line-height: 0.98;
+ font-size: 28px;
+ line-height: 1;
letter-spacing: -0.06em;
font-weight: 800;
color: var(--ink);
@@ -241,35 +233,31 @@ header .logout-btn:hover,
letter-spacing: 0.08em;
text-transform: uppercase;
}
-.portal-shell-head-stats {
+.portal-shell-head-summary {
display: flex;
- align-items: stretch;
+ align-items: center;
gap: 8px;
align-self: start;
+ flex-wrap: wrap;
}
-.portal-shell-head-stat {
- display: flex;
- flex-direction: column;
- justify-content: center;
- min-width: 132px;
- min-height: 0;
- padding: 10px 12px;
+.portal-shell-summary-pill {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ min-height: 32px;
+ padding: 0 12px;
border: 1px solid var(--line);
- border-radius: 12px;
+ border-radius: 999px;
background: rgba(255, 255, 255, 0.92);
+ font-size: 12px;
+ color: var(--ink-soft);
}
-.portal-shell-head-stat-label {
+.portal-shell-summary-pill strong {
+ color: var(--ink);
font-size: 11px;
- font-weight: 700;
- color: var(--ink-muted);
- letter-spacing: 0.06em;
- text-transform: uppercase;
-}
-.portal-shell-head-stat-value {
- font-size: 14px;
font-weight: 800;
- line-height: 1.25;
- letter-spacing: -0.04em;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
}
.portal-command-strip,
.intro-card,
@@ -1796,9 +1784,6 @@ header .logout-btn:hover,
.portal-account-bar-row {
align-items: start;
}
- .portal-shell-head-stats {
- flex-wrap: wrap;
- }
.workspace-row {
grid-template-columns: 1fr;
}
diff --git a/internal/cloudcp/portal/dist/portal_app.js b/internal/cloudcp/portal/dist/portal_app.js
index d78f12e24f..a799d4fd01 100644
--- a/internal/cloudcp/portal/dist/portal_app.js
+++ b/internal/cloudcp/portal/dist/portal_app.js
@@ -1764,9 +1764,8 @@
function renderOverviewBand(accounts) {
var hosted = hasHostedAccounts(accounts);
var workspaceTotal = countWorkspaces(accounts);
- var statusText = hosted ? "Hosted access is active on this account." : "No hosted workspace access is attached to this account yet.";
var summary = hosted ? "Hosted operations, operator access, and commercial account services." : "Billing, license recovery, refunds, and privacy actions until hosted access is attached.";
- return 'Pulse Account
' + (hosted ? "Operator console" : "Account console") + '
' + (hosted ? "Operator ready" : "Self-hosted only") + "" + statusText + " " + summary + '
Hosted access' + (hosted ? "Active" : "Not attached") + '
Accounts' + (accounts.length === 1 ? "1 account" : String(accounts.length) + " accounts") + '
Workspace fleet' + (workspaceTotal ? workspaceCountLabel(workspaceTotal) : "0 workspaces") + "
";
+ return 'Pulse Account
' + (hosted ? "Operator console" : "Account console") + '
' + (hosted ? "Operator ready" : "Self-hosted only") + "" + summary + '
Hosted access' + (hosted ? "Active" : "Not attached") + 'Accounts' + (accounts.length === 1 ? "1 account" : String(accounts.length) + " accounts") + 'Workspace fleet' + (workspaceTotal ? workspaceCountLabel(workspaceTotal) : "0 workspaces") + "
";
}
function renderPrimaryAccountBar(account) {
var workspaceLabel = workspaceCountLabel((account.workspaces || []).length);
diff --git a/internal/cloudcp/portal/frontend/src/shell_view.test.ts b/internal/cloudcp/portal/frontend/src/shell_view.test.ts
index d64797a47f..57bffa9143 100644
--- a/internal/cloudcp/portal/frontend/src/shell_view.test.ts
+++ b/internal/cloudcp/portal/frontend/src/shell_view.test.ts
@@ -127,7 +127,7 @@ describe('shell view', function() {
expect(html).toContain('portal-shell-head-kicker">Pulse Account');
expect(html).toContain('portal-shell-head-title">Operator console');
- expect(html).toContain('Hosted access is active on this account.');
+ expect(html).toContain('Hosted operations, operator access, and commercial account services.');
expect(html).toContain('portal-shell-nav');
expect(html).toContain('Overview');
expect(html).toContain('Workspaces');
@@ -198,7 +198,7 @@ describe('shell view', function() {
expect(html).toContain('Pulse Account');
expect(html).toContain('Self-hosted only');
expect(html).toContain('portal-shell-head-title">Account console');
- expect(html).toContain('No hosted workspace access is attached to this account yet.');
+ expect(html).toContain('Billing, license recovery, refunds, and privacy actions until hosted access is attached.');
expect(html).toContain('Use these tools for self-hosted billing, license recovery, refunds, and privacy.');
expect(html).toContain('Account services');
expect(html).not.toContain('Self-hosted licenses and billing');
diff --git a/internal/cloudcp/portal/frontend/src/shell_view.ts b/internal/cloudcp/portal/frontend/src/shell_view.ts
index abe5efb9f9..e5386fa1ec 100644
--- a/internal/cloudcp/portal/frontend/src/shell_view.ts
+++ b/internal/cloudcp/portal/frontend/src/shell_view.ts
@@ -196,7 +196,6 @@ function renderAttentionPanel(workspaces: PortalWorkspaceSummary[]): string {
function renderOverviewBand(accounts: PortalAccountSummary[]): string {
var hosted = hasHostedAccounts(accounts);
var workspaceTotal = countWorkspaces(accounts);
- var statusText = hosted ? 'Hosted access is active on this account.' : 'No hosted workspace access is attached to this account yet.';
var summary = hosted
? 'Hosted operations, operator access, and commercial account services.'
: 'Billing, license recovery, refunds, and privacy actions until hosted access is attached.';
@@ -211,21 +210,12 @@ function renderOverviewBand(accounts: PortalAccountSummary[]): string {
'
' + (hosted ? 'Operator console' : 'Account console') + '
' +
'' + (hosted ? 'Operator ready' : 'Self-hosted only') + '' +
'' +
- '' + statusText + ' ' + summary + '
' +
+ '' + summary + '
' +
'' +
- '' +
- '
' +
- 'Hosted access' +
- '' + (hosted ? 'Active' : 'Not attached') + '' +
- '
' +
- '
' +
- 'Accounts' +
- '' + (accounts.length === 1 ? '1 account' : String(accounts.length) + ' accounts') + '' +
- '
' +
- '
' +
- 'Workspace fleet' +
- '' + (workspaceTotal ? workspaceCountLabel(workspaceTotal) : '0 workspaces') + '' +
- '
' +
+ '
' +
+ 'Hosted access' + (hosted ? 'Active' : 'Not attached') + '' +
+ 'Accounts' + (accounts.length === 1 ? '1 account' : String(accounts.length) + ' accounts') + '' +
+ 'Workspace fleet' + (workspaceTotal ? workspaceCountLabel(workspaceTotal) : '0 workspaces') + '' +
'
' +
'
' +
'' +
diff --git a/internal/cloudcp/portal/frontend/src/styles.css b/internal/cloudcp/portal/frontend/src/styles.css
index ae75a97d32..0fefffdcd3 100644
--- a/internal/cloudcp/portal/frontend/src/styles.css
+++ b/internal/cloudcp/portal/frontend/src/styles.css
@@ -159,16 +159,15 @@ header .logout-btn:hover,
}
.portal-shell-head {
- padding: 20px 22px 18px;
+ padding: 16px 22px 14px;
border-bottom: 1px solid var(--line);
- background:
- linear-gradient(180deg, rgba(248, 250, 252, 0.98), rgba(245, 248, 250, 0.96));
+ background: rgba(246, 248, 251, 0.96);
}
.portal-shell-head-main {
display: flex;
flex-direction: column;
- gap: 10px;
+ gap: 8px;
}
.portal-shell-head-kicker,
@@ -195,27 +194,22 @@ header .logout-btn:hover,
.intro-card p {
margin: 0;
font-size: 12px;
- line-height: 1.45;
+ line-height: 1.5;
color: var(--ink-soft);
}
-.portal-shell-head p strong {
- color: var(--ink);
- font-weight: 700;
-}
-
.portal-shell-head-row {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
- gap: 16px;
- align-items: end;
+ gap: 14px;
+ align-items: center;
}
.portal-shell-head-copy {
display: flex;
flex-direction: column;
- gap: 6px;
- max-width: 860px;
+ gap: 4px;
+ max-width: 760px;
}
.portal-shell-head-brand-row {
@@ -227,8 +221,8 @@ header .logout-btn:hover,
.portal-shell-head-title {
margin: 0;
- font-size: 32px;
- line-height: 0.98;
+ font-size: 28px;
+ line-height: 1;
letter-spacing: -0.06em;
font-weight: 800;
color: var(--ink);
@@ -248,38 +242,33 @@ header .logout-btn:hover,
text-transform: uppercase;
}
-.portal-shell-head-stats {
+.portal-shell-head-summary {
display: flex;
- align-items: stretch;
+ align-items: center;
gap: 8px;
align-self: start;
+ flex-wrap: wrap;
}
-.portal-shell-head-stat {
- display: flex;
- flex-direction: column;
- justify-content: center;
- min-width: 132px;
- min-height: 0;
- padding: 10px 12px;
+.portal-shell-summary-pill {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ min-height: 32px;
+ padding: 0 12px;
border: 1px solid var(--line);
- border-radius: 12px;
+ border-radius: 999px;
background: rgba(255, 255, 255, 0.92);
+ font-size: 12px;
+ color: var(--ink-soft);
}
-.portal-shell-head-stat-label {
+.portal-shell-summary-pill strong {
+ color: var(--ink);
font-size: 11px;
- font-weight: 700;
- color: var(--ink-muted);
- letter-spacing: 0.06em;
- text-transform: uppercase;
-}
-
-.portal-shell-head-stat-value {
- font-size: 14px;
font-weight: 800;
- line-height: 1.25;
- letter-spacing: -0.04em;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
}
.portal-command-strip,
@@ -2037,10 +2026,6 @@ header .logout-btn:hover,
align-items: start;
}
- .portal-shell-head-stats {
- flex-wrap: wrap;
- }
-
.workspace-row {
grid-template-columns: 1fr;
}