Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed .DS_Store
Binary file not shown.
Empty file removed .nojekyll
Empty file.
272 changes: 216 additions & 56 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,65 +1,225 @@
<!DOCTYPE html>
<html lang="de">
<html class="light" lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Der Title wird dynamisch angepasst -->
<title>Lean Canvas</title>
<link rel="stylesheet" href="style.css">
<meta charset="utf-8" />
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
<title>LeanCanvas Editor | Local-First Workspace</title>
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&amp;display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet" />
<script id="tailwind-config">
tailwind.config = {
darkMode: "class",
theme: {
extend: {
colors: {
"on-tertiary-fixed-variant": "#555873",
"secondary-fixed": "#d5e3fc",
"on-primary-container": "#355379",
"inverse-on-surface": "#8e9eb7",
"primary-container": "#d3e4ff",
"secondary-dim": "#465468",
"on-primary": "#f6f7ff",
"error": "#9f403d",
"surface-container-low": "#eff4ff",
"on-surface": "#00345e",
"on-secondary-fixed-variant": "#4e5c71",
"tertiary-fixed": "#dcddfe",
"tertiary-fixed-dim": "#cecfef",
"on-primary-fixed-variant": "#3f5d83",
"on-primary-fixed": "#214165",
"surface-container-lowest": "#ffffff",
"tertiary-container": "#dcddfe",
"outline": "#477dbb",
"primary-fixed-dim": "#bbd6ff",
"surface-container": "#e5eeff",
"on-tertiary-fixed": "#393c55",
"outline-variant": "#81b5f6",
"surface": "#f8f9ff",
"secondary-fixed-dim": "#c7d5ed",
"on-surface-variant": "#26619d",
"secondary-container": "#d5e3fc",
"on-tertiary-container": "#4c4e69",
"surface-dim": "#c4dcff",
"on-error-container": "#752121",
"on-secondary-fixed": "#324053",
"inverse-primary": "#b3d1fd",
"primary": "#426086",
"surface-tint": "#426086",
"on-background": "#00345e",
"inverse-surface": "#000f21",
"background": "#f8f9ff",
"surface-variant": "#d2e4ff",
"on-tertiary": "#fbf8ff",
"tertiary-dim": "#4f516c",
"surface-bright": "#f8f9ff",
"on-secondary-container": "#455367",
"primary-fixed": "#d3e4ff",
"on-secondary": "#f8f8ff",
"error-dim": "#4e0309",
"surface-container-highest": "#d2e4ff",
"error-container": "#fe8983",
"primary-dim": "#365479",
"tertiary": "#5b5d78",
"surface-container-high": "#dce9ff",
"on-error": "#fff7f6",
"secondary": "#526074"
},
borderRadius: {
DEFAULT: "0.125rem",
lg: "0.25rem",
xl: "0.5rem",
full: "0.75rem"
},
fontFamily: {
headline: ["Inter"],
body: ["Inter"],
label: ["Inter"]
}
}
}
};
</script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- PDF Export Button -->
<div id="export-container">
<button id="exportPDF">PDF Export</button>
</div>

<!-- Header: Lean Canvas Überschrift inkl. dynamisch integriertem Markdown-Inhalt -->
<header id="lean-canvas-header">
<h1>Lean Canvas</h1>
</header>

<!-- Grid-Layout für den Lean Canvas -->
<div class="canvas">
<div id="problem" class="canvas-item">
<h2>Problem</h2>
<div class="content"></div>
</div>
<div id="solution" class="canvas-item">
<h2>Solution</h2>
<div class="content"></div>
</div>
<div id="unique-value-proposition" class="canvas-item">
<h2>Unique Value Proposition</h2>
<div class="content"></div>
</div>
<div id="unfair-advantage" class="canvas-item">
<h2>Unfair Advantage</h2>
<div class="content"></div>
<body class="bg-surface text-on-surface selection:bg-primary-container selection:text-on-primary-container">
<header class="fixed top-0 left-0 w-full z-50 flex justify-between items-center px-4 md:px-6 h-16 bg-white/80 backdrop-blur-md border-b border-slate-200/50 shadow-sm">
<div class="flex items-center gap-4 md:gap-8">
<span class="text-xl font-black text-blue-900 tracking-tighter">LeanCanvas</span>
</div>
<div id="customer-segment" class="canvas-item">
<h2>Customer Segment</h2>
<div class="content"></div>
<div class="flex items-center gap-2 md:gap-3">
<input id="importFileInput" type="file" accept=".md,.txt" class="hidden" />
<button id="importBtn" class="flex items-center gap-2 px-3 py-1.5 text-slate-500 hover:bg-slate-50 text-sm font-medium tracking-tight rounded border border-slate-200/50">
<span class="material-symbols-outlined text-sm">file_upload</span>
<span class="hidden sm:inline">Import</span>
</button>
<div id="saveMenuWrap" class="relative">
<button id="saveBtn" class="flex items-center gap-2 px-4 py-1.5 bg-primary text-on-primary hover:opacity-90 active:scale-[0.99] transition-all text-sm font-medium tracking-tight rounded shadow-sm">
<span class="material-symbols-outlined text-sm">save</span>
<span class="hidden sm:inline">Save</span>
</button>
<div id="saveMenu" class="hidden absolute right-0 mt-2 w-44 bg-white border border-slate-200 rounded-lg shadow-lg overflow-hidden z-50">
<button id="saveMarkdownBtn" class="w-full text-left px-3 py-2 text-sm text-slate-700 hover:bg-slate-50">Save as Markdown</button>
<button id="savePdfBtn" class="w-full text-left px-3 py-2 text-sm text-slate-700 hover:bg-slate-50">Save as PDF</button>
</div>
</div>
<div class="h-6 w-[1px] bg-slate-200 mx-1 md:mx-2"></div>
<button id="createBtn" class="flex items-center gap-2 px-3 py-1.5 text-primary border border-primary hover:bg-primary/5 active:scale-[0.99] transition-all text-sm font-medium tracking-tight rounded">
<span class="material-symbols-outlined text-sm">add_circle</span>
<span class="hidden sm:inline">Create</span>
</button>
</div>
<div id="key-metrics" class="canvas-item">
<h2>Key Metrics</h2>
<div class="content"></div>
</div>
<div id="channels" class="canvas-item">
<h2>Channels</h2>
<div class="content"></div>
</div>
<div id="cost-structure" class="canvas-item">
<h2>Cost Structure</h2>
<div class="content"></div>
</div>
<div id="revenue-streams" class="canvas-item">
<h2>Revenue Streams</h2>
<div class="content"></div>
</header>

<main class="pt-24 pb-20 min-h-screen px-4 md:px-6 lg:px-12 bg-surface">
<div class="max-w-7xl mx-auto">
<div class="mb-8 flex flex-col md:flex-row md:justify-between md:items-end gap-4">
<div>
<h2 id="canvasTitle" class="text-3xl font-black text-on-surface tracking-tighter">Lean Canvas</h2>
<p class="text-sm text-on-surface-variant mt-1">Tip: touch/click content to edit inline. Hover list items to remove them.</p>
</div>
<div class="flex items-center gap-4 text-xs font-medium text-on-surface-variant">
<span class="flex items-center gap-1"><span class="material-symbols-outlined text-sm">schedule</span> <span id="lastEditLabel">Last edit: --</span></span>
</div>
</div>

<div id="canvasMainGrid" class="grid grid-cols-1 md:grid-cols-5 md:grid-rows-2 gap-4 bg-surface-container-low p-4 rounded-xl border border-outline-variant/10">
<div class="md:col-span-1 md:row-span-2 flex flex-col gap-4">
<section class="flex-1 bg-surface-container-lowest p-5 rounded border-l-4 border-primary shadow-sm hover:shadow-md transition-shadow">
<header class="flex justify-between items-start mb-4">
<h3 class="section-edit-trigger text-sm font-bold text-on-surface-variant uppercase tracking-widest" data-key="problem">Problem</h3>
<span class="material-symbols-outlined text-primary/40 text-lg">report_problem</span>
</header>
<ul id="problemList" class="space-y-3 text-sm text-on-surface leading-relaxed"></ul>
</section>
<section class="h-40 overflow-y-auto bg-surface-container-low/50 p-5 rounded border-l-2 border-outline-variant/30">
<h4 class="section-edit-trigger text-[10px] font-bold text-on-surface-variant uppercase tracking-widest mb-3" data-key="existingAlternatives">Existing Alternatives</h4>
<div id="existingAlternativesTags" class="flex flex-wrap gap-2"></div>
</section>
</div>

<div class="md:col-span-1 md:row-span-2 flex flex-col gap-4">
<section class="flex-1 bg-surface-container-lowest p-5 rounded border-l-4 border-primary shadow-sm">
<header class="flex justify-between items-start mb-4">
<h3 class="section-edit-trigger text-sm font-bold text-on-surface-variant uppercase tracking-widest" data-key="solution">Solution</h3>
<span class="material-symbols-outlined text-primary/40 text-lg">lightbulb</span>
</header>
<p id="solutionText" class="text-sm text-on-surface leading-relaxed font-medium"></p>
<div class="mt-6 -rotate-1 bg-tertiary-container p-3 rounded shadow-sm text-xs text-on-tertiary-container border border-tertiary-dim/10">
<p class="font-bold mb-1">Observation:</p>
<p id="observationText"></p>
</div>
</section>
<section class="h-40 overflow-y-auto bg-surface-container p-5 rounded border-l-2 border-outline-variant/30">
<h4 class="section-edit-trigger text-[10px] font-bold text-on-surface-variant uppercase tracking-widest mb-3" data-key="keyMetrics">Key Metrics</h4>
<ul id="keyMetricsList" class="space-y-2 text-[11px] text-on-surface"></ul>
</section>
</div>

<div class="md:col-span-1 md:row-span-2 flex flex-col gap-4">
<section class="flex-1 bg-primary text-on-primary p-6 rounded shadow-xl relative overflow-hidden">
<div class="absolute -right-4 -top-4 opacity-10"><span class="material-symbols-outlined text-8xl">star</span></div>
<header class="flex justify-between items-start mb-4">
<h3 class="section-edit-trigger text-xs font-bold text-on-primary/70 uppercase tracking-widest" data-key="uniqueValueProposition">Unique Value Proposition</h3>
</header>
<p id="uvpText" class="text-base font-bold leading-tight mb-4"></p>
<div class="mt-auto pt-6 border-t border-on-primary/10">
<h4 class="section-edit-trigger text-[10px] font-bold text-on-primary/60 uppercase tracking-[0.2em] mb-2" data-key="highLevelConcept">High-Level Concept</h4>
<p id="highLevelConceptText" class="text-lg font-black tracking-tighter italic opacity-90"></p>
</div>
</section>
</div>

<div class="md:col-span-1 md:row-span-2 flex flex-col gap-4">
<section class="flex-1 bg-surface-container-lowest p-5 rounded border-l-4 border-primary shadow-sm">
<header class="flex justify-between items-start mb-4">
<h3 class="section-edit-trigger text-sm font-bold text-on-surface-variant uppercase tracking-widest" data-key="unfairAdvantage">Unfair Advantage</h3>
<span class="material-symbols-outlined text-primary/40 text-lg">workspace_premium</span>
</header>
<ul id="unfairAdvantageList" class="space-y-3 text-sm text-on-surface leading-relaxed font-medium"></ul>
</section>
<section class="h-40 overflow-y-auto bg-surface-container p-5 rounded border-l-2 border-outline-variant/30">
<h4 class="section-edit-trigger text-[10px] font-bold text-on-surface-variant uppercase tracking-widest mb-3" data-key="channels">Channels</h4>
<div id="channelsList" class="space-y-1"></div>
</section>
</div>

<div class="md:col-span-1 md:row-span-2 flex flex-col gap-4">
<section class="flex-1 bg-surface-container-lowest p-5 rounded border-l-4 border-primary shadow-sm">
<header class="flex justify-between items-start mb-4">
<h3 class="section-edit-trigger text-sm font-bold text-on-surface-variant uppercase tracking-widest" data-key="customerSegments">Customer Segments</h3>
<span class="material-symbols-outlined text-primary/40 text-lg">person_search</span>
</header>
<div id="customerSegmentsCards" class="space-y-2"></div>
</section>
<section class="h-40 overflow-y-auto bg-surface-container-low/50 p-5 rounded border-l-2 border-outline-variant/30">
<h4 class="section-edit-trigger text-[10px] font-bold text-on-surface-variant uppercase tracking-widest mb-3" data-key="earlyAdopters">Early Adopters</h4>
<div id="earlyAdoptersTags" class="flex flex-col gap-1"></div>
</section>
</div>
</div>

<div id="canvasBottomGrid" class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
<section class="bg-surface-container-lowest p-6 rounded shadow-sm border-t-4 border-error/20">
<header class="flex items-center gap-2 mb-4">
<span class="material-symbols-outlined text-error text-lg">payments</span>
<h3 class="section-edit-trigger text-sm font-bold text-on-surface-variant uppercase tracking-widest" data-key="costStructure">Cost Structure</h3>
</header>
<div id="costStructureList" class="grid grid-cols-1 sm:grid-cols-2 gap-y-3 gap-x-6 text-sm text-on-surface"></div>
</section>
<section class="bg-surface-container-lowest p-6 rounded shadow-sm border-t-4 border-primary/20">
<header class="flex items-center gap-2 mb-4">
<span class="material-symbols-outlined text-primary text-lg">monetization_on</span>
<h3 class="section-edit-trigger text-sm font-bold text-on-surface-variant uppercase tracking-widest" data-key="revenueStreams">Revenue Streams</h3>
</header>
<div id="revenueStreamsCards" class="flex flex-wrap gap-3"></div>
</section>
</div>
</div>
</div>
<!-- Der Todo Bereich wird dynamisch eingefügt, wenn in der Markdown ein Todo Abschnitt vorhanden ist -->
</main>

<div id="toast" class="fixed right-4 bottom-24 md:bottom-6 opacity-0 pointer-events-none transition-opacity bg-slate-900 text-white text-sm px-3 py-2 rounded shadow-lg"></div>

<script src="script.js"></script>
</body>
</html>
Expand Down
Loading