Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Add §1.5 visual quality bar; extend §3 errorList-blind list with empty-page failures + visible-on-open scan paragraph (covers Local AI demo failure pattern: empty MainPage, no empty-state placeholders, content below fold). No API/recipe claims.

...

Or, for a full-bleed dark background on a dark-themed display, place a full-size Rectangle with FillTheme: "PageBackground" as the first element.

Section

...

1.5 — The visual quality bar

The first 5 seconds an operator looks at the display decide whether the build is good. Compile cleanliness is necessary but not sufficient — errorList is blind to whether anyone would actually want to use the screen. Before responding as finished, three things must be true within five seconds of imagining the operator opening the display:

  1. The page is not empty. Every display, especially a landing display like MainPage, has at least one piece of content visible above the fold. An empty MainPage is a UX failure even when errorList is clean.
  2. The largest text is readable from operator working distance. Hero numbers 26–32, body text never below 14, meta text never below 10 (see §5 typography ramp). A page where every label is 9 pt is a fail regardless of layout.
  3. The layout has obvious top-to-bottom or left-to-right rhythm. Zones, cells, or sections — never a free-floating cluster of small elements with no spatial story. The viewer's eye should know where to start.

If any of the three fails, the build is not finished. Pair this with the errorList-blind list in §3 below: errorList handles compile correctness, the visual quality bar handles operator-perceived correctness. The two together — not errorList alone — gate "done."

Closing self-check before respond. Ask: "Would I be embarrassed to show this to an operator?" If the answer is "maybe" or "a little", run the visual checkpoint in §3 again before responding.

Section 2 — Write mechanics

The canonical display envelope

{
  "Name": "MyDisplay",

The canonical display envelope

{
  "Name": "MyDisplay",
  "PanelType": "Canvas",
  "DisplayMode": "Page",
  "Navigate": "true",
  "Size": "1600 x 900",
  "OnResize": "StretchFill",
  "Width": 1600,
  "Height": 900,
  "Background": "theme:PageBackground",
  "Elements": [ /* ... */ ]
}

...

What errorList covers, and what it doesn't

errorList is ground truth for compile correctness: bindings resolve, required fields are present, the display will render without crashing. A clean errorList is necessary before you respond as finished.

errorList is blind to visual correctness. None of the following produce an error:

  • Two elements overlapping at the same Left/Top
  • A TextBlock whose LinkedValue clips because its rendered length exceeds Width
  • An element placed outside its intended zone but still inside the display
  • A pipe endpoint 15 px off the tank nozzle it was supposed to connect to
  • A RadialGauge with YMaxValue below the tag's engineering-range maximum (pegs at max forever)
  • Three 48 pt "hero" numbers on the same display, all screaming for attention
  • A Polygon with valid Points but Fill equal to the background (invisible)

truth for compile correctness: bindings resolve, required fields are present, the display will render without crashing. A clean errorList is necessary before you respond as finished.

errorList is blind to visual correctness. None of the following produce an error:

  • Two elements overlapping at the same Left/Top
  • A TextBlock whose LinkedValue clips because its rendered length exceeds Width
  • An element placed outside its intended zone but still inside the display
  • A pipe endpoint 15 px off the tank nozzle it was supposed to connect to
  • A RadialGauge with YMaxValue below the tag's engineering-range maximum (pegs at max forever)
  • Three 48 pt "hero" numbers on the same display, all screaming for attention
  • A Polygon with valid Points but Fill equal to the background (invisible)
  • A MainPage (or any landing display) that opens empty
  • A detail panel that opens empty when no master row is selected (no empty-state placeholder)
  • A page where every visible element is below the fold or off in a corner — nothing in the top half of the canvas

All of those compile clean. All are operator-rejected.

Visible-on-open scan (both paradigms)

Before any paradigm-specific procedure, mentally open the display from the operator's seat, top edge first. If there is nothing in the top half of the canvas — or if the only thing there is a placeholder waiting for a master selection that never came — that is a failure even on a clean errorList. Go back and add content, restructure, or wire an empty-state placeholder before continuing to the paradigm-specific checkpoint below. This catches the empty-MainPage failure and the empty-detail-panel failure before any screenshot or pixel-tweakAll of those compile clean. All are operator-rejected.

Visual checkpoint — paradigm-specific

...

Section 7 — Symbols (all three sources)

Every symbol uses Type: "Symbol". Not Type: "Pump", not Type: "Valve". One element type, many SymbolName values.

{
"Type": "Symbol",
"SymbolName": "Wizard/PUMP",
"Left": 400, "Top": 300,
"Width": 80, "Height": 80,
"SymbolLabels": [
{ "Type": "SymbolLabel", "Key": "State", "LabelName": "State", "LabelValue": "@Tag.Pump1/Running", "FieldType": "Expression" },
{ "Type": "SymbolLabel", "Key": "RPM",   "LabelName": "RPM",   "LabelValue": "@Tag.Pump1/Speed",   "FieldType": "Expression" }
]
}

The 5 Wizard symbols

The complete Wizard catalog is 5 symbols:

...

SymbolName

...

What it is

...

Typical SymbolLabels

...

Wizard/BLOWER

...

Industrial blower/fan

...

State, RPM

...

Wizard/MOTOR

...

Electric motor

...

State, RPM

...

Wizard/PUMP

...

Pump (styles selectable in Designer)

...

State, RPM

...

Wizard/TANK

...

Storage tank

...

Level, Alarm

Every symbol uses Type: "Symbol". Not Type: "Pump", not Type: "Valve". One element type, many SymbolName values.

{
"Type": "Symbol",
"SymbolName": "Wizard/PUMP",
"Left": 400, "Top": 300,
"Width": 80, "Height": 80,
"SymbolLabels": [
{ "Type": "SymbolLabel", "Key": "State", "LabelName": "State", "LabelValue": "@Tag.Pump1/Running", "FieldType": "Expression" },
{ "Type": "SymbolLabel", "Key": "RPM",   "LabelName": "RPM",   "LabelValue": "@Tag.Pump1/Speed",   "FieldType": "Expression" }
]
}

The 5 Wizard symbols

The complete Wizard catalog is 5 symbols:

SymbolName

What it is

Typical SymbolLabels

Wizard/BLOWER

Industrial blower/fan

State, RPM

Wizard/MOTOR

Electric motor

State, RPM

Wizard/PUMP

Pump (styles selectable in Designer)

State, RPM

Wizard/TANK

Storage tank

Level, Alarm

Wizard/VALVE

Valve (various styles)

State, Position

When to reach for a Wizard. When the equipment in the spec is a fan/blower, a rotating drive, a liquid mover, a vessel with level dynamics, or a flow-control element, the corresponding Wizard is almost always the right first move — they ship with state dynamics already wired and avoid the cost of composing the same shape from primitives. The Wizard catalog stops at five canonical types on purpose; for anything outside (compressor, heat exchanger, conveyor, sensor, instrument), fall through to Solution / Library/HPG / Library/HMI in that order. Wizard styling variants (orientation, foot detail, port direction) are user-controlled in Designer via the symbol's configuration button, not by editing the placed element's geometry.

...

Wizard/VALVE

...

Valve (various styles)

...

Always treat list_elements('Wizard') as the authoritative runtime catalog — if an entry does not appear there, do not attempt to use it.

...