# Codeless themes: template overrides, the ninjatpl engine, seed, screenshots Read this before building or editing a codeless **theme** (a `.bnp` that re-skins the built-in blocks and ships page templates, presets, fonts, an email wrapper, and demo content). Distilled from the theme-fleet build (16 themes, 2026-07-05). Companion to `cms/docs/TEMPLATE_PLUGINS.md` and `cms/docs/theme-previews.md`. ## What a codeless theme is No Go, no `plugin.wasm`, **no `go.mod`, no `block_core` pin**. The repo is: ``` manifest.yaml # theme_presets, bundled_fonts, master_pages, system_templates, # page_templates, template_overrides, css.input_css_append, email wrappers plugin.mod # name/display_name/kind="theme"/scope="@themes"/categories/tags/required_icon_packs templates//*.html # the page templates (default, full-width, landing, article, blog-index, contact, auth) templates/overrides//*.ninjatpl # one per built-in block key you re-skin templates/email/.ninjatpl # email wrapper blocks/*.ninjatpl + *.schema.json # persona blocks ONLY (things no built-in covers) presets.json fonts.json master_pages.json seed/seed.json seed/workflows.json # demo content (demo:true) assets/ # fonts, css, static ``` Compatibility is not pinned in the repo — it is enforced by manifest synthesis in `ninja plugin build` and the registry gates. `kind = "theme"` is frozen at first publish. ## Re-skinning a built-in block = a template override Ship `templates/overrides//.ninjatpl` **plus** a `template_overrides` entry in `manifest.yaml` (`template_key: `, `block_key: `). Keys use the **dashed canonical form** (`video-embed`, `feature-grid`, `author-bio-hero`). Some accept underscore aliases, but overrides target the dashed key. A re-skin is **presentation only**. Copy the built-in's default template as your starting point (`cms/backend/blocks/builtin/manifest/{blocks.yaml,schemas,sample}` for declarative builtins; the compiled builtin's Go for the rest) and preserve **every** content-field read, provider variable, custom tag (`{% img %}`, `{% button %}`, `{% form %}`, `{% signup_form %}`, `{% auth_form %}`), and inline `