specsmd 0.1.68 → 0.1.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -634,6 +634,50 @@ function getOverviewViewHtml(data) {
634
634
  `).join('') : '<div class="empty-state"><div class="empty-state-text">No standards defined</div></div>'}
635
635
  </div>
636
636
  </div>
637
+ <div class="overview-resources-footer">
638
+ <div class="overview-fabriqa-card">
639
+ <div class="overview-fabriqa-brand">
640
+ <div class="overview-fabriqa-mark">FA</div>
641
+ <div>
642
+ <div class="overview-fabriqa-title">specs.md by Fabriqa.AI</div>
643
+ <div class="overview-fabriqa-subtitle">Spec-native agentic development environment</div>
644
+ </div>
645
+ </div>
646
+ <div class="overview-fabriqa-copy">
647
+ Use Fabriqa.AI with your existing AI subscription to design, run, and reuse agentic workflows around your specs. It is free to try.
648
+ </div>
649
+ <div class="overview-fabriqa-actions">
650
+ <div class="overview-fabriqa-link" data-url="https://fabriqa.ai">Explore Fabriqa.AI</div>
651
+ <div class="overview-fabriqa-link secondary" data-url="https://specs.md">Open specs.md</div>
652
+ </div>
653
+ </div>
654
+ <div class="overview-dashboard-tip">
655
+ <div>
656
+ <div class="overview-dashboard-title">Did you know?</div>
657
+ <div class="overview-dashboard-copy">
658
+ You can use the specsmd dashboard outside VS Code and VS Code variants. Run this from your project folder:
659
+ </div>
660
+ <code>npx specsmd@latest dashboard</code>
661
+ </div>
662
+ <div class="overview-fabriqa-link secondary" data-url="https://specs.md/getting-started/cli-dashboard">Dashboard docs</div>
663
+ </div>
664
+ <div class="overview-resources-title">Community</div>
665
+ <div class="overview-resources-links">
666
+ <div class="overview-resource-link" data-url="https://discord.specs.md" title="Discord">
667
+ <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
668
+ <path fill="currentColor" d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/>
669
+ </svg>
670
+ </div>
671
+ <div class="overview-resource-link" data-url="https://x.com/specsmd" title="X (Twitter)">
672
+ <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
673
+ <path fill="currentColor" d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
674
+ </svg>
675
+ </div>
676
+ </div>
677
+ <div class="overview-feedback-message">
678
+ We're new! Help us improve — <span class="overview-feedback-link" data-url="https://specs.md/feedback">share your feedback</span>
679
+ </div>
680
+ </div>
637
681
  </div>`;
638
682
  }
639
683
 
@@ -1,5 +1,43 @@
1
1
  (function () {
2
+ var themeKey = 'specsmd:webview-state';
3
+
4
+ function readTheme() {
5
+ try {
6
+ var stored = localStorage.getItem(themeKey);
7
+ if (stored === '"dark"' || stored === 'dark') {
8
+ return 'dark';
9
+ }
10
+ if (stored === '"light"' || stored === 'light') {
11
+ return 'light';
12
+ }
13
+ var parsed = JSON.parse(stored);
14
+ if (parsed === 'dark' || parsed === 'light') {
15
+ return parsed;
16
+ }
17
+ } catch (error) {
18
+ return 'dark';
19
+ }
20
+
21
+ return window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches
22
+ ? 'light'
23
+ : 'dark';
24
+ }
25
+
26
+ function applyTheme(theme) {
27
+ document.documentElement.dataset.theme = theme;
28
+ document.documentElement.style.colorScheme = theme;
29
+ }
30
+
2
31
  document.documentElement.dataset.host = 'dashboard-web';
32
+ applyTheme(readTheme());
33
+
34
+ window.addEventListener('storage', function (event) {
35
+ if (event.key !== themeKey) {
36
+ return;
37
+ }
38
+
39
+ applyTheme(readTheme());
40
+ });
3
41
 
4
42
  window.addEventListener('message', function (event) {
5
43
  if (event.data && event.data.type === 'setData') {
@@ -8,7 +8,7 @@
8
8
  </head>
9
9
  <body>
10
10
  <specsmd-app></specsmd-app>
11
- <script src="/webview-bundle.js"></script>
12
11
  <script src="/app.js"></script>
12
+ <script src="/webview-bundle.js"></script>
13
13
  </body>
14
14
  </html>
@@ -1,5 +1,8 @@
1
1
  :root {
2
- color-scheme: dark;
2
+ color-scheme: var(--specsmd-color-scheme, dark);
3
+ }
4
+
5
+ :root[data-theme="dark"] {
3
6
  --vscode-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
4
7
  --vscode-font-size: 13px;
5
8
  --vscode-foreground: #cccccc;
@@ -9,9 +12,36 @@
9
12
  --vscode-sideBarSectionHeader-background: #2d2d30;
10
13
  --vscode-sideBarSectionHeader-border: #454545;
11
14
  --vscode-input-background: #3c3c3c;
15
+ --vscode-input-border: #3f3f46;
12
16
  --vscode-list-hoverBackground: #2a2d2e;
17
+ --vscode-list-activeSelectionBackground: #094771;
18
+ --vscode-badge-background: #4d4d4d;
19
+ --vscode-badge-foreground: #ffffff;
20
+ --vscode-button-background: #0e639c;
21
+ --vscode-button-foreground: #ffffff;
22
+ --vscode-scrollbarSlider-background: #686868;
23
+ --specsmd-color-scheme: dark;
24
+ }
25
+
26
+ :root[data-theme="light"] {
27
+ --vscode-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
28
+ --vscode-font-size: 13px;
29
+ --vscode-foreground: #1f2328;
30
+ --vscode-descriptionForeground: #57606a;
31
+ --vscode-sideBar-background: #f6f8fa;
32
+ --vscode-editor-background: #ffffff;
33
+ --vscode-sideBarSectionHeader-background: #eef2f7;
34
+ --vscode-sideBarSectionHeader-border: #d0d7de;
35
+ --vscode-input-background: #ffffff;
36
+ --vscode-input-border: #d0d7de;
37
+ --vscode-list-hoverBackground: #eef2f7;
38
+ --vscode-list-activeSelectionBackground: #dbeafe;
39
+ --vscode-badge-background: #d0d7de;
40
+ --vscode-badge-foreground: #24292f;
13
41
  --vscode-button-background: #0e639c;
14
42
  --vscode-button-foreground: #ffffff;
43
+ --vscode-scrollbarSlider-background: #b6c2cf;
44
+ --specsmd-color-scheme: light;
15
45
  }
16
46
 
17
47
  html,
@@ -604,6 +604,114 @@
604
604
  }
605
605
 
606
606
  // src/webview/styles/theme.ts
607
+ var THEME_STORAGE_KEY = "specsmd:webview-theme";
608
+ var THEME_PALETTES = {
609
+ dark: {
610
+ "--vscode-foreground": "#cccccc",
611
+ "--vscode-descriptionForeground": "#8b8b8b",
612
+ "--vscode-sideBar-background": "#252526",
613
+ "--vscode-editor-background": "#1e1e1e",
614
+ "--vscode-sideBarSectionHeader-background": "#2d2d30",
615
+ "--vscode-sideBarSectionHeader-border": "#454545",
616
+ "--vscode-input-background": "#3c3c3c",
617
+ "--vscode-input-border": "#3f3f46",
618
+ "--vscode-list-hoverBackground": "#2a2d2e",
619
+ "--vscode-list-activeSelectionBackground": "#094771",
620
+ "--vscode-badge-background": "#4d4d4d",
621
+ "--vscode-badge-foreground": "#ffffff",
622
+ "--vscode-button-background": "#0e639c",
623
+ "--vscode-button-foreground": "#ffffff",
624
+ "--vscode-scrollbarSlider-background": "#686868",
625
+ "--vscode-font-family": "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
626
+ "--vscode-font-size": "13px",
627
+ "--specsmd-color-scheme": "dark",
628
+ "--specsmd-surface-glow": "rgba(249, 115, 22, 0.05)"
629
+ },
630
+ light: {
631
+ "--vscode-foreground": "#1f2328",
632
+ "--vscode-descriptionForeground": "#57606a",
633
+ "--vscode-sideBar-background": "#f6f8fa",
634
+ "--vscode-editor-background": "#ffffff",
635
+ "--vscode-sideBarSectionHeader-background": "#eef2f7",
636
+ "--vscode-sideBarSectionHeader-border": "#d0d7de",
637
+ "--vscode-input-background": "#ffffff",
638
+ "--vscode-input-border": "#d0d7de",
639
+ "--vscode-list-hoverBackground": "#eef2f7",
640
+ "--vscode-list-activeSelectionBackground": "#dbeafe",
641
+ "--vscode-badge-background": "#d0d7de",
642
+ "--vscode-badge-foreground": "#24292f",
643
+ "--vscode-button-background": "#0e639c",
644
+ "--vscode-button-foreground": "#ffffff",
645
+ "--vscode-scrollbarSlider-background": "#b6c2cf",
646
+ "--vscode-font-family": "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
647
+ "--vscode-font-size": "13px",
648
+ "--specsmd-color-scheme": "light",
649
+ "--specsmd-surface-glow": "rgba(14, 99, 156, 0.06)"
650
+ }
651
+ };
652
+ function isThemeMode(value) {
653
+ return value === "dark" || value === "light";
654
+ }
655
+ function getThemeRoot(target) {
656
+ if (typeof document === "undefined") {
657
+ return null;
658
+ }
659
+ if (!target) {
660
+ return document.documentElement;
661
+ }
662
+ if (target instanceof Document) {
663
+ return target.documentElement;
664
+ }
665
+ return target;
666
+ }
667
+ function readStoredTheme() {
668
+ if (typeof window === "undefined" || typeof localStorage === "undefined") {
669
+ return null;
670
+ }
671
+ try {
672
+ const stored = localStorage.getItem(THEME_STORAGE_KEY);
673
+ return isThemeMode(stored) ? stored : null;
674
+ } catch {
675
+ return null;
676
+ }
677
+ }
678
+ function getSystemTheme() {
679
+ if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
680
+ return window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
681
+ }
682
+ return "dark";
683
+ }
684
+ function getInitialTheme(state2) {
685
+ if (isThemeMode(state2)) {
686
+ return state2;
687
+ }
688
+ const stored = readStoredTheme();
689
+ if (stored) {
690
+ return stored;
691
+ }
692
+ return getSystemTheme();
693
+ }
694
+ function persistTheme(theme) {
695
+ if (typeof window === "undefined" || typeof localStorage === "undefined") {
696
+ return;
697
+ }
698
+ try {
699
+ localStorage.setItem(THEME_STORAGE_KEY, theme);
700
+ } catch {
701
+ }
702
+ }
703
+ function applyTheme(theme, target) {
704
+ const root = getThemeRoot(target);
705
+ if (!root) {
706
+ return;
707
+ }
708
+ const palette = THEME_PALETTES[theme];
709
+ for (const [name, value] of Object.entries(palette)) {
710
+ root.style.setProperty(name, value);
711
+ }
712
+ root.dataset.theme = theme;
713
+ root.style.setProperty("color-scheme", palette["--specsmd-color-scheme"]);
714
+ }
607
715
  var themeStyles = i`
608
716
  :host {
609
717
  /* VS Code font */
@@ -623,6 +731,8 @@
623
731
  --status-active: #f97316;
624
732
  --status-pending: #6b7280;
625
733
  --status-blocked: #ef4444;
734
+
735
+ color-scheme: var(--specsmd-color-scheme, dark);
626
736
  }
627
737
  `;
628
738
  var resetStyles = i`
@@ -6497,8 +6607,17 @@
6497
6607
 
6498
6608
  // src/webview/vscode-api.ts
6499
6609
  function createStandaloneApi() {
6610
+ const stateKey = "specsmd:webview-state";
6500
6611
  let state2 = null;
6501
6612
  let eventsConnected = false;
6613
+ try {
6614
+ const stored = typeof localStorage !== "undefined" ? localStorage.getItem(stateKey) : null;
6615
+ if (stored !== null) {
6616
+ state2 = JSON.parse(stored);
6617
+ }
6618
+ } catch {
6619
+ state2 = null;
6620
+ }
6502
6621
  const connectEvents = () => {
6503
6622
  if (eventsConnected || typeof EventSource !== "function") {
6504
6623
  return;
@@ -6537,6 +6656,12 @@
6537
6656
  },
6538
6657
  setState(nextState) {
6539
6658
  state2 = nextState;
6659
+ try {
6660
+ if (typeof localStorage !== "undefined") {
6661
+ localStorage.setItem(stateKey, JSON.stringify(nextState));
6662
+ }
6663
+ } catch {
6664
+ }
6540
6665
  }
6541
6666
  };
6542
6667
  }
@@ -6555,6 +6680,7 @@
6555
6680
  this._availableFlows = [];
6556
6681
  this._fireData = null;
6557
6682
  this._fireActiveTab = "runs";
6683
+ this._theme = "dark";
6558
6684
  /**
6559
6685
  * Version counter for specs HTML to track when handlers need reattachment.
6560
6686
  * Incremented each time _specsHtml changes.
@@ -6650,6 +6776,9 @@
6650
6776
  }
6651
6777
  connectedCallback() {
6652
6778
  super.connectedCallback();
6779
+ this._theme = getInitialTheme(vscode.getState());
6780
+ this._applyTheme(this._theme);
6781
+ vscode.setState(this._theme);
6653
6782
  window.addEventListener("message", this._handleMessage);
6654
6783
  vscode.postMessage({ type: "ready" });
6655
6784
  }
@@ -6759,7 +6888,7 @@
6759
6888
  }
6760
6889
  });
6761
6890
  });
6762
- overviewView.querySelectorAll(".overview-resource-link").forEach((link) => {
6891
+ overviewView.querySelectorAll(".overview-resource-link, .overview-fabriqa-link").forEach((link) => {
6763
6892
  const htmlLink = link;
6764
6893
  link.addEventListener("click", () => {
6765
6894
  const url = htmlLink.dataset.url;
@@ -6799,11 +6928,44 @@
6799
6928
  }
6800
6929
  render() {
6801
6930
  if (!this._loaded) {
6802
- return b2`<div class="loading">Loading...</div>`;
6931
+ return b2`
6932
+ <div class="shell">
6933
+ <div class="shell-chrome">
6934
+ <div class="shell-brand">
6935
+ <span class="shell-mark">⚡</span>
6936
+ <div class="shell-brand-copy">
6937
+ <div class="shell-title">SpecsMD</div>
6938
+ <div class="shell-subtitle">Loading dashboard</div>
6939
+ </div>
6940
+ </div>
6941
+ <div class="shell-actions">
6942
+ ${this._renderThemeToggle()}
6943
+ </div>
6944
+ </div>
6945
+ <div class="loading">Loading...</div>
6946
+ </div>
6947
+ `;
6803
6948
  }
6804
6949
  const isFireFlow = this._activeFlow?.id === "fire";
6805
6950
  return b2`
6806
- ${isFireFlow ? this._renderFireApp() : this._renderAidlcApp()}
6951
+ <div class="shell">
6952
+ <div class="shell-chrome">
6953
+ <div class="shell-brand">
6954
+ <span class="shell-mark">⚡</span>
6955
+ <div class="shell-brand-copy">
6956
+ <div class="shell-title">SpecsMD</div>
6957
+ <div class="shell-subtitle">${isFireFlow ? "FIRE dashboard" : "AI-DLC dashboard"}</div>
6958
+ </div>
6959
+ </div>
6960
+ <div class="shell-actions">
6961
+ ${this._renderThemeToggle()}
6962
+ </div>
6963
+ </div>
6964
+
6965
+ <div class="app-body">
6966
+ ${isFireFlow ? this._renderFireApp() : this._renderAidlcApp()}
6967
+ </div>
6968
+ </div>
6807
6969
  `;
6808
6970
  }
6809
6971
  /**
@@ -6893,6 +7055,28 @@
6893
7055
  ></fire-view>
6894
7056
  `;
6895
7057
  }
7058
+ /**
7059
+ * Render the theme toggle control.
7060
+ */
7061
+ _renderThemeToggle() {
7062
+ const isDark = this._theme === "dark";
7063
+ const nextTheme = isDark ? "light" : "dark";
7064
+ const label = isDark ? "Light" : "Dark";
7065
+ const title = `Switch to ${nextTheme} mode`;
7066
+ const icon = isDark ? w`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 8.25A3.75 3.75 0 1 0 12 15.75 3.75 3.75 0 0 0 12 8.25Zm0-6a1 1 0 0 1 1 1.06l-.05 1.94a1 1 0 1 1-2 0l-.05-1.94A1 1 0 0 1 12 2.25Zm0 16.5a1 1 0 0 1 1 1.06l-.05 1.94a1 1 0 1 1-2 0l-.05-1.94a1 1 0 0 1 1.05-1.06Zm10.5-6a1 1 0 0 1-1.06 1l-1.94-.05a1 1 0 1 1 0-2l1.94-.05a1 1 0 0 1 1.06 1.1ZM4.5 12a1 1 0 0 1-1.06 1l-1.94-.05a1 1 0 1 1 0-2l1.94-.05A1 1 0 0 1 4.5 12Zm14.45-7.95a1 1 0 0 1 .04 1.41l-1.37 1.37a1 1 0 1 1-1.41-1.41l1.37-1.37a1 1 0 0 1 1.37 0Zm-11.14 11.1a1 1 0 0 1 .04 1.41l-1.37 1.37a1 1 0 1 1-1.41-1.41l1.37-1.37a1 1 0 0 1 1.37 0Zm11.14 2.78a1 1 0 0 1-1.41.04l-1.37-1.37a1 1 0 1 1 1.41-1.41l1.37 1.37a1 1 0 0 1 0 1.37ZM7.81 7.81a1 1 0 0 1-1.41.04L5.03 6.48a1 1 0 1 1 1.41-1.41l1.37 1.37a1 1 0 0 1 0 1.37Z"/></svg>` : w`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21.75 14.2A9.7 9.7 0 0 1 9.8 2.25a1 1 0 0 0-1.16 1.16 8.5 8.5 0 1 0 12.95 11.95 1 1 0 0 0 .16-1.16Z"/></svg>`;
7067
+ return b2`
7068
+ <button
7069
+ class="theme-toggle"
7070
+ type="button"
7071
+ title=${title}
7072
+ aria-label=${title}
7073
+ @click=${this._toggleTheme}
7074
+ >
7075
+ <span class="theme-toggle-icon">${icon}</span>
7076
+ <span class="theme-toggle-text">${label}</span>
7077
+ </button>
7078
+ `;
7079
+ }
6896
7080
  // ==================== FIRE Event Handlers ====================
6897
7081
  _handleFireTabChange(e7) {
6898
7082
  this._fireActiveTab = e7.detail.tab;
@@ -6932,6 +7116,21 @@
6932
7116
  _handleFlowSwitch(e7) {
6933
7117
  vscode.postMessage({ type: "switchFlow" });
6934
7118
  }
7119
+ /**
7120
+ * Toggle the dashboard theme and persist it locally.
7121
+ */
7122
+ _toggleTheme() {
7123
+ this._theme = this._theme === "dark" ? "light" : "dark";
7124
+ this._applyTheme(this._theme);
7125
+ vscode.setState(this._theme);
7126
+ persistTheme(this._theme);
7127
+ }
7128
+ /**
7129
+ * Apply the selected theme to the document root.
7130
+ */
7131
+ _applyTheme(theme) {
7132
+ applyTheme(theme, document.documentElement);
7133
+ }
6935
7134
  /**
6936
7135
  * Handle tab change from the tabs component.
6937
7136
  */
@@ -7001,15 +7200,126 @@
7001
7200
  ...BaseElement.baseStyles,
7002
7201
  i`
7003
7202
  :host {
7004
- display: flex;
7005
- flex-direction: column;
7203
+ display: block;
7006
7204
  height: 100vh;
7007
7205
  overflow: hidden;
7206
+ position: relative;
7008
7207
  background: var(--background);
7009
7208
  }
7010
7209
 
7210
+ .shell {
7211
+ display: flex;
7212
+ flex-direction: column;
7213
+ position: absolute;
7214
+ inset: 0;
7215
+ width: 100%;
7216
+ height: 100%;
7217
+ min-height: 0;
7218
+ overflow: hidden;
7219
+ }
7220
+
7221
+ .shell-chrome {
7222
+ display: flex;
7223
+ align-items: center;
7224
+ justify-content: space-between;
7225
+ gap: 12px;
7226
+ padding: 10px 12px;
7227
+ background: linear-gradient(180deg, var(--editor-background) 0%, var(--vscode-sideBarSectionHeader-background) 100%);
7228
+ border-bottom: 1px solid var(--border-color);
7229
+ }
7230
+
7231
+ .shell-brand {
7232
+ display: flex;
7233
+ align-items: center;
7234
+ gap: 10px;
7235
+ min-width: 0;
7236
+ }
7237
+
7238
+ .shell-mark {
7239
+ width: 24px;
7240
+ height: 24px;
7241
+ border-radius: 6px;
7242
+ display: inline-flex;
7243
+ align-items: center;
7244
+ justify-content: center;
7245
+ background: var(--accent-primary);
7246
+ color: #ffffff;
7247
+ font-size: 13px;
7248
+ flex-shrink: 0;
7249
+ }
7250
+
7251
+ .shell-brand-copy {
7252
+ min-width: 0;
7253
+ }
7254
+
7255
+ .shell-title {
7256
+ font-size: 12px;
7257
+ font-weight: 600;
7258
+ line-height: 1.2;
7259
+ }
7260
+
7261
+ .shell-subtitle {
7262
+ font-size: 10px;
7263
+ color: var(--description-foreground);
7264
+ line-height: 1.2;
7265
+ }
7266
+
7267
+ .shell-actions {
7268
+ display: flex;
7269
+ align-items: center;
7270
+ gap: 8px;
7271
+ flex-shrink: 0;
7272
+ }
7273
+
7274
+ .theme-toggle {
7275
+ display: inline-flex;
7276
+ align-items: center;
7277
+ gap: 6px;
7278
+ padding: 6px 10px;
7279
+ border-radius: 6px;
7280
+ border: 1px solid var(--border-color);
7281
+ background: var(--vscode-input-background);
7282
+ color: var(--foreground);
7283
+ font-size: 11px;
7284
+ font-weight: 500;
7285
+ transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
7286
+ }
7287
+
7288
+ .theme-toggle:hover {
7289
+ background: var(--vscode-list-hoverBackground);
7290
+ border-color: var(--accent-primary);
7291
+ }
7292
+
7293
+ .theme-toggle-icon {
7294
+ display: inline-flex;
7295
+ align-items: center;
7296
+ justify-content: center;
7297
+ width: 14px;
7298
+ height: 14px;
7299
+ flex-shrink: 0;
7300
+ }
7301
+
7302
+ .theme-toggle-icon svg {
7303
+ width: 14px;
7304
+ height: 14px;
7305
+ fill: currentColor;
7306
+ }
7307
+
7308
+ .theme-toggle-text {
7309
+ min-width: 0;
7310
+ }
7311
+
7312
+ .app-body {
7313
+ display: flex;
7314
+ flex-direction: column;
7315
+ flex: 1;
7316
+ min-height: 0;
7317
+ overflow: hidden;
7318
+ }
7319
+
7011
7320
  .view-container {
7012
7321
  flex: 1;
7322
+ min-height: 0;
7013
7323
  overflow-y: auto;
7014
7324
  display: none;
7015
7325
  }
@@ -7017,6 +7327,7 @@
7017
7327
  .view-container.active {
7018
7328
  display: flex;
7019
7329
  flex-direction: column;
7330
+ min-height: 0;
7020
7331
  }
7021
7332
 
7022
7333
  bolts-view {
@@ -7441,6 +7752,114 @@
7441
7752
  border-top: 1px solid var(--border-color);
7442
7753
  }
7443
7754
 
7755
+ .overview-fabriqa-card {
7756
+ margin-bottom: 14px;
7757
+ padding: 14px;
7758
+ border: 1px solid var(--border-color);
7759
+ border-radius: 8px;
7760
+ background: var(--editor-background);
7761
+ }
7762
+
7763
+ .overview-fabriqa-brand {
7764
+ display: flex;
7765
+ align-items: center;
7766
+ gap: 10px;
7767
+ margin-bottom: 10px;
7768
+ }
7769
+
7770
+ .overview-fabriqa-mark {
7771
+ width: 34px;
7772
+ height: 34px;
7773
+ border-radius: 8px;
7774
+ display: inline-flex;
7775
+ align-items: center;
7776
+ justify-content: center;
7777
+ background: var(--accent-primary);
7778
+ color: #ffffff;
7779
+ font-size: 12px;
7780
+ font-weight: 700;
7781
+ flex-shrink: 0;
7782
+ }
7783
+
7784
+ .overview-fabriqa-title {
7785
+ font-size: 13px;
7786
+ font-weight: 700;
7787
+ color: var(--foreground);
7788
+ line-height: 1.25;
7789
+ }
7790
+
7791
+ .overview-fabriqa-subtitle,
7792
+ .overview-fabriqa-copy,
7793
+ .overview-dashboard-copy {
7794
+ color: var(--description-foreground);
7795
+ font-size: 11px;
7796
+ line-height: 1.45;
7797
+ }
7798
+
7799
+ .overview-fabriqa-copy {
7800
+ margin-bottom: 12px;
7801
+ }
7802
+
7803
+ .overview-fabriqa-actions {
7804
+ display: flex;
7805
+ flex-wrap: wrap;
7806
+ gap: 8px;
7807
+ }
7808
+
7809
+ .overview-fabriqa-link {
7810
+ display: inline-flex;
7811
+ align-items: center;
7812
+ justify-content: center;
7813
+ min-height: 30px;
7814
+ padding: 0 10px;
7815
+ border-radius: 6px;
7816
+ background: var(--accent-primary);
7817
+ color: #ffffff;
7818
+ font-size: 11px;
7819
+ font-weight: 700;
7820
+ cursor: pointer;
7821
+ }
7822
+
7823
+ .overview-fabriqa-link.secondary {
7824
+ background: var(--vscode-input-background);
7825
+ color: var(--foreground);
7826
+ border: 1px solid var(--border-color);
7827
+ }
7828
+
7829
+ .overview-fabriqa-link:hover {
7830
+ opacity: 0.88;
7831
+ }
7832
+
7833
+ .overview-dashboard-tip {
7834
+ display: flex;
7835
+ align-items: flex-start;
7836
+ justify-content: space-between;
7837
+ gap: 12px;
7838
+ margin-bottom: 14px;
7839
+ padding: 12px;
7840
+ border: 1px solid var(--border-color);
7841
+ border-radius: 8px;
7842
+ background: var(--vscode-input-background);
7843
+ }
7844
+
7845
+ .overview-dashboard-title {
7846
+ margin-bottom: 4px;
7847
+ color: var(--foreground);
7848
+ font-size: 12px;
7849
+ font-weight: 700;
7850
+ }
7851
+
7852
+ .overview-dashboard-tip code {
7853
+ display: inline-block;
7854
+ margin-top: 8px;
7855
+ padding: 5px 7px;
7856
+ border-radius: 4px;
7857
+ background: var(--editor-background);
7858
+ color: var(--foreground);
7859
+ font-size: 10px;
7860
+ white-space: nowrap;
7861
+ }
7862
+
7444
7863
  .overview-resources-title {
7445
7864
  font-size: 9px;
7446
7865
  font-weight: 600;
@@ -7546,6 +7965,9 @@
7546
7965
  __decorateClass([
7547
7966
  r5()
7548
7967
  ], SpecsmdApp.prototype, "_fireActiveTab", 2);
7968
+ __decorateClass([
7969
+ r5()
7970
+ ], SpecsmdApp.prototype, "_theme", 2);
7549
7971
  SpecsmdApp = __decorateClass([
7550
7972
  t3("specsmd-app")
7551
7973
  ], SpecsmdApp);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specsmd",
3
- "version": "0.1.68",
3
+ "version": "0.1.70",
4
4
  "description": "Multi-agent orchestration system for AI-native software development. Delivers AI-DLC, Agile, and custom SDLC flows as markdown-based agent systems.",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {