Build Beautiful.ai

KINDAreplaces $45/mosaves $540/yrback to the verdict

0%0 of 20 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

Slides defined as structured content bound to layout rules that compute positions, text that auto-fits within readable bounds, a theme applied by reference so a brand change updates every slide, and export to PDF and to a presentation format that opens correctly elsewhere.

estimated effort multi-daythe files for this build are in the project pack

RuntimeTypeScript with ViteLayoutRules computing positions from content, never free positioningRenderingSVG for the editor and for PDF, through one layout functionExportPDF from the same layout, plus a presentation format for people who need the fileTextMeasured with the real font before layout

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. installfree

    Why Runs the build and the export pipeline.

    Get it nodejs.org, or nvm install 22. open ↗

    Verify node --version prints v22 or higher

  2. installvaries; a free alternative is adequate for a fidelity check

    Why Phase 5 is only meaningful if you open the exported file where your audience will. Your own renderer agreeing with itself proves nothing.

    Get it Whichever your colleagues use. If several, test in each, because they differ.

    Verify An exported deck opens with text and images in the right places

  3. have readyfree with open licences

    Why Both exports embed or substitute fonts, and substitution is what breaks a deck on someone else's machine.

    Get it Openly licensed families with their licence files kept alongside.

    Verify Each bundled font permits embedding

  4. have readyfree

    Why Layout rules are only testable against real content, which has the long headings and awkward bullet counts that invented content does not.

    Get it Take a deck you actually presented and rebuild it. The slides that resist are where the layout rules need work.

    Verify A real deck of at least ten slides is rebuilt

  5. have readyfree

    Why Phase 4's focal point handling cannot be judged without an image whose subject is not centred.

    Get it Any photo library. One tall portrait with a face near the top is the case that matters.

    Verify The portrait is available as a fixture

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- decks(id, title, theme_id, created_at, updated_at)
- slides(id, deck_id, ordinal, layout_key, content_json, notes)
- layouts(key, name, slots_json, rules_json) · slots describe what content a layout accepts and rules compute geometry from it
- themes(id, name, palette_json, fonts_json, spacing_json)
- assets(id, deck_id, kind, path, bytes, focal_x, focal_y)
- Content is stored as structure rather than as positioned boxes. Position is always derived, which is what makes reflow possible.

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
VITE_AUTOFIT_MIN_PTrequired14Smallest size auto-fit will produce before reporting the content is too long. Presentation text has a real readability floor.
VITE_MAX_IMAGE_PXrequired3000Longest edge kept on import.
VITE_FONT_DIRrequired/fontsSelf-hosted fonts with licences beside them.
VITE_EXPORT_DPIrequired150Rasterisation density for images in exports.
VITE_LAYOUT_DIRrequired/layoutsLayout definitions as data. Adding a layout is a file here.

The build, in order

  1. One layout that computes itself

    A slide reflows when its content changes, without anyone moving anything.

    1. Slots and rules. Written down before implementation, like any format that others will extend.

      Files docs/layout-format.md

    2. Content and theme in, geometry out. No document object model access, so it is testable directly.

      Files src/layout.ts

    3. Grep the schema. A stored position is the thing that breaks reflow.

      Files src/model.ts

    done when · tick each as it passes
    watch out
    • Building an editor with draggable boxes first and adding rules later never works, because the stored positions become the source of truth and the rules have nothing to compute. Start with computed geometry and never store a position.
  2. Text that fits and stays readable

    Auto-fit shrinks text to fit and stops before it becomes unreadable.

    1. Await font loading, then measure. Re-measure on load completion if you measured early.

      Files src/text.ts

    2. Below the floor is a content problem, not a sizing problem, and the layout should say so.

      Files src/autofit.ts

    3. A profile without the font cached. This is where a fallback measurement shows up.

    done when · tick each as it passes
    watch out
    • Measuring against a fallback font and rendering with the real one produces text that overflows by a word once the face loads, and the failure appears only on someone else's machine. Wait for font loading before measuring, and re-measure when a font finishes loading.
  3. Themes applied by reference

    Changing the brand updates every slide at once.

    1. Palette, fonts, spacing. Layouts read from the theme rather than embedding values.

      Files src/theme.ts

    2. Because font metrics changed, auto-fit must run again across the deck.

      Files src/deck.ts

    3. Or make them named variants. This is the rule that keeps the premise intact.

      Files src/model.ts

    done when · tick each as it passes
    watch out
    • Letting a slide override a theme value with a literal is the feature that destroys the premise, because within a week half the deck is hand-coloured and a brand change no longer works. If overrides are needed, keep them as named theme variants rather than arbitrary values.
  4. Images without ruining the layout

    An image of any shape fits its slot without distortion or a decapitated subject.

    1. Cover fit anchored to the focal point, adjustable, defaulting to centre.

      Files src/image.ts

    2. A twelve megapixel photo in a slide is wasted bytes and a slow editor.

      Files src/assets.ts

    3. The layout rule accounts for the image slot. An image placed over text is the thing this product avoids.

      Files src/layout.ts

    done when · tick each as it passes
    watch out
    • Centre-cropping a portrait into a wide slot removes the top of whatever matters, reliably. Store a focal point per image, default it to centre and make it adjustable, which is a small feature that prevents most bad slides.
  5. Export, including the file people ask for

    A PDF is faithful, and the presentation file opens correctly enough to present from.

    1. The same geometry as the preview. Any divergence here is a bug rather than a format difference.

      Files src/export-pdf.ts

    2. Absolute boxes with embedded or substituted fonts, accepting the loss.

      Files src/export-pptx.ts

    3. From the first template. This is the check people skip and regret.

      Files docs/export-fidelity.md

    done when · tick each as it passes
    watch out
    • A presentation format export is inherently lossy: your computed layout becomes absolutely positioned boxes, and fonts, line breaking and effects may all differ in the receiving application. Test in a real one from the first template and write down what is lost, rather than discovering it when someone opens your deck before a meeting.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more presentations.