The 1920 × 1080 canvas
The canvas never changes size, so a pixel you write is the pixel that ships.
Every page is laid out inside a box that is exactly 1920 × 1080 CSS pixels. The
runtime measures whatever container the box is sitting in — the editor canvas, a
thumbnail in the rail, a projector in fullscreen — takes
min(width / 1920, height / 1080), and applies that as a single uniform
transform: scale().
Nothing about the page changes. It is the same 1920 × 1080 layout at every size, just drawn larger or smaller.
Why it is fixed
A deck is a visual artefact that has to survive being moved around: you build it on a laptop, present it on a projector at a different aspect and resolution, then send a PDF of it to someone who was not in the room. It has to look the same in all three.
Uniform scaling makes that free. Because there is no reflow, there is no breakpoint that can fire on stage and no line that wraps differently in the export than it did in the preview. What you positioned is what everyone sees.
The trade you accept is that the canvas does not scroll. Anything you place
below 1080px is cropped and gone — so page count is the release valve, not
overflow. The slide-authoring skill carries the arithmetic for staying inside
the budget.
The constants are exported if you need to compute against them:
import { CANVAS_WIDTH, CANVAS_HEIGHT } from '@beem-slide/core';
// 1920, 1080Laying out inside it
Work in absolute pixels. rem inherits from a root font size you do not
control, and vw / vh track the viewport rather than the canvas — both
of them break the guarantee the fixed canvas exists to give you.
Two patterns cover almost everything:
Absolute placement. position: absolute with pixel coordinates. Nothing
moves unless you move it, which makes a page trivial to reason about and
trivial for an agent to edit precisely.
Flex or grid, centred. When you want a row of cards to distribute evenly or a headline to sit optically centred, let the layout engine do it. Just skip the media queries — there is only ever one width.
One useful third option: if you are building a component that has to look right
at more than one size — a widget you also embed somewhere smaller — set
containerType: 'inline-size' on its wrapper and size its type in cqw. It
then scales with its own box rather than the canvas.
Type and colour
Absolute pixels mean you need a deliberate type ramp rather than a default one.
The slide-authoring skill ships a scale and a palette so agent-written pages
come out consistent, and per-deck themes override them
when you want a specific look.