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.
- package/bin/create-dss-project.js +4 -0
- package/lib/index.js +80 -0
- package/lib/project-types.js +74 -0
- package/lib/prompts.js +42 -0
- package/lib/scaffold.js +169 -0
- package/package.json +30 -0
- package/template/.github/workflows/dashboard-build.yml +27 -0
- package/template/.github/workflows/template-lint.yml +71 -0
- package/template/CHANGELOG.md +43 -0
- package/template/CLAUDE.md +145 -0
- package/template/LICENSE +21 -0
- package/template/README.md +201 -0
- package/template/STATUS.md +34 -0
- package/template/context/competitor-snapshot.md +27 -0
- package/template/context/market-snapshot.md +32 -0
- package/template/context/pipeline-state.md +36 -0
- package/template/context/project-state.md +45 -0
- package/template/dashboard/CLAUDE.md +36 -0
- package/template/dashboard/DEPLOY.md +60 -0
- package/template/dashboard/build-data.js +395 -0
- package/template/dashboard/competitors.html +143 -0
- package/template/dashboard/css/styles.css +143 -0
- package/template/dashboard/data/.gitkeep +0 -0
- package/template/dashboard/decisions.html +132 -0
- package/template/dashboard/index.html +152 -0
- package/template/dashboard/js/app.js +59 -0
- package/template/dashboard/js/overview.js +50 -0
- package/template/dashboard/js/sidebar.js +62 -0
- package/template/dashboard/js/tailwind-config.js +52 -0
- package/template/dashboard/package-lock.json +351 -0
- package/template/dashboard/package.json +17 -0
- package/template/dashboard/pipeline.html +149 -0
- package/template/dashboard/research.html +215 -0
- package/template/dashboard/robots.txt +2 -0
- package/template/dashboard/scoring.html +187 -0
- package/template/dashboard/timeline.html +165 -0
- package/template/dashboard/vercel.json +5 -0
- package/template/dashboard/watch.js +57 -0
- package/template/data/.gitkeep +0 -0
- package/template/discovery/calls/.gitkeep +0 -0
- package/template/discovery/outreach/.gitkeep +0 -0
- package/template/discovery/prep/.gitkeep +0 -0
- package/template/docs/decks/.gitkeep +0 -0
- package/template/docs/executive-summary.md +104 -0
- package/template/docs/getting-started.md +274 -0
- package/template/docs/memos/evidence-grading.md +27 -0
- package/template/docs/memos/housekeeping-reference.md +101 -0
- package/template/docs/memos/reference-context.md +30 -0
- package/template/docs/output/project-activity.md +8 -0
- package/template/docs/output/status-blurb.md +4 -0
- package/template/docs/output/work-log.md +8 -0
- package/template/docs/skill-authoring-guide.md +212 -0
- package/template/memory/MEMORY.md +84 -0
- package/template/memory/decisions.md +13 -0
- package/template/memory/discovery.md +48 -0
- package/template/memory/research.md +33 -0
- package/template/memory/scoring.md +34 -0
- package/template/project.config.example.json +31 -0
- package/template/research/competitors/.gitkeep +0 -0
- package/template/research/market/.gitkeep +0 -0
- package/template/research/technical/.gitkeep +0 -0
- package/template/scripts/.gitkeep +0 -0
- package/template/scripts/build-cli-template.sh +32 -0
- package/template/scripts/health-check.sh +152 -0
- package/template/scripts/reset-to-template.sh +115 -0
- package/template/scripts/validate-placeholders.sh +47 -0
- package/template/skills/compare-options/SKILL.md +97 -0
- package/template/skills/critical-reasoning/SKILL.md +107 -0
- package/template/skills/decision/SKILL.md +75 -0
- package/template/skills/enrich-entity/SKILL.md +107 -0
- package/template/skills/health-check/SKILL.md +144 -0
- package/template/skills/onboard/SKILL.md +434 -0
- package/template/skills/outreach-sequence/SKILL.md +79 -0
- package/template/skills/pipeline-update/SKILL.md +90 -0
- package/template/skills/process-call/SKILL.md +96 -0
- package/template/skills/rebuild-snapshots/SKILL.md +88 -0
- package/template/skills/session-end/SKILL.md +120 -0
- package/template/skills/session-start/SKILL.md +93 -0
- package/template/skills/synthesise/SKILL.md +108 -0
- package/template/skills/weekly-report/SKILL.md +79 -0
- package/template/templates/call-notes.md +67 -0
- package/template/templates/call-prep.md +65 -0
- 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
|
+
}
|