# 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`:
```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:
```css
: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:
```css
.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:
1. **Use semantic class naming**: `.layout-[layout-name]`
2. **Include slot elements** for editable content
3. **Use Handlebars syntax** for template variables
### Slot System
Slots are editable areas defined with specific data attributes:
```html
{{slot-id}}
```
#### Slot Data Attributes:
- `data-slot="[id]"`: Unique identifier for the slot
- `data-placeholder="[text]"`: Placeholder text when empty
- `data-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"` with `data-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]`
```css
.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`:
```html
```
### 2. Add Layout Styles to theme CSS
Add to the theme's `style.css`:
```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
```css
.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
```css
/* 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`:
```html
```
Style master slide elements:
```css
.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:
```css
.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:
```css
@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:
```css
@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
```html
{{content}}
```
#### 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
```css
.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
1. **Use clamp() for responsive typography**: `font-size: clamp(min, preferred, max)`
2. **Leverage CSS custom properties**: Makes themes easily customizable
3. **Follow existing naming conventions**: `.layout-[name]`, `.slot[data-slot="name"]`
4. **Test across aspect ratios**: Ensure layouts work in 16:9, 4:3, and 16:10
5. **Consider accessibility**: Use sufficient color contrast and readable fonts
6. **Use semantic HTML**: Proper heading hierarchy and meaningful class names
7. **Keep layouts flexible**: Use flexbox/grid for responsive behavior
8. **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