Package files

Every field of Style, Format, Manifest, and rapid.lock, with types and defaults.

Every field of the four package files, from the schemas in contracts/src/ (style.ts, format.ts, manifest.ts). A field with a default may be left out.

Common types:

TypeIs
hex#rrggbb or #rrggbbaa
tokenlowercase, starting with a letter, then a-z, 0-9, -; up to 40 characters
namelowercase, starting with a letter, then a-z, 0-9, -; 2–48 characters
versionsemantic: 1.2.3, optionally with a pre-release, 1.2.3-beta.1
sha25664 lowercase hex digits
secondsa finite number, 0 or more

Style

style.json. Schema version 1.

FieldTypeDefault
schema_version1required
tokensTokensrequired
motionMotionall defaults
soundSoundall defaults
componentsobject: component name → object of parameters{}; a place for a style to note values for agents. No code reads it, and it isn't the components/ folder
formatsobject: token (a format's name) → Adaptationrequired; a format not listed isn't supported
gridGridnone
videoVideoTypenone

The components folder

Apart from style.json, a style may ship components/: working scenes for the pieces its look needs that the kit doesn't have, one file each, with components/README.md listing them. A style can't carry scripts, so each piece's behaviour lives in a marked <script> block with its settings at the top. A builder copies that into a scene and tunes it, or writes a variation; the piece's look stays in style.css, and its pictures load as rapid:style/<path>. Render one to see it:

rapid still styles/bubble/components/<file> --style styles/bubble --t 1.8

See making a style.

Tokens

FieldTypeDefault
paletteobject: token → hexrequired; colours blend in OKLab
fontsobject: token (a role: display, voice, ui, …) → FontFacerequired
type_scaleobject: token → positive number{}; pixels at the format's base width
leading{ min, max }, positive numbers{ "min": 0.86, "max": 1.2 }
margins{ x, y }, numbers 0 or more{ "x": 72, "y": 72 }; pixels at the base width

FontFace

FieldTypeDefault
familystring, 1–120required; as the system names it
weightinteger 100–1000400
stylenormal or italicnormal
substitutesarray of strings[]; families that may stand in, in order

Motion

FieldTypeDefault
exitoff-edge, fade, cut, or scaleoff-edge
easingobject: token → string{}; eases by role
transitionsarray of strings[]; a note of the hand-offs the look prefers, for agents to read. No code reads it, and its words needn't be the join's named moves: the storyboard's out decides what's drawn
pacing.line_holdseconds0.6; how long a line holds after it lands
pacing.shotpositive number2.5; typical shot length in seconds
pacing.words_per_secondpositive number3.6; for timing spoken lines
pacing.chars_per_secondpositive number38; for timing typed replies

Sound

FieldTypeDefault
cuesobject: cue kind → instrument{}
colorsobject: token (a palette name) → instrument{}; used when a cue carries a colour
tempopositive numbernone

An instrument is one of the engine's voices: kick, hat, pad, sub, keys, rim, room, click, or whoosh. A cue picks its instrument by its colour first, then its kind; a kind that is itself an instrument's name plays it with no mapping. rapid style check refuses a style that names any other instrument, and rapid mix reports the cues that played nothing and fails a video whose cues all played nothing.

Adaptation

FieldTypeDefault
margins{ x, y }the style's margins
type_kpositive numbernone; a factor on the type scale
gridGridthe style's grid

Grid

The grid scenes align to, in pixels at the base width; scenes see it as --rapid-grid-*, and the grid check holds key-frame text to it.

FieldTypeDefault
columnsinteger 1–24required; between the margins
gutternumber, 0 or morerequired
baselinepositive numbernone; text blocks start on its multiples from the top margin

VideoType

FieldTypeDefault
stepsobject: token → positive number{}; sizes in pixels at the base width, as --rapid-video-<step>
hero_rationumber, 1 or more3; the least the hero type may be over the body, for the scale check

Format

format.json. Schema version 1.

FieldTypeDefault
schema_version1required
width, heightpositive even integersrequired
fpspositive number, up to 120required
length{ min, max }: seconds; max may be null for no limitrequired
guidesarray of Guide[]
min_textpositive numbernone; the smallest line height type may have, in pixels
phone.max_bytespositive integer30000000
phone.shrink_afterpositive number120; above this many seconds the phone copy drops to 720p on its short side

Guide

A named region of the frame that is never drawn; the checks hold elements to it by role.

FieldTypeDefault
namestring, 1–40required
rolesafe, keep-out, band, trim, or noterequired
rect{ x, y, w, h } in frame pixelsrequired
appliesarray of element roles (type, object, card, bubble, texture, mark, other)[]: every role but texture

safe is where elements must stay; keep-out is where they must not go; band is where type must sit. The reel format:

{
  "schema_version": 1,
  "width": 1080,
  "height": 1920,
  "fps": 30,
  "min_text": 40,
  "length": { "min": 0, "max": null },
  "guides": [
    { "name": "safe", "role": "safe", "rect": { "x": 72, "y": 72, "w": 936, "h": 1776 }, "applies": [] },
    { "name": "band", "role": "band", "rect": { "x": 0, "y": 240, "w": 1080, "h": 1320 }, "applies": [] },
    { "name": "feed-buttons", "role": "keep-out", "rect": { "x": 960, "y": 900, "w": 120, "h": 750 }, "applies": ["type", "card", "bubble"] }
  ],
  "phone": { "max_bytes": 30000000, "shrink_after": 120 }
}

Manifest

manifest.json, at the root of every style, format, or recipe.

FieldTypeDefault
kindstyle, format, or reciperequired
namenamerequired
versionversionrequired
schema_versionpositive integerrequired; the major version of the kind's schema the package was made for. A newer one than rapid knows is refused
descriptionstring, 1–280required
tagsarray of strings 1–32, at most 16[]
formatsarray of names[]; for a style, the formats it supports, each also in style.json
fontsarray of FontFace[]
filesarray of { path, sha256, bytes }required; every file but manifest.json
proofProofnone; required to share a style in rapid's repository

A file's path is relative to the package root, with forward slashes, no leading /, no .., and no \. rapid style check --write fills files in.

Proof

FieldTypeDefault
scenestringrequired; the sample scene, proof/scene.html: an HTML scene that links rapid:style
videostringrequired; the example video, at phone size
posterstringrequired; the poster still
goldenarray of { t, path }, at least 1required; frames a new render of the sample must match (rapid style proof --check)

Every proof path must be a file in the package. rapid style proof writes all of them and fills this in; see making a style.

Rules

  • Allowed file types: .json, .css, .html, .md, .txt, .svg, .png, .jpg, .jpeg, .webp, .mp4, .wav, and the fonts .woff2, .woff, .ttf, .otf.
  • A font file sits in a folder with the full text of a free licence (OFL.txt, LICENSE.txt, LICENCE.txt, LICENSE.md, LICENCE.md, or UFL.txt).
  • A style holds style.css, which styles every class of the kit.
  • A stylesheet has no @import, and its url()s name only the package's own files.
  • At most 25 MiB in all.
  • Every file is listed, and every listed file is present with its size and sha256.
  • A repository holding several packages lists them in an index.json: { "packages": [{ "name", "path", "kind"? }] }.

The lockfile

A project's pins, written by rapid style use and rapid format use.

FieldType
lock_version1
packagesarray of LockEntry, sorted by kind then name

LockEntry

FieldTypeMeans
kindstyle, format, or recipe
namename
versionversion
sha256sha256of the package packed canonically (sorted entries, fixed stamps), not of the bytes as downloaded, so the same files pin the same hash from any source
sourcestringwhere to fetch it again: an absolute path, an address, or a github: spec
{
  "lock_version": 1,
  "packages": [
    { "kind": "style", "name": "swiss", "version": "0.1.0", "sha256": "3a74…", "source": "/Users/you/code/rapid/styles/swiss" }
  ]
}