Two paths: AI generates sections, OR the operator picks from a widget library. Both insert into the structure tree with a slot number. Renumbering is automatic โ slots are just addresses, not fixed IDs. The widget tree, the AI tree, and the renumbering all share one rule: slot = position-in-tree.
+ button appears above and below. Click it โ widget library opens โ pick one โ inserts at that position.
+ Section / + Container / + Widget appends to the end of the tree.
{
"id": "S-3",
"type": "section",
"name": "Services"
}
{
"slot": 3, โ position
"uuid": "a7f3...", โ stable ID
"type": "section",
"name": "Services"
}
function displayId(slot) {
return `S-${slot}`;
}
// Renumber = re-index array.
// No ID changes, no CSS breaks.
// Operator sees the new slot
// in green, then it settles.
+ Widget in the bottom bar, or a + next to a tree node, or drags onto a slot+ button above + below. Click โ library opens scoped to that slot+ Section / + Container / + Widget โ appends to the end. + Widget opens the libraryinsertAt(slot, widgetType, options)S-3) is regenerated from position on every render. So it always reads correctlyid: "S-3". Insert at S-2 breaks everything that referenced S-3slot: 3 and uuid: "a7f3...". Insert at slot 2 โ slot 3's section becomes slot 4, but its UUID stays the same. CSS that targeted the old S-3 still works because it uses UUID+ Widget is the primary action (green). + Section / + Container are secondary