diff --git a/docs/release-control/v6/internal/subsystems/frontend-primitives.md b/docs/release-control/v6/internal/subsystems/frontend-primitives.md index 44938d4c99..46bc482d17 100644 --- a/docs/release-control/v6/internal/subsystems/frontend-primitives.md +++ b/docs/release-control/v6/internal/subsystems/frontend-primitives.md @@ -2427,6 +2427,17 @@ not a replacement status card, CTA band, or page-local nested card. shared owner must also cap concurrent numeric animations and snap overflow readouts to their current target so a realtime estate update cannot make animation cost grow with the number of visible resources. + Background colours come from the `@theme inline` surface tokens in + `frontend-modern/src/index.css` and the `bg-page` utility beside them. + `bg-page` paints the page backdrop (`--color-bg-base`) for a well that + should read as the page behind a surface card: command and JSON blocks, + the branding header preview, and the segmented filter track. A block that + sits directly on a `bg-surface-alt` body, such as resource drawer content, + uses `bg-surface` instead. No theme colour may be named `base`: it also + colours the `text-base` font-size utility, and without it Tailwind 4 + renders `bg-base` as nothing, which left those wells and the alert + selection bar transparent. `src/__tests__/App.architecture.test.ts` fails + if either comes back. Shared primitives must not reintroduce app-shell monitored-system capacity banners. Monitored-system grouping and ledger presentation belongs in the owned settings surfaces, while commercial plan explanation belongs in diff --git a/frontend-modern/browser-verification/435f865dac7a10df.json b/frontend-modern/browser-verification/435f865dac7a10df.json new file mode 100644 index 0000000000..3d6e87cc26 --- /dev/null +++ b/frontend-modern/browser-verification/435f865dac7a10df.json @@ -0,0 +1,134 @@ +{ + "version": 1, + "base_sha": "8d77c0e2772fe7c023f4be963721c4c7709c57e0", + "verified_at": "2026-10-05T22:54:59Z", + "result": "passed", + "changed_paths": [ + "frontend-modern/src/App.tsx", + "frontend-modern/src/AppLayout.tsx", + "frontend-modern/src/components/Alerts/ResourceTable.tsx", + "frontend-modern/src/components/AppBootstrapStatus.tsx", + "frontend-modern/src/components/ErrorBoundary.tsx", + "frontend-modern/src/components/Infrastructure/ResourceChangeSummary.tsx", + "frontend-modern/src/components/Infrastructure/ResourceCorrelationSummary.tsx", + "frontend-modern/src/components/Infrastructure/ResourceDetailDrawerDebugTab.tsx", + "frontend-modern/src/components/Infrastructure/ResourceDetailDrawerOverviewTab.tsx", + "frontend-modern/src/components/Infrastructure/ResourceDetailDrawerSupportDisclosure.tsx", + "frontend-modern/src/components/Infrastructure/ResourcePolicySummary.tsx", + "frontend-modern/src/components/Login.tsx", + "frontend-modern/src/components/Settings/AIProviderConfigurationSection.tsx", + "frontend-modern/src/components/Settings/AgentIntegrationsPanel.tsx", + "frontend-modern/src/components/Settings/BackupTransferDialogs.tsx", + "frontend-modern/src/components/Settings/BrandingSettingsCard.tsx", + "frontend-modern/src/components/Settings/CopyCommandBlock.tsx", + "frontend-modern/src/components/Settings/InfrastructureAgentDoctorPage.tsx", + "frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx", + "frontend-modern/src/components/Settings/NodeModalSetupGuideSection.tsx", + "frontend-modern/src/components/Settings/QuickSecuritySetup.tsx", + "frontend-modern/src/components/Settings/SSOProvidersPanel.tsx", + "frontend-modern/src/components/Settings/SuggestProfileModal.tsx", + "frontend-modern/src/components/Settings/UpdateInstallGuide.tsx", + "frontend-modern/src/components/Settings/updatesSettingsModel.ts", + "frontend-modern/src/components/SetupWizard/SetupWizard.tsx", + "frontend-modern/src/components/SetupWizard/steps/SecurityStep.tsx", + "frontend-modern/src/components/SetupWizard/steps/WelcomeStep.tsx", + "frontend-modern/src/components/patrol/RunToolCallTrace.tsx", + "frontend-modern/src/components/shared/Card.tsx", + "frontend-modern/src/components/shared/CommandPaletteModal.tsx", + "frontend-modern/src/components/shared/EmptyState.tsx", + "frontend-modern/src/components/shared/filterButtonGroupModel.ts", + "frontend-modern/src/features/alerts/AlertDeadManDestinationSection.tsx", + "frontend-modern/src/index.css" + ], + "content_sha256": { + "frontend-modern/src/App.tsx": "00a405e01fc87c3f738fb744876e16f13e68d50cb8f31d469f040c637a6f59f0", + "frontend-modern/src/AppLayout.tsx": "3cb3f11a0f39adcd33cef84e7e99451395909313f1898383aa9fcc221dcb0f49", + "frontend-modern/src/components/Alerts/ResourceTable.tsx": "760ff1b760ac8c910582c5b81900a15788fa1ec5a08edd989c54cfafd0a55f49", + "frontend-modern/src/components/AppBootstrapStatus.tsx": "f33978b847c89626e24698dbe5c27db587425a4968573eb75a92f2f75b35f726", + "frontend-modern/src/components/ErrorBoundary.tsx": "ac334eb9bd8aebdb8d8c5fe62e82c399d393a1c670f30f600457278bf98ca45e", + "frontend-modern/src/components/Infrastructure/ResourceChangeSummary.tsx": "4f3f035d2c87e562680dcf61c88cfbc0bb4f2daced31c0bda8427194fe25d992", + "frontend-modern/src/components/Infrastructure/ResourceCorrelationSummary.tsx": "cf77b97ce7bfce0aa642668f4f0123a9e592196e7b5e83a9791ef8e95dca33e5", + "frontend-modern/src/components/Infrastructure/ResourceDetailDrawerDebugTab.tsx": "77ebc85ed5b7de3624c87846288dadc887b5555bac325b98f347246222d7b4c4", + "frontend-modern/src/components/Infrastructure/ResourceDetailDrawerOverviewTab.tsx": "63192be4ab8de0e2aa920207cec14d593571f282d8bde1c8951a2d1413c00fc8", + "frontend-modern/src/components/Infrastructure/ResourceDetailDrawerSupportDisclosure.tsx": "c0f3aaac14865c0944969b2fbfc898bd311def49f25db6938ccbadac9bc822e3", + "frontend-modern/src/components/Infrastructure/ResourcePolicySummary.tsx": "7d87ab5e6ea2948160bf275b6d9fec7ff4ee38ce457f75b85d24c1dbb2c95203", + "frontend-modern/src/components/Login.tsx": "0790413c0199b2bd0e0fcb9dc53cfa0fc6ac84717acbfa4f5140e725cf3d2ff2", + "frontend-modern/src/components/Settings/AIProviderConfigurationSection.tsx": "686708cbbddce209b141e1f9b4c60b0ad57079432be77e384c0d0c4e88dbf7e4", + "frontend-modern/src/components/Settings/AgentIntegrationsPanel.tsx": "45b3473d4a67cf505651c483616a0724085bbaa2f3f1e53c2021c5cfda2d6d0c", + "frontend-modern/src/components/Settings/BackupTransferDialogs.tsx": "a873e334d4eaf5b25bc31ba8922b07119fe16da169b91966c591b8f3a60cf06b", + "frontend-modern/src/components/Settings/BrandingSettingsCard.tsx": "c36f0f518c9674eb05c5050e2e23b9598673a5adf00d039c143cf180a8f21f7f", + "frontend-modern/src/components/Settings/CopyCommandBlock.tsx": "084835c7beb84d0800f9b5590fcb899f7e6088513fc1251b2a74f15e2225b411", + "frontend-modern/src/components/Settings/InfrastructureAgentDoctorPage.tsx": "6064372d8a07257b222888e47c075e5428a6a9392ffbd257963855d0fbe31d38", + "frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx": "9787d5c0615787f6e0a3fc1caefc3ebef93f4618f6f74b4b2470a0fa0c40e37f", + "frontend-modern/src/components/Settings/NodeModalSetupGuideSection.tsx": "0b8b4600e20bcbd5235a5a7fecffd99c9752d8417955b23c8ce7be473f18042c", + "frontend-modern/src/components/Settings/QuickSecuritySetup.tsx": "8884d86ac12281a5805c33ef608fb0f86f6a61166a6eb72edcc2412b477781b5", + "frontend-modern/src/components/Settings/SSOProvidersPanel.tsx": "2f56e9f1635b34581457c00a60a49166caceeeed2209a187d032704b3d2ca716", + "frontend-modern/src/components/Settings/SuggestProfileModal.tsx": "b54c5c7449fe824f1ba13676bd3bac151bc0b6a880d831b211480dc41f6806d1", + "frontend-modern/src/components/Settings/UpdateInstallGuide.tsx": "65877c2b8a4706721881545dd4f769a41485d3c8df2ede5f9022c337c77d6e92", + "frontend-modern/src/components/Settings/updatesSettingsModel.ts": "7c8cbb83097f65bb1e17fbab859fd0711f870bb0aaa1e9c91fcc71cfd165bb49", + "frontend-modern/src/components/SetupWizard/SetupWizard.tsx": "c96e980aec912bfae0976132168121d45fe2ba8b8e92af9c998e6cf7d69edf56", + "frontend-modern/src/components/SetupWizard/steps/SecurityStep.tsx": "2ae173c4fc65b7aa528d1ca4196d085547081c9742e4f504d00a0baeccbc20b1", + "frontend-modern/src/components/SetupWizard/steps/WelcomeStep.tsx": "4849c5fe13442131a5c6427d81f3c366c94e48a9701f41d1c927476b7af17dbc", + "frontend-modern/src/components/patrol/RunToolCallTrace.tsx": "88b4bedf474d2fa23f56d59db0c746c83e004b920489c86bb6827d50133a7366", + "frontend-modern/src/components/shared/Card.tsx": "03e4ff8a482b6dd086eb4b2765fa517edc229c02ff27105b0e572523c07a7d5f", + "frontend-modern/src/components/shared/CommandPaletteModal.tsx": "8e0a8aaa1bbd2151ddb578e65c1230ef710b2666647cec3ab55a27fc23ac28c3", + "frontend-modern/src/components/shared/EmptyState.tsx": "ee47b2b011fd67fc79913be1c86d8526ffaea8b49716965e0b8f358ebbc2dd74", + "frontend-modern/src/components/shared/filterButtonGroupModel.ts": "a180ecf16e3bb84dadbd6f59a036190960082a527272551648fa9a6e9dd168ab", + "frontend-modern/src/features/alerts/AlertDeadManDestinationSection.tsx": "57b1d0468a61a3e382a72649cb3fd5764e7d00e25f529fa156706bb54121e099", + "frontend-modern/src/index.css": "8ee3a5cfffdf960243238f037147d817a950c65cadb5d36fdc59d58d3837572b" + }, + "routes": [ + "/settings/pulse-intelligence/assistant", + "/settings/infrastructure/agent-doctor", + "/settings/system-recovery", + "/standalone/machines", + "/proxmox/overview", + "/alerts/notifications", + "/alerts/thresholds", + "/alerts/schedule", + "/settings/system-updates", + "/settings", + "/machines", + "/settings/security/api", + "/patrol", + "/settings/system-general", + "/settings/pulse-intelligence/provider", + "/settings/infrastructure", + "/settings/security-sso" + ], + "viewports": [ + { + "width": 1440, + "height": 1000 + }, + { + "width": 390, + "height": 844 + } + ], + "states": [ + "Private mock stack (backend 7781, Vite 5281). Every capture was taken on main and on the change in the same session by swapping the files under Vite, in light and dark", + "External agents connector setup with every details panel open: install and client-config command blocks, the capability chip, the access-model panels and their lists were transparent on the white card; they now read as slate-100 wells in light and slate-900 wells in dark", + "Agent Doctor command blocks, the export-configuration options box, the Ollama pull command, the agent installer commands, the Proxmox node setup-guide command and the SAML metadata XML preview: transparent before, page-coloured wells after", + "Update install guide for systemd and Docker (version response set to that deployment type): the wells now paint, and the green and blue command text gained light-mode shades, because green-400 on a light well measured about 1.6:1", + "Dead Man's Switch: the \"Not configured\" pill had no fill and read as plain text; it is now a white chip with a border ring in light and a ringed chip in dark. The detail grid is a recessed well", + "Alert threshold bulk-selection bar after ticking two storage rows: before, light mode showed white count text on a see-through pill (the count was invisible) and dark mode showed the table through it; after, it is an opaque bg-surface pill with readable text in both themes", + "Command palette shortcut chips read as keycaps; the palette input already painted bg-surface, so its redundant class was removed", + "Patrol mode segmented control (ai_autofix capability supplied): the selected option was a white chip on a white track; the track is now page-coloured and the selection stands out in both themes", + "Branding header preview (white_label capability supplied): the preview header bar now sits on a page-coloured backdrop instead of disappearing into the card", + "Muted Card tone (API token hint, alert configuration summary): slate-100 in light, unchanged in dark. The unused glass tone was removed", + "Machine drawer Debug tab: JSON blocks sit on the drawer's bg-surface-alt body, so they use bg-surface like the drawer's other cards (white on slate-100 in light, flat in dark as before)", + "Setup wizard (security status set to no authentication, bootstrap validation fulfilled with a dummy value): Welcome command wells with legible text and copy buttons, and the Security step wells and footer band, in both themes", + "Login, wizard root, app scroll shell and the framed 404 empty state dropped a class that generated no CSS: the Login page and the empty-state element are pixel-identical before and after, and the shells sit directly on body, which already paints the page colour", + "Hover-only drawer buttons, measured with their exact classes in the live drawer: hover:bg-base never changed the colour; hover:bg-surface-hover goes to rgb(248,250,252) in light and rgb(51,65,85) in dark", + "Not reachable on the mock stack and judged from their containers: the drawer change-history filters, change reason and metadata, the correlation and change summary cards and the coloured drawer buttons (the compact drawer fetches no history in mock), Quick Security Setup (unauthenticated sessions go to the wizard), the agent-profile suggestion JSON, the Patrol tool-call trace, other node-modal tabs, the needs-setup nav tab, the bootstrap/error/init shells, and ResourcePolicySummary, which has no production caller", + "Phone at 390: Dead Man's Switch grid, External agents command block, update steps and wizard command wells render the same wells in both themes" + ], + "interactions": [ + "Opened connector setup and expanded every details panel; opened the machine drawer and its Debug tab; opened the command palette with Cmd/Ctrl+K", + "Expanded all threshold groups and ticked two storage rows to raise the bulk-edit bar", + "Opened Create Backup, Add infrastructure > Install Pulse Agent > Generate token, Add infrastructure > Proxmox VE with an endpoint entered, Add SAML > Preview metadata, and the Ollama provider section", + "Advanced the setup wizard to the Security step; showed the Login page via the logged-out flag", + "Hovered the old and new drawer button classes in light and dark; repeated the key surfaces at 390px" + ] +} diff --git a/frontend-modern/src/App.tsx b/frontend-modern/src/App.tsx index 42a975de6d..b2ee82ea2b 100644 --- a/frontend-modern/src/App.tsx +++ b/frontend-modern/src/App.tsx @@ -527,7 +527,7 @@ function App() { +
Initializing...
} @@ -559,7 +559,7 @@ function App() { {/* Main content area - shrinks when AI panel is open, scrolls independently */}
} > -
+
{props.children}
diff --git a/frontend-modern/src/AppLayout.tsx b/frontend-modern/src/AppLayout.tsx index 330044bf00..917a12d94c 100644 --- a/frontend-modern/src/AppLayout.tsx +++ b/frontend-modern/src/AppLayout.tsx @@ -694,7 +694,7 @@ export function AppLayout(props: AppLayoutProps) { return `${baseClasses} bg-surface text-blue-600 dark:text-blue-400 border-border border-b border-b-surface shadow-xs font-semibold`; } if (needsSetup()) { - return `${baseClasses} text-muted opacity-70 bg-base hover:bg-surface-hover`; + return `${baseClasses} text-muted opacity-70 hover:bg-surface-hover`; } return `${baseClasses} text-muted hover:text-base-content hover:bg-surface-hover`; }; diff --git a/frontend-modern/src/__tests__/App.architecture.test.ts b/frontend-modern/src/__tests__/App.architecture.test.ts index e9d9cc865b..ea0251af87 100644 --- a/frontend-modern/src/__tests__/App.architecture.test.ts +++ b/frontend-modern/src/__tests__/App.architecture.test.ts @@ -1007,30 +1007,30 @@ describe('App architecture', () => { }); }); +function collectFrontendSources(dir: string): Array<{ path: string; source: string }> { + return readdirSync(dir, { withFileTypes: true }).flatMap((entry) => { + const entryPath = join(dir, entry.name); + if (entry.isDirectory()) { + return collectFrontendSources(entryPath); + } + // Only runtime sources matter; a test may quote an old shape in order to + // assert against it, as the guards below do. + if (!/\.(css|ts|tsx)$/.test(entry.name)) { + return []; + } + if (entryPath.includes('__tests__') || /\.(test|spec)\./.test(entry.name)) { + return []; + } + return [{ path: entryPath, source: readFileSync(entryPath, 'utf8') }]; + }); +} + describe('mobile bottom navigation clearance', () => { const NAV_HEIGHT_VARIABLE = '--pulse-mobile-nav-height'; // Matches the shape every drifted copy used, spaced or not. The lookbehind // keeps the declared 2.5rem fallback from matching its own guard. const HARDCODED_BAR_HEIGHT = /(? { - return readdirSync(dir, { withFileTypes: true }).flatMap((entry) => { - const entryPath = join(dir, entry.name); - if (entry.isDirectory()) { - return collectFrontendSources(entryPath); - } - // Only runtime sources matter; a test may quote the old shape in order - // to assert against it, as this one does. - if (!/\.(css|ts|tsx)$/.test(entry.name)) { - return []; - } - if (entryPath.includes('__tests__') || /\.(test|spec)\./.test(entry.name)) { - return []; - } - return [{ path: entryPath, source: readFileSync(entryPath, 'utf8') }]; - }); - } - it('declares the bar height as a single custom property', () => { expect(appStylesSource).toContain(NAV_HEIGHT_VARIABLE); }); @@ -1050,6 +1050,33 @@ describe('mobile bottom navigation clearance', () => { }); }); +describe('page background utility', () => { + // Tailwind 4 emits nothing for a colour it does not know, so `bg-base` + // rendered transparent without any error: command blocks, the alert + // selection bar and segmented-control tracks all lost their backgrounds. + // A theme colour named `base` is not the fix either, because it also gives + // the `text-base` font-size utility a colour and paints text in the page + // colour. The page backdrop is the bg-page utility. + const DEAD_BASE_BACKGROUND = /(? { + expect(appStylesSource).toMatch( + /@utility bg-page \{\s*background-color: var\(--color-bg-base\);\s*\}/, + ); + expect(appStylesSource).not.toMatch(/--color-base\s*:/); + }); + + it('keeps every runtime class off the bg-base utility that renders nothing', () => { + const offenders = collectFrontendSources(join(process.cwd(), 'src')) + .filter(({ source }) => DEAD_BASE_BACKGROUND.test(source.replace(COMMENTS, '$1'))) + .map(({ path }) => path.slice(process.cwd().length + 1)); + + expect(offenders).toEqual([]); + }); +}); + describe('Docker phone update reflow boundary', () => { it('scopes label wrapping to narrow Docker cells without restoring a nested scrollport', () => { const phoneStyles = appStylesSource.slice(appStylesSource.indexOf('/* Phone update states')); diff --git a/frontend-modern/src/components/Alerts/ResourceTable.tsx b/frontend-modern/src/components/Alerts/ResourceTable.tsx index 38cca6f3f0..284837fbd9 100644 --- a/frontend-modern/src/components/Alerts/ResourceTable.tsx +++ b/frontend-modern/src/components/Alerts/ResourceTable.tsx @@ -145,9 +145,9 @@ export function ResourceTable(props: ResourceTableProps) { 0 && props.onBulkEdit}> -
- - {selectedIds().size} selected +
+ + {selectedIds().size} selected
@@ -473,7 +473,7 @@ export const ResourceDetailDrawerOverviewTab: Component drawer.setTimelineKindFilter( @@ -489,7 +489,7 @@ export const ResourceDetailDrawerOverviewTab: Component drawer.setTimelineSourceTypeFilter( @@ -505,7 +505,7 @@ export const ResourceDetailDrawerOverviewTab: Component drawer.setTimelineSourceAdapterFilter( @@ -618,12 +618,12 @@ export const ResourceDetailDrawerOverviewTab: Component
-
+
{change.reason}
-
+
Metadata @@ -867,7 +867,7 @@ export const ResourceDetailDrawerOverviewTab: Component {drawer.showDockerUpdateControls() ? 'Hide actions' : 'Show actions'} @@ -1114,7 +1114,7 @@ export const ResourceDetailDrawerOverviewTab: Component drawer.setShowPbsJobDetail((value) => !value)} - class="inline-flex items-center rounded-md border border-indigo-200 bg-surface px-2.5 py-1 text-[10px] font-medium text-indigo-700 transition-colors hover:bg-base dark:border-indigo-700 dark:text-indigo-300" + class="inline-flex items-center rounded-md border border-indigo-200 bg-surface px-2.5 py-1 text-[10px] font-medium text-indigo-700 transition-colors hover:bg-surface-hover dark:border-indigo-700 dark:text-indigo-300" > {drawer.showPbsJobDetail() ? 'Hide jobs' : 'Show jobs'} @@ -1242,7 +1242,7 @@ export const ResourceDetailDrawerOverviewTab: Component drawer.setShowPmgMailFlowDetail((value) => !value)} - class="inline-flex items-center rounded-md border border-rose-200 bg-surface px-2.5 py-1 text-[10px] font-medium text-rose-700 transition-colors hover:bg-base dark:border-rose-700 dark:text-rose-300" + class="inline-flex items-center rounded-md border border-rose-200 bg-surface px-2.5 py-1 text-[10px] font-medium text-rose-700 transition-colors hover:bg-surface-hover dark:border-rose-700 dark:text-rose-300" > {drawer.showPmgMailFlowDetail() ? 'Hide mail flow' : 'Show mail flow'} diff --git a/frontend-modern/src/components/Infrastructure/ResourceDetailDrawerSupportDisclosure.tsx b/frontend-modern/src/components/Infrastructure/ResourceDetailDrawerSupportDisclosure.tsx index 6e047607b7..a1f90f8ce2 100644 --- a/frontend-modern/src/components/Infrastructure/ResourceDetailDrawerSupportDisclosure.tsx +++ b/frontend-modern/src/components/Infrastructure/ResourceDetailDrawerSupportDisclosure.tsx @@ -48,7 +48,7 @@ export const ResourceDetailDrawerSupportDisclosure: Component< onClick={props.onToggle} class={ props.buttonClass ?? - 'inline-flex min-h-11 shrink-0 items-center rounded-md border border-border bg-surface px-2.5 py-1 text-[10px] font-medium text-base-content transition-colors hover:bg-base sm:min-h-0' + 'inline-flex min-h-11 shrink-0 items-center rounded-md border border-border bg-surface px-2.5 py-1 text-[10px] font-medium text-base-content transition-colors hover:bg-surface-hover sm:min-h-0' } > {props.expanded ? props.hideLabel : props.showLabel} diff --git a/frontend-modern/src/components/Infrastructure/ResourcePolicySummary.tsx b/frontend-modern/src/components/Infrastructure/ResourcePolicySummary.tsx index 582a4f8b31..93e03a566f 100644 --- a/frontend-modern/src/components/Infrastructure/ResourcePolicySummary.tsx +++ b/frontend-modern/src/components/Infrastructure/ResourcePolicySummary.tsx @@ -24,7 +24,7 @@ export const ResourcePolicySummary: Component = (pro return ( {(value) => ( -
+

diff --git a/frontend-modern/src/components/Login.tsx b/frontend-modern/src/components/Login.tsx index d783c6a03c..1d9e14e6c7 100644 --- a/frontend-modern/src/components/Login.tsx +++ b/frontend-modern/src/components/Login.tsx @@ -344,7 +344,7 @@ export const Login: Component = (props) => { +

Checking authentication...

@@ -379,7 +379,7 @@ export const Login: Component = (props) => { > +

Loading setup...

@@ -438,7 +438,7 @@ const LoginForm: Component<{ } = props; return ( -
+
{/* Demo Credentials Banner */} diff --git a/frontend-modern/src/components/Settings/AIProviderConfigurationSection.tsx b/frontend-modern/src/components/Settings/AIProviderConfigurationSection.tsx index 066f8ccc46..dcb876753e 100644 --- a/frontend-modern/src/components/Settings/AIProviderConfigurationSection.tsx +++ b/frontend-modern/src/components/Settings/AIProviderConfigurationSection.tsx @@ -297,7 +297,7 @@ export const AIProviderConfigurationSection: Component

{suggestedModelNote()}

diff --git a/frontend-modern/src/components/Settings/AgentIntegrationsPanel.tsx b/frontend-modern/src/components/Settings/AgentIntegrationsPanel.tsx index 5dff1e4314..2087e78c30 100644 --- a/frontend-modern/src/components/Settings/AgentIntegrationsPanel.tsx +++ b/frontend-modern/src/components/Settings/AgentIntegrationsPanel.tsx @@ -309,7 +309,7 @@ export const AgentIntegrationsPanel: Component = () => {
@@ -319,7 +319,7 @@ export const AgentIntegrationsPanel: Component = () => {
@@ -353,7 +353,7 @@ export const AgentIntegrationsPanel: Component = () => {
@@ -371,7 +371,7 @@ export const AgentIntegrationsPanel: Component = () => {
@@ -395,7 +395,7 @@ export const AgentIntegrationsPanel: Component = () => { {(posture) => (
@@ -411,7 +411,7 @@ export const AgentIntegrationsPanel: Component = () => { )} 0}> -
+
Patrol access model @@ -432,7 +432,7 @@ export const AgentIntegrationsPanel: Component = () => { {(badge) => ( - + {badge} )} @@ -449,7 +449,7 @@ export const AgentIntegrationsPanel: Component = () => {
-
+
Live manifest details @@ -468,7 +468,7 @@ export const AgentIntegrationsPanel: Component = () => {
-
    +
      {(prompt) => (
    • @@ -548,7 +548,7 @@ export const AgentIntegrationsPanel: Component = () => { {(summary) => ( {summary.code} @@ -591,7 +591,7 @@ export const AgentIntegrationsPanel: Component = () => {

      {section.description}

-
    +
      {(cap) => (
    • diff --git a/frontend-modern/src/components/Settings/BackupTransferDialogs.tsx b/frontend-modern/src/components/Settings/BackupTransferDialogs.tsx index eee2faea0d..fbd3163b33 100644 --- a/frontend-modern/src/components/Settings/BackupTransferDialogs.tsx +++ b/frontend-modern/src/components/Settings/BackupTransferDialogs.tsx @@ -45,7 +45,7 @@ export const BackupTransferDialogs: Component = (pro
      -
      +
      -
      +

      Header preview

      diff --git a/frontend-modern/src/components/Settings/CopyCommandBlock.tsx b/frontend-modern/src/components/Settings/CopyCommandBlock.tsx index 1f60bddc8e..e48e15c0fc 100644 --- a/frontend-modern/src/components/Settings/CopyCommandBlock.tsx +++ b/frontend-modern/src/components/Settings/CopyCommandBlock.tsx @@ -11,7 +11,7 @@ interface CopyCommandBlockProps { const DEFAULT_CONTAINER_CLASS = 'relative group'; const DEFAULT_CODE_CLASS = - 'block rounded-md border border-border bg-base p-3 font-mono text-sm text-base-content'; + 'block rounded-md border border-border bg-page p-3 font-mono text-sm text-base-content'; export function CopyCommandBlock(props: CopyCommandBlockProps) { const handleCopy = () => { diff --git a/frontend-modern/src/components/Settings/InfrastructureAgentDoctorPage.tsx b/frontend-modern/src/components/Settings/InfrastructureAgentDoctorPage.tsx index ec9aa1bf5b..329edd39a5 100644 --- a/frontend-modern/src/components/Settings/InfrastructureAgentDoctorPage.tsx +++ b/frontend-modern/src/components/Settings/InfrastructureAgentDoctorPage.tsx @@ -654,7 +654,7 @@ export const InfrastructureAgentDoctorPage: Component -
      +                                      
                                               
                                                 {buildSafeCollectorInspectCommand({
                                                   pulseUrl: operations.selectedAgentUrl(),
      @@ -682,7 +682,7 @@ export const InfrastructureAgentDoctorPage: Component
      -                                      
      +                                      
                                               
                                                 {buildSafeCollectorApplyCommand({
                                                   pulseUrl: operations.selectedAgentUrl(),
      @@ -767,7 +767,7 @@ export const InfrastructureAgentDoctorPage: Component void copyCommand(tokenFileCommand())}
                                                 label="Copy private token-file command"
                                               />
      -                                        
      +                                        
                                                 {tokenFileCommand()}
                                               
      @@ -782,7 +782,7 @@ export const InfrastructureAgentDoctorPage: Component -
      +                                        
                                                 {reveal().token}
                                               
      @@ -796,7 +796,7 @@ export const InfrastructureAgentDoctorPage: Component void copyCommand(installCommand())} label="Copy action-runner installer command" /> -
      +                                        
                                                 {installCommand()}
                                               
      @@ -914,7 +914,7 @@ export const InfrastructureAgentDoctorPage: Component -
      +                                    
                                             {command()}
                                           
      -
      +                                          
                                                   
                                                     {operations.getPlatformUninstallCommand(
                                                       entry.platform,
      diff --git a/frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx b/frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx
      index 5c1e32eeae..a44b51fb27 100644
      --- a/frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx
      +++ b/frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx
      @@ -715,7 +715,7 @@ export const InfrastructureInstallerSection: Component
      -                                
      +                                
                                         {copyCommand()}
                                       
      diff --git a/frontend-modern/src/components/Settings/NodeModalSetupGuideSection.tsx b/frontend-modern/src/components/Settings/NodeModalSetupGuideSection.tsx index cff9e37b00..11079ba4f6 100644 --- a/frontend-modern/src/components/Settings/NodeModalSetupGuideSection.tsx +++ b/frontend-modern/src/components/Settings/NodeModalSetupGuideSection.tsx @@ -165,7 +165,7 @@ export const NodeModalSetupGuideSection: Component Run this command on your Proxmox VE node:

      -
      +
      -
      +
      Password Setup
      @@ -390,7 +390,7 @@ Important:
      -
      +
      Username
      @@ -406,7 +406,7 @@ Important:
      -
      +
      Password
      @@ -422,7 +422,7 @@ Important:
      -
      +
      API token
      diff --git a/frontend-modern/src/components/Settings/SSOProvidersPanel.tsx b/frontend-modern/src/components/Settings/SSOProvidersPanel.tsx index 38606de496..0853a41a39 100644 --- a/frontend-modern/src/components/Settings/SSOProvidersPanel.tsx +++ b/frontend-modern/src/components/Settings/SSOProvidersPanel.tsx @@ -940,7 +940,7 @@ export const SSOProvidersPanel: Component = (props) => { Copy
      -
      +              
                       {metadataPreview()?.xml}
                     
      diff --git a/frontend-modern/src/components/Settings/SuggestProfileModal.tsx b/frontend-modern/src/components/Settings/SuggestProfileModal.tsx index 59ef76cc9d..79c8f33e3a 100644 --- a/frontend-modern/src/components/Settings/SuggestProfileModal.tsx +++ b/frontend-modern/src/components/Settings/SuggestProfileModal.tsx @@ -525,8 +525,8 @@ export const SuggestProfileModal: Component = (props)
      Raw JSON
      -
      -
      +                        
      +
                                   {JSON.stringify(sugg().config, null, 2)}
                                 
      diff --git a/frontend-modern/src/components/Settings/UpdateInstallGuide.tsx b/frontend-modern/src/components/Settings/UpdateInstallGuide.tsx index 81fadd3b1d..e615c10a86 100644 --- a/frontend-modern/src/components/Settings/UpdateInstallGuide.tsx +++ b/frontend-modern/src/components/Settings/UpdateInstallGuide.tsx @@ -57,7 +57,7 @@ function InstallStep(props: { step: UpdateInstallStep; index: number }) { containerClass="ml-0 sm:ml-8 relative group" codeClass={ props.step.commandCodeClass ?? - 'block rounded-md border border-border bg-base p-3 font-mono text-sm text-green-400' + 'block rounded-md border border-border bg-page p-3 font-mono text-sm text-green-700 dark:text-green-400' } /> @@ -181,7 +181,7 @@ export const UpdateInstallGuide: Component = (props) =>

      Not using Compose?{' '} diff --git a/frontend-modern/src/components/Settings/__tests__/updatesSettingsModel.branchcov0712.test.ts b/frontend-modern/src/components/Settings/__tests__/updatesSettingsModel.branchcov0712.test.ts index ef808ed5a4..d51154749d 100644 --- a/frontend-modern/src/components/Settings/__tests__/updatesSettingsModel.branchcov0712.test.ts +++ b/frontend-modern/src/components/Settings/__tests__/updatesSettingsModel.branchcov0712.test.ts @@ -54,9 +54,9 @@ const makeDockerUpdate = (overrides: Partial = {}): Docker }); const PRO_STEP_CODE_CLASS = - 'block rounded-md border border-border bg-base p-3 font-mono text-sm text-green-400 whitespace-pre-wrap break-all'; + 'block rounded-md border border-border bg-page p-3 font-mono text-sm text-green-700 dark:text-green-400 whitespace-pre-wrap break-all'; const SYSTEMD_DOWNLOAD_CODE_CLASS = - 'block rounded-md border border-border bg-base p-3 font-mono text-sm text-base-content whitespace-pre-wrap break-all'; + 'block rounded-md border border-border bg-page p-3 font-mono text-sm text-base-content whitespace-pre-wrap break-all'; // ---- buildIdleDockerComposeCommand ----------------------------------------- // Single return path; assert the exact constant. diff --git a/frontend-modern/src/components/Settings/__tests__/updatesSettingsModel.branchcov0712c.test.ts b/frontend-modern/src/components/Settings/__tests__/updatesSettingsModel.branchcov0712c.test.ts index bb39fdc2ef..a216fee840 100644 --- a/frontend-modern/src/components/Settings/__tests__/updatesSettingsModel.branchcov0712c.test.ts +++ b/frontend-modern/src/components/Settings/__tests__/updatesSettingsModel.branchcov0712c.test.ts @@ -52,7 +52,7 @@ const makeDockerUpdate = (overrides: Partial = {}): Docker }); const PRO_STEP_CODE_CLASS = - 'block rounded-md border border-border bg-base p-3 font-mono text-sm text-green-400 whitespace-pre-wrap break-all'; + 'block rounded-md border border-border bg-page p-3 font-mono text-sm text-green-700 dark:text-green-400 whitespace-pre-wrap break-all'; // ---- buildUpdateInstallGuide (complementary branch-coverage) ---------------- diff --git a/frontend-modern/src/components/Settings/updatesSettingsModel.ts b/frontend-modern/src/components/Settings/updatesSettingsModel.ts index 4efc9ca918..46629dc86d 100644 --- a/frontend-modern/src/components/Settings/updatesSettingsModel.ts +++ b/frontend-modern/src/components/Settings/updatesSettingsModel.ts @@ -70,14 +70,14 @@ function buildProDockerUpdateSteps(dockerUpdate: DockerUpdateCommands): UpdateIn title: 'Pull the new Pulse Pro image (pinned to this release’s digest)', command: dockerUpdate.composePullCommand, commandCodeClass: - 'block rounded-md border border-border bg-base p-3 font-mono text-sm text-green-400 whitespace-pre-wrap break-all', + 'block rounded-md border border-border bg-page p-3 font-mono text-sm text-green-700 dark:text-green-400 whitespace-pre-wrap break-all', }, { id: 'docker-pro-up', title: 'Recreate the container on the new image', command: dockerUpdate.composeUpCommand, commandCodeClass: - 'block rounded-md border border-border bg-base p-3 font-mono text-sm text-green-400 whitespace-pre-wrap break-all', + 'block rounded-md border border-border bg-page p-3 font-mono text-sm text-green-700 dark:text-green-400 whitespace-pre-wrap break-all', }, ]; if (dockerUpdate.loginCommand) { @@ -192,7 +192,7 @@ export function buildUpdateInstallGuide( title: 'Download and extract the new version', command: systemdDownloadCommand, commandCodeClass: - 'block rounded-md border border-border bg-base p-3 font-mono text-sm text-base-content whitespace-pre-wrap break-all', + 'block rounded-md border border-border bg-page p-3 font-mono text-sm text-base-content whitespace-pre-wrap break-all', }, { id: 'systemd-start', title: 'Start the service', command: 'sudo systemctl start pulse' }, ], diff --git a/frontend-modern/src/components/SetupWizard/SetupWizard.tsx b/frontend-modern/src/components/SetupWizard/SetupWizard.tsx index 31f303501a..decd560ced 100644 --- a/frontend-modern/src/components/SetupWizard/SetupWizard.tsx +++ b/frontend-modern/src/components/SetupWizard/SetupWizard.tsx @@ -67,11 +67,7 @@ export const SetupWizard: Component = (props) => { ]); return ( -

      +
      {/* Background decoration */} diff --git a/frontend-modern/src/components/SetupWizard/steps/SecurityStep.tsx b/frontend-modern/src/components/SetupWizard/steps/SecurityStep.tsx index 9bd832abf9..35716c367c 100644 --- a/frontend-modern/src/components/SetupWizard/steps/SecurityStep.tsx +++ b/frontend-modern/src/components/SetupWizard/steps/SecurityStep.tsx @@ -229,7 +229,7 @@ export const SecurityStep: Component = (props) => {
      -
      +
      setShareUsageStatistics(!shareUsageStatistics())} @@ -238,7 +238,7 @@ export const SecurityStep: Component = (props) => { />
      -
      +
      {t('setup.security.nextScreen.title')}
      @@ -250,7 +250,7 @@ export const SecurityStep: Component = (props) => {
      {/* Actions */} -
      +
      diff --git a/frontend-modern/src/components/patrol/RunToolCallTrace.tsx b/frontend-modern/src/components/patrol/RunToolCallTrace.tsx index d1bc4ec145..0ecf3ac165 100644 --- a/frontend-modern/src/components/patrol/RunToolCallTrace.tsx +++ b/frontend-modern/src/components/patrol/RunToolCallTrace.tsx @@ -200,7 +200,7 @@ export const RunToolCallTrace: Component = (props) => {
      Input
      -
      +                              
                                       {truncate(call.input, 500)}
                                     
      @@ -208,7 +208,7 @@ export const RunToolCallTrace: Component = (props) => {
      Output
      -
      +                              
                                       {truncate(call.output, 500)}
                                     
      diff --git a/frontend-modern/src/components/shared/Card.tsx b/frontend-modern/src/components/shared/Card.tsx index b281bb01a1..f84b58505b 100644 --- a/frontend-modern/src/components/shared/Card.tsx +++ b/frontend-modern/src/components/shared/Card.tsx @@ -1,6 +1,6 @@ import { JSX, splitProps, mergeProps } from 'solid-js'; -type Tone = 'default' | 'muted' | 'info' | 'success' | 'warning' | 'danger' | 'card' | 'glass'; +type Tone = 'default' | 'muted' | 'info' | 'success' | 'warning' | 'danger' | 'card'; type Padding = 'none' | 'sm' | 'md' | 'lg'; export type CardProps = { @@ -12,13 +12,12 @@ export type CardProps = { const toneClassMap: Record = { default: 'bg-surface', - muted: 'bg-base', + muted: 'bg-surface-alt', info: 'bg-blue-50 dark:bg-blue-900/25', success: 'bg-emerald-50 dark:bg-emerald-900/25', warning: 'bg-amber-50 dark:bg-amber-900/25', danger: 'bg-red-50 dark:bg-red-900/25', card: 'bg-surface', - glass: 'bg-base', }; const paddingClassMap: Record = { diff --git a/frontend-modern/src/components/shared/CommandPaletteModal.tsx b/frontend-modern/src/components/shared/CommandPaletteModal.tsx index c155a5283b..22aac7f70a 100644 --- a/frontend-modern/src/components/shared/CommandPaletteModal.tsx +++ b/frontend-modern/src/components/shared/CommandPaletteModal.tsx @@ -39,7 +39,6 @@ export function CommandPaletteModal(props: CommandPaletteModalProps) { onKeyDown={commandPalette.handleInputKeyDown} placeholder="Type a command or search..." class="w-full" - inputClass="bg-base" clearOnFocusedEscape={false} shortcutHint="Cmd+K" role="combobox" @@ -84,7 +83,7 @@ export function CommandPaletteModal(props: CommandPaletteModalProps) {
      - + {command.shortcut} diff --git a/frontend-modern/src/components/shared/EmptyState.tsx b/frontend-modern/src/components/shared/EmptyState.tsx index 10aa30da90..982c331e74 100644 --- a/frontend-modern/src/components/shared/EmptyState.tsx +++ b/frontend-modern/src/components/shared/EmptyState.tsx @@ -34,7 +34,7 @@ export function EmptyState(props: EmptyStateProps) { const containerClass = [ 'flex w-full animate-fade-in flex-col', variant === 'framed' - ? 'rounded-md border border-dashed border-border bg-base px-6 py-10 sm:px-8 sm:py-16' + ? 'rounded-md border border-dashed border-border px-6 py-10 sm:px-8 sm:py-16' : 'px-4 py-8', alignment === 'center' ? 'items-center text-center' : 'items-start text-left', local.class ?? '', diff --git a/frontend-modern/src/components/shared/filterButtonGroupModel.ts b/frontend-modern/src/components/shared/filterButtonGroupModel.ts index c406f6fb7b..043e8f4ec9 100644 --- a/frontend-modern/src/components/shared/filterButtonGroupModel.ts +++ b/frontend-modern/src/components/shared/filterButtonGroupModel.ts @@ -39,7 +39,7 @@ const groupClassByVariant: Record = { 'inline-flex items-center gap-1 bg-surface-hover rounded-md p-0.5 ring-1 ring-border-subtle overflow-x-auto scrollbar-hide', prominent: 'grid grid-cols-1 gap-2', segmented: - 'flex items-center gap-1 rounded-md border border-border bg-base p-1 shadow-inner overflow-x-auto scrollbar-hide', + 'flex items-center gap-1 rounded-md border border-border bg-page p-1 shadow-inner overflow-x-auto scrollbar-hide', }; const labelClassByVariant: Partial> = { diff --git a/frontend-modern/src/features/alerts/AlertDeadManDestinationSection.tsx b/frontend-modern/src/features/alerts/AlertDeadManDestinationSection.tsx index c04ad89bd7..3dc701bdd4 100644 --- a/frontend-modern/src/features/alerts/AlertDeadManDestinationSection.tsx +++ b/frontend-modern/src/features/alerts/AlertDeadManDestinationSection.tsx @@ -15,7 +15,10 @@ interface AlertDeadManDestinationSectionProps { const REDACTED_PING_URL = '***REDACTED***'; const statusPresentation: Record = { - disabled: { label: 'Not configured', class: 'bg-base text-muted' }, + disabled: { + label: 'Not configured', + class: 'bg-surface text-muted ring-1 ring-inset ring-border', + }, starting: { label: 'Starting', class: 'bg-blue-100 text-blue-800 dark:bg-blue-900/25 dark:text-blue-100', @@ -153,7 +156,7 @@ export function AlertDeadManDestinationSection(props: AlertDeadManDestinationSec {(current) => ( -
      +
      Last success
      diff --git a/frontend-modern/src/index.css b/frontend-modern/src/index.css index e2b4d75377..1a512157dc 100644 --- a/frontend-modern/src/index.css +++ b/frontend-modern/src/index.css @@ -97,6 +97,15 @@ } } +/* The page backdrop as a background, for wells inside a surface card (code + blocks, previews, segmented-control tracks) that should read as the page + behind the card. It is a utility rather than a theme colour on purpose: a + colour named `base` also gave `text-base` a colour and painted text in the + page colour, and without that colour the old class rendered nothing. */ +@utility bg-page { + background-color: var(--color-bg-base); +} + @utility animate-slideDown { animation: slideDown 0.3s ease-out; }