Craft

Designing Layouts

This is a technical reference — most players don't need to read this. If you want a better-looking sheet, just describe it to Orbit ("make my spell slots tappable dots") and it will design the layout following these guidelines. The details are here for anyone curious about what's possible, or who wants to edit layouts by hand.

A layout controls how files of a type look on their detail view — the character sheet, the quest card, the item page. The schema says what a file stores; the layout says how that information is arranged, and which values players can change with a tap during play. A type with no layout falls back to a plain field-by-field display, which is fine for simple types and usually worth replacing for anything players look at often.

The best mental model: a layout is a lens for play. Design it around what a player needs to recognize (who is this?), decide (what can I do?), and change (spend a spell slot, tick a wound) — not around dumping every stored field onto the screen.

How you edit a layout

  • Build it in the Layout Designer. The visual path. In a file type's settings, the Layout tab's "Edit Manually" button opens a full-screen drag-and-drop designer — palette, live canvas, inspector. Covered in the next section.

  • Ask the AI. The fastest path. In a file type's settings, use "Edit with AI" — or just tell Orbit what you want: "give my character sheet a hero image, tabs for stats and inventory, and tappable spell slot dots." The component names below are the vocabulary the AI designs with, so knowing them helps you ask precisely.

  • Edit the JSON directly. A layout is a JSON spec stored on the file type. You can view and edit it in the type's settings or in the designer's JSON drawer — handy for small tweaks like reordering sections or changing a color.

The Layout Designer

The designer is a full-screen editor with three panes: a component palette and a layers tree on the left, a live canvas in the middle, and an inspector on the right. The canvas renders the layout exactly as players will see it, against one of your real files or mock data — pick the preview file from the dropdown in the header, and switch the canvas between phone, tablet, and desktop widths to check the sheet at every size. It needs a desktop-sized screen; on a phone, use Edit with AI instead.

  • Palette — every component in the catalog below, grouped and searchable. Drag one onto the canvas, or click it to insert at a sensible spot near your selection.

  • Layers panel — the layout tree. Use it to select and rearrange elements the canvas can't show, like the panels of an inactive tab or a section hidden by a visibility condition.

  • Inspector — everything about the selected element: its props, tab management, a visibility-condition builder, and duplicate/delete.

  • Binding picker — any data prop can hold a fixed value or bind to a field. The picker lists the type's fields with a live preview of what each resolves to on the previewed file, so you never type a path by hand.

  • JSON drawer — the code button opens the raw spec under the canvas. Applied edits are validated and join the same undo history as visual changes, so ⌘Z works across both.

A blank canvas offers starting points: generate a scaffold with every schema field placed and bound, or start from a template and adjust. Nothing is saved while you experiment — edits stay local until you apply, so undo freely.

Apply layout is the save. Because a layout belongs to the file type, applying restyles every file of that type at once, and the save is recorded as a new version of the file type — the previous layout stays recoverable from version history. The same "Edit Manually" entry lives in the layout menu of a file's toolbar; opened from there, applying asks you to confirm first, since it changes more than the file you were looking at. Closing the designer with unapplied edits prompts you to save or discard them, so half-finished work never silently vanishes.

How a layout is put together

A layout is a tree of components. Each component binds to fields from the schema — a heading shows /name, a dot tracker shows /kiPoints. A small taste of the format:

{
  "type": "StatGrid",
  "props": {
    "items": [
      ["Strength", { "$state": "/strength" }],
      ["Dexterity", { "$state": "/dexterity" }]
    ],
    "cols": 2
  }
}

Two other building blocks come up in almost every good layout:

  • Visibility conditions — sections can hide themselves when a field is empty, so an unwritten backstory collapses instead of leaving a lonely heading behind.

  • Repeating — design one block and it repeats for every item of a list field, so you never hand-build one card per spell, weapon, or slot. See below.

Repeating a block over a list

Any part of a layout can repeat itself once per item of a list field. Design a single spell card — name, level, a cast button-style toggle — bind it to the knownSpells list, and it renders once per spell the character knows. One tracker row bound to a resources list becomes the whole resource panel.

Repeating is what keeps sheets maintainable:

  • The sheet grows by itself. Learn an eleventh spell and an eleventh card appears — no layout edit, ever.

  • One design, applied everywhere. Restyle the block once and every card changes together, instead of touching ten hand-placed copies.

  • Repeated rows stay editable. A Dots or Stepper inside a repeated block saves back to its own row — tap the third resource's dots and only that resource changes. This works even when the list itself is a computed field, like class resources assembled from the character's class.

If you're asking Orbit, the magic words are "one card per…": "show each known spell as its own card with its level and a prepared toggle."

The component catalog

These are the components a layout can use. You don't need to memorize props — the AI handles the details — but knowing what exists is how you ask for the sheet you actually want.

Every component also accepts a className prop of extra Tailwind utility classes for fine-grained control the built-in props don't cover — spanning columns in a Grid (col-span-2), nudging spacing ( mt-4), or capping width (max-w-sm). It lives in the inspector's Advanced section in the designer.

Structure

  • Stack — arranges children vertically or horizontally with consistent spacing. The workhorse container.

  • Grid — a column grid (up to 12 columns) for dashboards and stat clusters.

  • Card — a bordered container with an optional title and description; groups a section visually.

  • Tabs — splits a busy sheet into panels. The classic cure for a long vertical scroll: identity up top, then tabs like Stats, Inventory, and Notes.

  • Accordion and Collapsible — sections that expand on demand, for reference text that shouldn't crowd the sheet.

  • Separator — a divider line between sections.

  • Table — a simple static table of text cells. For editable structured rows, use DataTable below instead.

Text, images, and stats

  • ImageHeader — a hero image with a title and subtitle overlaid. The usual opener for characters and locations; it renders a tasteful gradient when the file has no image yet.

  • Image — a plain image bound to any image field, with size, alignment, and aspect-ratio options.

  • Heading and Text — section titles and paragraphs, with variants for captions, muted notes, and code.

  • Markdown — renders a long-text field as formatted prose. The right choice for backstories, lore, and rules text.

  • StatGrid — a grid of labeled values; the standard block for ability scores and quick stats.

  • DerivedStatGrid — like StatGrid, but each entry pairs an editable base value with a derived one — ability score next to its modifier.

  • FieldList — a vertical label/value list for details that read better as rows than as a grid.

  • Badge and BadgeList — small pills for single values and for string lists like tags, traits, or known languages. BadgeList can also act as a compact editable reference list.

  • List — a bullet, numbered, or inline list for string lists — traits, features, rumors — when items read better as lines than as pills. Items can also be objects (pick a label and description field), and bound string lists gain inline add and remove.

  • Avatar — a small circular portrait that falls back to initials.

  • Alert — an info/success/warning/error callout box.

  • Callout — a framed flavor block: an accent-bordered quote with an optional attribution, or a soft panel with an icon and title. Alert is for status messages; Callout is for lore and voice.

  • FormattedDate and FormattedNumber — dates as "April 29" or "2 days ago"; numbers as currency or percentages.

Play-time controls

These are the components that make a sheet playable: each one saves with a single tap, right where the value is displayed.

  • Dots — filled and empty dots for small pools: spell slots, ki points, uses per rest. Tap a dot to set the value.

  • Stepper — a −/+ counter for values that move a lot during play: hit points, ammo, gold. Also click-to-type.

  • Progress — a progress bar with an optional built-in stepper, for values with a visible maximum.

  • TrackBoxes — a row of square boxes, either filled-count style or multi-state cycling (bashing/lethal/aggravated damage, stress tracks).

  • Clock — a segmented circular countdown clock in the Blades in the Dark style, for ritual progress and looming threats.

  • Toggle — a one-tap boolean as a switch, chip, or checkbox: inspiration, concentration, exhausted.

  • Checkbox and Switch — standalone labeled booleans for the same job in a fixed form-style look: a check box or an on/off switch. Tap to flip, with a color option for the checked state.

  • ConditionToggles — an always-visible roster of status chips; tapping toggles a condition on or off.

  • Checklist — a read-only checklist with optional progress bar, for quest objectives and task lists.

  • DataTable — an editable table over a structured list field: weapons with damage and range, inventory rows with quantities.

  • Select — a dropdown, from a fixed option list or from all files of a type (see references below).

  • VoiceSelect — the voice picker for character dialogue.

  • TurnTracker — a full encounter tracker: combatants, initiative order, health bars, conditions, and notes.

Reference components

When a field points at other files (see Reference Fields), three components do the heavy lifting:

  • Select with a file type — a dropdown of every file of that type, for single references like equipped armor or home location.

  • FileReferenceGrid — cards for a list of referenced files, with a built-in picker for adding and removing, and editable metadata badges for sibling fields like quantity or equipped. The standard inventory and party-roster component. Each card's name can sit below the image (the default), above it, over the artwork's lower edge, or be hidden entirely (titlePosition), and the metadata badges can render beside the name, in their own wrapping row underneath (roomier for text values), or not at all (metadataPosition). In the designer, the grid's Metadata Fields control (under Advanced) lists the bound field's sibling fields and lets you hide individual ones from cards (they stay editable in the card's edit dialog), reorder them, and rename them.

  • ReferenceValue — a live value read from the referenced file itself, shown as text or a badge: the equipped armor's AC bonus on the character sheet, without copying it. Read-only by design — the value belongs to the other file.

Both handle reference fields that target multiple file types — a loot list that accepts weapons and items, say. The picker gets a per-type filter and labels each result with its type. Fields annotated in the schema work automatically; a hand-written layout can also list the types explicitly with the fileTypeSlugs prop.

Best practices

  • Open with identity. An ImageHeader with name and a one-line subtitle, then the stats that matter most. A player glancing at the sheet should know who and what within a second.

  • Make play-time values one-tap editable. Anything that changes during a session — HP, slots, conditions — should be a Dots, Stepper, Toggle, TrackBoxes, or Clock right where it is shown, never a number buried in a form.

  • Reach for tabs before the sheet gets long. Two to five task-oriented tabs beat an endless scroll. Keep always-needed identity and summary content outside the tabs.

  • Let empty sections disappear. Wrap optional sections in a visibility condition so files without a backstory don't show an empty heading.

  • One value, one place. Show each stat once, with the right component for its role: StatGrid for numbers, Markdown for prose, BadgeList for tags, FileReferenceGrid for references.

  • Keep a house style. When adding a new type to a project, match the layout patterns your other types already use — a consistent world reads better than ten clever one-offs.