- Reveal.js presentation on Skills and Subagents pattern - Nix flake with Caddy-based HTTP server and process-compose orchestration - ADRs documenting architectural decisions - Skills for AI implementation guidance - Full Scott Scoble author attribution in README
234 lines
6.6 KiB
HTML
234 lines
6.6 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Beyond the Prompt - Printable Version</title>
|
|
<style>
|
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap');
|
|
@import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap');
|
|
|
|
@page {
|
|
size: letter;
|
|
margin: 0.75in;
|
|
}
|
|
|
|
body {
|
|
font-family: 'Inter', sans-serif;
|
|
font-size: 11pt;
|
|
line-height: 1.5;
|
|
color: #2c3e50;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.slide {
|
|
page-break-after: always;
|
|
margin-bottom: 2em;
|
|
border-bottom: 3px solid #5277c3;
|
|
padding-bottom: 1em;
|
|
}
|
|
|
|
.slide-header {
|
|
background: #5277c3;
|
|
color: white;
|
|
padding: 0.5em 1em;
|
|
margin: -0.75in -0.75in 1em -0.75in;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.slide-content h1 {
|
|
color: #5277c3;
|
|
font-size: 24pt;
|
|
margin-top: 0;
|
|
border-bottom: 3px solid #5277c3;
|
|
padding-bottom: 0.25em;
|
|
}
|
|
|
|
.slide-content h2 {
|
|
color: #5277c3;
|
|
font-size: 18pt;
|
|
margin-top: 0.5em;
|
|
}
|
|
|
|
.slide-content h3 {
|
|
color: #5277c3;
|
|
font-size: 14pt;
|
|
}
|
|
|
|
.slide-content p {
|
|
margin: 0.75em 0;
|
|
}
|
|
|
|
.slide-content ul, .slide-content ol {
|
|
margin: 0.75em 0;
|
|
padding-left: 2em;
|
|
}
|
|
|
|
.slide-content li {
|
|
margin: 0.5em 0;
|
|
}
|
|
|
|
.slide-content code {
|
|
font-family: 'Fira Code', monospace;
|
|
background: #f8f9fa;
|
|
padding: 0.1em 0.3em;
|
|
border-radius: 3px;
|
|
font-size: 10pt;
|
|
}
|
|
|
|
.slide-content pre {
|
|
background: #f8f9fa;
|
|
border: 1px solid #e9ecef;
|
|
border-radius: 4px;
|
|
padding: 1em;
|
|
overflow-x: auto;
|
|
font-size: 9pt;
|
|
}
|
|
|
|
.slide-content pre code {
|
|
background: none;
|
|
padding: 0;
|
|
}
|
|
|
|
.speaker-notes {
|
|
background: #f8f9fa;
|
|
border-left: 2px solid #5277c3;
|
|
padding: 0.4em 0.6em;
|
|
margin-top: 0.5em;
|
|
font-size: 7pt;
|
|
font-style: italic;
|
|
color: #666;
|
|
line-height: 1.3;
|
|
}
|
|
|
|
.speaker-notes-header {
|
|
font-weight: 600;
|
|
color: #5277c3;
|
|
font-style: normal;
|
|
margin-bottom: 0.25em;
|
|
font-size: 7pt;
|
|
}
|
|
|
|
.speaker-notes p {
|
|
margin: 0.25em 0;
|
|
font-size: 7pt;
|
|
}
|
|
|
|
.incremental {
|
|
margin-left: 2em;
|
|
color: #666;
|
|
}
|
|
|
|
.incremental::before {
|
|
content: "→ ";
|
|
color: #5277c3;
|
|
}
|
|
|
|
blockquote {
|
|
border-left: 4px solid #5277c3;
|
|
padding-left: 1em;
|
|
margin: 1em 0;
|
|
font-style: italic;
|
|
color: #666;
|
|
}
|
|
|
|
strong {
|
|
color: #5277c3;
|
|
font-weight: 700;
|
|
}
|
|
|
|
table {
|
|
border-collapse: collapse;
|
|
width: 100%;
|
|
margin: 1em 0;
|
|
font-size: 10pt;
|
|
}
|
|
|
|
th {
|
|
background: #5277c3;
|
|
color: white;
|
|
padding: 0.5em;
|
|
text-align: left;
|
|
}
|
|
|
|
td {
|
|
padding: 0.5em;
|
|
border-bottom: 1px solid #e9ecef;
|
|
}
|
|
|
|
@media print {
|
|
.slide {
|
|
page-break-after: always;
|
|
}
|
|
|
|
.slide-header {
|
|
margin: 0;
|
|
margin-bottom: 1em;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<script>
|
|
// Fetch and parse the markdown
|
|
fetch('slides.md')
|
|
.then(response => response.text())
|
|
.then(markdown => {
|
|
const slides = markdown.split(/\n---\n/);
|
|
const container = document.body;
|
|
|
|
slides.forEach((slide, index) => {
|
|
const parts = slide.split(/\n\?\?\?\n/);
|
|
const content = parts[0].trim();
|
|
const notes = parts[1] ? parts[1].trim() : '';
|
|
|
|
const slideDiv = document.createElement('div');
|
|
slideDiv.className = 'slide';
|
|
|
|
const header = document.createElement('div');
|
|
header.className = 'slide-header';
|
|
header.textContent = `Slide ${index + 1}`;
|
|
slideDiv.appendChild(header);
|
|
|
|
const slideContent = document.createElement('div');
|
|
slideContent.className = 'slide-content';
|
|
|
|
// Parse markdown content
|
|
let html = content
|
|
.replace(/^class: center, middle$/gm, '<div style="text-align: center;">')
|
|
.replace(/^--$/gm, '<div class="incremental">')
|
|
.replace(/^# (.*$)/gm, '<h1>$1</h1>')
|
|
.replace(/^## (.*$)/gm, '<h2>$1</h2>')
|
|
.replace(/^### (.*$)/gm, '<h3>$1</h3>')
|
|
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
|
.replace(/`([^`]+)`/g, '<code>$1</code>')
|
|
.replace(/^- (.*$)/gm, '<li>$1</li>')
|
|
.replace(/^(\d+)\. (.*$)/gm, '<li>$2</li>')
|
|
.replace(/^> (.*$)/gm, '<blockquote>$1</blockquote>')
|
|
.replace(/```(\w*)\n([\s\S]*?)```/g, '<pre><code>$2</code></pre>')
|
|
.replace(/\n\n/g, '</p><p>');
|
|
|
|
// Wrap li in ul
|
|
html = html.replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>');
|
|
|
|
slideContent.innerHTML = '<p>' + html + '</p>';
|
|
slideDiv.appendChild(slideContent);
|
|
|
|
if (notes) {
|
|
const notesDiv = document.createElement('div');
|
|
notesDiv.className = 'speaker-notes';
|
|
notesDiv.innerHTML = '<div class="speaker-notes-header">Speaker Notes:</div>' +
|
|
notes.replace(/\n\n/g, '</p><p>').replace(/^/, '<p>').replace(/$/, '</p>');
|
|
slideDiv.appendChild(notesDiv);
|
|
}
|
|
|
|
container.appendChild(slideDiv);
|
|
});
|
|
|
|
// Auto-print after a short delay
|
|
setTimeout(() => {
|
|
window.print();
|
|
}, 1000);
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|