The .ws Language: Scenes, Beats & Intents

Every video in Workshop starts as a .ws script. The language is structured, indentation-based, and designed so the compiler can make layout and animation decisions on your behalf. This guide covers the three core concepts: structure, timing, and intent.

Document Structure

A .ws script is a tree. At the top sits a single Film block. Below it are one or more Scenes. Inside each scene are elements (text, images, numbers, shapes) and timing markers (beats, holds).

ws
Film "Product Launch"
  mood: confident
  aspect: 9:16

Scene "The Hook"
  show "Your workflow is broken."
    size: hero
  beat 0.5s
  show "We fixed it."
    size: title
    color: accent

Scene "The Proof"
  show number "$4.2M"
    size: hero
    weight: black
  show "Revenue generated in Q1"
    size: body

Indentation defines hierarchy. The Film block is at indent level 0. Scene blocks are also at level 0. Elements inside a scene are at indent level 1, and element settings are at indent level 2.

Film Block

The Film block sets project-wide defaults. Every setting here cascades to all scenes unless overridden.

Setting Example Purpose
mood: confident, dramatic + elegant Visual personality — colors, fonts, animation curves
aspect: 16:9, 9:16, 1:1, 4:5 Video dimensions
tempo: rapid, upbeat, measured, deliberate, glacial Animation speed
font: Inter, Montserrat Primary font family
music: "track.mp3" Background audio file
musicVolume: 75 Audio level (0–100)
theme: "neon-nights" Apply a ThemePack
palette: { accent: "#FF6B00" } Override mood colors

Scene Block

Each scene is a self-contained visual segment — think of it as one "slide" in a presentation, but with cinematic entrance and exit animations.

ws
Scene "Title Goes Here" [3s]
  intent: shift
  background: dark
  transition: fade
  camera: push-in

The optional [3s] after the title is a duration hint that tells the compiler how long the scene should run.

Scene Settings

Setting Values Default
intent: problem, shift, reveal, proof, authority, contrast, resolve, cta Auto-inferred
background: dark, light, accent, #hex, video "file.mp4", generative, gradient Derived from mood
transition: cut, fade, dissolve, push, wipe Mood default
camera: still, breathe, drift, push-in, pull-out Mood default
layout: grid 2x2, split, split 60-40 Auto
audio-mode: muted, speech-primary, ambient muted

Elements

Elements are the visible content inside a scene. The show keyword introduces every element.

Text

ws
show "Your message here."
  size: hero
  color: accent
  enter: rise
  weight: heavy
  emphasis: "message"

The emphasis setting highlights a word or phrase within the text — the compiler applies accent color and may adjust weight.

Numbers

ws
show number "$4.2M"
  size: hero
  countFrom: 0
  label: "Revenue"

Numbers animate from countFrom to the displayed value. The compiler parses $, %, M, K, and other suffixes automatically.

Images, Videos & Logos

ws
show image "product-shot.jpg"
  fit: fill
  position: center

show logo "brand-mark.svg"
  size: body
  opacity: 0.8

show video "demo-clip.mp4"
  fit: bleed

Media elements reference uploaded asset URLs. The fit setting controls how the media fills its bounding box: fill (cover, crop), fit (contain, letterbox), or bleed (extend beyond bounds).

Shapes

ws
show shape "circle"
  color: accent
  size: display
  layer: back
  opacity: 0.3
  style: outline

Available geometries: circle, square, triangle, ring, line, pentagon, hexagon, octagon.

Charts

ws
show chart "Quarterly Revenue"
  data: [10, 45, 80, 32]
  labels: ["Q1", "Q2", "Q3", "Q4"]
  color: accent

Element Settings Reference

These settings apply to most element types:

Setting Values Purpose
size: caption, body, subhead, title, display, hero Scale/typography size
color: primary, accent, muted, contrast Palette color token
enter: fade, rise, drop, push, scale, pop, typewriter, cascade, reveal, blur, bounce, cut, split Entry animation
exit: Same as enter Exit animation (auto-paired if omitted)
position: center, upper-left, lower-third, left, right, etc. Screen placement
weight: light, regular, medium, heavy, black Font weight
align: left, center, right Text alignment
case: upper, lower, title, sentence Text transform
maxWidth: narrow, medium, wide Column width constraint
layer: back, middle, front Z-order stacking
opacity: 0 to 1 Transparency

Sequencing — How Elements Animate in Order

By default, elements animate in sequence — the first element enters, holds, exits, then the second begins. You can change this with sequencing prefixes:

ws
Scene "Layered Intro"
  show "First line appears."
  with show "This appears at the same time."
  then show "This waits for the previous to exit."
  after 1s show "This waits one extra second."
Prefix Behavior
show or then show Wait for previous element to finish (default)
with show Enter simultaneously with the previous element
after Ns show Wait N seconds after the previous element starts

Beats & Holds — Controlling Timing

Beats insert a pause between elements:

ws
show "Line one."
beat 0.5s
show "Line two."

The 0.5s gap sits between the first element's exit and the second's entrance.

Holds freeze the current frame:

ws
show "Important statement."
hold 2s
show "Follow-up."

Duration formats: 1s (seconds), 500ms (milliseconds), 1min (minutes).

The Intent System

Intents are the most important concept in .ws beyond basic structure. An intent tells the compiler what narrative role a scene plays. The compiler uses this to select animations, colors, positions, and typographic weight.

You can set intent explicitly:

ws
Scene "The Problem"
  intent: problem

Or let the compiler infer it automatically based on your content. The compiler is good at recognizing common narrative patterns — you usually do not need to set intents by hand.

Intent Meaning
problem Present the pain point
shift Pivot to the solution
reveal Uncover or disclose
proof Show evidence or data
authority Establish credibility
contrast Juxtapose two ideas
resolve Conclude or summarize
cta Call to action

Each mood applies different visual treatments per intent — animations, color emphasis, and layout all adapt to the narrative role of the scene.

You do not need to set intents manually. The auto-inference works well for typical narrative structures (problem → solution → proof → CTA). Use explicit intents when the compiler guesses wrong or when you want a specific visual treatment.

## Templates — Reusable Scene Structures

Define a scene template with placeholder variables, then stamp out copies:

ws
define template stat-card [1.5s]
  show number "{value}"
    size: hero
    weight: black
  show "{label}"
    size: body

Scene "Revenue" from stat-card
  value: "$42M"
  label: "Annual revenue"

Scene "Users" from stat-card
  value: "10K+"
  label: "Active users"

Templates keep your scripts DRY when you have repeating visual patterns.

Putting It Together

Here is a complete script that uses most of the concepts covered:

ws
Film "Apex Launch"
  mood: confident + elegant
  aspect: 9:16
  tempo: measured

Scene "Hook" [3s]
  background: dark
  camera: breathe
  show "Your tools are failing you."
    size: hero
    enter: rise
    emphasis: "failing"
  beat 0.5s
  show "It doesn't have to be this way."
    size: title
    color: accent

Scene "Solution" [3s]
  intent: shift
  transition: fade
  camera: push-in
  show "Meet Apex."
    size: display
    enter: pop
    weight: heavy
  with show shape "circle"
    color: accent
    layer: back
    opacity: 0.2
    size: hero

Scene "Proof" [4s]
  intent: proof
  layout: grid 2x2
  show number "$42M"
    size: hero
    color: accent
  show "Revenue"
    size: caption
  show number "10x"
    size: hero
    color: primary
  show "Faster"
    size: caption

Scene "CTA" [2s]
  intent: cta
  background: accent
  show "Start free today."
    size: display
    weight: black
    enter: scale

The compiler takes these 30-odd lines and produces a fully animated, properly timed video — no timeline required.