Skip to content

Example: Bonus Cashback, red flash

Manifest row 07 · built today as betta-bonus-cashback-flash

Bare yellow BONUS with no panel, then a red panel tipped 3° carrying a white UP TO stack beside a big white $300, then bare white Cashback, then a footnote. No shadows. Everything sits on a coloured scene background, which is why two of the three rows have no pill of their own. Rows wipe on from the left four frames apart; the three rows breathe on a shared pulse; the footnote slides down and fades in.

flowchart TB
    subgraph scene["scene-cashback  (one motion graph per ratio)"]
        ROOT["flash-root<br/>flowBox · column · absolute (120,120)"]
        PANELS["flash-rows<br/>flowBox · column · flow · pulse"]
        BONUS["bonus · bare text · flow · wipe"]
        AMT["amount-row<br/>flowBox · row · flow · wipe"]
        PRE["amount-prefix · text 'UP TO' · flow"]
        HERO["amount-hero · text price run · flow"]
        AMTBG["amount-bg · background · derived"]
        CASH["cashback · bare text · flow · wipe"]
        FN["footnote · text · flow · slideFade"]
        PANELS -- flowIn --> ROOT
        FN -- flowIn --> ROOT
        BONUS -- flowIn --> PANELS
        AMT -- flowIn --> PANELS
        CASH -- flowIn --> PANELS
        PRE -- flowIn --> AMT
        HERO -- flowIn --> AMT
        AMTBG -- of --> AMT
    end

The document

{
  "id": "scene-cashback",
  "durationInFrames": 75,
  "layers": [
    {
      "id": "flash-root",
      "type": "flowBox",
      "zIndex": 0,
      "layout": {
        "mode": "absolute",
        "16:9": { "x": 120, "y": 120, "w": "content", "h": "content", "anchor": "top-left" },
        "9:16": { /* own position */ },
        "1:1":  { /* own position */ }
      },
      "props": { "direction": "column", "alignAcross": "centre", "gap": 46 }
    },

    // ── The three pulsing rows.
    {
      "id": "flash-rows",
      "type": "flowBox",
      "zIndex": 0,
      "layout": {
        "mode": "flow",
        "16:9": { "flowIn": "flash-root", "w": "content", "h": "content" },
        "9:16": { "flowIn": "flash-root", "w": "content", "h": "content" },
        "1:1":  { "flowIn": "flash-root", "w": "content", "h": "content" }
      },
      "props": { "direction": "column", "alignAcross": "centre", "gap": 34 },
      "animations": [
        { "animation": "pulse", "params": { "scale": 1.05, "periodInFrames": 40, "delay": 30 } }
      ]
    },

    // ── Bare text, no pill: the scene background is the panel.
    {
      "id": "bonus",
      "type": "text",
      "zIndex": 2,
      "layout": {
        "mode": "flow",
        "16:9": { "flowIn": "flash-rows", "w": "content", "h": "content" },
        "9:16": { "flowIn": "flash-rows", "w": "content", "h": "content" },
        "1:1":  { "flowIn": "flash-rows", "w": "content", "h": "content" }
      },
      "typography": {
        "16:9": { "family": "GT Eesti Display", "weight": 700, "size": 200, "color": "#ffd100", "case": "uppercase" }
      },
      "props": { "content": [ { "value": "Bonus" } ] },
      "animations": [
        { "animation": "wipe", "params": { "direction": "from-left", "durationInFrames": 12 },
          "at": { "mode": "cueOffset", "cue": "start", "offsetFrames": 0 } }
      ]
    },

    // ── The red panel: a tilted row of two white texts, background derived around them.
    {
      "id": "amount-row",
      "type": "flowBox",
      "zIndex": 2,
      "layout": {
        "mode": "flow",
        "16:9": { "flowIn": "flash-rows", "w": "content", "h": "content", "rotation": -3 },
        "9:16": { "flowIn": "flash-rows", "w": "content", "h": "content", "rotation": -3 },
        "1:1":  { "flowIn": "flash-rows", "w": "content", "h": "content", "rotation": -3 }
      },
      "props": { "direction": "row", "alignAcross": "bottom", "gap": 28 },
      "animations": [
        { "animation": "wipe", "params": { "direction": "from-left", "durationInFrames": 12 },
          "at": { "mode": "cueOffset", "cue": "start", "offsetFrames": 4 } }
      ]
    },
    {
      "id": "amount-prefix",
      "type": "text",
      "zIndex": 2,
      "layout": {
        "mode": "flow",
        "16:9": { "flowIn": "amount-row", "w": "content", "h": "content" },
        "9:16": { "flowIn": "amount-row", "w": "content", "h": "content" },
        "1:1":  { "flowIn": "amount-row", "w": "content", "h": "content" }
      },
      "typography": {
        "16:9": { "family": "GT Eesti Display", "weight": 400, "size": 85, "color": "#ffffff",
                  "case": "uppercase", "lineHeight": 0.9, "multiline": true, "horizontalAlign": "center" }
      },
      "props": { "content": [ { "value": "up\nto" } ] }
    },
    {
      "id": "amount-hero",
      "type": "text",
      "zIndex": 2,
      "layout": {
        "mode": "flow",
        "16:9": { "flowIn": "amount-row", "w": "content", "h": "content" },
        "9:16": { "flowIn": "amount-row", "w": "content", "h": "content" },
        "1:1":  { "flowIn": "amount-row", "w": "content", "h": "content" }
      },
      "typography": {
        "16:9": { "family": "GT Eesti Display", "weight": 700, "size": 210, "color": "#ffffff" }
      },
      "props": {
        "content": [
          { "price": { "amount": 300, "currency": "AUD", "locale": "en-AU" },
            "typography": { "currencySymbol": { "size": { "ofRoot": 0.72 }, "baseline": 0.12 } } }
        ]
      }
    },
    {
      "id": "amount-bg",
      "type": "background",
      "zIndex": 1,
      "layout": {
        "mode": "derived",
        "16:9": { "of": ["amount-row"], "ofBounds": "extents" },
        "9:16": { "of": ["amount-row"], "ofBounds": "extents" },
        "1:1":  { "of": ["amount-row"], "ofBounds": "extents" }
      },
      "props": {
        "fill": "#ed1c24", "radius": 11,
        "padding": { "top": 24, "right": 50, "bottom": 12, "left": 33 }
      },
      "animations": [
        { "animation": "wipe", "params": { "direction": "from-left", "durationInFrames": 12 },
          "at": { "mode": "cueOffset", "cue": "start", "offsetFrames": 4 } }
      ]
    },

    {
      "id": "cashback",
      "type": "text",
      "zIndex": 2,
      "layout": {
        "mode": "flow",
        "16:9": { "flowIn": "flash-rows", "w": "content", "h": "content" },
        "9:16": { "flowIn": "flash-rows", "w": "content", "h": "content" },
        "1:1":  { "flowIn": "flash-rows", "w": "content", "h": "content" }
      },
      "typography": {
        "16:9": { "family": "GT Eesti Display", "weight": 700, "size": 174, "color": "#ffffff" }
      },
      "props": { "content": [ { "value": "Cashback" } ] },
      "animations": [
        { "animation": "wipe", "params": { "direction": "from-left", "durationInFrames": 12 },
          "at": { "mode": "cueOffset", "cue": "start", "offsetFrames": 8 } }
      ]
    },

    // ── Footnote, directly in the root so it sits outside the pulse.
    {
      "id": "footnote",
      "type": "text",
      "zIndex": 3,
      "layout": {
        "mode": "flow",
        "16:9": { "flowIn": "flash-root", "w": "content", "h": "content" },
        "9:16": { "flowIn": "flash-root", "w": "content", "h": "content" },
        "1:1":  { "flowIn": "flash-root", "w": "content", "h": "content" }
      },
      "typography": {
        "16:9": { "family": "GT Eesti Display", "weight": 400, "size": 50, "color": "#ffffff", "tracking": 1 }
      },
      "props": {
        "content": [ { "value": "with selected Laundry appliances*" } ],
        "patterns": [ { "expression": "\\*$", "typography": { "size": { "ofRoot": 0.58 }, "baseline": 0.45 } } ]
      },
      "animations": [
        { "animation": "slideFade", "params": { "from": "top", "distance": 20, "durationInFrames": 12 },
          "at": { "mode": "cueOffset", "cue": "start", "offsetFrames": 16 } }
      ]
    }
  ]
}
Note Binding target Control
Editable text bonus…value, amount-prefix…value, cashback…value, footnote…value text
Editable amount amount-hero.props.content[0].price.amount number
Change colours amount-bg.props.fill, *.typography[ratio].color colour
Pulse toggle per row no numeric leaf — see stress points

What the engine does with it

Resolve. The price run formats; { ofRoot } on the symbol multiplies against 210; five at references resolve against start; three names expand into tracks.

Solve. Four content-sized texts measure; amount-row packs prefix and hero with a 28px gap, bottoms aligned; amount-bg grows the row's extents by its asymmetric padding; flash-rows stacks the three rows centred; flash-root adds the footnote 46px under them.

Animate. flash-rows pulses; bonus, the row, and cashback inherit; prefix and hero inherit the row's scale and tilt in turn. amount-bg follows the row's animated extents. The footnote never joins the pulse.

Place. Nine positioned elements; one derived fill; the browser paints glyphs.

What this shows

  • Bare text and text-on-a-pill are the same layer type, differing only by the presence of props.background. The scene's own background does the rest.
  • The only three-layer construct is, again, the two-text panel — the row, its members, and a derived fill.

Stress points

The same family-wide points as the full stack — wipe versus transform-only, the derived background under a tilted row (-3° here), single gap (the preset has 31 / 37 / 46, rounded to 34 and 46), first-line-only baseline on the UP / TO stack, and the unbindable pulse toggle. No shadows in this variant, so background.shadow isn't needed here.