diff --git a/src/engineering_platform/assets/dashboard.css b/src/engineering_platform/assets/dashboard.css
index f241d4b8..3d4bd533 100644
--- a/src/engineering_platform/assets/dashboard.css
+++ b/src/engineering_platform/assets/dashboard.css
@@ -1119,7 +1119,7 @@ html[data-theme="light"] .dashboard-status-banner--provider-auth_required .provi
/* The absence of a selected project is neutral context, kept visible with
the other operational banners rather than as a scrolling dashboard card. */
-.dashboard-sticky-header:has(#noProjectSelected){padding-bottom:7px}.dashboard-status-banner--no-project{align-items:center;background:#163b59;border-bottom:1px solid #62bdf0;color:#e7f5ff;font:600 13px/1.45 system-ui}.dashboard-status-banner--no-project strong{color:#9bd7ff}html[data-theme="light"] .dashboard-status-banner--no-project{background:#e2f3ff;color:#12466b}html[data-theme="light"] .dashboard-status-banner--no-project strong{color:#075985}
+.dashboard-sticky-header:has(#noProjectSelected:not([hidden])){padding-bottom:7px}.dashboard-status-banner--no-project{align-items:center;background:#163b59;border-bottom:1px solid #62bdf0;color:#e7f5ff;font:600 13px/1.45 system-ui}.dashboard-status-banner--no-project strong{color:#9bd7ff}.no-project-selected__dismiss{align-items:center;background:transparent!important;border:1px solid currentColor!important;border-radius:50%;color:inherit!important;cursor:pointer;display:inline-flex;flex:none;font:22px/1 system-ui;height:30px;justify-content:center;margin-left:auto;min-height:30px;min-width:30px;padding:0;width:30px}.no-project-selected__dismiss:hover,.no-project-selected__dismiss:focus-visible{background:#9bd7ff!important;border-color:#9bd7ff!important;color:#123a58!important}.no-project-selected__dismiss:focus-visible{box-shadow:0 0 0 4px #9bd7ff55!important;outline:2px solid #9bd7ff!important;outline-offset:2px!important}html[data-theme="light"] .dashboard-status-banner--no-project{background:#e2f3ff;color:#12466b}html[data-theme="light"] .dashboard-status-banner--no-project strong{color:#075985}html[data-theme="light"] .no-project-selected__dismiss:hover,html[data-theme="light"] .no-project-selected__dismiss:focus-visible{background:#075985!important;border-color:#075985!important;color:#fff!important}
/* Managed PR evidence remains a normal link, positioned under execution
context so both current and historical operational context stay scannable. */
diff --git a/src/engineering_platform/assets/dashboard.js b/src/engineering_platform/assets/dashboard.js
index 6c0d6a48..30b8bda5 100644
--- a/src/engineering_platform/assets/dashboard.js
+++ b/src/engineering_platform/assets/dashboard.js
@@ -5832,6 +5832,20 @@ document.addEventListener("pointerdown", (event) => {
const workspaceLocation = document.querySelector('[data-workspace-label="ui.workspace_location"] + pre');
replaceWithLocalFilesystemLink(workspaceLocation);
replaceWithLocalFilesystemLink($("rateLimitProviderPath"));
+const noProjectDismissalStorageKey = "engineering-platform.no-project-selected.dismissed.v1";
+function initializeNoProjectSelectedBanner() {
+ const banner = $("noProjectSelected"), dismiss = $("noProjectSelectedDismiss");
+ if (!banner || !dismiss || dismiss.dataset.dismissBound) return;
+ dismiss.dataset.dismissBound = "true";
+ try {
+ banner.hidden = localStorage.getItem(noProjectDismissalStorageKey) === "true";
+ } catch {}
+ dismiss.addEventListener("click", () => {
+ banner.hidden = true;
+ try { localStorage.setItem(noProjectDismissalStorageKey, "true"); } catch {}
+ });
+}
+initializeNoProjectSelectedBanner();
applyDashboardLocale();
let dashboardConfiguration = {}, dashboardConfigurationLoaded = false;
const configurationFields = Object.freeze({
diff --git a/src/engineering_platform/server.py b/src/engineering_platform/server.py
index 7097287e..da8ceadd 100644
--- a/src/engineering_platform/server.py
+++ b/src/engineering_platform/server.py
@@ -2171,7 +2171,7 @@ def _no_project_console_document(projects: list[dict[str, str]], data_root: Path
options = _console_project_options(None, projects)
selector = f''''''
boundary = ''''''.replace("$CENTRAL_DATABASE_SCRIPT", _central_database_script())
- empty_state = ''''''
+ empty_state = ''''''
scoped_style = '''