Beem Slide

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, 1080

Laying 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.

On this page