Guide: Presentation slides
- Make each slide a frame of 1920 by 1080. Put the slides in reading order from left to right, 100 px apart: `x` is 0, 2020, 4040 and so on. - Make a small set
- Make each slide a frame of 1920 by 1080. Put the slides in reading order from left to right, 100 px apart:
xis 0, 2020, 4040 and so on. - Make a small set of slide components, such as a title slide and a slide with points. Place each one many times, with different
propson each frame. - Keep text short. Make titles 64 to 96 px and body text 32 to 40 px, with six lines or less on a slide.
- Keep a margin of 120 px on each side. Put the slide number in the same place on each slide.
- Use a title slide, an agenda, one idea on each slide and a closing slide.
- Make charts as in guide/dashboard.md, at a larger size.
type TitleSlideProps = { title?: string; subtitle?: string; className?: string }
export function TitleSlide({
title = 'Ledger',
subtitle = 'Board update, October 2026',
className = ''
}: TitleSlideProps) {
return (
<section
className={`flex size-full flex-col justify-end gap-6 bg-foreground p-30 text-background ${className}`}
>
<h1 className="font-display text-[120px] leading-none font-semibold tracking-tight">
{title}
</h1>
<p className="text-[40px] opacity-70">{subtitle}</p>
</section>
)
}
type PointsSlideProps = {
number?: string
title?: string
point1?: string
point2?: string
point3?: string
className?: string
}
export function PointsSlide({
number = '02',
title = 'What changed',
point1 = 'Revenue grew 18% on the last quarter.',
point2 = '',
point3 = '',
className = ''
}: PointsSlideProps) {
return (
<section
className={`flex size-full flex-col gap-16 bg-background p-30 text-foreground ${className}`}
>
<div className="flex items-baseline justify-between">
<h2 className="text-[80px] leading-none font-semibold tracking-tight">{title}</h2>
<span className="font-mono text-[32px] text-muted-foreground">{number}</span>
</div>
<ul className="flex flex-col gap-8 text-[40px] leading-snug">
{point1 && <li>{point1}</li>}
{point2 && <li>{point2}</li>}
{point3 && <li>{point3}</li>}
</ul>
</section>
)
}
export const canvas = {
pages: [
{
name: 'Deck',
items: [
{ render: TitleSlide, x: 0, y: 0, width: 1920, height: 1080 },
{
render: PointsSlide,
props: {
number: '02',
title: 'What changed',
point1: 'Revenue grew 18% on the last quarter.',
point2: 'Overdue invoices fell to 6%.',
point3: 'Payouts now reach 40 countries.'
},
x: 2020,
y: 0,
width: 1920,
height: 1080
},
{
render: PointsSlide,
props: {
number: '03',
title: 'Next quarter',
point1: 'Launch in Japan.',
point2: 'Hire two engineers.'
},
x: 4040,
y: 0,
width: 1920,
height: 1080
}
]
},
{ name: 'Components', kind: 'components', items: [] }
]
}
The subset has no lists from arrays, so a slide with points has one prop for each point. An empty point does not show.