create-dss-project 0.1.0

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.
Files changed (83) hide show
  1. package/bin/create-dss-project.js +4 -0
  2. package/lib/index.js +80 -0
  3. package/lib/project-types.js +74 -0
  4. package/lib/prompts.js +42 -0
  5. package/lib/scaffold.js +169 -0
  6. package/package.json +30 -0
  7. package/template/.github/workflows/dashboard-build.yml +27 -0
  8. package/template/.github/workflows/template-lint.yml +71 -0
  9. package/template/CHANGELOG.md +43 -0
  10. package/template/CLAUDE.md +145 -0
  11. package/template/LICENSE +21 -0
  12. package/template/README.md +201 -0
  13. package/template/STATUS.md +34 -0
  14. package/template/context/competitor-snapshot.md +27 -0
  15. package/template/context/market-snapshot.md +32 -0
  16. package/template/context/pipeline-state.md +36 -0
  17. package/template/context/project-state.md +45 -0
  18. package/template/dashboard/CLAUDE.md +36 -0
  19. package/template/dashboard/DEPLOY.md +60 -0
  20. package/template/dashboard/build-data.js +395 -0
  21. package/template/dashboard/competitors.html +143 -0
  22. package/template/dashboard/css/styles.css +143 -0
  23. package/template/dashboard/data/.gitkeep +0 -0
  24. package/template/dashboard/decisions.html +132 -0
  25. package/template/dashboard/index.html +152 -0
  26. package/template/dashboard/js/app.js +59 -0
  27. package/template/dashboard/js/overview.js +50 -0
  28. package/template/dashboard/js/sidebar.js +62 -0
  29. package/template/dashboard/js/tailwind-config.js +52 -0
  30. package/template/dashboard/package-lock.json +351 -0
  31. package/template/dashboard/package.json +17 -0
  32. package/template/dashboard/pipeline.html +149 -0
  33. package/template/dashboard/research.html +215 -0
  34. package/template/dashboard/robots.txt +2 -0
  35. package/template/dashboard/scoring.html +187 -0
  36. package/template/dashboard/timeline.html +165 -0
  37. package/template/dashboard/vercel.json +5 -0
  38. package/template/dashboard/watch.js +57 -0
  39. package/template/data/.gitkeep +0 -0
  40. package/template/discovery/calls/.gitkeep +0 -0
  41. package/template/discovery/outreach/.gitkeep +0 -0
  42. package/template/discovery/prep/.gitkeep +0 -0
  43. package/template/docs/decks/.gitkeep +0 -0
  44. package/template/docs/executive-summary.md +104 -0
  45. package/template/docs/getting-started.md +274 -0
  46. package/template/docs/memos/evidence-grading.md +27 -0
  47. package/template/docs/memos/housekeeping-reference.md +101 -0
  48. package/template/docs/memos/reference-context.md +30 -0
  49. package/template/docs/output/project-activity.md +8 -0
  50. package/template/docs/output/status-blurb.md +4 -0
  51. package/template/docs/output/work-log.md +8 -0
  52. package/template/docs/skill-authoring-guide.md +212 -0
  53. package/template/memory/MEMORY.md +84 -0
  54. package/template/memory/decisions.md +13 -0
  55. package/template/memory/discovery.md +48 -0
  56. package/template/memory/research.md +33 -0
  57. package/template/memory/scoring.md +34 -0
  58. package/template/project.config.example.json +31 -0
  59. package/template/research/competitors/.gitkeep +0 -0
  60. package/template/research/market/.gitkeep +0 -0
  61. package/template/research/technical/.gitkeep +0 -0
  62. package/template/scripts/.gitkeep +0 -0
  63. package/template/scripts/build-cli-template.sh +32 -0
  64. package/template/scripts/health-check.sh +152 -0
  65. package/template/scripts/reset-to-template.sh +115 -0
  66. package/template/scripts/validate-placeholders.sh +47 -0
  67. package/template/skills/compare-options/SKILL.md +97 -0
  68. package/template/skills/critical-reasoning/SKILL.md +107 -0
  69. package/template/skills/decision/SKILL.md +75 -0
  70. package/template/skills/enrich-entity/SKILL.md +107 -0
  71. package/template/skills/health-check/SKILL.md +144 -0
  72. package/template/skills/onboard/SKILL.md +434 -0
  73. package/template/skills/outreach-sequence/SKILL.md +79 -0
  74. package/template/skills/pipeline-update/SKILL.md +90 -0
  75. package/template/skills/process-call/SKILL.md +96 -0
  76. package/template/skills/rebuild-snapshots/SKILL.md +88 -0
  77. package/template/skills/session-end/SKILL.md +120 -0
  78. package/template/skills/session-start/SKILL.md +93 -0
  79. package/template/skills/synthesise/SKILL.md +108 -0
  80. package/template/skills/weekly-report/SKILL.md +79 -0
  81. package/template/templates/call-notes.md +67 -0
  82. package/template/templates/call-prep.md +65 -0
  83. package/template/templates/entity-teardown.md +58 -0
@@ -0,0 +1,132 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="robots" content="noindex, nofollow">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <meta name="generator" content="DS Strategy Stack by DiffTheEnder (github.com/DiffTheEnder/DSS-Claude-Stack)">
8
+ <title>Decisions — {{PROJECT_NAME}}</title>
9
+ <link rel="preconnect" href="https://fonts.googleapis.com">
10
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
+ <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=Instrument+Serif&family=Syne:wght@600;700&display=swap" rel="stylesheet">
12
+ <script src="https://cdn.tailwindcss.com"></script>
13
+ <script>
14
+ tailwind.config = {
15
+ darkMode: 'class',
16
+ theme: { extend: {
17
+ colors: {
18
+ cream: { 50:"#F7F4EF",100:"#f5f2ed",200:"#efe9e0",300:"#e8e0d4",400:"#E3DDD4",white:"#FEFCF9" },
19
+ warmgray: { 100:"#f0ebe3",300:"#d4c8b8",400:"#9B9183",500:"#7D7265",600:"#5C5044",700:"#4a3c2e",900:"#2C2418" },
20
+ warmdark: { 950:"#1A1612",900:"#242018",800:"#2C2720",700:"#3A3530",600:"#4a3f32" },
21
+ accent: { 50:"#F2F7F5",100:"#E3EEEA",200:"#C5D9D4",400:"#2DB892",500:"#0E9C82",600:"#0E7C6B",700:"#0B6358",800:"#084C44",900:"#053B35" },
22
+ },
23
+ fontFamily: { sans:['DM Sans','system-ui','sans-serif'], serif:['Instrument Serif','Georgia','serif'], syne:['Syne','sans-serif'] }
24
+ }}
25
+ }
26
+ </script>
27
+ <link rel="stylesheet" href="css/styles.css">
28
+ </head>
29
+ <body class="bg-cream-50 dark:bg-warmdark-950 text-warmgray-900 dark:text-warmgray-100 min-h-screen flex">
30
+
31
+ <!-- Sidebar -->
32
+ <aside id="sidebar" class="sidebar flex flex-col shrink-0">
33
+ <a href="index.html" class="sidebar-brand" style="text-decoration:none;color:inherit">
34
+ <svg width="32" height="32" viewBox="0 0 32 32" fill="none">
35
+ <rect x="2" y="2" width="28" height="28" rx="8" stroke="rgba(255,255,255,0.15)" stroke-width="1.5"/>
36
+ <circle cx="16" cy="16" r="3" stroke="#2DB892" stroke-width="1.5"/>
37
+ <line x1="16" y1="6" x2="16" y2="12" stroke="#2DB892" stroke-width="1.5" stroke-linecap="round"/>
38
+ <line x1="16" y1="20" x2="16" y2="26" stroke="#2DB892" stroke-width="1.5" stroke-linecap="round"/>
39
+ <line x1="6" y1="16" x2="12" y2="16" stroke="#2DB892" stroke-width="1.5" stroke-linecap="round"/>
40
+ <line x1="20" y1="16" x2="26" y2="16" stroke="#2DB892" stroke-width="1.5" stroke-linecap="round"/>
41
+ </svg>
42
+ <div>
43
+ <div class="sidebar-title">{{PROJECT_NAME}}</div>
44
+ <div class="sidebar-subtitle">Strategy Dashboard</div>
45
+ </div>
46
+ </a>
47
+ <nav class="sidebar-nav">
48
+ <div class="sidebar-label">Core</div>
49
+ <a href="index.html" class="nav-link"><svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="8" cy="8" r="6"/><path d="M8 5v3l2 2"/></svg>Overview</a>
50
+ <a href="pipeline.html" class="nav-link"><svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M2 4h12M2 8h8M2 12h5"/></svg>Pipeline</a>
51
+ <a href="competitors.html" class="nav-link"><svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><rect x="2" y="2" width="5" height="5" rx="1"/><rect x="9" y="2" width="5" height="5" rx="1"/><rect x="2" y="9" width="5" height="5" rx="1"/><rect x="9" y="9" width="5" height="5" rx="1"/></svg>Competitors</a>
52
+ <div class="sidebar-label" style="margin-top: 0.75rem">Strategy</div>
53
+ <a href="decisions.html" class="nav-link"><svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M8 2v12M2 8h12"/><circle cx="8" cy="8" r="6"/></svg>Decisions</a>
54
+ <a href="scoring.html" class="nav-link"><svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M3 13l3-4 3 2 4-6"/></svg>Scoring</a>
55
+ <a href="timeline.html" class="nav-link"><svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M2 3h12M2 8h12M2 13h12"/><circle cx="5" cy="3" r="1" fill="currentColor"/><circle cx="10" cy="8" r="1" fill="currentColor"/><circle cx="7" cy="13" r="1" fill="currentColor"/></svg>Timeline</a>
56
+ <a href="research.html" class="nav-link"><svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="7" cy="7" r="5"/><path d="M11 11l3 3"/></svg>Research Hub</a>
57
+ </nav>
58
+ <div style="padding: 0.75rem; border-top: 1px solid rgba(255,248,240,0.06);">
59
+ <button id="dark-toggle" class="nav-link" style="width:100%; border:none; background:none; cursor:pointer">
60
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M8 1a7 7 0 100 14 5 5 0 010-10"/></svg>Toggle Theme
61
+ </button>
62
+ </div>
63
+ <div style="padding: 0.5rem 0.75rem; border-top: 1px solid rgba(255,248,240,0.06); text-align: center;">
64
+ <a href="https://github.com/DiffTheEnder/DSS-Claude-Stack" target="_blank" rel="noopener" style="font-size: 0.65rem; color: rgba(155,145,131,0.5); text-decoration: none;">Powered by DS Strategy Stack</a>
65
+ </div>
66
+ </aside>
67
+
68
+ <!-- Main Content -->
69
+ <main class="flex-1 ml-[240px] p-8">
70
+ <header class="mb-8">
71
+ <h1 class="font-serif text-3xl mb-2">Strategic Decisions</h1>
72
+ <p class="text-warmgray-400 text-sm">Data from <code>memory/decisions.md</code></p>
73
+ </header>
74
+
75
+ <div id="decisions-grid" class="grid grid-cols-1 lg:grid-cols-2 gap-4">
76
+ <!-- Populated by JS -->
77
+ </div>
78
+ </main>
79
+
80
+ <script src="js/app.js"></script>
81
+ <script>
82
+ // Decisions page logic — loads decisions.json
83
+ document.addEventListener('DOMContentLoaded', async () => {
84
+ initDarkMode();
85
+ initSidebar();
86
+ initNav();
87
+
88
+ try {
89
+ const decisions = await loadJSON('decisions.json');
90
+ const grid = document.getElementById('decisions-grid');
91
+
92
+ if (!decisions || decisions.length === 0) {
93
+ grid.innerHTML = '<div class="col-span-full bg-white dark:bg-warmdark-800 rounded-xl border border-cream-300 dark:border-warmdark-700 p-6 text-center text-warmgray-400">No decisions recorded yet. Use <code>/decision</code> to record strategic choices.</div>';
94
+ return;
95
+ }
96
+
97
+ decisions.forEach(d => {
98
+ const card = document.createElement('div');
99
+ card.className = 'bg-white dark:bg-warmdark-800 rounded-xl border border-cream-300 dark:border-warmdark-700 p-5 hover:shadow-md transition-shadow';
100
+
101
+ // Reversibility badge colour
102
+ const rev = (d.reversibility || '').toLowerCase();
103
+ let revClass = '';
104
+ if (rev.includes('easy')) revClass = 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300';
105
+ else if (rev.includes('moderate')) revClass = 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300';
106
+ else if (rev.includes('hard')) revClass = 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300';
107
+ else if (rev.includes('irreversible')) revClass = 'bg-red-200 text-red-900 dark:bg-red-950/40 dark:text-red-400';
108
+ else revClass = 'bg-warmgray-100 text-warmgray-500 dark:bg-warmdark-700 dark:text-warmgray-300';
109
+
110
+ card.innerHTML = `
111
+ <div class="flex items-start justify-between mb-3">
112
+ <div>
113
+ <span class="text-xs font-semibold text-warmgray-400 uppercase tracking-wider">${d.number || ''}</span>
114
+ <h3 class="font-semibold text-base mt-0.5">${d.title || 'Untitled Decision'}</h3>
115
+ </div>
116
+ <span class="text-xs text-warmgray-400 whitespace-nowrap ml-3">${d.date || ''}</span>
117
+ </div>
118
+ <p class="text-sm leading-relaxed mb-3">${d.decision || d.text || d.description || ''}</p>
119
+ <div class="flex items-center gap-2 flex-wrap">
120
+ ${d.reversibility ? '<span class="inline-block px-2 py-0.5 rounded text-xs font-medium ' + revClass + '">' + d.reversibility + '</span>' : ''}
121
+ </div>
122
+ ${d.revisitTrigger || d.revisit_trigger ? '<p class="text-xs text-warmgray-400 mt-3">Revisit: ' + (d.revisitTrigger || d.revisit_trigger) + '</p>' : ''}
123
+ `;
124
+ grid.appendChild(card);
125
+ });
126
+ } catch (e) {
127
+ console.warn('Could not load decisions data:', e.message);
128
+ }
129
+ });
130
+ </script>
131
+ </body>
132
+ </html>
@@ -0,0 +1,152 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="robots" content="noindex, nofollow">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <meta name="generator" content="DS Strategy Stack by DiffTheEnder (github.com/DiffTheEnder/DSS-Claude-Stack)">
8
+ <title>Overview — {{PROJECT_NAME}}</title>
9
+ <link rel="preconnect" href="https://fonts.googleapis.com">
10
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
+ <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=Instrument+Serif&family=Syne:wght@600;700&display=swap" rel="stylesheet">
12
+ <script src="https://cdn.tailwindcss.com"></script>
13
+ <script>
14
+ tailwind.config = {
15
+ darkMode: 'class',
16
+ theme: {
17
+ extend: {
18
+ colors: {
19
+ cream: {
20
+ 50: "#F7F4EF",
21
+ 100: "#f5f2ed",
22
+ 200: "#efe9e0",
23
+ 300: "#e8e0d4",
24
+ 400: "#E3DDD4",
25
+ white: "#FEFCF9",
26
+ },
27
+ warmgray: {
28
+ 100: "#f0ebe3",
29
+ 300: "#d4c8b8",
30
+ 400: "#9B9183",
31
+ 500: "#7D7265",
32
+ 600: "#5C5044",
33
+ 700: "#4a3c2e",
34
+ 900: "#2C2418",
35
+ },
36
+ warmdark: {
37
+ 950: "#1A1612",
38
+ 900: "#242018",
39
+ 800: "#2C2720",
40
+ 700: "#3A3530",
41
+ 600: "#4a3f32",
42
+ },
43
+ accent: {
44
+ 50: "#F2F7F5",
45
+ 100: "#E3EEEA",
46
+ 200: "#C5D9D4",
47
+ 400: "#2DB892",
48
+ 500: "#0E9C82",
49
+ 600: "#0E7C6B",
50
+ 700: "#0B6358",
51
+ 800: "#084C44",
52
+ 900: "#053B35",
53
+ },
54
+ },
55
+ fontFamily: {
56
+ sans: ['DM Sans', 'system-ui', 'sans-serif'],
57
+ serif: ['Instrument Serif', 'Georgia', 'serif'],
58
+ syne: ['Syne', 'sans-serif'],
59
+ }
60
+ }
61
+ }
62
+ }
63
+ </script>
64
+ <link rel="stylesheet" href="css/styles.css">
65
+ </head>
66
+ <body class="bg-cream-50 dark:bg-warmdark-950 text-warmgray-900 dark:text-warmgray-100 min-h-screen flex">
67
+
68
+ <!-- Sidebar -->
69
+ <aside id="sidebar" class="sidebar flex flex-col shrink-0">
70
+ <a href="index.html" class="sidebar-brand" style="text-decoration:none;color:inherit">
71
+ <svg width="32" height="32" viewBox="0 0 32 32" fill="none">
72
+ <rect x="2" y="2" width="28" height="28" rx="8" stroke="rgba(255,255,255,0.15)" stroke-width="1.5"/>
73
+ <circle cx="16" cy="16" r="3" stroke="#2DB892" stroke-width="1.5"/>
74
+ <line x1="16" y1="6" x2="16" y2="12" stroke="#2DB892" stroke-width="1.5" stroke-linecap="round"/>
75
+ <line x1="16" y1="20" x2="16" y2="26" stroke="#2DB892" stroke-width="1.5" stroke-linecap="round"/>
76
+ <line x1="6" y1="16" x2="12" y2="16" stroke="#2DB892" stroke-width="1.5" stroke-linecap="round"/>
77
+ <line x1="20" y1="16" x2="26" y2="16" stroke="#2DB892" stroke-width="1.5" stroke-linecap="round"/>
78
+ </svg>
79
+ <div>
80
+ <div class="sidebar-title">{{PROJECT_NAME}}</div>
81
+ <div class="sidebar-subtitle">Strategy Dashboard</div>
82
+ </div>
83
+ </a>
84
+ <nav class="sidebar-nav">
85
+ <div class="sidebar-label">Core</div>
86
+ <a href="index.html" class="nav-link">
87
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="8" cy="8" r="6"/><path d="M8 5v3l2 2"/></svg>
88
+ Overview
89
+ </a>
90
+ <a href="pipeline.html" class="nav-link">
91
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M2 4h12M2 8h8M2 12h5"/></svg>
92
+ Pipeline
93
+ </a>
94
+ <a href="competitors.html" class="nav-link">
95
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><rect x="2" y="2" width="5" height="5" rx="1"/><rect x="9" y="2" width="5" height="5" rx="1"/><rect x="2" y="9" width="5" height="5" rx="1"/><rect x="9" y="9" width="5" height="5" rx="1"/></svg>
96
+ Competitors
97
+ </a>
98
+ <div class="sidebar-label" style="margin-top: 0.75rem">Strategy</div>
99
+ <a href="decisions.html" class="nav-link">
100
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M8 2v12M2 8h12"/><circle cx="8" cy="8" r="6"/></svg>
101
+ Decisions
102
+ </a>
103
+ <a href="scoring.html" class="nav-link">
104
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M3 13l3-4 3 2 4-6"/></svg>
105
+ Scoring
106
+ </a>
107
+ <a href="timeline.html" class="nav-link">
108
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M2 3h12M2 8h12M2 13h12"/><circle cx="5" cy="3" r="1" fill="currentColor"/><circle cx="10" cy="8" r="1" fill="currentColor"/><circle cx="7" cy="13" r="1" fill="currentColor"/></svg>
109
+ Timeline
110
+ </a>
111
+ <a href="research.html" class="nav-link">
112
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="7" cy="7" r="5"/><path d="M11 11l3 3"/></svg>
113
+ Research Hub
114
+ </a>
115
+ </nav>
116
+ <div style="padding: 0.75rem; border-top: 1px solid rgba(255,248,240,0.06);">
117
+ <button id="dark-toggle" class="nav-link" style="width:100%; border:none; background:none; cursor:pointer">
118
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M8 1a7 7 0 100 14 5 5 0 010-10"/></svg>
119
+ Toggle Theme
120
+ </button>
121
+ </div>
122
+ <div style="padding: 0.5rem 0.75rem; border-top: 1px solid rgba(255,248,240,0.06); text-align: center;">
123
+ <a href="https://github.com/DiffTheEnder/DSS-Claude-Stack" target="_blank" rel="noopener" style="font-size: 0.65rem; color: rgba(155,145,131,0.5); text-decoration: none;">Powered by DS Strategy Stack</a>
124
+ </div>
125
+ </aside>
126
+
127
+ <!-- Main Content -->
128
+ <main class="flex-1 ml-[240px] p-8">
129
+ <header class="mb-8">
130
+ <h1 class="font-serif text-3xl mb-2">Project Overview</h1>
131
+ <p id="build-time" class="text-warmgray-400 text-sm"></p>
132
+ </header>
133
+
134
+ <!-- Status Blurb -->
135
+ <section class="bg-white dark:bg-warmdark-800 rounded-xl border border-cream-300 dark:border-warmdark-700 p-6 mb-6">
136
+ <h2 class="font-syne text-sm font-bold uppercase tracking-wider text-warmgray-400 mb-3">Current Status</h2>
137
+ <p id="status-blurb" class="text-base leading-relaxed"></p>
138
+ </section>
139
+
140
+ <!-- Kill Conditions -->
141
+ <section class="mb-8">
142
+ <h2 class="font-syne text-sm font-bold uppercase tracking-wider text-warmgray-400 mb-4">Kill Conditions</h2>
143
+ <div id="kc-grid" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
144
+ <!-- Populated by JS -->
145
+ </div>
146
+ </section>
147
+ </main>
148
+
149
+ <script src="js/app.js"></script>
150
+ <script src="js/overview.js"></script>
151
+ </body>
152
+ </html>
@@ -0,0 +1,59 @@
1
+ // Shared utilities for all dashboard pages
2
+
3
+ const DATA_DIR = 'data/';
4
+
5
+ async function loadJSON(filename) {
6
+ const resp = await fetch(DATA_DIR + filename);
7
+ if (!resp.ok) throw new Error(`Failed to load ${filename}: ${resp.status}`);
8
+ return resp.json();
9
+ }
10
+
11
+ // Dark mode
12
+ function initDarkMode() {
13
+ const toggle = document.getElementById('dark-toggle');
14
+ const html = document.documentElement;
15
+ const stored = localStorage.getItem('dark-mode');
16
+ if (stored === 'true' || (stored === null && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
17
+ html.classList.add('dark');
18
+ }
19
+ if (toggle) {
20
+ toggle.addEventListener('click', () => {
21
+ html.classList.toggle('dark');
22
+ localStorage.setItem('dark-mode', html.classList.contains('dark'));
23
+ });
24
+ }
25
+ }
26
+
27
+ // Mobile sidebar toggle
28
+ function initSidebar() {
29
+ const btn = document.getElementById('sidebar-toggle');
30
+ const sidebar = document.getElementById('sidebar');
31
+ if (btn && sidebar) {
32
+ btn.addEventListener('click', () => sidebar.classList.toggle('open'));
33
+ document.addEventListener('click', (e) => {
34
+ if (!sidebar.contains(e.target) && !btn.contains(e.target)) sidebar.classList.remove('open');
35
+ });
36
+ }
37
+ }
38
+
39
+ // Highlight active nav
40
+ function initNav() {
41
+ const page = window.location.pathname.split('/').pop() || 'index.html';
42
+ document.querySelectorAll('.nav-link').forEach(link => {
43
+ if (link.getAttribute('href') === page) {
44
+ link.classList.add('active');
45
+ }
46
+ });
47
+ }
48
+
49
+ // Kill condition status to CSS class
50
+ function kcStatusClass(status) {
51
+ const s = (status || '').toUpperCase().trim();
52
+ if (s.includes('UNTESTED')) return 'kc-untested';
53
+ if (s.includes('EARLY SIGNAL')) return 'kc-early-signal';
54
+ if (s.includes('BUILDING')) return 'kc-building';
55
+ if (s.includes('WEAKENING')) return 'kc-weakening';
56
+ if (s.includes('PASSED')) return 'kc-passed';
57
+ if (s.includes('FAILED')) return 'kc-failed';
58
+ return 'kc-untested';
59
+ }
@@ -0,0 +1,50 @@
1
+ // Overview page logic
2
+
3
+ document.addEventListener('DOMContentLoaded', async () => {
4
+ initDarkMode();
5
+ initSidebar();
6
+ initNav();
7
+
8
+ try {
9
+ const data = await loadJSON('overview.json');
10
+
11
+ // Status blurb
12
+ const blurbEl = document.getElementById('status-blurb');
13
+ if (blurbEl && data.statusBlurb) {
14
+ blurbEl.textContent = data.statusBlurb;
15
+ } else if (blurbEl) {
16
+ blurbEl.textContent = 'No status blurb yet. Update docs/output/status-blurb.md and rebuild.';
17
+ blurbEl.classList.add('text-warmgray-400', 'italic');
18
+ }
19
+
20
+ // Build time
21
+ const buildTimeEl = document.getElementById('build-time');
22
+ if (buildTimeEl && data.buildTime) {
23
+ const d = new Date(data.buildTime);
24
+ buildTimeEl.textContent = `Last built: ${d.toLocaleDateString()} ${d.toLocaleTimeString()}`;
25
+ }
26
+
27
+ // Kill conditions
28
+ const kcGrid = document.getElementById('kc-grid');
29
+ if (kcGrid && data.killConditions && data.killConditions.length > 0) {
30
+ data.killConditions.forEach(kc => {
31
+ const card = document.createElement('div');
32
+ card.className = 'kc-card';
33
+ card.innerHTML = `
34
+ <div class="flex items-center justify-between mb-2">
35
+ <span class="font-syne text-xs font-bold uppercase tracking-wider text-warmgray-400">KC${kc.id}</span>
36
+ <span class="kc-badge ${kcStatusClass(kc.status)}">${kc.status}</span>
37
+ </div>
38
+ <p class="text-sm leading-relaxed">${kc.condition}</p>
39
+ ${kc.evidence ? `<p class="text-xs text-warmgray-400 mt-2">${kc.evidence}</p>` : ''}
40
+ `;
41
+ kcGrid.appendChild(card);
42
+ });
43
+ } else if (kcGrid) {
44
+ kcGrid.innerHTML = '<p class="text-warmgray-400 italic col-span-3">No kill conditions defined yet. Add them to docs/executive-summary.md and rebuild.</p>';
45
+ }
46
+
47
+ } catch (e) {
48
+ console.warn('Could not load overview data:', e.message);
49
+ }
50
+ });
@@ -0,0 +1,62 @@
1
+ // Shared sidebar component — injected into all dashboard pages
2
+ // Usage: include this script, then call renderSidebar() before app.js
3
+
4
+ function renderSidebar() {
5
+ const sidebar = document.getElementById('sidebar');
6
+ if (!sidebar) return;
7
+
8
+ sidebar.innerHTML = `
9
+ <a href="index.html" class="sidebar-brand" style="text-decoration:none;color:inherit">
10
+ <svg width="32" height="32" viewBox="0 0 32 32" fill="none">
11
+ <rect x="2" y="2" width="28" height="28" rx="8" stroke="rgba(255,255,255,0.15)" stroke-width="1.5"/>
12
+ <circle cx="16" cy="16" r="3" stroke="#2DB892" stroke-width="1.5"/>
13
+ <line x1="16" y1="6" x2="16" y2="12" stroke="#2DB892" stroke-width="1.5" stroke-linecap="round"/>
14
+ <line x1="16" y1="20" x2="16" y2="26" stroke="#2DB892" stroke-width="1.5" stroke-linecap="round"/>
15
+ <line x1="6" y1="16" x2="12" y2="16" stroke="#2DB892" stroke-width="1.5" stroke-linecap="round"/>
16
+ <line x1="20" y1="16" x2="26" y2="16" stroke="#2DB892" stroke-width="1.5" stroke-linecap="round"/>
17
+ </svg>
18
+ <div>
19
+ <div class="sidebar-title">{{PROJECT_NAME}}</div>
20
+ <div class="sidebar-subtitle">Strategy Dashboard</div>
21
+ </div>
22
+ </a>
23
+ <nav class="sidebar-nav">
24
+ <div class="sidebar-label">Core</div>
25
+ <a href="index.html" class="nav-link">
26
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="8" cy="8" r="6"/><path d="M8 5v3l2 2"/></svg>
27
+ Overview
28
+ </a>
29
+ <a href="pipeline.html" class="nav-link">
30
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M2 4h12M2 8h8M2 12h5"/></svg>
31
+ Pipeline
32
+ </a>
33
+ <a href="competitors.html" class="nav-link">
34
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><rect x="2" y="2" width="5" height="5" rx="1"/><rect x="9" y="2" width="5" height="5" rx="1"/><rect x="2" y="9" width="5" height="5" rx="1"/><rect x="9" y="9" width="5" height="5" rx="1"/></svg>
35
+ Competitors
36
+ </a>
37
+ <div class="sidebar-label" style="margin-top: 0.75rem">Strategy</div>
38
+ <a href="decisions.html" class="nav-link">
39
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M8 2v12M2 8h12"/><circle cx="8" cy="8" r="6"/></svg>
40
+ Decisions
41
+ </a>
42
+ <a href="scoring.html" class="nav-link">
43
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M3 13l3-4 3 2 4-6"/></svg>
44
+ Scoring
45
+ </a>
46
+ <a href="timeline.html" class="nav-link">
47
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M2 3h12M2 8h12M2 13h12"/><circle cx="5" cy="3" r="1" fill="currentColor"/><circle cx="10" cy="8" r="1" fill="currentColor"/><circle cx="7" cy="13" r="1" fill="currentColor"/></svg>
48
+ Timeline
49
+ </a>
50
+ <a href="research.html" class="nav-link">
51
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="7" cy="7" r="5"/><path d="M11 11l3 3"/></svg>
52
+ Research Hub
53
+ </a>
54
+ </nav>
55
+ <div style="padding: 0.75rem; border-top: 1px solid rgba(255,248,240,0.06);">
56
+ <button id="dark-toggle" class="nav-link" style="width:100%; border:none; background:none; cursor:pointer">
57
+ <svg class="nav-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M8 1a7 7 0 100 14 5 5 0 010-10"/></svg>
58
+ Toggle Theme
59
+ </button>
60
+ </div>
61
+ `;
62
+ }
@@ -0,0 +1,52 @@
1
+ // Shared Tailwind configuration for all dashboard pages
2
+ // Include this script AFTER the Tailwind CDN script tag
3
+
4
+ tailwind.config = {
5
+ darkMode: 'class',
6
+ theme: {
7
+ extend: {
8
+ colors: {
9
+ cream: {
10
+ 50: "#F7F4EF",
11
+ 100: "#f5f2ed",
12
+ 200: "#efe9e0",
13
+ 300: "#e8e0d4",
14
+ 400: "#E3DDD4",
15
+ white: "#FEFCF9",
16
+ },
17
+ warmgray: {
18
+ 100: "#f0ebe3",
19
+ 300: "#d4c8b8",
20
+ 400: "#9B9183",
21
+ 500: "#7D7265",
22
+ 600: "#5C5044",
23
+ 700: "#4a3c2e",
24
+ 900: "#2C2418",
25
+ },
26
+ warmdark: {
27
+ 950: "#1A1612",
28
+ 900: "#242018",
29
+ 800: "#2C2720",
30
+ 700: "#3A3530",
31
+ 600: "#4a3f32",
32
+ },
33
+ accent: {
34
+ 50: "#F2F7F5",
35
+ 100: "#E3EEEA",
36
+ 200: "#C5D9D4",
37
+ 400: "#2DB892",
38
+ 500: "#0E9C82",
39
+ 600: "#0E7C6B",
40
+ 700: "#0B6358",
41
+ 800: "#084C44",
42
+ 900: "#053B35",
43
+ },
44
+ },
45
+ fontFamily: {
46
+ sans: ['DM Sans', 'system-ui', 'sans-serif'],
47
+ serif: ['Instrument Serif', 'Georgia', 'serif'],
48
+ syne: ['Syne', 'sans-serif'],
49
+ }
50
+ }
51
+ }
52
+ }