Skip to content

Example: Footy Finals banner

Manifest row 04 · built today as betta-footy-finals-banner

A small yellow label panel, FOOTY FINALS in navy, over a large red hero panel tilted 5° anticlockwise reading BONUS TV* with the asterisk small and raised. Both panels drop a soft shadow, wipe on from the left four frames apart, and breathe on one beat. The label is centred over the hero.

flowchart TB
    subgraph scene["scene-footy-finals"]
        ROOT["ff-lockup<br/>flowBox column · absolute (120,120)"]
        LABEL["ff-label<br/>text · flow · pulse"]
        HERO["ff-hero<br/>text · flow · rotation −5 · pulse"]
        LABEL -- flowIn --> ROOT
        HERO -- flowIn --> ROOT
    end

The document

{
  "id": "scene-footy-finals",
  "durationInFrames": 75,
  "layers": [
    {
      "id": "ff-lockup",
      "type": "flowBox",
      "zIndex": 0,
      "layout": {
        "mode": "absolute",
        "16:9": { "x": 120, "y": 120, "w": "content", "h": "content", "anchor": "top-left" },
        "9:16": { /* own x/y */ }, "1:1": { /* own x/y */ }
      },
      "props": { "direction": "column", "alignAcross": "centre", "gap": 14 }
    },
    {
      "id": "ff-label",
      "type": "text",
      "zIndex": 1,
      "layout": {
        "mode": "flow",
        "16:9": { "flowIn": "ff-lockup", "w": "content", "h": "content" },
        "9:16": { /* … */ }, "1:1": { /* … */ }
      },
      "typography": {
        "16:9": { "family": "GT Eesti Display", "weight": 700, "size": 80, "color": "#054f8e",
                  "case": "uppercase", "tracking": 2, "horizontalAlign": "center" }
      },
      "props": {
        "content": [ { "value": "Footy Finals" } ],
        "background": { "fill": "#fed109", "radius": 7,
                        "padding": { "top": 24, "right": 40, "bottom": 25, "left": 46 } }
      },
      "effects": [ { "type": "dropShadow", "color": "#000000", "opacity": 0.3, "blurPx": 6, "offsetX": 4, "offsetY": 3 } ],
      "animations": [
        { "animation": "wipe", "params": { "direction": "from-left", "durationInFrames": 12 },
          "at": { "mode": "cueOffset", "cue": "start", "offsetFrames": 0 } },
        { "animation": "pulse", "params": { "scale": 1.05, "periodInFrames": 40, "delay": 30 },
          "at": { "mode": "cueOffset", "cue": "start", "offsetFrames": 0 } }
      ]
    },
    {
      "id": "ff-hero",
      "type": "text",
      "zIndex": 2,
      "layout": {
        "mode": "flow",
        "16:9": { "flowIn": "ff-lockup", "w": "content", "h": "content", "rotation": -5 },
        "9:16": { /* … */ }, "1:1": { /* … */ }
      },
      "typography": {
        "16:9": { "family": "GT Eesti Display", "weight": 700, "size": 181, "color": "#ffffff",
                  "case": "uppercase", "tracking": 4.5, "horizontalAlign": "center" }
      },
      "props": {
        "content": [ { "value": "Bonus TV*" } ],
        "patterns": [
          { "expression": "\\*$", "typography": { "size": { "ofRoot": 0.43 }, "baseline": 0.75 } }
        ],
        "background": { "fill": "#ed1c24", "radius": 10,
                        "padding": { "top": 56, "right": 41, "bottom": 52, "left": 41 } }
      },
      "animations": [
        { "animation": "wipe", "params": { "direction": "from-left", "durationInFrames": 12 },
          "at": { "mode": "cueOffset", "cue": "start", "offsetFrames": 4 } },
        { "animation": "pulse", "params": { "scale": 1.05, "periodInFrames": 40, "delay": 30 },
          "at": { "mode": "cueOffset", "cue": "start", "offsetFrames": 0 } }
      ]
    }
  ]
}
Note Field path Control
Editable text ff-label.props.content[0].value, ff-hero.props.content[0].value text
Change colours ff-*.props.background.fill, ff-*.typography[ratio].color colour
Pulse toggle per panel ff-*.animations[1] on/off no bindable leaf — see Stress points
Tilt ff-hero.layout[ratio].rotation degrees

Panel shadows are layer effects

Each panel above carries a drop shadow in the source artwork. A shadow is a per-layer effect, applied to the whole layer (glyphs and pill together), not a field on background — see Coordinate System & Sizing. Where text and its panel need different shadows, they become two layers: a text layer and a background layer spanning it, each with its own effects.

What the engine does with it

Resolve. Two wipes at 0 and 4, two continuous scale tracks, 0.43 × 181 for the asterisk.

Solve. Both texts measure unconstrained; the column stacks them 14px apart and centres them on the wider hero. The hero's 5° tilt doesn't touch the packing — the label sits over the hero's resting, untransformed box.

Animate. Each panel pulses about its own content centre and wipes on its own clip. The label inherits nothing from the hero: they're siblings, not parent and child.

Place. Three elements.

What this shows

  • The minimum lockup. Two text layers and a column — everything a "panel with a word on it" needs is props.background, and everything "stacked and centred" needs is one flowBox.
  • Uppercase is typography, not copy. case: "uppercase" keeps the bound value Footy Finals human-readable while rendering the reference's caps.

Stress points

  1. background.shadow — same as 03.
  2. Wipe is a clip animation — same as 01.
  3. Pulse pivot and toggle binding — same as 01. With only two panels the shared-centre difference is small but visible: in the built component the label drifts down toward the hero as both grow; here it grows in place.
  4. rotation on a flow member assumed — same as 01.

Nothing else in this component strained the schema.