{
  "version": 1,
  "note": "Platform reference of block types: what exists and how it is configured. Identical for every shop — no shop data here. Settings live in a block section: GET /content-blocks, then PUT /content-blocks/{id}. sections is a replace-set: send the whole list. A 200 does not prove the value took effect — a value outside enum is accepted silently and the default is rendered.",
  "widgets": [
    {
      "kind": "articleGrid",
      "label": {
        "ru": "Новости: лента рубрики",
        "en": "News: rubric feed"
      },
      "placement": "page",
      "render": "section",
      "writePath": "props.articleGrid",
      "see": "packages/sections/src/widgets/articleGrid/ТЗ.md",
      "content": {
        "text": "Unused; the rubric feed has no separate heading of its own."
      },
      "contentPath": "section",
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "view": {
            "type": "string",
            "default": "tiles",
            "enum": [
              "tiles",
              "masonry",
              "rows"
            ],
            "description": "tiles (default): uniform cards in a grid; masonry: card height follows the image (CSS columns, reading order runs down each column); rows: cover beside the text."
          },
          "columns": {
            "type": "integer",
            "default": 3,
            "description": "Desktop columns 1..6, default 3."
          },
          "columnsTablet": {
            "type": "integer",
            "default": 2,
            "description": "Columns under 1024px, 1..6; default min(columns, 2)."
          },
          "columnsMobile": {
            "type": "integer",
            "default": 1,
            "description": "Columns under 640px, 1..6; default 1."
          },
          "datePosition": {
            "type": "string",
            "default": "meta",
            "enum": [
              "meta",
              "title",
              "author"
            ],
            "description": "meta (default): next to the rubric; title: under the headline; author: in the author row."
          },
          "dateMode": {
            "type": "string",
            "default": "published",
            "enum": [
              "published",
              "modified",
              "both"
            ],
            "description": "Which dates to print: published (default) — the publication date; modified — \"Updated <date>\" from the article field modified_at (falls back to the publication date when never modified); both — \"<published> · Updated <modified>\", the update skipped when it is the same day. Dates are fields of the article (published_at, modified_at), not of the widget."
          },
          "authorPosition": {
            "type": "string",
            "default": "below",
            "enum": [
              "inside",
              "below"
            ],
            "description": "inside: the author line sits in the text area under the announce; below: a caption under the card. Default inside for rows, below otherwise."
          },
          "cardStyle": {
            "type": "object",
            "default": {
              "radius": 18,
              "padding": {
                "top": 8,
                "right": 8,
                "bottom": 8,
                "left": 8
              }
            },
            "description": "Surface of the card itself: background, border, radius, padding, shadow. Defaults padding 8, radius 18; padding 0 puts the cover edge to edge."
          },
          "coverStyle": {
            "type": "object",
            "default": {
              "radius": 10
            },
            "description": "Surface of the cover: radius (default card radius minus card padding) and border."
          },
          "coverFit": {
            "type": "null",
            "description": "cover (default) fills the frame; contain fits the whole image inside it."
          },
          "textStyle": {
            "type": "object",
            "default": {
              "padding": {
                "top": 12,
                "right": 10,
                "bottom": 10,
                "left": 10
              }
            },
            "description": "Surface of the text area under the cover: its own background, border, padding (default 12/10/10/10; rows 6/8/8/0)."
          },
          "rubricsStyle": {
            "type": "null",
            "description": "Surface of the rubric switcher band."
          },
          "rubricChip": {
            "type": "object",
            "default": {
              "labelStyle": {
                "base": {
                  "size": 14,
                  "lineHeight": 1.2
                },
                "hover": {}
              },
              "activeLabelStyle": {
                "color": {
                  "hex": "#ffffff"
                }
              },
              "itemStyle": {
                "base": {
                  "border": {
                    "width": 1,
                    "color": {
                      "hex": "#e5e7eb"
                    },
                    "style": "solid"
                  },
                  "radius": 999,
                  "padding": {
                    "top": 7,
                    "right": 16,
                    "bottom": 7,
                    "left": 16
                  }
                },
                "hover": {
                  "border": {
                    "width": 1,
                    "color": {
                      "hex": "#9ca3af"
                    },
                    "style": "solid"
                  }
                },
                "active": {
                  "background": {
                    "fill": {
                      "kind": "color",
                      "color": {
                        "hex": "#111827"
                      }
                    }
                  },
                  "border": {
                    "width": 1,
                    "color": {
                      "hex": "#111827"
                    },
                    "style": "solid"
                  }
                }
              }
            },
            "description": "One rubric chip block, the same contract as the articleRubrics widget: {itemStyle: States<Surface> {base, hover, active} — fill, border, radius, padding, shadow per state, active = the rubric of the current page; labelStyle: States<Typography> (base + hover color/decoration); activeLabelStyle: Typography (default white)}. Default: pill with a thin border, active dark."
          },
          "rubricGap": {
            "type": "integer",
            "default": 8,
            "description": "Gap between rubric chips, px 0..48, default 8."
          },
          "searchInputStyle": {
            "type": "object",
            "default": {
              "surface": {
                "background": {
                  "fill": {
                    "kind": "color",
                    "color": {
                      "hex": "#f7f7f8"
                    }
                  }
                },
                "border": {
                  "width": 1,
                  "color": {
                    "hex": "#e5e7eb"
                  },
                  "style": "solid"
                },
                "radius": 999,
                "padding": {
                  "top": 6,
                  "right": 8,
                  "bottom": 6,
                  "left": 14
                }
              },
              "focus": {
                "border": {
                  "width": 1,
                  "color": {
                    "hex": "#9ca3af"
                  },
                  "style": "solid"
                }
              },
              "text": {
                "size": 14
              },
              "placeholderColor": {
                "hex": "#9ca3af"
              },
              "iconShow": false,
              "iconColor": {
                "hex": "#9ca3af"
              },
              "height": 40
            },
            "description": "InputStyle of the field itself (shared input object): surface {base, hover, focus} — fill, border, radius, padding, shadow per state (focus = :focus-within); text {size, color}; placeholderColor; iconShow + iconColor (magnifier on the left); height (min, px). Default: pill, light grey fill, thin border that darkens on focus, height 40."
          },
          "searchButtonStyle": {
            "type": "object",
            "default": {
              "kind": "solid",
              "size": "s",
              "base": {
                "surface": {
                  "background": {
                    "fill": {
                      "kind": "color",
                      "color": {
                        "hex": "#111827"
                      }
                    }
                  },
                  "radius": 999
                },
                "text": {
                  "weight": "600",
                  "color": {
                    "hex": "#ffffff"
                  }
                }
              }
            },
            "description": "ButtonStyle of the submit button (same button object as readMoreStyle). Default: solid dark, size s, pill."
          },
          "searchButtonVisible": {
            "type": "boolean",
            "default": true,
            "description": "false hides the submit button; Enter still searches."
          },
          "searchClearStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 13,
                "color": {
                  "hex": "#6b7280"
                }
              },
              "hover": {}
            },
            "description": "Text style of the \"Clear\" link shown inside the field while a query is active (same text contract as headlineStyle)."
          },
          "badgeStyle": {
            "type": "null",
            "description": "BadgeStyle {surface, text} for the badge over the cover; the badge text comes from the article."
          },
          "readMoreStyle": {
            "type": "object",
            "default": {
              "kind": "outline",
              "size": "s",
              "base": {}
            },
            "description": "ButtonStyle {kind, size, base:{surface,text}, hover} of the \"Read more\" link button in the card (default outline, size s). Hide it via hiddenParts: readMore. Hidden on narrow screens."
          },
          "headlineStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 17,
                "weight": "700",
                "lineHeight": 1.3
              },
              "hover": {}
            },
            "description": "States<Typography>: base has size/weight/lineHeight/color/transform/decoration; hover only color/decoration."
          },
          "rubricStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 12,
                "weight": "700",
                "transform": "uppercase"
              },
              "hover": {}
            },
            "description": "Same text style contract as headlineStyle."
          },
          "datesStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 12
              },
              "hover": {}
            },
            "description": "Same text style contract; date format comes from the shop settings."
          },
          "announceStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 14,
                "lineHeight": 1.45
              },
              "hover": {}
            },
            "description": "Same text style contract."
          },
          "authorStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 14,
                "weight": "500"
              },
              "hover": {}
            },
            "description": "Same text style contract."
          },
          "coverAspect": {
            "type": "string",
            "default": "3/2",
            "enum": [
              "3/4",
              "4/3",
              "3/2",
              "16/9",
              "1/1"
            ],
            "description": "Cover ratio for tiles and rows: 3/4, 4/3, 3/2, 16/9 or 1/1. Default 3/2 in tiles, 4/3 in rows. Ignored in masonry."
          },
          "rowCoverWidth": {
            "type": "integer",
            "default": 320,
            "description": "rows only: cover column width in px, 160..640, default 320."
          },
          "rowMaxWidth": {
            "type": "integer",
            "default": 0,
            "description": "rows only: maximum row width in px; 0 (default) means no limit."
          },
          "width": {
            "type": "string",
            "default": "content",
            "description": "content (default) keeps the site content width; full spans the screen."
          },
          "openInNewTab": {
            "type": "boolean",
            "default": false,
            "description": "true opens material in a new tab (rel=noopener)."
          },
          "paging": {
            "type": "string",
            "default": "auto",
            "enum": [
              "none",
              "pages",
              "more",
              "auto"
            ],
            "description": "Shared feed paging: none — first page only; pages — server-rendered page links (?page=N); more — a \"show more\" button appends the next page with the same card; auto (default) — the next pages load by themselves near the end of the feed, up to 3 in a row, then the button. Page links stay in the markup for crawlers in more/auto; the address updates to ?page=N without a reload."
          },
          "limit": {
            "type": "integer",
            "default": 20,
            "description": "Materials per page, 1..48, default 20."
          },
          "categoryId": {
            "type": "integer",
            "default": 0,
            "description": "0 uses the page rubric, falling back to the root news rubric; a positive id selects that rubric and its descendants."
          },
          "rubricsVisible": {
            "type": "boolean",
            "default": true,
            "description": "false hides the rubric switcher above the list."
          },
          "searchVisible": {
            "type": "boolean",
            "default": true,
            "description": "false hides the search field (full width under the rubric band). The field searches news only, inside the page rubric and its descendants; submit reloads the feed with ?q=."
          },
          "searchStyle": {
            "type": "null",
            "description": "Surface of the band around the search field (wrapper), not the field itself."
          },
          "hiddenParts": {
            "type": "array",
            "default": [],
            "description": "Card parts to hide: cover, badge, rubric, date, author, announce, readMore. The headline always stays."
          }
        }
      },
      "choices": {
        "view": [
          "tiles",
          "masonry",
          "rows"
        ],
        "datePosition": [
          "meta",
          "title",
          "author"
        ],
        "dateMode": [
          "published",
          "modified",
          "both"
        ],
        "authorPosition": [
          "inside",
          "below"
        ],
        "coverAspect": [
          "3/4",
          "4/3",
          "3/2",
          "16/9",
          "1/1"
        ],
        "paging": [
          "none",
          "pages",
          "more",
          "auto"
        ]
      },
      "props": {
        "view": "tiles",
        "columns": 3,
        "columnsTablet": 2,
        "columnsMobile": 1,
        "datePosition": "meta",
        "dateMode": "published",
        "authorPosition": "below",
        "cardStyle": {
          "radius": 18,
          "padding": {
            "top": 8,
            "right": 8,
            "bottom": 8,
            "left": 8
          }
        },
        "coverStyle": {
          "radius": 10
        },
        "textStyle": {
          "padding": {
            "top": 12,
            "right": 10,
            "bottom": 10,
            "left": 10
          }
        },
        "rubricChip": {
          "labelStyle": {
            "base": {
              "size": 14,
              "lineHeight": 1.2
            },
            "hover": {}
          },
          "activeLabelStyle": {
            "color": {
              "hex": "#ffffff"
            }
          },
          "itemStyle": {
            "base": {
              "border": {
                "width": 1,
                "color": {
                  "hex": "#e5e7eb"
                },
                "style": "solid"
              },
              "radius": 999,
              "padding": {
                "top": 7,
                "right": 16,
                "bottom": 7,
                "left": 16
              }
            },
            "hover": {
              "border": {
                "width": 1,
                "color": {
                  "hex": "#9ca3af"
                },
                "style": "solid"
              }
            },
            "active": {
              "background": {
                "fill": {
                  "kind": "color",
                  "color": {
                    "hex": "#111827"
                  }
                }
              },
              "border": {
                "width": 1,
                "color": {
                  "hex": "#111827"
                },
                "style": "solid"
              }
            }
          }
        },
        "rubricGap": 8,
        "searchInputStyle": {
          "surface": {
            "background": {
              "fill": {
                "kind": "color",
                "color": {
                  "hex": "#f7f7f8"
                }
              }
            },
            "border": {
              "width": 1,
              "color": {
                "hex": "#e5e7eb"
              },
              "style": "solid"
            },
            "radius": 999,
            "padding": {
              "top": 6,
              "right": 8,
              "bottom": 6,
              "left": 14
            }
          },
          "focus": {
            "border": {
              "width": 1,
              "color": {
                "hex": "#9ca3af"
              },
              "style": "solid"
            }
          },
          "text": {
            "size": 14
          },
          "placeholderColor": {
            "hex": "#9ca3af"
          },
          "iconShow": false,
          "iconColor": {
            "hex": "#9ca3af"
          },
          "height": 40
        },
        "searchButtonStyle": {
          "kind": "solid",
          "size": "s",
          "base": {
            "surface": {
              "background": {
                "fill": {
                  "kind": "color",
                  "color": {
                    "hex": "#111827"
                  }
                }
              },
              "radius": 999
            },
            "text": {
              "weight": "600",
              "color": {
                "hex": "#ffffff"
              }
            }
          }
        },
        "searchButtonVisible": true,
        "searchClearStyle": {
          "base": {
            "size": 13,
            "color": {
              "hex": "#6b7280"
            }
          },
          "hover": {}
        },
        "readMoreStyle": {
          "kind": "outline",
          "size": "s",
          "base": {}
        },
        "headlineStyle": {
          "base": {
            "size": 17,
            "weight": "700",
            "lineHeight": 1.3
          },
          "hover": {}
        },
        "rubricStyle": {
          "base": {
            "size": 12,
            "weight": "700",
            "transform": "uppercase"
          },
          "hover": {}
        },
        "datesStyle": {
          "base": {
            "size": 12
          },
          "hover": {}
        },
        "announceStyle": {
          "base": {
            "size": 14,
            "lineHeight": 1.45
          },
          "hover": {}
        },
        "authorStyle": {
          "base": {
            "size": 14,
            "weight": "500"
          },
          "hover": {}
        },
        "coverAspect": "3/2",
        "rowCoverWidth": 320,
        "rowMaxWidth": 0,
        "width": "content",
        "openInNewTab": false,
        "paging": "auto",
        "limit": 20,
        "categoryId": 0,
        "rubricsVisible": true,
        "searchVisible": true,
        "hiddenParts": []
      }
    },
    {
      "kind": "articleListing",
      "label": {
        "ru": "Новости: список",
        "en": "News list"
      },
      "placement": "page",
      "render": "section",
      "writePath": "props.articles",
      "see": "packages/sections/src/widgets/articleListing/MCP.md. Set props.articles.previewVersion=2 for independent cover and thumbnail visibility in hiddenEls; legacy hidden cover hides both. Inner background/border/padding/shadow are in props.surface, NOT props.articles. Outer wrapper is independent. Surface uses the same desktop -> tablet (<1024px) -> mobile (<640px) cascade in canvas and SSR. Delete only the selected override field to inherit; shadow none explicitly disables it. Forms must be created in the full form editor and then linked.",
      "content": {
        "text": "Legacy field retained in payload; the news list has no separate heading.",
        "items": "Ordered manual cards when articles.source=manual. All non-hidden items render; limit only applies to the automatic news feed.",
        "files": "Read-only server-resolved files for manual card file_id values.",
        "item": {
          "title": "Card headline.",
          "subtitle": "Rubric label.",
          "published_at": "Publication date, ISO date or timestamp.",
          "file_id": "Uploaded image id; server resolves its URL.",
          "linkTarget": "Canonical LinkRef, including form or category. Legacy fallback: link.",
          "hidden": "Keeps the card but excludes it from display."
        }
      },
      "contentPath": "section",
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "default": "news",
            "enum": [
              "news",
              "manual"
            ],
            "description": "news (default): automatic feed; manual: section.items, without a feed request or limit."
          },
          "view": {
            "type": "string",
            "default": "list",
            "enum": [
              "list"
            ]
          },
          "itemGap": {
            "type": "integer",
            "default": 24,
            "description": "Space between cards, 0..160px. No extra outer spacing."
          },
          "dividerVisible": {
            "type": "boolean",
            "default": true,
            "description": "false hides separators without erasing divider settings."
          },
          "divider": {
            "type": "object",
            "default": {
              "width": 1,
              "color": {
                "hex": "#e5e7eb"
              },
              "style": "solid"
            },
            "description": "Border {width,style,color}; separate from the outer surface border."
          },
          "coverBleed": {
            "type": "boolean",
            "default": false,
            "description": "Large first image reaches surface edges; text keeps surface padding. Four custom corners remain effective. Not viewport full bleed."
          },
          "layout": {
            "type": "string",
            "default": "feature",
            "enum": [
              "feature",
              "feature-list",
              "compact",
              "numbered"
            ],
            "description": "feature: large cover then small previews; feature-list: large cover then text rows; compact: small previews; numbered: no images."
          },
          "categoryId": {
            "type": "integer",
            "default": 0,
            "description": "0 uses the root news rubric; a positive id selects that rubric and descendants within the current shop."
          },
          "limit": {
            "type": "integer",
            "default": 3,
            "description": "Automatic feed only: integer 1..24, default 3. Ignored for manual cards."
          },
          "headlineTag": {
            "type": "string",
            "default": "h3"
          },
          "rubricTag": {
            "type": "string",
            "default": "div"
          },
          "datesTag": {
            "type": "string",
            "default": "div"
          },
          "headlineStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 16,
                "weight": "600",
                "lineHeight": 1.375,
                "color": {
                  "hex": "#111827"
                }
              },
              "hover": {}
            },
            "description": "States<Typography>: base has size/weight/lineHeight/color/transform/decoration; hover only color/decoration."
          },
          "rubricStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 12,
                "weight": "500",
                "color": {
                  "hex": "#6b7280"
                }
              },
              "hover": {}
            },
            "description": "Same text style contract as headlineStyle."
          },
          "datesStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 12,
                "lineHeight": 1.375,
                "color": {
                  "hex": "#6b7280"
                }
              },
              "hover": {}
            },
            "description": "Same style contract; date formatting comes from the shop, not this widget."
          },
          "dateMode": {
            "type": "string",
            "default": "published",
            "enum": [
              "published",
              "modified",
              "both"
            ],
            "description": "Which dates to print: published (default) — the publication date; modified — \"Updated <date>\" from the article field modified_at (falls back to the publication date when never modified); both — \"<published> · Updated <modified>\", the update skipped when it is the same day. Dates are fields of the article (published_at, modified_at), not of the widget."
          },
          "authorStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 12,
                "lineHeight": 1.375,
                "color": {
                  "hex": "#6b7280"
                }
              },
              "hover": {}
            },
            "description": "Text style of the author name line under the date (hide via props.hiddenEls=[author]); shown only when the article has an author."
          },
          "thumbnailStyle": {
            "type": "object",
            "default": {
              "radius": 16
            },
            "description": "Independent small image Surface; only radius falls back to legacy coverStyle, never its padding/border/shadow."
          },
          "thumbnailFit": {
            "type": "string",
            "default": "cover",
            "enum": [
              "cover",
              "contain"
            ]
          },
          "thumbnailAspect": {
            "type": "string",
            "default": "1/1",
            "enum": [
              "3/2",
              "16/9",
              "1/1"
            ]
          },
          "coverStyle": {
            "type": "object",
            "default": {
              "radius": 16
            },
            "description": "Independent image Surface. Radius: number or {tl,tr,br,bl}."
          },
          "coverFit": {
            "type": "string",
            "default": "cover",
            "enum": [
              "cover",
              "contain"
            ]
          },
          "coverAspect": {
            "type": "string",
            "default": "3/2",
            "enum": [
              "3/2",
              "16/9",
              "1/1"
            ]
          }
        }
      },
      "choices": {
        "source": [
          "news",
          "manual"
        ],
        "view": [
          "list"
        ],
        "layout": [
          "feature",
          "feature-list",
          "compact",
          "numbered"
        ],
        "dateMode": [
          "published",
          "modified",
          "both"
        ],
        "thumbnailFit": [
          "cover",
          "contain"
        ],
        "thumbnailAspect": [
          "3/2",
          "16/9",
          "1/1"
        ],
        "coverFit": [
          "cover",
          "contain"
        ],
        "coverAspect": [
          "3/2",
          "16/9",
          "1/1"
        ]
      },
      "props": {
        "source": "news",
        "view": "list",
        "itemGap": 24,
        "dividerVisible": true,
        "divider": {
          "width": 1,
          "color": {
            "hex": "#e5e7eb"
          },
          "style": "solid"
        },
        "coverBleed": false,
        "layout": "feature",
        "categoryId": 0,
        "limit": 3,
        "headlineTag": "h3",
        "rubricTag": "div",
        "datesTag": "div",
        "headlineStyle": {
          "base": {
            "size": 16,
            "weight": "600",
            "lineHeight": 1.375,
            "color": {
              "hex": "#111827"
            }
          },
          "hover": {}
        },
        "rubricStyle": {
          "base": {
            "size": 12,
            "weight": "500",
            "color": {
              "hex": "#6b7280"
            }
          },
          "hover": {}
        },
        "datesStyle": {
          "base": {
            "size": 12,
            "lineHeight": 1.375,
            "color": {
              "hex": "#6b7280"
            }
          },
          "hover": {}
        },
        "dateMode": "published",
        "authorStyle": {
          "base": {
            "size": 12,
            "lineHeight": 1.375,
            "color": {
              "hex": "#6b7280"
            }
          },
          "hover": {}
        },
        "thumbnailStyle": {
          "radius": 16
        },
        "thumbnailFit": "cover",
        "thumbnailAspect": "1/1",
        "coverStyle": {
          "radius": 16
        },
        "coverFit": "cover",
        "coverAspect": "3/2"
      }
    },
    {
      "kind": "articleHeader",
      "label": {
        "ru": "Шапка новости",
        "en": "Article header"
      },
      "placement": "page",
      "render": "section",
      "writePath": "props.articleHeader",
      "see": "packages/sections/src/widgets/articleHeader/MCP.md. Title, description (Article.announce), rubric and publication date come from context.article. Never copy real article text into a shared template. Custom cover is section.file_id; uploaded URL is resolved read-only by the server. Independent inner background/border/padding/shadow live at props.surface. Block surface inherits desktop -> tablet (<1024px) -> mobile (<640px) equally in canvas and SSR. Decorative tags live in articleHeader.tags, not in the resource taxonomy. Gallery and mobile viewport bleed are not implemented yet.",
      "content": {
        "file_id": "Uploaded custom cover id. Used only when articleHeader.coverSource=custom.",
        "file": "Read-only resolved cover {id,url}. Never write a URL in place of file_id."
      },
      "contentPath": "section",
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "authorPhotoSize": {
            "type": "integer",
            "default": 40,
            "description": "Optional author photo size, 24..96px, default40; round, cropped, no placeholder when absent. Same non-interactive author on canvas and storefront."
          },
          "authorStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 14,
                "weight": "500",
                "color": {
                  "hex": "#111827"
                }
              },
              "hover": {}
            },
            "description": "Base Typography for context.article.author.name; default size14, weight500. Author identity is stored on the Article resource, never in widget props. No profile URL or navigation."
          },
          "authorDescriptionStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 12,
                "color": {
                  "hex": "#6b7280"
                }
              },
              "hover": {}
            },
            "description": "Base Typography for the optional author description; default size12. Photo/name/description are hidden together with props.hiddenEls=[author]. Missing author renders nothing."
          },
          "gap": {
            "type": "integer",
            "default": 20,
            "description": "Spacing between header elements, 0..160 px. New editor blocks explicitly set 7; legacy missing-field fallback is 20. New blocks also set coverPosition=before, props.hiddenEls=[rubric], props.paddingSides={top:0,right:0,bottom:24,left:0}, props.blockRadius=0; wrapper stays content-width with no border."
          },
          "tags": {
            "type": "array",
            "default": [],
            "description": "Ordered labels {key,text,hidden?,target?:LinkRef}. text is the label name; optional target uses the standard URL/resource/form link contract. No target means plain text. Links are inert in the editor and sanitized on the storefront. Shared template labels apply to all its pages; not resource taxonomy or search tags."
          },
          "tagsStyle": {
            "type": "object",
            "default": {
              "background": {
                "fill": {
                  "kind": "color",
                  "color": {
                    "hex": "#f3f4f6"
                  }
                }
              },
              "radius": 6,
              "padding": {
                "top": 4,
                "right": 8,
                "bottom": 4,
                "left": 8
              }
            },
            "description": "Independent Surface of each label; default radius6 and padding4/8."
          },
          "tagsTextStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 12,
                "weight": "500",
                "color": {
                  "hex": "#4b5563"
                }
              },
              "hover": {}
            },
            "description": "Base Typography shared by labels; default size12, weight500."
          },
          "coverPosition": {
            "type": "string",
            "default": "after",
            "enum": [
              "before",
              "after"
            ],
            "description": "before: image above title; after (default): image below article metadata."
          },
          "coverSource": {
            "type": "string",
            "default": "article",
            "enum": [
              "article",
              "custom"
            ],
            "description": "article (default) uses the resource cover; custom uses section.file_id. Switching source preserves the custom file. An empty custom source shows no image."
          },
          "coverStyle": {
            "type": "object",
            "default": {
              "radius": 16
            },
            "description": "Independent Surface for the image. Radius is number or four corners {tl,tr,br,bl}; default 16."
          },
          "coverFit": {
            "type": "string",
            "default": "cover",
            "enum": [
              "cover",
              "contain"
            ],
            "description": "cover crops to fill; contain preserves the whole image."
          },
          "coverAspect": {
            "type": "string",
            "default": "3/2",
            "enum": [
              "3/2",
              "16/9",
              "1/1"
            ],
            "description": "Image aspect ratio: 3/2, 16/9 or 1/1."
          },
          "titleTag": {
            "type": "string",
            "default": "h1",
            "description": "HTML tag: div, p, h1..h6. Default h1. Avoid a second h1 on the page."
          },
          "descriptionTag": {
            "type": "string",
            "default": "p",
            "description": "HTML tag for Article.announce; default p."
          },
          "rubricTag": {
            "type": "string",
            "default": "div",
            "description": "HTML tag for the actual rubric label; default div."
          },
          "datesTag": {
            "type": "string",
            "default": "div",
            "description": "Wrapper tag for a semantic time element; default div."
          },
          "titleStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 32,
                "weight": "600",
                "lineHeight": 1.25,
                "color": {
                  "hex": "#111827"
                }
              },
              "hover": {}
            },
            "description": "States<Typography>. Default base size32, weight600, lineHeight1.25. Legacy props.titleStyle remains a fallback."
          },
          "descriptionStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 18,
                "lineHeight": 1.5,
                "color": {
                  "hex": "#6b7280"
                }
              },
              "hover": {}
            },
            "description": "Base Typography: default size18, lineHeight1.5. Description is escaped plain text."
          },
          "rubricStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 14,
                "weight": "500",
                "color": {
                  "hex": "#6b7280"
                }
              },
              "hover": {}
            },
            "description": "Base Typography: default size14, weight500."
          },
          "datesStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 12,
                "color": {
                  "hex": "#6b7280"
                }
              },
              "hover": {}
            },
            "description": "Base Typography: default size12. Date language/timezone/format are inherited from shop settings."
          },
          "dateMode": {
            "type": "string",
            "default": "published",
            "enum": [
              "published",
              "modified",
              "both"
            ],
            "description": "Which dates to print: published (default) — the publication date; modified — \"Updated <date>\" from the article field modified_at (falls back to the publication date when never modified); both — \"<published> · Updated <modified>\", the update skipped when it is the same day. Dates are fields of the article (published_at, modified_at), not of the widget."
          }
        }
      },
      "choices": {
        "coverPosition": [
          "before",
          "after"
        ],
        "coverSource": [
          "article",
          "custom"
        ],
        "coverFit": [
          "cover",
          "contain"
        ],
        "coverAspect": [
          "3/2",
          "16/9",
          "1/1"
        ],
        "dateMode": [
          "published",
          "modified",
          "both"
        ]
      },
      "props": {
        "authorPhotoSize": 40,
        "authorStyle": {
          "base": {
            "size": 14,
            "weight": "500",
            "color": {
              "hex": "#111827"
            }
          },
          "hover": {}
        },
        "authorDescriptionStyle": {
          "base": {
            "size": 12,
            "color": {
              "hex": "#6b7280"
            }
          },
          "hover": {}
        },
        "gap": 20,
        "tags": [],
        "tagsStyle": {
          "background": {
            "fill": {
              "kind": "color",
              "color": {
                "hex": "#f3f4f6"
              }
            }
          },
          "radius": 6,
          "padding": {
            "top": 4,
            "right": 8,
            "bottom": 4,
            "left": 8
          }
        },
        "tagsTextStyle": {
          "base": {
            "size": 12,
            "weight": "500",
            "color": {
              "hex": "#4b5563"
            }
          },
          "hover": {}
        },
        "coverPosition": "after",
        "coverSource": "article",
        "coverStyle": {
          "radius": 16
        },
        "coverFit": "cover",
        "coverAspect": "3/2",
        "titleTag": "h1",
        "descriptionTag": "p",
        "rubricTag": "div",
        "datesTag": "div",
        "titleStyle": {
          "base": {
            "size": 32,
            "weight": "600",
            "lineHeight": 1.25,
            "color": {
              "hex": "#111827"
            }
          },
          "hover": {}
        },
        "descriptionStyle": {
          "base": {
            "size": 18,
            "lineHeight": 1.5,
            "color": {
              "hex": "#6b7280"
            }
          },
          "hover": {}
        },
        "rubricStyle": {
          "base": {
            "size": 14,
            "weight": "500",
            "color": {
              "hex": "#6b7280"
            }
          },
          "hover": {}
        },
        "datesStyle": {
          "base": {
            "size": 12,
            "color": {
              "hex": "#6b7280"
            }
          },
          "hover": {}
        },
        "dateMode": "published"
      }
    },
    {
      "kind": "articleRubrics",
      "label": {
        "ru": "Рубрики новостей",
        "en": "News rubrics"
      },
      "placement": "page",
      "render": "section",
      "writePath": "props.articleRubrics",
      "see": "packages/sections/src/widgets/articleRubrics/MCP.md. Real news root and children come from context.articleRubrics; do not persist demo/active/links. Inner block surface is props.surface; items have their own itemStyle. Block surface uses the same desktop -> tablet (<1024px) -> mobile (<640px) cascade in canvas and SSR. Item styling remains shared across devices.",
      "content": {
        "text": "Optional heading above the list."
      },
      "contentPath": "section",
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "layout": {
            "type": "string",
            "default": "list",
            "enum": [
              "list",
              "chips"
            ],
            "description": "list (default) or chips; switching preserves all styles."
          },
          "gap": {
            "type": "integer",
            "default": 4,
            "description": "Item spacing 0..160 px; default list=4, chips=8."
          },
          "titleTag": {
            "type": "string",
            "default": "h3",
            "enum": [
              "h2",
              "h3",
              "p",
              "div"
            ],
            "description": "Heading tag h2/h3/p/div, default h3. Text is section.text; typography is props.titleStyle."
          },
          "labelStyle": {
            "type": "object",
            "default": {
              "base": {
                "size": 14,
                "weight": "400",
                "lineHeight": 1.5,
                "color": {
                  "hex": "#4b5563"
                }
              },
              "hover": {}
            },
            "description": "States<Typography>: base text styling; hover color/decoration."
          },
          "activeLabelStyle": {
            "type": "object",
            "default": {
              "weight": "600",
              "color": {
                "hex": "#111827"
              }
            },
            "description": "Active rubric text styling; default weight=600 and color=#111827."
          },
          "itemStyle": {
            "type": "object",
            "default": {
              "base": {
                "radius": 8,
                "padding": {
                  "top": 8,
                  "right": 12,
                  "bottom": 8,
                  "left": 12
                }
              },
              "hover": {
                "background": {
                  "fill": {
                    "kind": "color",
                    "color": {
                      "hex": "#f9fafb"
                    }
                  }
                }
              },
              "active": {
                "background": {
                  "fill": {
                    "kind": "color",
                    "color": {
                      "hex": "#f3f4f6"
                    }
                  }
                }
              }
            },
            "description": "States<Surface>: base/hover/active. Independent item fill, border, radius, padding and shadow."
          }
        }
      },
      "choices": {
        "layout": [
          "list",
          "chips"
        ],
        "titleTag": [
          "h2",
          "h3",
          "p",
          "div"
        ]
      },
      "props": {
        "layout": "list",
        "gap": 4,
        "titleTag": "h3",
        "labelStyle": {
          "base": {
            "size": 14,
            "weight": "400",
            "lineHeight": 1.5,
            "color": {
              "hex": "#4b5563"
            }
          },
          "hover": {}
        },
        "activeLabelStyle": {
          "weight": "600",
          "color": {
            "hex": "#111827"
          }
        },
        "itemStyle": {
          "base": {
            "radius": 8,
            "padding": {
              "top": 8,
              "right": 12,
              "bottom": 8,
              "left": 12
            }
          },
          "hover": {
            "background": {
              "fill": {
                "kind": "color",
                "color": {
                  "hex": "#f9fafb"
                }
              }
            }
          },
          "active": {
            "background": {
              "fill": {
                "kind": "color",
                "color": {
                  "hex": "#f3f4f6"
                }
              }
            }
          }
        }
      }
    },
    {
      "kind": "breadcrumbs",
      "label": {
        "ru": "Хлебные крошки",
        "en": "Breadcrumbs"
      },
      "placement": "page",
      "render": "slot",
      "writePath": "props",
      "see": null,
      "content": null,
      "contentPath": null,
      "schema": null,
      "choices": {},
      "props": null
    },
    {
      "kind": "pageHeading",
      "label": {
        "ru": "Заголовок страницы",
        "en": "Page heading"
      },
      "placement": "page",
      "render": "slot",
      "writePath": "props",
      "see": null,
      "content": null,
      "contentPath": null,
      "schema": null,
      "choices": {},
      "props": null
    },
    {
      "kind": "productListing",
      "label": {
        "ru": "Товары категории",
        "en": "Category products"
      },
      "placement": "page",
      "render": "slot",
      "writePath": "props.listing",
      "see": null,
      "content": null,
      "contentPath": null,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "categoryId": {
            "type": "integer",
            "default": 0
          },
          "template": {
            "type": "string",
            "default": "",
            "description": "Card design override for this block; empty = the shop default. Unknown value reads as `default`."
          },
          "showFilter": {
            "type": "boolean",
            "default": true
          },
          "limit": {
            "type": "integer",
            "default": 24,
            "description": "Products per page, 4..48."
          },
          "cardClick": {
            "type": "string",
            "default": "link",
            "enum": [
              "link",
              "modal"
            ],
            "description": "`link` — a plain click navigates to the product page; `modal` — it opens the product in a quick view window instead."
          },
          "showQuickViewButton": {
            "type": "boolean",
            "default": false,
            "description": "A separate \"Quick view\" button on every tile, regardless of `cardClick`."
          },
          "paging": {
            "type": "string",
            "default": "auto",
            "enum": [
              "none",
              "pages",
              "more",
              "auto"
            ],
            "description": "Shared feed paging: none — first page only; pages — page links (?<ns>page=N); more — a \"show more\" button appends the next page; auto (default) — the next pages load by themselves near the end, up to 3 in a row, then the button. Page links stay in the markup for crawlers in more/auto."
          },
          "modalTpl": {
            "type": "integer",
            "default": 0,
            "description": "id of the design group to draw the window body with; `0` = the shop ladder decides, same as the product page."
          },
          "modalSize": {
            "type": "string",
            "default": "medium",
            "enum": [
              "small",
              "medium",
              "full"
            ],
            "description": "Quick view window: `small` = 480px, `medium` = the shop content width plus its gutters (up to 1648px on a wide screen), `full` = the whole screen."
          },
          "modalNav": {
            "type": "boolean",
            "default": true,
            "description": "Let the window walk the products of THIS listing with the arrows (the arrows themselves live in the window footer)."
          },
          "source": {
            "type": "string",
            "default": "category",
            "enum": [
              "category",
              "children",
              "shop"
            ],
            "description": "`category` — products of `categoryId`; `children` — the children of a container product; `shop` — the whole catalogue (`categoryId` is not read)."
          },
          "parentProductId": {
            "type": "integer",
            "default": 0
          }
        }
      },
      "choices": {
        "cardClick": [
          "link",
          "modal"
        ],
        "paging": [
          "none",
          "pages",
          "more",
          "auto"
        ],
        "modalSize": [
          "small",
          "medium",
          "full"
        ],
        "source": [
          "category",
          "children",
          "shop"
        ]
      },
      "props": {
        "categoryId": 0,
        "template": "",
        "showFilter": true,
        "limit": 24,
        "cardClick": "link",
        "showQuickViewButton": false,
        "paging": "auto",
        "modalTpl": 0,
        "modalSize": "medium",
        "modalNav": true,
        "source": "category",
        "parentProductId": 0
      }
    },
    {
      "kind": "productCard",
      "label": {
        "ru": "Карточка товара",
        "en": "Product card"
      },
      "placement": "page",
      "render": "slot",
      "writePath": "props.card",
      "see": null,
      "content": null,
      "contentPath": null,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "productId": {
            "type": "integer",
            "default": 0
          }
        }
      },
      "choices": {},
      "props": {
        "productId": 0
      }
    },
    {
      "kind": "slideshow",
      "label": {
        "ru": "Слайд-шоу",
        "en": "Slideshow"
      },
      "placement": "page",
      "render": "section",
      "writePath": "props.slideshow",
      "see": null,
      "content": {
        "file_ids": "The slides: ids of uploaded images, in show order. This is where the pictures come from.",
        "items": "Optional meta for a slide, matched by file_id — one entry per slide you want to annotate.",
        "item": {
          "file_id": "Which slide of file_ids this entry describes.",
          "text": "Caption of the slide (shown when props.slideshow.caption is on).",
          "alt": "Alt text of the image.",
          "hidden": "true keeps the slide in the payload but not in the show."
        },
        "files": "Resolved by the backend from file_ids (url, id) — read-only, do not write it."
      },
      "contentPath": "section",
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "aspect": {
            "type": "string",
            "default": "16:9"
          },
          "aspectClass": {
            "type": "string",
            "default": "aspect-video"
          },
          "controls": {
            "type": "string",
            "default": "arrows_dots"
          },
          "showArrows": {
            "type": "boolean",
            "default": true
          },
          "showDots": {
            "type": "boolean",
            "default": true
          },
          "transition": {
            "type": "string",
            "default": "slide"
          },
          "autoplay": {
            "type": "integer",
            "default": 0
          },
          "radius": {
            "type": "null"
          },
          "caption": {
            "type": "string",
            "default": "off"
          },
          "captionStyle": {
            "type": "object",
            "default": {}
          },
          "captionClass": {
            "type": "string",
            "default": "text-sm sm:text-base"
          },
          "zoom": {
            "type": "boolean",
            "default": false
          },
          "hiddenEls": {
            "type": "array",
            "default": []
          },
          "legacy": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "choices": {},
      "props": {
        "aspect": "16:9",
        "aspectClass": "aspect-video",
        "controls": "arrows_dots",
        "showArrows": true,
        "showDots": true,
        "transition": "slide",
        "autoplay": 0,
        "caption": "off",
        "captionStyle": {},
        "captionClass": "text-sm sm:text-base",
        "zoom": false,
        "hiddenEls": [],
        "legacy": true
      }
    },
    {
      "kind": "reels",
      "label": {
        "ru": "Видеолента",
        "en": "Video strip"
      },
      "placement": "page",
      "render": "section",
      "writePath": "props.reels",
      "see": null,
      "content": {
        "text": "Heading above the strip.",
        "items": "The clips, in order. An entry with neither a file nor a poster is skipped.",
        "item": {
          "file_id": "The video file — id of an uploaded file; the server resolves it into url.",
          "poster_id": "Poster frame shown before playback — id of an uploaded image.",
          "text": "Caption on the tile and in the player.",
          "alt": "Alt text of the poster.",
          "duration": "Length in SECONDS — prints the \"0:37\" badge; omit it and no badge is shown.",
          "btn": "Button inside the player: {label, url, target}.",
          "hidden": "true keeps the entry in the payload but not on the site."
        },
        "files": "Resolved by the backend from the ids above (url, id) — read-only, do not write it."
      },
      "contentPath": "section",
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "layout": {
            "type": "string",
            "default": "grid",
            "enum": [
              "strip",
              "grid"
            ]
          },
          "tileHeight": {
            "type": "string",
            "default": "m"
          },
          "tileWidth": {
            "type": "integer",
            "default": 172
          },
          "tileAspect": {
            "type": "string",
            "default": "9:16"
          },
          "aspectClass": {
            "type": "string",
            "default": "aspect-[9/16]"
          },
          "columns": {
            "type": "integer",
            "default": 4
          },
          "gridClass": {
            "type": "string",
            "default": "grid-cols-2 @2xl:grid-cols-4"
          },
          "gap": {
            "type": "integer",
            "default": 12
          },
          "radius": {
            "type": "null"
          },
          "overflow": {
            "type": "string",
            "default": "plusN",
            "enum": [
              "plusN",
              "scroll"
            ]
          },
          "drift": {
            "type": "string",
            "default": "off",
            "enum": [
              "off",
              "slow",
              "mid",
              "fast"
            ]
          },
          "preview": {
            "type": "string",
            "default": "poster",
            "enum": [
              "poster",
              "hover"
            ]
          },
          "showTileCaptions": {
            "type": "boolean",
            "default": true
          },
          "showDuration": {
            "type": "boolean",
            "default": true
          },
          "autoAdvance": {
            "type": "boolean",
            "default": true
          },
          "loopAll": {
            "type": "boolean",
            "default": false
          },
          "title": {
            "type": "object",
            "default": {}
          },
          "titleTag": {
            "type": "string",
            "default": "h3",
            "enum": [
              "h2",
              "h3",
              "p",
              "div"
            ]
          },
          "hiddenEls": {
            "type": "array",
            "default": []
          }
        }
      },
      "choices": {
        "layout": [
          "strip",
          "grid"
        ],
        "overflow": [
          "plusN",
          "scroll"
        ],
        "drift": [
          "off",
          "slow",
          "mid",
          "fast"
        ],
        "preview": [
          "poster",
          "hover"
        ],
        "titleTag": [
          "h2",
          "h3",
          "p",
          "div"
        ]
      },
      "props": {
        "layout": "grid",
        "tileHeight": "m",
        "tileWidth": 172,
        "tileAspect": "9:16",
        "aspectClass": "aspect-[9/16]",
        "columns": 4,
        "gridClass": "grid-cols-2 @2xl:grid-cols-4",
        "gap": 12,
        "overflow": "plusN",
        "drift": "off",
        "preview": "poster",
        "showTileCaptions": true,
        "showDuration": true,
        "autoAdvance": true,
        "loopAll": false,
        "title": {},
        "titleTag": "h3",
        "hiddenEls": []
      }
    },
    {
      "kind": "cards",
      "label": {
        "ru": "Карточки",
        "en": "Cards"
      },
      "placement": "page",
      "render": "section",
      "writePath": "props",
      "see": null,
      "content": {
        "text": "Heading above the cards.",
        "items": "The cards, in order (used when props.source is \"manual\" — the other sources fill the block from the catalogue).",
        "item": {
          "title": "Card title.",
          "subtitle": "Card subtitle.",
          "text": "Card body text.",
          "badge": "Sticker over the picture (\"-17%\").",
          "file_id": "Card picture — id of an uploaded file; the server resolves it into url.",
          "alt": "Alt text of the picture.",
          "linkTarget": "Where the whole card leads: a LinkRef ({type,id}); the plain string link is the legacy fallback.",
          "btn": "First button: {label, url, target}.",
          "btn2": "Second button, same shape.",
          "hidden": "true keeps the card in the payload but not on the site."
        }
      },
      "contentPath": "section",
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "default": "manual"
          },
          "productRefs": {
            "type": "array",
            "default": []
          },
          "articlesLimit": {
            "type": "integer",
            "default": 4
          },
          "textOverPosition": {
            "type": "string",
            "default": "bottom",
            "enum": [
              "top",
              "bottom"
            ]
          },
          "textOverShade": {
            "type": "boolean",
            "default": true
          },
          "sliderFullWidth": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "choices": {
        "textOverPosition": [
          "top",
          "bottom"
        ]
      },
      "props": {
        "source": "manual",
        "productRefs": [],
        "articlesLimit": 4,
        "textOverPosition": "bottom",
        "textOverShade": true,
        "sliderFullWidth": false
      }
    },
    {
      "kind": "steps",
      "label": {
        "ru": "Этапы",
        "en": "Steps"
      },
      "placement": "page",
      "render": "section",
      "writePath": "props.steps",
      "see": null,
      "content": {
        "text": "Heading above the steps.",
        "items": "The steps, in order — the numbering follows this order (see props.steps.startFrom).",
        "item": {
          "title": "The step name.",
          "text": "The explaining line under it.",
          "file_id": "Marker icon of the step (used when props.steps.marker is \"icon\").",
          "alt": "Alt text of the marker icon.",
          "hidden": "true keeps the entry in the payload but not on the site — numbering skips it."
        }
      },
      "contentPath": "section",
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "layout": {
            "type": "string",
            "default": "grid",
            "enum": [
              "grid",
              "timeline"
            ]
          },
          "columns": {
            "type": "integer",
            "default": 4
          },
          "gridClass": {
            "type": "string",
            "default": "@2xl:grid-cols-2 @5xl:grid-cols-4"
          },
          "gap": {
            "type": "integer",
            "default": 24
          },
          "marker": {
            "type": "string",
            "default": "circle",
            "enum": [
              "circle",
              "square",
              "plain",
              "icon",
              "none"
            ]
          },
          "markerSize": {
            "type": "string",
            "default": "m"
          },
          "markerClass": {
            "type": "string",
            "default": "size-8 text-sm"
          },
          "markerPx": {
            "type": "integer",
            "default": 32
          },
          "markerFill": {
            "type": "object",
            "default": {
              "hex": ""
            }
          },
          "markerColor": {
            "type": "object",
            "default": {
              "hex": ""
            }
          },
          "connector": {
            "type": "boolean",
            "default": false
          },
          "connectorStyle": {
            "type": "string",
            "default": "solid",
            "enum": [
              "solid",
              "dashed"
            ]
          },
          "connectorColor": {
            "type": "object",
            "default": {
              "hex": ""
            }
          },
          "startFrom": {
            "type": "integer",
            "default": 1
          },
          "stepTitle": {
            "type": "object",
            "default": {}
          },
          "stepTitleClass": {
            "type": "string",
            "default": "text-base"
          },
          "stepText": {
            "type": "object",
            "default": {}
          },
          "stepTextClass": {
            "type": "string",
            "default": "text-sm"
          },
          "title": {
            "type": "object",
            "default": {}
          },
          "titleTag": {
            "type": "string",
            "default": "h3",
            "enum": [
              "h2",
              "h3",
              "p",
              "div"
            ]
          },
          "hiddenEls": {
            "type": "array",
            "default": []
          },
          "legacy": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "choices": {
        "layout": [
          "grid",
          "timeline"
        ],
        "marker": [
          "circle",
          "square",
          "plain",
          "icon",
          "none"
        ],
        "connectorStyle": [
          "solid",
          "dashed"
        ],
        "titleTag": [
          "h2",
          "h3",
          "p",
          "div"
        ]
      },
      "props": {
        "layout": "grid",
        "columns": 4,
        "gridClass": "@2xl:grid-cols-2 @5xl:grid-cols-4",
        "gap": 24,
        "marker": "circle",
        "markerSize": "m",
        "markerClass": "size-8 text-sm",
        "markerPx": 32,
        "markerFill": {
          "hex": ""
        },
        "markerColor": {
          "hex": ""
        },
        "connector": false,
        "connectorStyle": "solid",
        "connectorColor": {
          "hex": ""
        },
        "startFrom": 1,
        "stepTitle": {},
        "stepTitleClass": "text-base",
        "stepText": {},
        "stepTextClass": "text-sm",
        "title": {},
        "titleTag": "h3",
        "hiddenEls": [],
        "legacy": true
      }
    },
    {
      "kind": "faq",
      "label": {
        "ru": "Вопрос-ответ",
        "en": "FAQ"
      },
      "placement": "page",
      "render": "section",
      "writePath": "props.faq",
      "see": null,
      "content": {
        "text": "Heading above the list. Omit it and the block starts with the first question.",
        "items": "The questions, in order. An entry without title is skipped.",
        "item": {
          "title": "The question — the always visible line of <summary>.",
          "text": "The answer, revealed when the item opens. Line breaks are kept.",
          "hidden": "true keeps the entry in the payload but not on the site."
        }
      },
      "contentPath": "section",
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "openMode": {
            "type": "string",
            "default": "multi",
            "enum": [
              "multi",
              "single"
            ]
          },
          "firstOpen": {
            "type": "boolean",
            "default": false
          },
          "icon": {
            "type": "string",
            "default": "chevron",
            "enum": [
              "chevron",
              "plus",
              "none"
            ]
          },
          "frame": {
            "type": "boolean",
            "default": true
          },
          "bg": {
            "type": "object",
            "default": {
              "hex": ""
            }
          },
          "dividers": {
            "type": "boolean",
            "default": true
          },
          "dividerColor": {
            "type": "object",
            "default": {
              "hex": ""
            }
          },
          "gap": {
            "type": "integer",
            "default": 0
          },
          "question": {
            "type": "object",
            "default": {}
          },
          "questionClass": {
            "type": "string",
            "default": "text-base"
          },
          "answer": {
            "type": "object",
            "default": {}
          },
          "answerClass": {
            "type": "string",
            "default": "text-sm"
          },
          "title": {
            "type": "object",
            "default": {}
          },
          "titleTag": {
            "type": "string",
            "default": "h3",
            "enum": [
              "h2",
              "h3",
              "p",
              "div"
            ]
          },
          "hiddenEls": {
            "type": "array",
            "default": []
          },
          "legacy": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "choices": {
        "openMode": [
          "multi",
          "single"
        ],
        "icon": [
          "chevron",
          "plus",
          "none"
        ],
        "titleTag": [
          "h2",
          "h3",
          "p",
          "div"
        ]
      },
      "props": {
        "openMode": "multi",
        "firstOpen": false,
        "icon": "chevron",
        "frame": true,
        "bg": {
          "hex": ""
        },
        "dividers": true,
        "dividerColor": {
          "hex": ""
        },
        "gap": 0,
        "question": {},
        "questionClass": "text-base",
        "answer": {},
        "answerClass": "text-sm",
        "title": {},
        "titleTag": "h3",
        "hiddenEls": [],
        "legacy": true
      }
    },
    {
      "kind": "features",
      "label": {
        "ru": "Преимущества",
        "en": "Features"
      },
      "placement": "page",
      "render": "section",
      "writePath": "props.features",
      "see": null,
      "content": {
        "text": "Heading above the grid.",
        "items": "The advantages, in order. An entry with neither title, text nor icon is skipped.",
        "item": {
          "title": "The advantage name.",
          "text": "The explaining line under it.",
          "file_id": "Icon of the item — id of an uploaded file; the server resolves it into url.",
          "alt": "Alt text of the icon.",
          "hidden": "true keeps the entry in the payload but not on the site."
        }
      },
      "contentPath": "section",
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "columns": {
            "type": "integer",
            "default": 3
          },
          "gridClass": {
            "type": "string",
            "default": "@2xl:grid-cols-2 @5xl:grid-cols-3"
          },
          "gap": {
            "type": "integer",
            "default": 24
          },
          "align": {
            "type": "string",
            "default": "left",
            "enum": [
              "left",
              "center"
            ]
          },
          "icon": {
            "type": "string",
            "default": "rounded"
          },
          "iconSize": {
            "type": "string",
            "default": "m"
          },
          "iconClass": {
            "type": "string",
            "default": "size-12 rounded-xl bg-gray-100"
          },
          "iconFill": {
            "type": "object",
            "default": {
              "hex": ""
            }
          },
          "itemTitle": {
            "type": "object",
            "default": {}
          },
          "itemTitleClass": {
            "type": "string",
            "default": "text-base"
          },
          "itemText": {
            "type": "object",
            "default": {}
          },
          "itemTextClass": {
            "type": "string",
            "default": "text-sm"
          },
          "title": {
            "type": "object",
            "default": {}
          },
          "titleTag": {
            "type": "string",
            "default": "h3",
            "enum": [
              "h2",
              "h3",
              "p",
              "div"
            ]
          },
          "hiddenEls": {
            "type": "array",
            "default": []
          },
          "legacy": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "choices": {
        "align": [
          "left",
          "center"
        ],
        "titleTag": [
          "h2",
          "h3",
          "p",
          "div"
        ]
      },
      "props": {
        "columns": 3,
        "gridClass": "@2xl:grid-cols-2 @5xl:grid-cols-3",
        "gap": 24,
        "align": "left",
        "icon": "rounded",
        "iconSize": "m",
        "iconClass": "size-12 rounded-xl bg-gray-100",
        "iconFill": {
          "hex": ""
        },
        "itemTitle": {},
        "itemTitleClass": "text-base",
        "itemText": {},
        "itemTextClass": "text-sm",
        "title": {},
        "titleTag": "h3",
        "hiddenEls": [],
        "legacy": true
      }
    },
    {
      "kind": "cta",
      "label": {
        "ru": "Призыв к действию",
        "en": "Call to action"
      },
      "placement": "page",
      "render": "section",
      "writePath": "props.cta",
      "see": null,
      "content": {
        "text": "The headline of the call to action.",
        "subtitle": "The line under the headline.",
        "cta": "The button: {label, url, target} — target is a LinkRef ({type,id}), url a plain address."
      },
      "contentPath": "section",
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "align": {
            "type": "string",
            "default": "center"
          },
          "left": {
            "type": "boolean",
            "default": false
          },
          "bg": {
            "type": "object",
            "default": {
              "hex": ""
            }
          },
          "bgCss": {
            "type": "null"
          },
          "height": {
            "type": "string",
            "default": "normal"
          },
          "padClass": {
            "type": "string",
            "default": "px-8 py-10 sm:px-12"
          },
          "button": {
            "type": "null"
          },
          "target": {
            "type": "null"
          },
          "title": {
            "type": "object",
            "default": {}
          },
          "titleClass": {
            "type": "string",
            "default": "text-2xl sm:text-3xl"
          },
          "titleTag": {
            "type": "string",
            "default": "h3",
            "enum": [
              "h2",
              "h3",
              "p",
              "div"
            ]
          },
          "subtitle": {
            "type": "object",
            "default": {}
          },
          "subtitleClass": {
            "type": "string",
            "default": "text-base"
          },
          "hiddenEls": {
            "type": "array",
            "default": []
          },
          "legacy": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "choices": {
        "titleTag": [
          "h2",
          "h3",
          "p",
          "div"
        ]
      },
      "props": {
        "align": "center",
        "left": false,
        "bg": {
          "hex": ""
        },
        "height": "normal",
        "padClass": "px-8 py-10 sm:px-12",
        "title": {},
        "titleClass": "text-2xl sm:text-3xl",
        "titleTag": "h3",
        "subtitle": {},
        "subtitleClass": "text-base",
        "hiddenEls": [],
        "legacy": true
      }
    },
    {
      "kind": "columns",
      "label": {
        "ru": "Колонки",
        "en": "Columns"
      },
      "placement": "page",
      "render": "section",
      "writePath": "props.cols",
      "see": null,
      "content": {
        "text": "Optional heading above the columns.",
        "cols": "One list of ordinary sections per column: [[section, …], [section, …]]. The number of columns is the length of this list."
      },
      "contentPath": "section",
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "layoutKey": {
            "type": "string",
            "default": "2"
          },
          "template": {
            "type": "string",
            "default": "1fr 1fr"
          },
          "stack": {
            "type": "boolean",
            "default": true
          },
          "vAlign": {
            "type": "string",
            "default": "top"
          },
          "vAlignClass": {
            "type": "string",
            "default": "items-start"
          },
          "gap": {
            "type": "integer",
            "default": 24
          },
          "title": {
            "type": "object",
            "default": {}
          },
          "titleTag": {
            "type": "string",
            "default": "h3",
            "enum": [
              "h2",
              "h3",
              "p",
              "div"
            ]
          },
          "legacy": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "choices": {
        "titleTag": [
          "h2",
          "h3",
          "p",
          "div"
        ]
      },
      "props": {
        "layoutKey": "2",
        "template": "1fr 1fr",
        "stack": true,
        "vAlign": "top",
        "vAlignClass": "items-start",
        "gap": 24,
        "title": {},
        "titleTag": "h3",
        "legacy": true
      }
    },
    {
      "kind": "form",
      "label": {
        "ru": "Лид-форма",
        "en": "Lead form"
      },
      "placement": "page",
      "render": "slot",
      "writePath": "props.form",
      "see": "Fields, notifications and sandboxes belong to the form entity, not to this block: GET /docs/webcoding, section 13.4 (lead forms). The block holds only props.form.formId; a button anywhere can open the same form with href=\"form:<id>\".",
      "content": null,
      "contentPath": null,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {}
      },
      "choices": {},
      "props": {}
    },
    {
      "kind": "html",
      "label": {
        "ru": "html",
        "en": "html"
      },
      "placement": "page",
      "render": "slot",
      "writePath": "props.html",
      "see": null,
      "content": null,
      "contentPath": null,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "html_document_id": {
            "type": "null",
            "description": "Id of the html-document whose folder is rendered here. The markup itself is NOT stored in props: upload it, create the document (POST /html-documents), point the block at it."
          },
          "level": {
            "type": "integer",
            "default": 1,
            "enum": [
              1,
              2,
              3
            ],
            "description": "Isolation: 1 — sanitised HTML/CSS, scripts stripped, indexed; 2 — your scripts in a sandbox frame, not indexed; 3 — your HTML, CSS and <script> as real page DOM (needs role owner/admin plus the server flag). See /docs/vz-keys, section \"levels\"."
          },
          "productsCategoryId": {
            "type": "integer",
            "default": 0,
            "description": "Category id whose products fill the scope feed products[] for THIS block. Absent (0) keeps the old rule — the feed is the category the PAGE is, which on a landing means no products at all. Set it and the same markup shows live prices anywhere: <ul><li vz-for=\"p in products\">{{ p.name }} — {{ p.price_text }}</li></ul>. Two blocks on one page may name different categories; one category is fetched once however many blocks use it, and a block that never mentions products pays nothing. Everything else about the feed is unchanged: up to 48 items, same fields, same combo enrichment. A category of ANOTHER shop yields an empty feed, never foreign goods — the request is always scoped to this shop. See /docs/own-markup, section 2."
          },
          "productsMode": {
            "type": "string",
            "default": "flat",
            "description": "Feed mode of products[] for THIS insertion: \"collapse\" makes one tile per group of linked products (product groups with axes like size and colour) — each tile carries p.members[] (a full card per member: own price, photo, stock, url, actions), p.group (all variants with links) and per-member p.members[].variants (switch chips). Paging and the total count go by groups. Absent or \"flat\" keeps the plain feed. Use with vz-panes / vz-pane / vz-pick to switch members in place. See /docs/own-markup."
          },
          "productsAttributes": {
            "type": "array",
            "default": [],
            "description": "Ordered list of attribute codes (up to 32) to load for each product of the feed: p.attrs.<code> ({code, name, value, values, options}) and p.attributes[] in this order. Only attributes visible to buyers in lists are returned; hidden and unknown codes are simply absent. Codes may contain hyphens: {{ p.attrs.bed-size.value }}. See /docs/own-markup."
          },
          "productsIds": {
            "type": "array",
            "default": [],
            "description": "Pick list for THIS insertion: up to 48 product ids — the feed is exactly these products in THIS order instead of a category (productsCategoryId is then ignored; one page, no paging). With productsMode \"collapse\" a listed product is the position of its group: it is the member shown first, the rest of the group still comes as p.members[]. List one member per group. Products of another shop, drafts and hidden ones are simply absent. See /docs/own-markup."
          },
          "boxed": {
            "type": "boolean",
            "default": false,
            "description": "Level 3 renders without the platform box (no .vz-box/.vz-inner, no padding or radius) — the page starts at the edge. true brings the standard block wrapper back, in a chrome slot too. Levels 1 and 2 are boxed either way."
          },
          "modalTargets": {
            "type": "array",
            "default": [],
            "description": "Modal targets the backend must materialise with the page: a list of LinkRef ({type:\"group\", id}). Required for every `modal:group:<id>` opened from this document — the server cannot guess it from the markup. Product quick views need no entry."
          }
        }
      },
      "choices": {
        "level": [
          1,
          2,
          3
        ]
      },
      "props": {
        "level": 1,
        "productsCategoryId": 0,
        "productsMode": "flat",
        "productsAttributes": [],
        "productsIds": [],
        "boxed": false,
        "modalTargets": []
      }
    },
    {
      "kind": "component",
      "label": {
        "ru": "Компонент",
        "en": "Component"
      },
      "placement": "page",
      "render": "slot",
      "writePath": "props.component",
      "see": null,
      "content": null,
      "contentPath": null,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "ref": {
            "type": "integer",
            "default": 0,
            "description": "id of the html document (kind=component) whose folder holds the markup: index.html plus a component.json schema of typed parameters. Full area doc: /docs/components."
          },
          "params": {
            "type": "object",
            "default": {},
            "description": "object {key: value} — values for THIS insertion, by the keys of component.json. The server substitutes {{key}} by the parameter TYPE: text is escaped, html goes through the level-1 sanitiser, image resolves a file_id to a resized URL, link accepts only http(s), a site path, mailto: and tel:. A key that is not in the schema renders as an empty string — there is no raw {{ }}; a missing one falls back to the schema default; a value of the wrong type counts as missing. At most 8 KB. Two sections with the same ref and different params render different content — that is the whole point, and nothing of the markup is stored in the section."
          },
          "productsCategoryId": {
            "type": "integer",
            "default": 0,
            "description": "Category id whose products fill the scope feed products[] for THIS insertion. Absent (0) keeps the old rule — the feed is the category the PAGE is, which on a landing means no products at all. It is NOT a component parameter: it never reaches {{ }} and is not part of component.json — the page builder reads it, so one component document can stand twice on one page over two different categories. Same field and same meaning on the html widget. A category of ANOTHER shop yields an empty feed, never foreign goods. See /docs/own-markup, section 2."
          },
          "productsMode": {
            "type": "string",
            "default": "flat",
            "description": "Feed mode of products[] for THIS insertion: \"collapse\" makes one tile per group of linked products (product groups with axes like size and colour) — each tile carries p.members[] (a full card per member: own price, photo, stock, url, actions), p.group (all variants with links) and per-member p.members[].variants (switch chips). Paging and the total count go by groups. Absent or \"flat\" keeps the plain feed. Use with vz-panes / vz-pane / vz-pick to switch members in place. See /docs/own-markup."
          },
          "productsAttributes": {
            "type": "array",
            "default": [],
            "description": "Ordered list of attribute codes (up to 32) to load for each product of the feed: p.attrs.<code> ({code, name, value, values, options}) and p.attributes[] in this order. Only attributes visible to buyers in lists are returned; hidden and unknown codes are simply absent. Codes may contain hyphens: {{ p.attrs.bed-size.value }}. See /docs/own-markup."
          },
          "productsIds": {
            "type": "array",
            "default": [],
            "description": "Pick list for THIS insertion: up to 48 product ids — the feed is exactly these products in THIS order instead of a category (productsCategoryId is then ignored; one page, no paging). With productsMode \"collapse\" a listed product is the position of its group: it is the member shown first, the rest of the group still comes as p.members[]. List one member per group. Products of another shop, drafts and hidden ones are simply absent. See /docs/own-markup."
          }
        }
      },
      "choices": {},
      "props": {
        "ref": 0,
        "params": {},
        "productsCategoryId": 0,
        "productsMode": "flat",
        "productsAttributes": [],
        "productsIds": []
      }
    },
    {
      "kind": "siteHeader",
      "label": {
        "ru": "Шапка сайта",
        "en": "Site header"
      },
      "placement": "chrome",
      "render": "section",
      "writePath": "props",
      "see": null,
      "content": null,
      "contentPath": null,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "theme": {
            "type": "string",
            "default": "dark",
            "enum": [
              "light",
              "dark"
            ],
            "description": "Light or dark header band."
          },
          "bg": {
            "type": "object",
            "default": {
              "hex": "",
              "opacity": 100
            }
          },
          "bgFill": {
            "type": "null"
          },
          "width": {
            "type": "string",
            "default": "content",
            "enum": [
              "content",
              "full"
            ],
            "description": "`content` — contents sit in the site container, `full` — edge to edge."
          },
          "sticky": {
            "type": "boolean",
            "default": false
          },
          "height": {
            "type": "integer",
            "default": 64
          },
          "padX": {
            "type": "integer",
            "default": 24
          },
          "iconSize": {
            "type": "integer",
            "default": 24
          },
          "navShow": {
            "type": "boolean",
            "default": true
          },
          "showIcons": {
            "type": "boolean",
            "default": true
          },
          "search": {
            "type": "boolean",
            "default": true
          },
          "ctaEnabled": {
            "type": "boolean",
            "default": true
          },
          "ctaLabel": {
            "type": "string",
            "default": ""
          },
          "ctaStyle": {
            "type": "object",
            "default": {
              "kind": "solid",
              "size": "s",
              "textColor": "#111827",
              "bg": "#ffffff",
              "borderColor": "",
              "borderWidth": 0,
              "radius": 999
            }
          },
          "ctaPosition": {
            "type": "string",
            "default": "after",
            "enum": [
              "before",
              "after"
            ]
          },
          "ctaTarget": {
            "type": "null",
            "default": null
          },
          "showLogo": {
            "type": "boolean",
            "default": true
          },
          "showName": {
            "type": "boolean",
            "default": true
          },
          "navAlign": {
            "type": "string",
            "default": "center",
            "enum": [
              "start",
              "center",
              "end"
            ]
          },
          "navStyle": {
            "type": "object",
            "default": {
              "size": 14,
              "weight": "500",
              "color": {
                "hex": "",
                "opacity": 100
              },
              "colorHover": {
                "hex": "",
                "opacity": 100
              },
              "bg": {
                "hex": "",
                "opacity": 100
              },
              "bgHover": {
                "hex": "",
                "opacity": 100
              },
              "radius": 8,
              "padX": 0,
              "padY": 0,
              "gap": 24,
              "colorActive": {
                "hex": "",
                "opacity": 100
              },
              "weightActive": "600",
              "underline": "none"
            }
          },
          "ctaStates": {
            "type": "object",
            "default": {
              "hover": {
                "text": {
                  "hex": "",
                  "opacity": 100
                },
                "bg": {
                  "hex": "",
                  "opacity": 100
                }
              },
              "active": {
                "text": {
                  "hex": "",
                  "opacity": 100
                },
                "bg": {
                  "hex": "",
                  "opacity": 100
                }
              }
            }
          },
          "logo": {
            "type": "object",
            "default": {
              "height": 32,
              "fileId": "",
              "url": "",
              "filters": {
                "exposure": 0,
                "contrast": 0,
                "saturation": 0,
                "temperature": 0,
                "tint": 0,
                "highlights": 0,
                "shadows": 0,
                "blend": "normal"
              }
            }
          },
          "icons": {
            "type": "object",
            "default": {
              "color": {
                "hex": "",
                "opacity": 100
              },
              "colorHover": {
                "hex": "",
                "opacity": 100
              },
              "bg": {
                "hex": "",
                "opacity": 100
              },
              "bgHover": {
                "hex": "",
                "opacity": 100
              },
              "badgeBg": {
                "hex": "",
                "opacity": 100
              },
              "badgeColor": {
                "hex": "",
                "opacity": 100
              },
              "avatarRing": {
                "hex": "",
                "opacity": 100
              },
              "avatarRingWidth": 0
            }
          },
          "nameText": {
            "type": "string",
            "default": ""
          },
          "nameStyle": {
            "type": "object",
            "default": {
              "color": {
                "hex": "",
                "opacity": 100
              },
              "size": 18,
              "weight": "600"
            }
          },
          "nameLook": {
            "type": "null"
          },
          "searchBar": {
            "type": "object",
            "default": {
              "bg": {
                "hex": "",
                "opacity": 100
              },
              "border": {
                "hex": "",
                "opacity": 100
              },
              "borderWidth": 1,
              "radius": 999,
              "textColor": {
                "hex": "",
                "opacity": 100
              },
              "iconColor": {
                "hex": "",
                "opacity": 100
              },
              "placeholderColor": {
                "hex": "",
                "opacity": 100
              },
              "height": 40,
              "buttonShow": true,
              "buttonLabel": ""
            }
          },
          "searchMode": {
            "type": "string",
            "default": "button",
            "enum": [
              "always",
              "button"
            ],
            "description": "always — the search field is always visible in the bar; button (default) — a magnifier opens it under the header."
          },
          "searchScopeMode": {
            "type": "string",
            "default": "products",
            "enum": [
              "products",
              "all",
              "custom"
            ],
            "description": "What the search field and /search look through: products (default) — products and catalogue sections; all — every kind, including kinds added later; custom — the kinds listed in searchScope."
          },
          "searchScope": {
            "type": "array",
            "default": [
              "products",
              "categories"
            ],
            "description": "Kinds for searchScopeMode=custom, in any order: products (name and SKU), categories (catalogue sections: category type product/model), pages (category type page), articles (materials by title and summary, plus their rubrics). Read back expanded for every mode. An empty or unknown list in custom reads as the default [\"products\",\"categories\"]; in the other modes the list is ignored."
          },
          "links": {
            "type": "null",
            "default": null
          },
          "tablet": {
            "type": "object",
            "default": {
              "logo": {
                "fileId": "",
                "url": "",
                "height": 32,
                "filters": {
                  "exposure": 0,
                  "contrast": 0,
                  "saturation": 0,
                  "temperature": 0,
                  "tint": 0,
                  "highlights": 0,
                  "shadows": 0,
                  "blend": "normal"
                }
              },
              "burger": false,
              "over": {}
            }
          },
          "mobile": {
            "type": "object",
            "default": {
              "logo": {
                "fileId": "",
                "url": "",
                "height": 28,
                "filters": {
                  "exposure": 0,
                  "contrast": 0,
                  "saturation": 0,
                  "temperature": 0,
                  "tint": 0,
                  "highlights": 0,
                  "shadows": 0,
                  "blend": "normal"
                }
              },
              "burger": true,
              "over": {}
            }
          }
        }
      },
      "choices": {
        "theme": [
          "light",
          "dark"
        ],
        "width": [
          "content",
          "full"
        ],
        "ctaPosition": [
          "before",
          "after"
        ],
        "navAlign": [
          "start",
          "center",
          "end"
        ],
        "searchMode": [
          "always",
          "button"
        ],
        "searchScopeMode": [
          "products",
          "all",
          "custom"
        ]
      },
      "props": {
        "theme": "dark",
        "bg": {
          "hex": "",
          "opacity": 100
        },
        "width": "content",
        "sticky": false,
        "height": 64,
        "padX": 24,
        "iconSize": 24,
        "navShow": true,
        "showIcons": true,
        "search": true,
        "ctaEnabled": true,
        "ctaLabel": "",
        "ctaStyle": {
          "kind": "solid",
          "size": "s",
          "textColor": "#111827",
          "bg": "#ffffff",
          "borderColor": "",
          "borderWidth": 0,
          "radius": 999
        },
        "ctaPosition": "after",
        "ctaTarget": null,
        "showLogo": true,
        "showName": true,
        "navAlign": "center",
        "navStyle": {
          "size": 14,
          "weight": "500",
          "color": {
            "hex": "",
            "opacity": 100
          },
          "colorHover": {
            "hex": "",
            "opacity": 100
          },
          "bg": {
            "hex": "",
            "opacity": 100
          },
          "bgHover": {
            "hex": "",
            "opacity": 100
          },
          "radius": 8,
          "padX": 0,
          "padY": 0,
          "gap": 24,
          "colorActive": {
            "hex": "",
            "opacity": 100
          },
          "weightActive": "600",
          "underline": "none"
        },
        "ctaStates": {
          "hover": {
            "text": {
              "hex": "",
              "opacity": 100
            },
            "bg": {
              "hex": "",
              "opacity": 100
            }
          },
          "active": {
            "text": {
              "hex": "",
              "opacity": 100
            },
            "bg": {
              "hex": "",
              "opacity": 100
            }
          }
        },
        "logo": {
          "height": 32,
          "fileId": "",
          "url": "",
          "filters": {
            "exposure": 0,
            "contrast": 0,
            "saturation": 0,
            "temperature": 0,
            "tint": 0,
            "highlights": 0,
            "shadows": 0,
            "blend": "normal"
          }
        },
        "icons": {
          "color": {
            "hex": "",
            "opacity": 100
          },
          "colorHover": {
            "hex": "",
            "opacity": 100
          },
          "bg": {
            "hex": "",
            "opacity": 100
          },
          "bgHover": {
            "hex": "",
            "opacity": 100
          },
          "badgeBg": {
            "hex": "",
            "opacity": 100
          },
          "badgeColor": {
            "hex": "",
            "opacity": 100
          },
          "avatarRing": {
            "hex": "",
            "opacity": 100
          },
          "avatarRingWidth": 0
        },
        "nameText": "",
        "nameStyle": {
          "color": {
            "hex": "",
            "opacity": 100
          },
          "size": 18,
          "weight": "600"
        },
        "searchBar": {
          "bg": {
            "hex": "",
            "opacity": 100
          },
          "border": {
            "hex": "",
            "opacity": 100
          },
          "borderWidth": 1,
          "radius": 999,
          "textColor": {
            "hex": "",
            "opacity": 100
          },
          "iconColor": {
            "hex": "",
            "opacity": 100
          },
          "placeholderColor": {
            "hex": "",
            "opacity": 100
          },
          "height": 40,
          "buttonShow": true,
          "buttonLabel": ""
        },
        "searchMode": "button",
        "searchScopeMode": "products",
        "searchScope": [
          "products",
          "categories"
        ],
        "links": null,
        "tablet": {
          "logo": {
            "fileId": "",
            "url": "",
            "height": 32,
            "filters": {
              "exposure": 0,
              "contrast": 0,
              "saturation": 0,
              "temperature": 0,
              "tint": 0,
              "highlights": 0,
              "shadows": 0,
              "blend": "normal"
            }
          },
          "burger": false,
          "over": {}
        },
        "mobile": {
          "logo": {
            "fileId": "",
            "url": "",
            "height": 28,
            "filters": {
              "exposure": 0,
              "contrast": 0,
              "saturation": 0,
              "temperature": 0,
              "tint": 0,
              "highlights": 0,
              "shadows": 0,
              "blend": "normal"
            }
          },
          "burger": true,
          "over": {}
        }
      }
    },
    {
      "kind": "siteMenu",
      "label": {
        "ru": "Меню категорий",
        "en": "Category menu"
      },
      "placement": "chrome",
      "render": "section",
      "writePath": "props",
      "see": null,
      "content": null,
      "contentPath": null,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "theme": {
            "type": "string",
            "default": "light",
            "enum": [
              "light",
              "dark"
            ]
          },
          "bg": {
            "type": "object",
            "default": {
              "hex": "",
              "opacity": 100
            }
          },
          "bgFill": {
            "type": "null"
          },
          "width": {
            "type": "string",
            "default": "content",
            "enum": [
              "content",
              "full"
            ]
          },
          "source": {
            "type": "string",
            "default": "categories",
            "enum": [
              "categories",
              "custom"
            ],
            "description": "`categories` — items come from the shop sections; `custom` — your own list in `customItems`."
          },
          "customItems": {
            "type": "array",
            "default": [],
            "description": "Your own list of items; used only when `source` is `custom`."
          },
          "kind": {
            "type": "string",
            "default": "icons",
            "enum": [
              "icons",
              "text"
            ]
          },
          "iconStyle": {
            "type": "string",
            "default": "plain",
            "enum": [
              "plain",
              "card"
            ],
            "description": "`plain` — a strip with captions, `card` — cards with section images."
          },
          "labels": {
            "type": "boolean",
            "default": true
          },
          "align": {
            "type": "string",
            "default": "center",
            "enum": [
              "start",
              "center",
              "end"
            ],
            "description": "Where items sit in the strip. The human word \"left\" is `start` here."
          },
          "labelStyle": {
            "type": "object",
            "default": {
              "size": 12,
              "color": {
                "hex": "",
                "opacity": 100
              },
              "colorHover": {
                "hex": "",
                "opacity": 100
              }
            }
          },
          "cardStyle": {
            "type": "object",
            "default": {
              "bg": {
                "hex": "",
                "opacity": 100
              },
              "bgHover": {
                "hex": "",
                "opacity": 100
              },
              "border": {
                "hex": "",
                "opacity": 100
              },
              "borderHover": {
                "hex": "",
                "opacity": 100
              },
              "borderWidth": 1,
              "radius": 16,
              "iconBg": {
                "hex": "",
                "opacity": 100
              },
              "iconSize": 80,
              "iconRadius": 999,
              "pad": {
                "top": 20,
                "right": 16,
                "bottom": 20,
                "left": 16
              },
              "innerGap": 12
            }
          },
          "gap": {
            "type": "integer",
            "default": 32
          },
          "blockPad": {
            "type": "object",
            "default": {
              "top": 24,
              "right": 0,
              "bottom": 24,
              "left": 0
            }
          },
          "level2": {
            "type": "boolean",
            "default": true,
            "description": "Second level: sub-sections drop down on hover."
          },
          "level3Columns": {
            "type": "boolean",
            "default": true,
            "description": "Third level inside the dropdown, laid out in columns."
          }
        }
      },
      "choices": {
        "theme": [
          "light",
          "dark"
        ],
        "width": [
          "content",
          "full"
        ],
        "source": [
          "categories",
          "custom"
        ],
        "kind": [
          "icons",
          "text"
        ],
        "iconStyle": [
          "plain",
          "card"
        ],
        "align": [
          "start",
          "center",
          "end"
        ]
      },
      "props": {
        "theme": "light",
        "bg": {
          "hex": "",
          "opacity": 100
        },
        "width": "content",
        "source": "categories",
        "customItems": [],
        "kind": "icons",
        "iconStyle": "plain",
        "labels": true,
        "align": "center",
        "labelStyle": {
          "size": 12,
          "color": {
            "hex": "",
            "opacity": 100
          },
          "colorHover": {
            "hex": "",
            "opacity": 100
          }
        },
        "cardStyle": {
          "bg": {
            "hex": "",
            "opacity": 100
          },
          "bgHover": {
            "hex": "",
            "opacity": 100
          },
          "border": {
            "hex": "",
            "opacity": 100
          },
          "borderHover": {
            "hex": "",
            "opacity": 100
          },
          "borderWidth": 1,
          "radius": 16,
          "iconBg": {
            "hex": "",
            "opacity": 100
          },
          "iconSize": 80,
          "iconRadius": 999,
          "pad": {
            "top": 20,
            "right": 16,
            "bottom": 20,
            "left": 16
          },
          "innerGap": 12
        },
        "gap": 32,
        "blockPad": {
          "top": 24,
          "right": 0,
          "bottom": 24,
          "left": 0
        },
        "level2": true,
        "level3Columns": true
      }
    },
    {
      "kind": "siteFooter",
      "label": {
        "ru": "Футер сайта",
        "en": "Site footer"
      },
      "placement": "chrome",
      "render": "section",
      "writePath": "props",
      "see": null,
      "content": null,
      "contentPath": null,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "variant": {
            "type": "string",
            "default": "simple",
            "enum": [
              "simple",
              "mega"
            ],
            "description": "`simple` — a single row, `mega` — columns of links."
          },
          "theme": {
            "type": "string",
            "default": "light",
            "enum": [
              "light",
              "dark"
            ]
          },
          "bg": {
            "type": "object",
            "default": {
              "hex": "",
              "opacity": 100
            }
          },
          "bgFill": {
            "type": "null"
          },
          "width": {
            "type": "string",
            "default": "content",
            "enum": [
              "content",
              "full"
            ]
          },
          "align": {
            "type": "string",
            "default": "start",
            "enum": [
              "start",
              "center",
              "end"
            ]
          },
          "linkStyle": {
            "type": "object",
            "default": {
              "size": 14,
              "color": {
                "hex": "",
                "opacity": 100
              },
              "colorHover": {
                "hex": "",
                "opacity": 100
              }
            }
          },
          "columns": {
            "type": "null",
            "default": null,
            "description": "Footer link columns: a data structure, not text."
          },
          "social": {
            "type": "null",
            "default": null
          },
          "payments": {
            "type": "null",
            "default": null
          },
          "showSocial": {
            "type": "boolean",
            "default": true
          },
          "showPayments": {
            "type": "boolean",
            "default": true
          },
          "showCopyright": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "choices": {
        "variant": [
          "simple",
          "mega"
        ],
        "theme": [
          "light",
          "dark"
        ],
        "width": [
          "content",
          "full"
        ],
        "align": [
          "start",
          "center",
          "end"
        ]
      },
      "props": {
        "variant": "simple",
        "theme": "light",
        "bg": {
          "hex": "",
          "opacity": 100
        },
        "width": "content",
        "align": "start",
        "linkStyle": {
          "size": 14,
          "color": {
            "hex": "",
            "opacity": 100
          },
          "colorHover": {
            "hex": "",
            "opacity": 100
          }
        },
        "columns": null,
        "social": null,
        "payments": null,
        "showSocial": true,
        "showPayments": true,
        "showCopyright": true
      }
    }
  ],
  "wrapper": {
    "note": "Every block on a page is drawn inside a standard wrapper, and the wrapper is configurable through the same section object as the widget itself — these keys sit at the root of payload.props (props.blockWidth, …), beside the widget's own nest (props.component, props.html), NOT next to \"kind\" and NOT inside the widget writePath. Send the whole sections list: it is a replace-set. To make a block look unlike the platform: put your own class on the wrapper (props.wrapperClass) and restyle it from your own CSS, or switch off the wrapper setting that is in your way — \"elements\" below lists what the wrapper sets by default, with the file:line that sets it.",
    "axes": [
      {
        "path": "props.blockWidth",
        "type": "\"content\" | \"full\"",
        "description": "Band width. \"content\" fits the site container; \"full\" bleeds to the screen edges — use it for landings and hero strips.",
        "default": "\"content\"",
        "anchor": {
          "file": "packages/sections/src/SectionBox.tsx",
          "line": "w === 'full' ? 'vz-edge' : null,",
          "at": "packages/sections/src/SectionBox.tsx:551"
        }
      },
      {
        "path": "props.paddingSides",
        "type": "{ \"top\": px, \"right\": px, \"bottom\": px, \"left\": px }",
        "description": "Padding of the WRAPPER (the band). Omit an axis to keep the platform default.",
        "default": "12px vertical, 24px horizontal (0 horizontally when blockWidth is \"full\")",
        "anchor": {
          "file": "storefront/src/app/globals.css",
          "line": ".vz-box { --vz-px-auto: 24px; --vz-py-auto: 12px; }",
          "at": "storefront/src/app/globals.css:193"
        }
      },
      {
        "path": "props.containerPadding",
        "type": "{ \"top\": px, \"right\": px, \"bottom\": px, \"left\": px }",
        "description": "Padding of the CONTENT container inside the band — the inner box, not the band.",
        "default": "0px",
        "anchor": {
          "file": "storefront/src/app/globals.css",
          "line": "padding-top: var(--vz-ipt, 0px);",
          "at": "storefront/src/app/globals.css:300"
        }
      },
      {
        "path": "props.blockRadius",
        "type": "px | { \"tl\": px, \"tr\": px, \"br\": px, \"bl\": px }",
        "description": "Corner rounding of the band; the object form rounds each corner separately. Note the band is SQUARE by default — the 16px rounding you see inside blocks belongs to their own elements, not to the wrapper.",
        "default": "0px",
        "anchor": {
          "file": "storefront/src/app/globals.css",
          "line": "border-radius: var(--vz-radius, 0px);",
          "after": "background: var(--vz-bg, transparent);",
          "until": "}",
          "at": "storefront/src/app/globals.css:215"
        }
      },
      {
        "path": "props.container",
        "type": "{ \"fill\": …, \"borderTop\": px, \"borderBottom\": px, \"borderColor\": … }",
        "description": "Band background and hairlines. A background image is a separate media field.",
        "default": "transparent",
        "anchor": {
          "file": "storefront/src/app/globals.css",
          "line": "background: var(--vz-bg, transparent);",
          "at": "storefront/src/app/globals.css:208"
        }
      },
      {
        "path": "props.contentWidth",
        "type": "\"content\" | \"full\"",
        "description": "Width of the content INSIDE the band. \"full\" lets it fill the band; \"content\" keeps it in the shop content width while the background stays wide — a full-bleed banner whose text does not run to the screen edge. (There is no props.innerMax: earlier versions of this reference named one, and nothing ever read it.)",
        "default": "\"full\" inside a full-bleed band, the shop content width otherwise",
        "anchor": {
          "file": "storefront/src/app/globals.css",
          "line": ".vz-edge > .vz-inner { max-width: var(--vz-inner-max, none); }",
          "at": "storefront/src/app/globals.css:309"
        }
      },
      {
        "path": "props.overflow",
        "type": "\"visible\" | \"clip\"",
        "description": "What happens to content that sticks out of the band. \"visible\" leaves glows, shadows and dropdowns whole; \"clip\" cuts at the edge — use it when the band has a radius and an image inside must round with it. Note that \"clip\" also breaks position: sticky for anything inside the block. ⚠️ The \"html\" widget is the exception: its shadow host clips by DEFAULT (\"clip\"), so a dropdown or a modal in your own markup needs props.overflow:\"visible\" set explicitly — leaving the key out is not the same as \"visible\" there.",
        "default": "\"visible\" on the band",
        "anchor": {
          "file": "packages/sections/src/SectionBox.tsx",
          "line": "export function wrapperFrameStyle(",
          "at": "packages/sections/src/SectionBox.tsx:275"
        }
      },
      {
        "path": "props.position",
        "type": "\"static\" | \"sticky\"",
        "description": "Make the band stick to the top of the viewport. It is applied to the block wrapper itself, which is the only node with room to travel — a sticky element placed inside the block cannot move, because its parent is exactly as tall as the block. Own markup can ask for the same with the vz-sticky key.",
        "default": "\"static\"",
        "anchor": {
          "file": "packages/sections/src/SectionBox.tsx",
          "line": "export function sectionSticky(",
          "at": "packages/sections/src/SectionBox.tsx:312"
        }
      },
      {
        "path": "props.stickyTop",
        "type": "px",
        "description": "Offset from the top for a sticky band — for example a sticky menu sitting under a sticky header.",
        "default": "0",
        "anchor": {
          "file": "packages/sections/src/SectionBox.tsx",
          "line": "style.top = props?.stickyTop != null ? `${props.stickyTop}px` : 0",
          "at": "packages/sections/src/SectionBox.tsx:296"
        }
      },
      {
        "path": "props.layer",
        "type": "number",
        "description": "Z-order of the band; setting it makes the block positioned. Use it when blocks are meant to overlap — a negative top margin pulls a block over its neighbour, and the layer decides which one wins. Left unset, blocks paint in document order and no stacking context is created (one would clip a neighbour’s dropdown).",
        "anchor": {
          "file": "packages/sections/src/SectionBox.tsx",
          "line": "export function wrapperFrameStyle(",
          "at": "packages/sections/src/SectionBox.tsx:275"
        }
      },
      {
        "path": "props.wrapperClass",
        "type": "string",
        "description": "YOUR OWN classes on the band — up to 3, separated by spaces. This is the intended way to make a block unique: give the wrapper a class and restyle it from your own CSS (`.my-hero > .vz-inner { max-width: none }`), instead of fighting the platform defaults listed in \"elements\". The classes are appended after the platform ones, so specificity — not order — decides. Each name must match ^[a-zA-Z_][a-zA-Z0-9_-]*$, be at most 48 characters and not start with \"vz-\" (the platform namespace); anything else is dropped before it reaches the markup.",
        "anchor": {
          "file": "packages/sections/src/wrapperClass.ts",
          "line": "export const WRAPPER_CLASS_MAX = 3",
          "at": "packages/sections/src/wrapperClass.ts:21"
        }
      },
      {
        "path": "props.wrapperId",
        "type": "string",
        "description": "YOUR OWN id on the band — one name, same rules as wrapperClass. Use it for in-page anchors (#prices) and for your own scripts. Uniqueness across the page is yours to keep: the platform does not check it.",
        "anchor": {
          "file": "packages/sections/src/wrapperClass.ts",
          "line": "export function wrapperIdOf(value: unknown): string | undefined {",
          "at": "packages/sections/src/wrapperClass.ts:69"
        }
      },
      {
        "path": "props.showInModal",
        "type": "boolean",
        "description": "Show this section inside the quick view WINDOW when its widget is hidden there by default. Only one kind is hidden today: breadcrumbs — page navigation has no place in a product window. Set it on the section that must come back. There is no opposite switch: a section you do not want in the window is simply not put in the body group. The window body is the product page body slot, so this key is read there and nowhere else.",
        "default": "unset — the widget decides (only breadcrumbs is hidden)",
        "anchor": {
          "file": "packages/sections/src/widgets/registry.ts",
          "line": "return section.props?.showInModal !== true",
          "at": "packages/sections/src/widgets/registry.ts:174"
        }
      }
    ],
    "elements": [
      {
        "selector": ".vz-box",
        "role": "The band: the outer div of every block. It carries the background, the hairlines, the padding and the block radius, and it is the node that becomes sticky.",
        "defaults": [
          {
            "property": "display",
            "value": "block",
            "note": "a plain <div>: it fills the width of its parent, no flex or grid of its own",
            "anchor": {
              "file": "packages/sections/src/SectionBox.tsx",
              "line": "'vz-box',",
              "after": "export function SectionBox({",
              "at": "packages/sections/src/SectionBox.tsx:549"
            }
          },
          {
            "property": "position",
            "value": "static",
            "note": "CSS initial — the renderer sets nothing. It becomes relative when the band has a background layer or props.layer, and sticky when props.position is \"sticky\"",
            "anchor": {
              "file": "packages/sections/src/SectionBox.tsx",
              "line": "export function wrapperFrameStyle(",
              "at": "packages/sections/src/SectionBox.tsx:275"
            }
          },
          {
            "property": "overflow",
            "value": "visible",
            "note": "CSS initial — the band itself never clips. Shadows, glows and dropdowns leave it whole; props.overflow:\"clip\" is what turns clipping on",
            "anchor": {
              "file": "packages/sections/src/SectionBox.tsx",
              "line": "export function wrapperFrameStyle(",
              "at": "packages/sections/src/SectionBox.tsx:275"
            }
          },
          {
            "property": "padding-block",
            "value": "12px",
            "note": "platform air above and below; props.paddingSides overrides it",
            "anchor": {
              "file": "storefront/src/app/globals.css",
              "line": ".vz-box { --vz-px-auto: 24px; --vz-py-auto: 12px; }",
              "at": "storefront/src/app/globals.css:193"
            }
          },
          {
            "property": "padding-inline",
            "value": "24px",
            "when": "blockWidth \"content\"",
            "note": "a full-bleed band (blockWidth \"full\") gets 0 — it is meant to reach the edge",
            "anchor": {
              "file": "storefront/src/app/globals.css",
              "line": ".vz-box { --vz-px-auto: 24px; --vz-py-auto: 12px; }",
              "at": "storefront/src/app/globals.css:193"
            }
          },
          {
            "property": "border-radius",
            "value": "0px",
            "note": "square by default; the 16px rounding lives on elements INSIDE the block (class .vz-radius), not on the band",
            "anchor": {
              "file": "storefront/src/app/globals.css",
              "line": "border-radius: var(--vz-radius, 0px);",
              "after": "background: var(--vz-bg, transparent);",
              "until": "}",
              "at": "storefront/src/app/globals.css:215"
            }
          },
          {
            "property": "background",
            "value": "transparent",
            "note": "the page shows through until props.container.fill is set",
            "anchor": {
              "file": "storefront/src/app/globals.css",
              "line": "background: var(--vz-bg, transparent);",
              "at": "storefront/src/app/globals.css:208"
            }
          }
        ]
      },
      {
        "selector": ".vz-inner",
        "role": "The content container: the only child of the band besides the optional background layer. It caps the width of the content and centres it.",
        "defaults": [
          {
            "property": "display",
            "value": "block",
            "note": "a plain <div>; your own layout (grid, flex) goes inside it",
            "anchor": {
              "file": "packages/sections/src/SectionBox.tsx",
              "line": "className={hasContainerPadding(props) ? 'vz-inner vz-ipad' : 'vz-inner'}",
              "at": "packages/sections/src/SectionBox.tsx:580"
            }
          },
          {
            "property": "max-width",
            "value": "var(--store-content-max)",
            "note": "the content width of the shop — this is what keeps text out of the far edges",
            "anchor": {
              "file": "storefront/src/app/globals.css",
              "line": ".vz-inner { max-width: var(--vz-inner-max, var(--store-content-max)); margin-inline: auto; }",
              "at": "storefront/src/app/globals.css:293"
            }
          },
          {
            "property": "max-width",
            "value": "none",
            "when": "inside a full-bleed band (blockWidth \"full\")",
            "note": "no cap at all, so the content can reach the screen edge; props.contentWidth \"content\" caps it again",
            "anchor": {
              "file": "storefront/src/app/globals.css",
              "line": ".vz-edge > .vz-inner { max-width: var(--vz-inner-max, none); }",
              "at": "storefront/src/app/globals.css:309"
            }
          },
          {
            "property": "margin-inline",
            "value": "auto",
            "note": "centred inside the band",
            "anchor": {
              "file": "storefront/src/app/globals.css",
              "line": ".vz-inner { max-width: var(--vz-inner-max, var(--store-content-max)); margin-inline: auto; }",
              "at": "storefront/src/app/globals.css:293"
            }
          },
          {
            "property": "padding",
            "value": "0px",
            "note": "padding here only appears when props.containerPadding is set",
            "anchor": {
              "file": "storefront/src/app/globals.css",
              "line": "padding-top: var(--vz-ipt, 0px);",
              "at": "storefront/src/app/globals.css:300"
            }
          },
          {
            "property": "position",
            "value": "static",
            "note": "CSS initial — nothing is set here by default",
            "anchor": {
              "file": "packages/sections/src/SectionBox.tsx",
              "line": "className={hasContainerPadding(props) ? 'vz-inner vz-ipad' : 'vz-inner'}",
              "at": "packages/sections/src/SectionBox.tsx:580"
            }
          },
          {
            "property": "position",
            "value": "relative",
            "when": "the band has a background image or overlay",
            "note": "so the content paints above the background layer; no z-index, so neighbouring dropdowns are not clipped",
            "anchor": {
              "file": "packages/sections/src/SectionBox.tsx",
              "line": "style={background.hasBgLayer ? { position: 'relative' } : undefined}",
              "at": "packages/sections/src/SectionBox.tsx:581"
            }
          }
        ]
      }
    ],
    "ownDefaults": [
      {
        "kind": "html",
        "defaults": {
          "paddingX": 0,
          "paddingY": 0,
          "radius": 0
        },
        "why": "The author owns how this block looks, so the platform adds no padding and no rounding of its own. Set the axes above explicitly if you do want them."
      },
      {
        "kind": "component",
        "defaults": {
          "paddingX": 0,
          "paddingY": 0,
          "radius": 0
        },
        "why": "The author owns how this block looks, so the platform adds no padding and no rounding of its own. Set the axes above explicitly if you do want them."
      }
    ],
    "responsive": "Tablet and mobile overrides live under props.tablet and props.mobile with the same keys (e.g. props.mobile.paddingSides). A layer that is absent falls back to the wider one."
  },
  "structural": [
    {
      "kind": "group",
      "configurable": false,
      "label": {
        "ru": "Группа оформления",
        "en": "Design group"
      },
      "description": "Container, not a widget: holds `props.widgets` — ids of the widget blocks that make up this group. Renders nothing itself; a page is assembled from groups. What KIND of group it is lives on the block as `group_type`, not inside a section — so reordering widgets never changes what the group means. A group of type `layout` is the page FEED: its list holds other groups plus the body marker (a negative number) marking where the resource template goes. Remove the marker and the page is your groups only.",
      "fields": {
        "props.widgets": "number[] — ids of the blocks in this group, in render order. For a `layout` group the list may also contain the body marker -1.",
        "group_type (on the block, not the section)": "chrome · product · category · news · article · design · layout. The set is open: new types are added in the core registry without a migration.",
        "HOWTO page skeleton": "A page has four slots — header · feed · body · footer — bound per resource in /design/bindings. Each inherits on its own ladder: page → resource type → shop. A binding with an empty block means \"nothing here\" and stops the inheritance; no binding at all means \"inherit\"."
      }
    },
    {
      "kind": "zone",
      "configurable": false,
      "label": {
        "ru": "Зона страницы",
        "en": "Page zone"
      },
      "description": "Container, not a widget: the page’s OWN blocks around the body it inherits. Service blocks `__page:top` (before the body) and `__page:bottom` (after it); on a grid page the zones of its geometry, e.g. `__page:main` with `props.zoneFlow` placing each ref before or after the body. `refs` (next to `kind`, JSON numbers) lists the blocks placed in the zone; the manifest and those blocks are bound with PUT /products/{id}/content-blocks. Renders nothing itself. The shop’s page editor writes these, and the body template stays inherited — recipe: /docs/components §4.7.1. The block named `__page:top` also carries `page` — the page settings described in `fields` below. Headers, footers and templates are groups, not zones.",
      "fields": {
        "page.hideSiteHeader": "boolean — hide the ENTIRE top area of the layout: header, menu and anything else placed in that zone. The page then starts with your own markup.",
        "page.hideSiteFooter": "boolean — hide the ENTIRE bottom area of the layout (footer and anything placed there).",
        "page.hideSystemBlock": "boolean — hide the ENTIRE technical layer: everything that came with the product or section (product card, product list, breadcrumbs, page heading — the body of the resource-type template plus the resource’s own bundled blocks). Nothing is deleted; unchecking brings it all back.",
        "HOWTO one-off landing": "Set all three flags to true on an empty page: your markup then owns the whole page and nothing of the platform shows through.",
        "HOWTO site-wide header": "Do NOT build a custom header inside a landing page — it would appear on that page only and the old one stays everywhere else (two headers on one site). Build it in the LAYOUT, zone `top` (footer — zone `bottom`): layout parts are shared, so it appears on every page of the shop.",
        "A settings acts on a LAYER, never on one widget": "There is no per-widget switch — e.g. no “hide breadcrumbs”. Breadcrumbs are an ordinary widget and can sit in any layer; they disappear together with the layer that holds them."
      }
    },
    {
      "kind": "chromeKit",
      "configurable": false,
      "label": {
        "ru": "Комплект хрома",
        "en": "Chrome kit"
      },
      "description": "Manifest of the site frame: `props.kit` = {top:[block ids], bottom:[block ids]} — header, menu and footer blocks by zone, in render order. On a page these parts are marked data-vz-kit with this block id; the editable block of each part is the one listed here."
    },
    {
      "kind": "heading",
      "configurable": true,
      "label": {
        "ru": "Заголовок",
        "en": "Heading"
      },
      "description": "Legacy section rendered by SectionRenderer, without a widget home of its own. Its fields sit on the section itself, not under props.",
      "fields": {
        "text": "Heading text (section.text).",
        "subtitle": "Optional subtitle below (section.subtitle).",
        "props.align": "`left` or centered when absent.",
        "props.level": "`h1` renders the large size; anything else renders the smaller one."
      }
    }
  ],
  "sectionKeys": [
    "__prov",
    "badge",
    "cols",
    "cta",
    "cta2",
    "editorKey",
    "extra",
    "file",
    "file_id",
    "file_ids",
    "files",
    "items",
    "kind",
    "name",
    "opaquePayload",
    "origin",
    "page",
    "payloadSchemaVersion",
    "payloadVersion",
    "props",
    "refs",
    "role",
    "subtitle",
    "templateFor",
    "text",
    "type",
    "video",
    "payload"
  ]
}
