Site and theme¶
The whole file, and the settings that apply to the whole site.
The top level of site.yaml is the Site model below; every other model here is a key under it or under one of its keys.
Site¶
The site spec: one YAML file describes a whole site. The UI, Claude and the CLI all edit this.
A site is a nav, a list of sections and a footer. A section is either a scene (a scroll-driven visual built by a scene module: film, artwork, scene3d, sequence, parallax, type) or a block (static content: intro, features, stats, timeline, quote, cta, gallery).
Site.model_json_schema() is the contract for the UI forms and the MCP tools.
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | required | |
description |
string | "" |
|
lang |
string | "en" |
|
theme |
Theme | {} (its own defaults) |
|
layout |
enum | "flow" |
flow: sections follow one another. stack: every section is a full-screen panel with rounded top corners that slides up over the one before it. Allowed values: "flow", "stack". |
nav |
Nav | {} (its own defaults) |
|
loader |
Loader | {} (its own defaults) |
|
scroll |
Scroll | {} (its own defaults) |
|
sections |
list of one of 30 models, chosen by type: FilmScene, ArtworkScene, Scene3DScene, SequenceScene, ParallaxScene, TypeScene, VectorScene, ChartScene, MapScene, SplatScene, CodeScene, ShowroomScene, DioramaScene, InsideScene, LightScene, StagesScene, IntroBlock, FeaturesBlock, StatsBlock, TimelineBlock, QuoteBlock, CtaBlock, GalleryBlock, HeroBlock, ProductBlock, StripBlock, OrbitBlock, FaqBlock, LogosBlock, SignupBlock |
required | |
footer |
Footer | {} (its own defaults) |
|
pages |
list of Page | [] |
Plain Markdown pages beside the site (privacy, support) |
product |
Product (optional) | null |
The product the site is about, declared once: takes, sequences, showroom scenes and image: {product: <view>} stills use it |
trailer |
Trailer (optional) | null |
A launch film built from the site's renders by studio trailer (16:9 and 9:16); {} derives the cut |
video_model |
enum (optional) | null |
Default video model for film beats, takes and theme.art: ltx (LTX-2.3) or wan (Wan 2.2). Unset = studio.toml's, then ltx Allowed values: "ltx", "wan". |
wan |
Wan | {} (its own defaults) |
Wan 2.2 settings used wherever video_model is wan |
imagery |
Imagery (optional) | null |
How every generated image and film is phrased (medium, light, lens, mood, palette), so the page looks like one shoot; written by picking a direction (studio directions) |
directions |
Directions (optional) | null |
Brief and constraints for studio directions: several complete art directions as side-by-side boards |
Theme¶
| Field | Type | Default | Description |
|---|---|---|---|
preset |
string | "night" |
night, brass, paper, lab, cosmos, studio, dusk, ink, blueprint, clinic (see engine/themes.yaml) |
style |
string (optional) | null |
An experience in one word: its own scroll mechanic, layout, transitions and look. particles, liquid-morph, holographic, neon-glow, wireframe-3d, glassmorphism, kinetic-type, isometric, clay-3d, ascii-art, gradient-mesh, comic-book, split-flap, retro-vhs, halftone, bauhaus, pixel-art, blueprint, art-deco, neo-brutalism, anime-intro, flipbook, pop-up-book, pinscreen, sand, zoetrope, stop-motion, paper-cut-out, scratch-film, smears, paint-on-glass, multiplane (see engine/styles/). Colours/fonts set here still win |
mode |
enum (optional) | null |
Override the preset's light/dark mode (set it when colors flip it) Allowed values: "light", "dark". |
colors |
map of string to string | {} |
Override tokens: bg, bg2, ink, accent, accent2 |
fonts |
map of string to string or FontFile | {} |
Fonts by role (display, body, mono): a Google Fonts family, or a file of the project's own ({file: fonts/Brand.woff2}), served from the site either way |
display_weight |
integer (optional) | null |
|
display_italic_em |
boolean (optional) | null |
Render <em> accent words in italic |
display_em |
enum (optional) | null |
How <em> words are set: accent (the accent colour, italic when display_italic_em), bold (bold italics in the text's own colour, so a headline reads as one face) or heavy (upright, the text's own colour, at the face's heaviest weight: pair with a light display_weight so emphasis is a change of weight) Allowed values: "accent", "bold", "heavy". |
labels |
enum (optional) | null |
Small labels (kickers, tags, timeline dates): caps (spaced capitals in the mono face, the default) or plain (sentence case in the body face, for brands that never set all-caps) Allowed values: "caps", "plain". |
display_optical_size |
integer (optional) | null |
Pin the display face's optical size (variable fonts such as Fraunces or Newsreader grow more expressive at large sizes; 36-48 keeps headlines calm) |
radius |
string (optional) | null |
|
art |
Art (optional) | null |
Artwork the style renders in its own medium (ascii-art: characters, particles: points). A prompt or a file, optionally animated |
space |
SpaceTokens (optional) | null |
Page spacing: gutter, max width, caption width |
type |
TypeTokens (optional) | null |
Type sizes: headline scale and running-text size |
shade |
ShadeTokens (optional) | null |
Strength of the shade over scene pictures |
motion |
MotionTokens (optional) | null |
Easing, how blocks arrive and how smooth scrolling follows |
grain |
number (optional) | null |
Film grain over the whole page: 0 none (the default) to 1; 0.15-0.3 reads as print or film Constraints: 0 to 1. |
from |
string or Brand (optional) | null |
Wear a brand: a web page URL, a logo image or a brand.yaml in the project (read once and kept in .build/brand/), or the brand's tokens themselves (what studio brand writes). Its colours, fonts, radius and logo go over the preset and the style; anything else set on theme still wins |
phone |
integer (optional) | null |
Width in px below which the page takes its phone layout, for the stylesheet and the runtime alike. Unset keeps the built-in widths (900 for the layout, 760 for scenes, 700 for one-take pages) Constraints: 320 to 1600. |
Used in: Site.theme.
Nav¶
| Field | Type | Default | Description |
|---|---|---|---|
logo |
string (optional) | null |
Inline SVG path data (24x24) or an image file |
links |
list of Link | [] |
Empty = generated from sections with nav_label |
cta |
Link (optional) | null |
Used in: Site.nav.
Loader¶
Loading screen: scrolling stays locked until every scene's media has loaded (videos fully downloaded, frames decoded, map tiles drawn), with a progress bar.
Used in: Site.loader.
Scroll¶
| Field | Type | Default | Description |
|---|---|---|---|
speed |
number | 1.0 |
Pace of the smooth scroll, anchor scrolls and scroll-driven reveals: 1.2 is a fifth faster, 0.8 a fifth slower |
Used in: Site.scroll.
Footer¶
| Field | Type | Default | Description |
|---|---|---|---|
left |
string (optional) | null |
|
right |
string (optional) | null |
|
links |
list of Link | [] |
Links shown before right, e.g. a privacy policy or terms hosted elsewhere (pages: adds its own) |
Used in: Site.footer.
Page¶
A plain page beside the site (privacy policy, support, press): Markdown set in the site's theme, served at /<slug>/ and linked from the footer.
Used in: Site.pages.
Product¶
The product the site is about, declared once. The model is converted, fixed (axes, units), centred on its
base, given its part materials and cached as one GLB; then takes (product: {}), sequences (model: product),
showroom scenes and product stills (image: {product: three-quarter}) all use it, and its credit and licence go
in the footer. One of model or from_photo.
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | required | Product name, e.g. 'Flipper Zero' |
maker |
string (optional) | null |
Who makes it, e.g. 'Flipper Devices' |
url |
string (optional) | null |
The maker's page for the product |
model |
string (optional) | null |
3D model: GLB/glTF, OBJ, FBX, STL, PLY, STEP/STP (converted locally with OpenCascade, parts kept with their names) or 3MF; a project file or an https URL (downloaded once) |
from_photo |
string (optional) | null |
A cut-out PNG turned into a 3D model with TRELLIS.2 (see ProductLayer) |
up |
enum | "auto" |
Which axis of the file points up. auto: the format's convention (glTF, FBX and OBJ: y; STL, PLY, STEP and 3MF: z) Allowed values: "auto", "z", "y", "x", "-z", "-y", "-x". |
units |
enum | "auto" |
Units the file is in. auto: metres for glTF/FBX/OBJ/PLY, millimetres for STL; STEP and 3MF carry their own; anything over 20 m is taken as millimetres Allowed values: "auto", "m", "cm", "mm", "in", "ft". |
rotation |
list of 3 numbers | [0, 0, 0] |
Euler degrees applied after the up fix: turn the product so its front faces -y (the front view) Constraints: exactly 3 items. |
parts |
list of PartMaterial | [] |
Material overrides by part name |
exclude |
list of string | [] |
Globs on part or assembly names to leave out: alternate variants stacked in one CAD file, internal parts, packaging |
tessellation |
enum | "normal" |
STEP: how finely curved surfaces are meshed (fine is smoother and heavier) Allowed values: "draft", "normal", "fine". |
max_triangles |
integer | 1500000 |
Decimate only above this many triangles Constraints: at least 10000. |
licence |
string (optional) | null |
The model's licence, e.g. 'CC BY 4.0'; shown with the credit |
credit |
string (optional) | null |
Attribution for the model, e.g. '3D model by Framework Computer Inc' (default: '<name> 3D model by <maker>') |
concept |
boolean | false |
Mark the page as a concept: the footer (and the trailer's end card) say 'Concept page. Not affiliated with <maker>.' |
Used in: Site.product.
Trailer¶
A launch film cut by the engine from the site's own renders (studio trailer): dist/trailer/trailer-16x9.mp4,
trailer-9x16.mp4 (reframed, never letterboxed) and their posters. Cuts land on a beat grid; captions and the end
card are set in the theme's fonts and colours. trailer: {} derives the cut: a hook shot, the middle of the
story, the product reveal, 2-4 feature callouts and an end card.
| Field | Type | Default | Description |
|---|---|---|---|
shots |
list of TrailerShot | [] |
The cut, in order. Empty: derived from the site |
formats |
list of enum | ["16x9", "9x16"] |
16x9: 1920x1080; 9x16: 1080x1920 for TikTok/Reels/Shorts Allowed values: "16x9", "9x16". |
seconds |
number | 24.0 |
Target length of a derived cut (15-30 s suits social) Constraints: 8 to 90. |
bpm |
number | 100.0 |
Tempo of the beat grid the cuts land on Constraints: 40 to 220. |
music |
string (optional) | null |
A local audio file (project path); none is generated. Without it the trailer is silent and the captions carry it |
music_start |
number | 0.0 |
Seconds into the music where the first cut lands (a downbeat) Constraints: at least 0. |
loudness |
number | -14.0 |
Music loudness target, integrated LUFS Constraints: -30 to -8. |
fps |
enum | 24 |
Allowed values: 24, 30. |
captions |
boolean | true |
Set captions over the shots |
title |
string (optional) | null |
End card name (default: the site name) |
tagline |
string (optional) | null |
End card line (default: the site description) |
cta |
string (optional) | null |
End card call to action (default: the nav button's label) |
url |
string (optional) | null |
End card address, e.g. stillwater.example (default: the nav button's link when it is a full URL) |
disclaimer |
string (optional) | null |
Small print on the end card (default: the product's concept line, 'Concept page. Not affiliated with <maker>.') |
end_beats |
integer | 8 |
Length of the end card on the beat grid Constraints: 2 to 32. |
end_background |
enum | "blur" |
blur: the last shot, blurred under the theme colour; theme: the plain background Allowed values: "blur", "theme". |
embed |
boolean | false |
Add a 'Watch the launch film' button to the first section that opens the trailer in a modal (built by studio trailer, picked up by the next build) |
embed_label |
string | "Watch the launch film" |
Label of the embed button |
Used in: Site.trailer.
Wan¶
Wan 2.2 A14B settings (video_model: wan). Two 14B experts sample in turn (high-noise for the first half of
the steps, low-noise for the rest). Renders at ~1280x720, 16 fps, up to 81 frames (~5 s) per clip; longer shots
chain clips from the previous last frame; frames are retimed to 24 fps and restored/upscaled as usual.
Imagery¶
How every image and film this site generates is phrased, so the whole page looks like one shoot. Each part is
added to every prompt the engine sends to the image and video models (a generate: image, a beat's frame and clip,
a take's keyframes and segments); the prompt itself stays about the subject. Unset, nothing is added. A direction
from studio directions writes this block when you pick it.
Used in: Site.imagery.
Directions¶
Art directions for this site (studio directions <project>): the studio's pitch. One brief in, several complete
directions out (concept, palette, type, style, imagery, motion), each a board of storyboard stills side by side; pick
one and it is written into this file. The writer is deterministic (curated design vocabularies combined by seed), so
the same brief and seed give the same boards. Copy is never changed.
| Field | Type | Default | Description |
|---|---|---|---|
brief |
string (optional) | null |
What to pitch, in your words: 'calmer, more editorial; for people who travel slowly'. Mood words in it steer the directions |
count |
integer | 6 |
How many directions Constraints: 2 to 12. |
seed |
integer | 1 |
Another seed, another set of directions |
moods |
list of string | [] |
Mood words to lean toward (calm, warm, bold, playful, technical, raw, nostalgic, futuristic, handmade, luxurious...) |
keep |
list of enum | [] |
Parts of the site's current look every direction must keep, varying the rest. The name and copy are always kept Allowed values: "style", "colors", "fonts", "imagery". |
styles |
Pool | {} (its own defaults) |
Which styles (engine/styles/) to consider or avoid; 'none' is the default editorial layout |
fonts |
Pool | {} (its own defaults) |
Google Fonts families to consider or avoid |
palettes |
PalettePool | {} (its own defaults) |
Palettes to consider or avoid, and brand colours to carry |
stills |
integer | 4 |
Storyboard stills per board: the hero, then key sections Constraints: 1 to 6. |
Used in: Site.directions.