Scenes¶
Sections with a scroll-driven visual. Each is chosen by type.
Every scene also takes the fields of SceneBase, listed first. Where a scene's type is one of these, its own fields follow.
SceneBase¶
| Field | Type | Default | Description |
|---|---|---|---|
id |
string | required | |
nav_label |
string (optional) | null |
|
layout |
enum | "overlay" |
overlay: captions over a full-bleed stage; split: pinned visual beside scrolling cards; cards: full-bleed stage with cards scrolling over it Allowed values: "overlay", "split", "cards". |
side |
enum | "right" |
split/cards: which side the visual sits on Allowed values: "left", "right". |
length |
number | 4.0 |
overlay layout: scroll distance in screen heights |
steps |
list of Step | [] |
|
hud |
Hud | {} (its own defaults) |
|
cue |
string (optional) | null |
'Scroll to …' hint shown at the start |
shade |
enum | "auto" |
Allowed values: "auto", "none", "strong". |
surface |
enum (optional) | null |
Colour scheme for the scene's panel in the stack layout (see blocks); sets the text colour over a backdrop Allowed values: "light", "dark", "accent". |
backdrop |
string or ImageInput (optional) | null |
Full-bleed image behind the whole section: a file, URL, generate: or gradient:. In the stack layout it is the panel's own backdrop. Pair with surface for legible text. |
locked |
boolean | false |
Keep this scene's renders as they are: studio build and studio storyboard never re-render it, even when its settings change (a log line says so). A locked scene that was never rendered is rendered once. Unlock (or delete the render) to redo it |
transition |
Transition (optional) | null |
How this section hands over to the next one, in film grammar: cut, dissolve, wipe, iris, whip, match (a shared shape) or carry (an element travels over). Unset: the sections just follow one another. A bare name works: transition: whip. See Transition |
frame |
"card" (optional) |
null |
card: present the section as a rounded card inset on a border in the theme's accent colours (accent to accent2), as many current landing pages frame their opening. Wide screens only: on a phone it stays full-bleed. Overlay and cards scenes frame their stage, split scenes their picture, a hero its whole panel |
FilmScene¶
A section with type: film.
AI film scrubbed by scroll. Blender blockout -> Z-Image keyframes -> LTX-2.3 -> encode. Or beats: a story told
in separate shots, each a generated still animated by LTX-2.3, joined with short crossfades; steps can pin
themselves to a beat with state: {beat: <id>}.
Also takes every field of SceneBase.
| Field | Type | Default | Description |
|---|---|---|---|
type |
"film" |
"film" |
|
video |
string (optional) | null |
Use an existing film instead of generating one |
shot |
map | {} |
Generation settings: fps, duration, preview_res, blockout {preset|file}, keyframes, ltx, upscale |
take |
Take (optional) | null |
A one-take film described in the spec (world, camera, product) instead of shot |
beats |
list of Beat | [] |
A story film shot by shot (instead of shot / take) |
beat_res |
list of 2 integers | [1920, 1088] |
beats: render size (multiples of 32) Constraints: exactly 2 items. |
beat_fade |
number | 0.4 |
beats: crossfade between shots, in seconds Constraints: 0 to 2. |
beat_restore |
integer (optional) | null |
beats: run SeedVR2 over the finished film at this height (e.g. 1088) to clean grain and redraw fine detail; slow |
finish |
Finish (optional) | null |
The finishing pass over the finished film (see Finish): SeedVR2 restore, deflicker, temporal denoise, sharpen, frame interpolation where motion is slow. finish: true for the defaults |
subject |
Subject (optional) | null |
beats: the one subject the story is about, kept the same from shot to shot (see Subject): beats without an image start on a picture of it made from the reference by the image editor |
gop |
integer | 6 |
|
journey |
Journey (optional) | null |
The page as one camera journey (see Journey): the world described once and an ordered list of stops, each a place in it that shows its blocks (hero, features, stats, quote, faq, cta ...) laid out to sit with the picture. The engine makes the beats (a frozen moment at every stop, a camera move between stops), the scroll timing and the page markup from it; do not write beats, steps or length yourself |
reveal |
Reveal (optional) | null |
Scroll-driven colour: the film is full colour, the page shows the base look and brings colour into tracked regions as you scroll |
faces |
Faces (optional) | null |
restore: repair the faces in the whole film (GFPGAN) before it is encoded; beats can set it per beat. Off by default |
pointer |
Pointer (optional) | null |
The visitor's pointer reveals the picture (see Pointer): {mode: lens} shows the colour (or a second picture) through a soft circle under the pointer, {mode: light} is a torch on a darkened picture. A film's lens shows its own colour |
depth_model |
enum (optional) | null |
Steps with in-world type (place: {kind: ...}): the Depth Anything V2 size that measures the film's depth per frame. small is Apache-2.0 (default); base/large are sharper but CC-BY-NC (non-commercial)Allowed values: "small", "base", "large". |
Used in: Site.sections.
ArtworkScene¶
A section with type: artwork.
Any image, drawn and painted in stages as you scroll.
Also takes every field of SceneBase.
| Field | Type | Default | Description |
|---|---|---|---|
layout |
enum | "split" |
Allowed values: "overlay", "split", "cards". |
type |
"artwork" |
"artwork" |
|
image |
string or ImageInput | required | |
focus |
"auto" or list of list of 2 numbers |
"auto" |
Where drawing starts: 'auto' (faces, then saliency) or [(x, y)] in 0-1 image coords Constraints: each: exactly 2 items. |
stages |
list of enum | ["guides", "lines", "value", "underpaint", "col… |
One stage per step after the intro step, in order Allowed values: "guides", "lines", "value", "underpaint", "colour". |
width |
integer | 1800 |
Working width of the layers in pixels |
line_density |
number | 1.0 |
More (>1) or fewer (<1) contour strokes |
underpaint |
string | "#5a3a22" |
Monochrome underpainting colour |
paper |
string | "#efe8da" |
Paper colour |
caption |
string (optional) | null |
Label under the canvas |
Used in: Site.sections.
Scene3DScene¶
A section with type: scene3d.
Live 3D: a zoom journey through nested levels built from generator presets (or glTF models).
Also takes every field of SceneBase.
| Field | Type | Default | Description |
|---|---|---|---|
layout |
enum | "cards" |
Allowed values: "overlay", "split", "cards". |
type |
"scene3d" |
"scene3d" |
|
style |
enum | "glow" |
glow: additive fluorescence; solid: lit PBR Allowed values: "glow", "solid". |
levels |
list of Level | required | |
zoom |
number | 14.0 |
Scale factor between levels |
background |
string (optional) | null |
|
bloom |
list of 3 numbers | [0.5, 0.45, 0.12] |
Constraints: exactly 3 items. |
final |
string (optional) | null |
Extra beat on the last level, e.g. 'dock' for molecule docking |
dust |
string | "#8fb8d8" |
Colour of the background dust particles |
seed |
integer | 7 |
Seed for the procedural presets |
Used in: Site.sections.
SequenceScene¶
A section with type: sequence.
A 3D model rendered to an image sequence (turntable, explode, assemble) and scrubbed by scroll.
Also takes every field of SceneBase.
Used in: Site.sections.
ParallaxScene¶
A section with type: parallax.
Photos turned into 2.5D camera moves with an estimated depth map; one photo per step, or several captions over
one photo (a step without an image keeps the photo before it).
Also takes every field of SceneBase.
| Field | Type | Default | Description |
|---|---|---|---|
layout |
enum | "cards" |
Allowed values: "overlay", "split", "cards". |
type |
"parallax" |
"parallax" |
|
move |
enum | "dolly" |
Default camera move for each photo Allowed values: "dolly", "pan", "orbit", "rise". |
moves |
list of enum | [] |
Per-photo moves, in step order Allowed values: "dolly", "pan", "orbit", "rise". |
strength |
number | 1.0 |
Depth effect amount |
depth_model |
enum | "small" |
Depth Anything V2 size. small is Apache-2.0; base/large are sharper but CC-BY-NC (non-commercial) Allowed values: "small", "base", "large". |
width |
integer | 2560 |
Max photo width served to desktop browsers |
pointer |
Pointer (optional) | null |
The visitor's pointer reveals the picture (see Pointer): {mode: lens} shows the colour (or a second picture) through a soft circle under the pointer, {mode: light} is a torch on a darkened picture. On photos the light uses each photo's depth map |
Used in: Site.sections.
TypeScene¶
A section with type: type.
Kinetic typography driven by scroll.
Also takes every field of SceneBase.
Used in: Site.sections.
VectorScene¶
A section with type: vector.
A logo or line drawing whose strokes draw themselves, then fill. From an SVG, or a raster image vectorised with vtracer (engravings, illustrations, logos).
Also takes every field of SceneBase.
| Field | Type | Default | Description |
|---|---|---|---|
layout |
enum | "split" |
Allowed values: "overlay", "split", "cards". |
type |
"vector" |
"vector" |
|
svg |
string (optional) | null |
SVG file (project path or https URL) |
image |
string or ImageInput (optional) | null |
Raster image to vectorise when there is no SVG |
order |
enum | "center" |
Which strokes draw first Allowed values: "center", "left", "top", "document". |
colors |
enum | "original" |
Fill colours: as traced, theme ink, or theme accent Allowed values: "original", "ink", "accent". |
detail |
number | 1.0 |
Vectorising detail: higher keeps smaller specks (more paths, heavier page) |
threshold |
integer | 140 |
Raster images: grey level below which a pixel counts as ink (0-255) |
max_width |
integer | 2000 |
Raster images are traced at this width |
background |
string (optional) | null |
Canvas colour behind the drawing (defaults to the theme) |
Used in: Site.sections.
ChartScene¶
A section with type: chart.
A data story: a chart that draws, zooms, highlights and annotates itself as the steps scroll past.
Each step's state says what to show: {show: [series], focus: [series], x: [x0, x1], y: [y0, y1],
reveal: true (draw the lines across this step), marks: [{series, x, label}]}.
Also takes every field of SceneBase.
Used in: Site.sections.
MapScene¶
A section with type: map.
A geographic journey on a live vector map. Each step's state moves the camera and draws routes:
{center: [lng, lat], zoom, pitch, bearing, routes: {route_id: 0-1}}. Tiles come from OpenFreeMap (no key).
Also takes every field of SceneBase.
| Field | Type | Default | Description |
|---|---|---|---|
layout |
enum | "cards" |
Allowed values: "overlay", "split", "cards". |
type |
"map" |
"map" |
|
style |
string | "https://tiles.openfreemap.org/styles/liberty" |
MapLibre style URL |
dark |
boolean | false |
Darken and desaturate the base map to sit under a dark theme |
routes |
list of Route | [] |
|
markers |
list of Marker | [] |
Used in: Site.sections.
SplatScene¶
A section with type: splat.
A real place, scanned: a Gaussian splat the camera flies through as you scroll. Bring a scan from any
phone app or trainer as .ply (3D Gaussian Splatting layout), .spz, or a gsplat .pt checkpoint; the build trims
it and writes a small .spz the page streams. studio build logs the scan's bounds to place the camera keys.
Also takes every field of SceneBase.
| Field | Type | Default | Description |
|---|---|---|---|
type |
"splat" |
"splat" |
|
source |
string | required | Scan file: project path or https URL (.ply, .spz, .pt) |
credit |
string (optional) | null |
Attribution shown in the footer |
max_splats |
integer | 600000 |
Keep the N most opaque splats (page weight ~16 bytes each) |
min_opacity |
number | 0.04 |
Drop splats fainter than this |
max_scale |
number | 0.0 |
Drop splats longer than this (scene units) on any axis: the smears scans leave in the air; 0 keeps all |
crop |
list of 6 numbers (optional) | null |
Keep only x0 y0 z0 x1 y1 z1 Constraints: exactly 6 items. |
sh |
integer | 1 |
Spherical-harmonic degree to keep (view-dependent colour); 0 is smallest Constraints: 0 to 3. |
up |
list of 3 numbers | [0, 0, 1] |
Which way is up in the scan Constraints: exactly 3 items. |
fov |
number | 60.0 |
Vertical field of view in degrees |
keys |
list of SplatKey | required | Camera path over scene progress Constraints: at least 2 items. |
background |
string (optional) | null |
Colour behind the splats (defaults to the theme background) |
Used in: Site.sections.
CodeScene¶
A section with type: code.
Fly through a codebase in live 3D, following an agent at work: the scene opens on its prompt, dives into the
files it reads, stops at each edit while the diff applies itself, and ends on the test run. Steps can pin
themselves to the route with state: {file: <path>} (or 'terminal' / 'outro') instead of at.
Also takes every field of SceneBase.
| Field | Type | Default | Description |
|---|---|---|---|
length |
number | 14.0 |
|
type |
"code" |
"code" |
|
terminal |
CodeTerminal (optional) | null |
|
files |
list of CodeFile | required | The route, in order Constraints: at least 1 items. |
tree |
list of string | [] |
More paths in the project, drawn around the route so it reads as a whole codebase |
Used in: Site.sections.
ShowroomScene¶
A section with type: showroom.
The real product, live in the page: three.js renders the product's normalised GLB with studio environment
lighting and a soft shadow; scroll turns, explodes and zooms it along keys, and the pointer nudges the view.
Also takes every field of SceneBase.
Used in: Site.sections.
DioramaScene¶
A section with type: diorama.
A miniature world: a tilt-shift diorama (a tiny harbour town, a desk, a factory floor, a studio) rendered live in
the page. Scrolling orbits the camera round the whole thing, dives to a place where that step's content sits,
lifts back out and travels to the next. Steps are the places' content: the first step may be an intro (the
world seen whole), the rest take the places in order (or a place names its own with step).
Also takes every field of SceneBase.
| Field | Type | Default | Description |
|---|---|---|---|
layout |
enum | "cards" |
Allowed values: "overlay", "split", "cards". |
length |
number | 10.0 |
|
type |
"diorama" |
"diorama" |
|
world |
DioramaWorld | {} (its own defaults) |
|
places |
list of DioramaPlace | required | Constraints: at least 1 items. |
camera |
DioramaCamera | {} (its own defaults) |
|
look |
DioramaLook | {} (its own defaults) |
|
movers |
list of DioramaMover | [] |
Things that travel routes (see DioramaMover); one may be driven by the scroll |
traffic |
list of DioramaTraffic | [] |
Crowds of movers wandering grids on their own (see DioramaTraffic) |
Used in: Site.sections.
InsideScene¶
A section with type: inside.
The product as the set: the camera flies into the product and the page happens inside it (between the layers of
a board, past the cone and magnet of a speaker, along a keyboard's switches). Each feature is a stop: the camera
lands at a named part with a macro lens and a shallow depth of field, and the copy (the steps, in order) arrives
with it. Rendered offline by Cycles from the site's product (site.product: any model with named parts), a frame
per slice of the flight, and scrubbed by scroll like a sequence. Parts between the camera and the stop's part
dissolve (a cutaway) so the camera can see and travel through the assembly.
Copy: leading steps with intro: true are shown over the opening wide shot; the next steps are matched to the
stops in order; steps after those are shown over the pull-back. studio inside <project> prints the plan (which
parts each stop found, where the copy sits) and renders a still of any stop.
Also takes every field of SceneBase.
| Field | Type | Default | Description |
|---|---|---|---|
layout |
"overlay" |
"overlay" |
overlay only: the camera is pinned and the copy arrives over it |
length |
number | 0.0 |
Scroll distance in screens (0: the sum of the stops' travel and hold, plus the opening and closing shots) |
type |
"inside" |
"inside" |
|
model |
string (optional) | null |
Model file or https URL; omit, or write 'product', to use site.product |
credit |
string (optional) | null |
Attribution shown in the footer (for a model that is not site.product) |
stops |
list of InsideStop (optional) | null |
The camera's stops, in order. Omit for automatic stops: as many as there are copy steps (5 without any), the model's most distinct named parts in a tour order |
establish |
boolean | true |
Open on a wide shot of the whole product, then dive in |
outro |
enum | "wide" |
wide: pull back to the whole product after the last stop (room for a closing step); stay: end at the last stop Allowed values: "wide", "stay". |
lens |
number | 60.0 |
Focal length in mm at the stops (the opening shot uses a wider lens) Constraints: above 4. |
fstop |
number | 11.0 |
Aperture at the stops, for the real product: this is macro, where f/2.8 leaves only a sliver in focus and f/11 keeps a part sharp with the rest falling softly away; f/16 keeps most in focus Constraints: above 0.5. |
explode |
number | 0.0 |
Spread of the parts at every stop unless it sets its own Constraints: 0 to 1.5. |
cutaway |
boolean | true |
Parts between the camera and the stop's part dissolve while the camera is behind them, so it can see (and fly) inside a closed product |
density |
number | 18.0 |
Rendered frames per screen of scroll. 18 is smooth on desktop; lower renders faster and steps more Constraints: above 1. |
size |
list of 2 integers | [1600, 900] |
Frame size (a second set at 960 px wide is made for phones) Constraints: exactly 2 items. |
samples |
integer | 64 |
Cycles samples per frame (denoised) Constraints: 4 to 4096. |
offset |
number | 0.2 |
How far the stop's part sits off the centre of the frame, as a share of its width, towards side (the copy has the other side). 0 centres itConstraints: 0 to 0.4. |
hdri |
string | "studio" |
Blender studio light the interior reflects: studio, city, courtyard, forest, interior, night, sunrise, sunset |
ambient |
number | 0.25 |
Strength of that light on the scene (low: the camera's own lamp lights the macro shot) Constraints: 0 to 4. |
lamp |
number | 1.0 |
Strength of the lamp that travels with the camera Constraints: 0 to 10. |
lamp_color |
string | "#ffe8d0" |
Colour of the camera lamp, hex |
rim |
number | 1.0 |
Strength of the light behind the stop's part (edges, translucent materials glow) Constraints: 0 to 10. |
exposure |
number | 0.0 |
Exposure in stops Constraints: -4 to 4. |
background |
string (optional) | null |
Colour of the void beyond the product (hex; default: the theme background) |
vignette |
number | 0.35 |
Darkening towards the corners Constraints: 0 to 1. |
grain |
number | 0.02 |
Film grain Constraints: 0 to 0.2. |
light |
list of InsideLight | [] |
The light changing along the flight: keys over the scene's progress (0-1, as studio inside prints the stops' rests), eased between keys: evening to lamplight to lights out. A key sets any of exposure, ambient, lamp, rim, lamp_color; what it leaves out stays the scene's. Empty: one light for the whole flight |
Used in: Site.sections.
LightScene¶
A section with type: light.
Light as the scroll: one place, relit from dawn to night as the page scrolls. The world is one picture (a file, a
generated image, or another scene's still); each time of day is that same picture relit with the geometry locked
(Qwen-Image-Edit, measured and aligned to the world), cached per time. In the browser the scroll moves continuously
through the day: a WebGL shader blends neighbouring times with the light itself (a front of new light spreads from
the sun, shadows sweep, windows and lamps come on one by one with a glow), a slow 2.5D drift lets the place
breathe, and the section's colours (captions, shade) follow the sky. Steps are the sections of the day: each sits at
a time (state: {time: <id>}, or in order). Reduced motion shows one still per step.
Also takes every field of SceneBase.
| Field | Type | Default | Description |
|---|---|---|---|
layout |
enum | "overlay" |
Allowed values: "overlay", "split", "cards". |
length |
number | 0.0 |
overlay layout: scroll distance in screen heights (0: 2.6 per time of day) |
type |
"light" |
"light" |
|
world |
string or ImageInput | required | The place: a file, a generated image, an edit, or scene:<id> for the first frame of another scene (built first). Neutral daylight with the lamps off relights best; everything in it stays where it is |
world_time |
string (optional) | null |
The id of the time the world picture already shows (it is used as it is, not relit): the cleanest anchor, e.g. noon |
times |
"day" or list of LightTime |
"day" |
The times of day in order, as presets or free text: [dawn, morning, noon, golden-hour, blue-hour, night]. day is that list. At least two |
hold |
number | 0.3 |
Share of each step the light holds still at its time (so a headline reads in its own light) before the next change begins Constraints: 0 to 0.9. |
lamps |
list of LightLamps | [] |
Lights that come on and go off (windows, lamps); found with Florence-2 + SAM 2.1 and switched one by one in the browser. Without it the build finds what changed from the pictures themselves |
sun |
boolean or LightSun | false |
A sun (and moon) glow that travels over the sky, clipped to it; true or a LightSun. Off by default: the relit pictures already paint a sun or a moon, so use it with prompts that leave the sky bare |
mist |
boolean | true |
Draw the times' haze as drifting mist, thicker with distance (needs depth) |
drift |
number | 0.5 |
A slow 2.5D camera drift through the depth map so the place breathes (0 off; reduced motion always off) Constraints: 0 to 2. |
follow |
boolean | true |
The section's colours follow the sky: caption ink, accent and the shade behind the text are measured from each time's picture and blended with the light |
clock |
boolean | true |
Show the time of day (a clock and a sun arc) in a corner |
focus |
list of 2 numbers | [0.5, 0.5] |
Where a narrow screen (a phone, in portrait) looks: the point of the picture, 0-1 across and down, kept in view when it is cropped Constraints: exactly 2 items. |
blend |
enum | "light" |
light: the light-aware transition; fade: a plain crossfade (for comparison, or a quieter page) Allowed values: "light", "fade". |
structure |
LightStructure | {} (its own defaults) |
Geometry lock: measure each relight against the world, warp small drift away, retry a relight that still drifts |
depth_model |
enum | "small" |
Depth Anything V2 size for the drift and the mist (small is Apache-2.0) Allowed values: "small", "base", "large". |
seed |
integer | 7 |
Seed for the relights |
edit_steps |
integer | 24 |
Qwen-Image-Edit sampling steps per relight Constraints: 4 to 60. |
width |
integer | 1920 |
Width of the pictures served to desktop browsers (phones get two thirds) Constraints: 640 to 3840. |
Used in: Site.sections.
StagesScene¶
A section with type: stages.
One subject through its states, in order: a sequence of stills of exactly the same view (a drawing becoming the
thing, a room before and after, a product being made), scrolled through so every state lines up with the one before.
Each change is revealed by a fade, a wipe or a map (each pixel arrives when the scroll reaches its grey, so parts can
land one by one), optionally with a band of light travelling with the front. The scroll holds on each state while its
step is read. Steps sit at stages (state: {stage: <id or index>}, or in order). Reduced motion and no WebGL show one
still per step.
Also takes every field of SceneBase.
| Field | Type | Default | Description |
|---|---|---|---|
length |
number | 0.0 |
overlay layout: scroll distance in screen heights (0: 2.2 per stage) |
type |
"stages" |
"stages" |
|
stages |
list of Stage | required | The states in order; the first is shown as it is Constraints: at least 2 items. |
hold |
number | 0.35 |
Share of each step the picture holds still at its stage, so a headline reads over a picture that is not changing Constraints: 0 to 0.9. |
drift |
number | 0.5 |
A slow push-in over the scene and an idle breath (0 off; reduced motion always off) Constraints: 0 to 2. |
fit |
StageFrame | {} (its own defaults) |
How the pictures sit in the stage (see StageFrame) |
phone |
StageFrame (optional) | null |
The same, on a phone (default: fit). {fit: contain, position: [0.5, 1]} keeps the whole subject in view below the words, which a phone sets near the top |
pointer |
Pointer (optional) | null |
The visitor's pointer reveals the picture (see Pointer): {mode: lens} shows the colour (or a second picture) through a soft circle under the pointer, {mode: light} is a torch on a darkened picture. Here it shows on the last stage, as the sequence arrives there; a second picture is one picture of the same view, and rest is a point of the picture |
width |
integer | 2048 |
Width of the pictures served to desktop browsers (phones get two thirds) Constraints: 640 to 3840. |
Used in: Site.sections.