diff --git a/CHANGELOG b/CHANGELOG
index 5815f9e..e8d53b2 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
---
+## [Unreleased]
+
+### Added
+- Announcement banner at the top of LaunchMap visualizer with localStorage persistence
+
## [0.2.0] - 2025-08-23
### Added
diff --git a/src/panel/getWebviewHtml.ts b/src/panel/getWebviewHtml.ts
index 864a116..b496af3 100644
--- a/src/panel/getWebviewHtml.ts
+++ b/src/panel/getWebviewHtml.ts
@@ -38,6 +38,10 @@ export function getWebviewHtml(
+
+ 💬 Join our Discord
+
+
diff --git a/webview/script.js b/webview/script.js
index 12b0f3c..7639559 100644
--- a/webview/script.js
+++ b/webview/script.js
@@ -27,3 +27,19 @@ const vscode = acquireVsCodeApi();
document.getElementById('export-btn')?.addEventListener('click', () => {
vscode.postMessage({ type: 'export-json' });
});
+
+// Announcement Banner Logic
+const announcementBanner = document.getElementById('announcement-banner');
+const dismissButton = document.getElementById('dismiss-banner');
+
+// Check if banner was previously dismissed
+const bannerDismissed = localStorage.getItem('announcementBannerDismissed');
+if (bannerDismissed === 'true') {
+ announcementBanner?.classList.add('hidden');
+}
+
+// Handle dismiss button click
+dismissButton?.addEventListener('click', () => {
+ announcementBanner?.classList.add('hidden');
+ localStorage.setItem('announcementBannerDismissed', 'true');
+});
diff --git a/webview/styles/base.css b/webview/styles/base.css
index 201e7fc..d069004 100644
--- a/webview/styles/base.css
+++ b/webview/styles/base.css
@@ -1,45 +1,52 @@
-#editor {
- width: 100%;
- height: 100vh;
- background-color: #1e1e1e;
- color: white;
- position: relative;
- overflow: scroll;
- font-family: monospace;
- margin-top: 40px;
-}
-
-#export-btn {
+/* Announcement Banner */
+.announcement-banner {
position: fixed;
- top: 12px;
- right: 12px;
- z-index: 1000;
- background: linear-gradient(145deg, #0e61a9, #0a3f6b);
- color: #ffffff;
- border: 2px solid #1c90f3;
- border-radius: 8px;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 1001;
+ background: linear-gradient(145deg, #f0f4f8, #e1e8ed);
+ color: #2c3e50;
+ padding: 12px 20px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-bottom: 1px solid #b0c4d4;
+ border-radius: 0 0 8px 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
font-size: 14px;
- font-weight: bold;
- padding: 8px 14px;
- box-shadow: 0 0 8px rgba(28, 144, 243, 0.4);
- transition: all 0.2s ease;
- cursor: pointer;
+ font-weight: 500;
+ transition: opacity 0.3s ease, transform 0.3s ease;
}
-#export-btn:hover {
- background: linear-gradient(145deg, #1287e2, #0b5185);
- box-shadow: 0 0 12px rgba(28, 144, 243, 0.6);
- transform: translateY(-1px);
+.announcement-banner.hidden {
+ display: none;
}
-#export-btn:active {
- transform: translateY(0);
- box-shadow: 0 0 6px rgba(28, 144, 243, 0.3);
+.announcement-text {
+ flex: 1;
+ text-align: center;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
}
-#zoom-layer {
- transform-origin: 0 0;
- will-change: transform;
+.dismiss-btn {
+ background: transparent;
+ border: none;
+ color: #95a5a6;
+ font-size: 16px;
+ cursor: pointer;
+ padding: 4px 8px;
+ transition: color 0.2s ease, transform 0.2s ease;
+ margin-left: 12px;
+}
+
+.dismiss-btn:hover {
+ color: #e74c3c;
+ transform: scale(1.1);
+}
+
+.dismiss-btn:active {
+ transform: scale(0.95);
}
#editor {