- Implement safe markdown processing with marked and DOMPurify - Add markdown-slide layout template with dedicated markdown slots - Support auto-detection of markdown content in text slots - Include comprehensive markdown styling (lists, headers, code, quotes, tables) - Maintain security with HTML sanitization and safe element filtering - Add markdown documentation to theme creation guidelines 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
9.8 KiB
Theme Creation Guidelines
Theme Structure
Each theme must follow this directory structure:
themes/
theme-name/
style.css # Theme styles and metadata
master-slide.html # Master slide template (optional)
layouts/ # Layout templates directory
layout1.html
layout2.html
...
CSS Theme Metadata
Theme metadata MUST be included as comments at the top of style.css
:
/*
* Theme: [theme-id]
* Name: [Display Name]
* Description: [Theme description]
* Author: [Author Name] ([email])
* Version: [version]
*/
CSS Variables System
Required Theme Variables
Define these CSS custom properties in :root
for consistent theming:
:root {
/* Colors */
--theme-primary: #color; /* Primary brand color */
--theme-secondary: #color; /* Secondary accent color */
--theme-accent: #color; /* Interactive accent color */
--theme-background: #color; /* Slide background */
--theme-text: #color; /* Primary text color */
--theme-text-secondary: #color; /* Secondary text color */
/* Typography */
--theme-font-heading: 'Font', fallback;
--theme-font-body: 'Font', fallback;
--theme-font-code: 'Font', fallback;
/* Layout */
--slide-padding: 5%; /* Slide edge padding */
--content-max-width: 90%; /* Max content width */
}
Required Base Slide Styling
Always include this base styling that works with the global .slide-container
classes:
.slide-container .slide-content,
.slide {
width: 100%;
height: 100%;
background: var(--theme-background);
color: var(--theme-text);
font-family: var(--theme-font-body);
padding: var(--slide-padding);
box-sizing: border-box;
display: flex;
flex-direction: column;
position: relative;
overflow: hidden;
justify-content: center;
align-items: center;
text-align: center;
}
Layout HTML Templates
Required Layout Structure
Each layout HTML file must:
- Use semantic class naming:
.layout-[layout-name]
- Include slot elements for editable content
- Use Handlebars syntax for template variables
Slot System
Slots are editable areas defined with specific data attributes:
<div class="slot [slot-type]"
data-slot="[slot-id]"
data-placeholder="[placeholder-text]"
data-required
data-multiline="true"
data-accept="image/*"
data-hidden="true">
{{slot-id}}
</div>
Slot Data Attributes:
data-slot="[id]"
: Unique identifier for the slotdata-placeholder="[text]"
: Placeholder text when emptydata-required
: Mark slot as required (optional)data-multiline="true"
: Allow multiline text input (optional)data-accept="image/*"
: For image slots (optional)data-hidden="true"
: Hide from direct editing (optional)
Common Slot Types:
- Title slots:
data-slot="title"
- Text content:
data-slot="content"
- Images:
data-slot="image"
withdata-accept="image/*"
- Subtitles:
data-slot="subtitle"
- Markdown content:
data-slot="content" data-type="markdown"
Layout CSS Naming Convention
Style layouts using the pattern: .layout-[layout-name]
.layout-my-layout,
.slide-container .layout-my-layout {
/* Layout-specific styles */
}
.layout-my-layout .slot[data-slot="title"] {
/* Slot-specific styles */
}
Creating New Layouts
1. Create Layout HTML Template
Create themes/[theme]/layouts/my-layout.html
:
<div class="slide layout-my-layout">
<h1 class="slot title-slot"
data-slot="title"
data-placeholder="Slide Title"
data-required>
{{title}}
</h1>
<div class="slot content-area"
data-slot="content"
data-placeholder="Your content here..."
data-multiline="true">
{{content}}
</div>
</div>
2. Add Layout Styles to theme CSS
Add to the theme's style.css
:
/* My Layout */
.layout-my-layout,
.slide-container .layout-my-layout {
justify-content: flex-start;
align-items: stretch;
}
.layout-my-layout .slot[data-slot="title"] {
font-size: clamp(1.5rem, 6vw, 2.5rem);
margin-bottom: 2rem;
text-align: center;
}
.layout-my-layout .slot[data-slot="content"] {
flex: 1;
font-size: clamp(1rem, 2.5vw, 1.25rem);
text-align: left;
}
Standard Slot Styles
Required Slot Base Styles
.slot {
position: relative;
border: 2px dashed transparent;
min-height: 2rem;
transition: border-color 0.2s ease;
width: 100%;
max-width: var(--content-max-width);
margin: 0 auto;
text-align: inherit;
}
.slot:hover,
.slot.editing {
border-color: var(--theme-accent);
border-radius: 4px;
}
.slot.empty {
border-color: var(--theme-secondary);
opacity: 0.5;
display: flex;
align-items: center;
justify-content: center;
}
.slot.empty::before {
content: attr(data-placeholder);
color: var(--theme-text-secondary);
font-style: italic;
}
Slot Type Styles
/* Text slots */
.slot[data-type="title"] {
font-family: var(--theme-font-heading);
font-weight: bold;
line-height: 1.2;
text-align: center;
}
.slot[data-type="subtitle"] {
font-family: var(--theme-font-heading);
line-height: 1.4;
opacity: 0.8;
text-align: center;
}
.slot[data-type="text"] {
line-height: 1.6;
text-align: left;
}
/* Image slots */
.slot[data-type="image"] {
display: flex;
align-items: center;
justify-content: center;
background: #f8fafc;
border-radius: 8px;
}
.slot[data-type="image"] img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
border-radius: 4px;
}
Master Slide Templates
Master slides provide unchangeable content that appears on all slides. Create master-slide.html
:
<div class="master-slide footer">
{{footerText}}
</div>
Style master slide elements:
.master-slide {
position: absolute;
z-index: 1;
}
.master-slide.footer {
bottom: 0;
left: 0;
right: 0;
padding: 1rem;
text-align: center;
font-size: 0.875rem;
opacity: 0.6;
}
Responsive Design
Aspect Ratio Support
Include aspect ratio specific adjustments:
.slide-container.aspect-16-9 .slide-content,
.slide-container.aspect-16-9 .slide {
--slide-padding: 4%;
--content-max-width: 85%;
}
.slide-container.aspect-4-3 .slide-content,
.slide-container.aspect-4-3 .slide {
--slide-padding: 6%;
--content-max-width: 80%;
}
Mobile Responsive
Add mobile breakpoints:
@media (max-width: 768px) {
:root {
--slide-padding: 3%;
--content-max-width: 95%;
}
.layout-my-layout .slot[data-slot="title"] {
font-size: clamp(1.2rem, 5vw, 2rem);
}
}
Print Support
Include print styles for presentation export:
@media print {
.slide {
page-break-after: always;
width: 100%;
height: 100vh;
}
.slot {
border: none !important;
}
.slot.empty::before {
display: none;
}
}
Markdown Support
Markdown Slots
Themes can include slots that automatically process markdown content. This enables rich text formatting while maintaining security.
Creating Markdown Slots
<div class="slot markdown-content"
data-slot="content"
data-type="markdown"
data-placeholder="Enter markdown content..."
data-multiline="true">
{{content}}
</div>
Supported Markdown Features
- Headers:
# H1
,## H2
,### H3
- Text formatting:
**bold**
,*italic*
,~~strikethrough~~
- Lists: Unordered (
-
,*
) and ordered (1.
) - Links:
[text](url)
- Inline code:
`code`
- Code blocks:
markdown```language
- Blockquotes:
> quote
- Tables: GitHub-flavored markdown tables
Security Features
- DOMPurify sanitization: All HTML is sanitized to prevent XSS
- No script execution: JavaScript and dangerous attributes are stripped
- Safe HTML subset: Only presentation-safe HTML elements allowed
- URL filtering: Only safe URL schemes (http, https, mailto) permitted
Styling Markdown Content
.markdown-content h1,
.markdown-content h2,
.markdown-content h3 {
font-family: var(--theme-font-heading);
color: var(--theme-primary);
margin: 1.5em 0 0.5em 0;
}
.markdown-content strong {
color: var(--theme-accent);
font-weight: 600;
}
.markdown-content code {
background: rgba(255, 255, 255, 0.1);
padding: 0.2em 0.4em;
border-radius: 3px;
font-family: var(--theme-font-code);
}
.markdown-content blockquote {
border-left: 4px solid var(--theme-accent);
padding-left: 1rem;
font-style: italic;
}
Auto-Detection
Text slots automatically detect markdown patterns and apply markdown rendering:
- Content with
#
,**
,*
,-
,>
, etc. is processed as markdown - Set
data-type="markdown"
to force markdown processing - Set
data-type="text"
to disable auto-detection
Best Practices
- Use clamp() for responsive typography:
font-size: clamp(min, preferred, max)
- Leverage CSS custom properties: Makes themes easily customizable
- Follow existing naming conventions:
.layout-[name]
,.slot[data-slot="name"]
- Test across aspect ratios: Ensure layouts work in 16:9, 4:3, and 16:10
- Consider accessibility: Use sufficient color contrast and readable fonts
- Use semantic HTML: Proper heading hierarchy and meaningful class names
- Keep layouts flexible: Use flexbox/grid for responsive behavior
- Use markdown for rich content: Enable
data-type="markdown"
for formatted text slots
Template Variables (Handlebars)
Use Handlebars syntax for dynamic content:
{{variableName}}
- Simple variable{{#if condition}}...{{/if}}
- Conditional rendering{{#image}}...{{/image}}
- Check if image exists
Common variables:
{{title}}
- Slide title{{content}}
- Main content{{image}}
- Image source{{imageAlt}}
- Image alt text{{footerText}}
- Footer text