{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "package": "@bytesbrains/weblocks",
  "version": "0.12.0",
  "description": "Block catalog for @bytesbrains/weblocks. Send this to the model as its API reference; it composes a SiteManifest ({ meta, design, blocks[] }) using ONLY these block types. The engine then validates and renders it.",
  "blockTypes": [
    "app-shell",
    "nav",
    "announcement-bar",
    "install-prompt",
    "sidebar",
    "hero",
    "hero-app",
    "profile-header",
    "experience",
    "skills",
    "features",
    "about",
    "rich-text",
    "split",
    "steps",
    "stats",
    "progress",
    "services-catalogue",
    "menu",
    "product",
    "pricing",
    "logos",
    "team",
    "gallery",
    "carousel",
    "video",
    "video-gallery",
    "map",
    "timeline",
    "tabs",
    "accordion",
    "testimonials",
    "reviews",
    "faq",
    "chat-thread",
    "blog-list",
    "blog-post",
    "feed",
    "booking",
    "contact-form",
    "newsletter",
    "search",
    "auth",
    "cta",
    "social-links",
    "contact-details",
    "hours",
    "directions",
    "legal",
    "divider",
    "spacer",
    "copyright",
    "credit",
    "footer"
  ],
  "blocks": [
    {
      "type": "app-shell",
      "description": "A persistent bottom tab bar for app-like navigation, each tab an optional icon plus a label linking to a view.",
      "schema": {
        "type": "object",
        "properties": {
          "brand": {
            "type": "string",
            "maxLength": 60,
            "default": ""
          },
          "tabs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                },
                "href": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "icon": {
                  "type": "string",
                  "maxLength": 8,
                  "default": ""
                }
              },
              "required": [
                "label"
              ],
              "additionalProperties": false
            },
            "maxItems": 6
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "nav",
      "description": "Top navigation bar: brand/logo text, a row of links, and an optional call-to-action button. Place first.",
      "schema": {
        "type": "object",
        "properties": {
          "brand": {
            "type": "string",
            "maxLength": 60,
            "default": "Brand"
          },
          "sticky": {
            "type": "boolean",
            "default": false
          },
          "links": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "maxLength": 40,
                  "default": "Link"
                },
                "href": {
                  "type": "string",
                  "maxLength": 300,
                  "default": "#"
                }
              },
              "required": [
                "label"
              ],
              "additionalProperties": false
            },
            "maxItems": 8
          },
          "cta": {
            "type": "object",
            "properties": {
              "label": {
                "type": "string",
                "maxLength": 40,
                "default": ""
              },
              "href": {
                "type": "string",
                "maxLength": 300,
                "default": "#"
              }
            },
            "additionalProperties": false
          }
        },
        "required": [
          "brand"
        ],
        "additionalProperties": false
      }
    },
    {
      "type": "announcement-bar",
      "description": "A dismissible full-width strip for a short promo or notice, with an optional inline link and info/promo/warning tone.",
      "schema": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "maxLength": 200,
            "default": ""
          },
          "linkLabel": {
            "type": "string",
            "maxLength": 40,
            "default": ""
          },
          "href": {
            "type": "string",
            "maxLength": 500,
            "default": ""
          },
          "tone": {
            "enum": [
              "info",
              "promo",
              "warning"
            ],
            "default": "info"
          },
          "dismissible": {
            "type": "boolean",
            "default": true
          }
        },
        "required": [
          "text"
        ],
        "additionalProperties": false
      }
    },
    {
      "type": "install-prompt",
      "description": "A dismissible toast inviting visitors to install the site as an app, with step-by-step \"Add to Home Screen\" instructions matched to their platform (iOS, Android, Chrome/Edge, macOS Safari). Pair it with a PWA-enabled manifest.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 60,
            "default": "Install this app"
          },
          "body": {
            "type": "string",
            "maxLength": 160,
            "default": "Add it to your home screen for one-tap access, even offline."
          },
          "actionLabel": {
            "type": "string",
            "maxLength": 30,
            "default": "How?"
          },
          "position": {
            "enum": [
              "bottom",
              "top",
              "bottom-right"
            ],
            "default": "bottom"
          },
          "tone": {
            "enum": [
              "info",
              "promo"
            ],
            "default": "info"
          },
          "delayMs": {
            "type": "integer",
            "minimum": 0,
            "maximum": 60000,
            "default": 0
          },
          "dismissible": {
            "type": "boolean",
            "default": true
          },
          "rememberDismiss": {
            "type": "boolean",
            "default": true
          },
          "platforms": {
            "type": "array",
            "items": {
              "enum": [
                "ios-safari",
                "ios-other",
                "android",
                "desktop-chrome",
                "macos-safari",
                "firefox"
              ]
            },
            "maxItems": 6
          }
        },
        "required": [
          "title"
        ],
        "additionalProperties": false
      }
    },
    {
      "type": "sidebar",
      "description": "A vertical section/drawer navigation for multi-view apps: an optional title over a list of icon-and-label links.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 60,
            "default": ""
          },
          "links": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "maxLength": 60,
                  "default": ""
                },
                "href": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "icon": {
                  "type": "string",
                  "maxLength": 8,
                  "default": ""
                }
              },
              "required": [
                "label"
              ],
              "additionalProperties": false
            },
            "maxItems": 20
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "hero",
      "description": "Top-of-page hero: a big headline with optional eyebrow, subheading, and CTA — optionally over a full-bleed background image banner with a legibility overlay.",
      "schema": {
        "type": "object",
        "properties": {
          "eyebrow": {
            "type": "string",
            "maxLength": 80,
            "default": ""
          },
          "headline": {
            "type": "string",
            "maxLength": 160,
            "default": "Your headline here"
          },
          "subhead": {
            "type": "string",
            "maxLength": 320,
            "default": ""
          },
          "align": {
            "enum": [
              "center",
              "left"
            ],
            "default": "center"
          },
          "image": {
            "type": "string",
            "maxLength": 500,
            "default": ""
          },
          "overlay": {
            "enum": [
              "scrim",
              "dark",
              "light",
              "none"
            ],
            "default": "scrim"
          },
          "minHeight": {
            "enum": [
              "auto",
              "sm",
              "md",
              "lg",
              "full"
            ],
            "default": "auto"
          },
          "cta": {
            "type": "object",
            "properties": {
              "label": {
                "type": "string",
                "maxLength": 40,
                "default": ""
              },
              "href": {
                "type": "string",
                "maxLength": 500,
                "default": "#"
              }
            },
            "additionalProperties": false
          }
        },
        "required": [
          "headline"
        ],
        "additionalProperties": false
      }
    },
    {
      "type": "hero-app",
      "description": "An app landing hero: a headline and subhead over a primary install button, with a horizontal scroll row of app screenshots.",
      "schema": {
        "type": "object",
        "properties": {
          "headline": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "subhead": {
            "type": "string",
            "maxLength": 240,
            "default": ""
          },
          "installLabel": {
            "type": "string",
            "maxLength": 40,
            "default": "Install app"
          },
          "installHref": {
            "type": "string",
            "maxLength": 500,
            "default": ""
          },
          "screenshots": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "src": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "alt": {
                  "type": "string",
                  "maxLength": 200,
                  "default": ""
                }
              },
              "required": [
                "src"
              ],
              "additionalProperties": false
            },
            "maxItems": 6
          }
        },
        "required": [
          "headline"
        ],
        "additionalProperties": false
      }
    },
    {
      "type": "profile-header",
      "description": "A résumé/CV header: avatar, name, role, location, a contact + social row, and optional Download-PDF and Share buttons.",
      "schema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "headline": {
            "type": "string",
            "maxLength": 160,
            "default": ""
          },
          "location": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "avatar": {
            "type": "string",
            "maxLength": 500,
            "default": ""
          },
          "summary": {
            "type": "string",
            "maxLength": 400,
            "default": ""
          },
          "contacts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "enum": [
                    "email",
                    "phone",
                    "website",
                    "location",
                    "linkedin",
                    "github",
                    "twitter",
                    "x",
                    "custom"
                  ],
                  "default": "custom"
                },
                "value": {
                  "type": "string",
                  "maxLength": 300,
                  "default": ""
                },
                "label": {
                  "type": "string",
                  "maxLength": 80,
                  "default": ""
                }
              },
              "required": [
                "value"
              ],
              "additionalProperties": false
            },
            "maxItems": 10
          },
          "showDownload": {
            "type": "boolean",
            "default": false
          },
          "downloadLabel": {
            "type": "string",
            "maxLength": 40,
            "default": "Download PDF"
          },
          "showShare": {
            "type": "boolean",
            "default": false
          },
          "shareLabel": {
            "type": "string",
            "maxLength": 40,
            "default": "Share"
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      }
    },
    {
      "type": "experience",
      "description": "A résumé section of dated entries (role, org, period, location, bullets). Reuse for Experience, Education, Certifications by changing the title.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": "Experience"
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "role": {
                  "type": "string",
                  "maxLength": 120,
                  "default": ""
                },
                "org": {
                  "type": "string",
                  "maxLength": 120,
                  "default": ""
                },
                "period": {
                  "type": "string",
                  "maxLength": 60,
                  "default": ""
                },
                "location": {
                  "type": "string",
                  "maxLength": 80,
                  "default": ""
                },
                "url": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "summary": {
                  "type": "string",
                  "maxLength": 300,
                  "default": ""
                },
                "bullets": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "maxLength": 300,
                    "default": ""
                  },
                  "maxItems": 12
                }
              },
              "required": [
                "role"
              ],
              "additionalProperties": false
            },
            "maxItems": 24
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "skills",
      "description": "Grouped skills shown as tags (with optional proficiency dots) or labelled level bars; also for languages and tools.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": "Skills"
          },
          "display": {
            "enum": [
              "tags",
              "bars"
            ],
            "default": "tags"
          },
          "groups": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "maxLength": 60,
                  "default": ""
                },
                "items": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "label": {
                        "type": "string",
                        "maxLength": 60,
                        "default": ""
                      },
                      "level": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 5,
                        "default": 0
                      }
                    },
                    "required": [
                      "label"
                    ],
                    "additionalProperties": false
                  },
                  "maxItems": 40
                }
              },
              "additionalProperties": false
            },
            "maxItems": 10
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "features",
      "description": "A grid of value propositions, each with an optional icon/emoji, a title, and a short line of text.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "subtitle": {
            "type": "string",
            "maxLength": 240,
            "default": ""
          },
          "columns": {
            "type": "integer",
            "enum": [
              2,
              3,
              4
            ],
            "default": 3
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "icon": {
                  "type": "string",
                  "maxLength": 8,
                  "default": ""
                },
                "title": {
                  "type": "string",
                  "maxLength": 80,
                  "default": "Feature"
                },
                "text": {
                  "type": "string",
                  "maxLength": 240,
                  "default": ""
                }
              },
              "required": [
                "title"
              ],
              "additionalProperties": false
            },
            "maxItems": 12
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "about",
      "description": "A story/mission section: eyebrow, title, prose body, and an optional side image (choose which side).",
      "schema": {
        "type": "object",
        "properties": {
          "eyebrow": {
            "type": "string",
            "maxLength": 60,
            "default": ""
          },
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": "About us"
          },
          "body": {
            "type": "string",
            "maxLength": 1200,
            "default": ""
          },
          "image": {
            "type": "string",
            "maxLength": 500,
            "default": ""
          },
          "imageAlt": {
            "type": "string",
            "maxLength": 200,
            "default": ""
          },
          "imageSide": {
            "enum": [
              "left",
              "right"
            ],
            "default": "right"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "rich-text",
      "description": "A typed prose section with ordered headings, paragraphs, quotes, and bullet/numbered lists — a safe freeform-content block, never raw HTML.",
      "schema": {
        "type": "object",
        "properties": {
          "blocks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "kind": {
                  "enum": [
                    "heading",
                    "subheading",
                    "paragraph",
                    "quote",
                    "bullet",
                    "numbered"
                  ],
                  "default": "paragraph"
                },
                "text": {
                  "type": "string",
                  "maxLength": 2000,
                  "default": ""
                }
              },
              "required": [
                "text"
              ],
              "additionalProperties": false
            },
            "maxItems": 60
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "split",
      "description": "Alternating image-and-text rows; the image side flips each row, and rows without an image collapse to centered text.",
      "schema": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string",
                  "maxLength": 120,
                  "default": ""
                },
                "text": {
                  "type": "string",
                  "maxLength": 600,
                  "default": ""
                },
                "image": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "imageAlt": {
                  "type": "string",
                  "maxLength": 200,
                  "default": ""
                }
              },
              "additionalProperties": false
            },
            "maxItems": 8
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "steps",
      "description": "A numbered how-it-works / process list: an optional title and subtitle over auto-numbered step cards, each with a title and short text.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "subtitle": {
            "type": "string",
            "maxLength": 240,
            "default": ""
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string",
                  "maxLength": 100,
                  "default": "Step"
                },
                "text": {
                  "type": "string",
                  "maxLength": 300,
                  "default": ""
                }
              },
              "required": [
                "title"
              ],
              "additionalProperties": false
            },
            "maxItems": 12
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "stats",
      "description": "A grid of metric counters: each stat shows an optional prefix/suffix around a big value with a muted label, with an optional count-up animation.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "columns": {
            "type": "integer",
            "enum": [
              2,
              3,
              4
            ],
            "default": 4
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "value": {
                  "type": "string",
                  "maxLength": 24,
                  "default": ""
                },
                "label": {
                  "type": "string",
                  "maxLength": 60,
                  "default": ""
                },
                "prefix": {
                  "type": "string",
                  "maxLength": 8,
                  "default": ""
                },
                "suffix": {
                  "type": "string",
                  "maxLength": 8,
                  "default": ""
                }
              },
              "required": [
                "value",
                "label"
              ],
              "additionalProperties": false
            },
            "maxItems": 8
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "progress",
      "description": "Progress and goal indicators — fundraising totals, completion, capacity or scarcity — as bars, discrete segments, donut rings or scaled meters, each with units and an optional target marker.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "subtitle": {
            "type": "string",
            "maxLength": 240,
            "default": ""
          },
          "display": {
            "enum": [
              "bars",
              "segments",
              "rings",
              "meters"
            ],
            "default": "bars"
          },
          "layout": {
            "enum": [
              "stack",
              "grid",
              "inline"
            ],
            "default": "stack"
          },
          "columns": {
            "type": "integer",
            "enum": [
              1,
              2,
              3,
              4
            ],
            "default": 3
          },
          "size": {
            "enum": [
              "sm",
              "md",
              "lg"
            ],
            "default": "md"
          },
          "showValue": {
            "type": "boolean",
            "default": true
          },
          "animate": {
            "type": "boolean",
            "default": false
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "maxLength": 80,
                  "default": ""
                },
                "value": {
                  "type": "integer",
                  "minimum": 0,
                  "default": 0
                },
                "max": {
                  "type": "integer",
                  "minimum": 1,
                  "default": 100
                },
                "prefix": {
                  "type": "string",
                  "maxLength": 8,
                  "default": ""
                },
                "suffix": {
                  "type": "string",
                  "maxLength": 16,
                  "default": ""
                },
                "caption": {
                  "type": "string",
                  "maxLength": 160,
                  "default": ""
                },
                "threshold": {
                  "type": "integer",
                  "minimum": 0,
                  "default": 0
                },
                "state": {
                  "enum": [
                    "default",
                    "accent",
                    "success",
                    "warning",
                    "danger"
                  ],
                  "default": "default"
                },
                "icon": {
                  "type": "string",
                  "maxLength": 8,
                  "default": ""
                }
              },
              "required": [
                "label"
              ],
              "additionalProperties": false
            },
            "maxItems": 12
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "services-catalogue",
      "description": "A grid of services or products, each with a name, optional price, description, and link. Use for \"what we offer\".",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "subtitle": {
            "type": "string",
            "maxLength": 240,
            "default": ""
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "maxLength": 80,
                  "default": "Service"
                },
                "description": {
                  "type": "string",
                  "maxLength": 300,
                  "default": ""
                },
                "price": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                },
                "ctaLabel": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                },
                "ctaHref": {
                  "type": "string",
                  "maxLength": 500,
                  "default": "#"
                }
              },
              "required": [
                "name"
              ],
              "additionalProperties": false
            },
            "maxItems": 24
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "menu",
      "description": "A food/drink menu: named sections, each with items that have an optional price, dietary/allergen tags (e.g. V, VG, GF), and a 0–3 spice level. Use for restaurants and cafés.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": "Menu"
          },
          "subtitle": {
            "type": "string",
            "maxLength": 240,
            "default": ""
          },
          "sections": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "maxLength": 80,
                  "default": "Section"
                },
                "note": {
                  "type": "string",
                  "maxLength": 200,
                  "default": ""
                },
                "items": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 100,
                        "default": "Item"
                      },
                      "description": {
                        "type": "string",
                        "maxLength": 300,
                        "default": ""
                      },
                      "price": {
                        "type": "string",
                        "maxLength": 40,
                        "default": ""
                      },
                      "tags": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "maxLength": 12,
                          "default": ""
                        },
                        "maxItems": 8
                      },
                      "spice": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 3,
                        "default": 0
                      }
                    },
                    "required": [
                      "name"
                    ],
                    "additionalProperties": false
                  },
                  "maxItems": 40
                }
              },
              "required": [
                "name"
              ],
              "additionalProperties": false
            },
            "maxItems": 20
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "product",
      "description": "A shoppable product grid: each item has an image, price (with optional \"was\" price and badge), and a buy/enquire link. Use for retail and e-commerce; the cart/checkout is the host's.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "subtitle": {
            "type": "string",
            "maxLength": 240,
            "default": ""
          },
          "columns": {
            "type": "integer",
            "enum": [
              2,
              3,
              4
            ],
            "default": 3
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "maxLength": 100,
                  "default": "Product"
                },
                "description": {
                  "type": "string",
                  "maxLength": 240,
                  "default": ""
                },
                "price": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                },
                "was": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                },
                "image": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "badge": {
                  "type": "string",
                  "maxLength": 24,
                  "default": ""
                },
                "ctaLabel": {
                  "type": "string",
                  "maxLength": 40,
                  "default": "Buy"
                },
                "ctaHref": {
                  "type": "string",
                  "maxLength": 500,
                  "default": "#"
                }
              },
              "required": [
                "name"
              ],
              "additionalProperties": false
            },
            "maxItems": 48
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "pricing",
      "description": "A row of pricing/tier cards, each with a name, price, feature list, and a call-to-action button; one plan can be highlighted.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "subtitle": {
            "type": "string",
            "maxLength": 240,
            "default": ""
          },
          "plans": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "maxLength": 60,
                  "default": ""
                },
                "price": {
                  "type": "string",
                  "maxLength": 24,
                  "default": ""
                },
                "period": {
                  "type": "string",
                  "maxLength": 24,
                  "default": ""
                },
                "features": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "maxLength": 120,
                    "default": ""
                  },
                  "maxItems": 12
                },
                "ctaLabel": {
                  "type": "string",
                  "maxLength": 40,
                  "default": "Choose"
                },
                "ctaHref": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "featured": {
                  "type": "boolean",
                  "default": false
                }
              },
              "required": [
                "name",
                "price"
              ],
              "additionalProperties": false
            },
            "maxItems": 6
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "logos",
      "description": "A centered strip of client or partner logos (grayscale until hover), each optionally linking out, under a short heading.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": "Trusted by"
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "src": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "alt": {
                  "type": "string",
                  "maxLength": 120,
                  "default": ""
                },
                "href": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                }
              },
              "required": [
                "src"
              ],
              "additionalProperties": false
            },
            "maxItems": 24
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "team",
      "description": "A grid of people cards with photo (or initials), name, role, a short bio, and optional social links.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "subtitle": {
            "type": "string",
            "maxLength": 240,
            "default": ""
          },
          "columns": {
            "type": "integer",
            "enum": [
              2,
              3,
              4
            ],
            "default": 3
          },
          "members": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "maxLength": 80,
                  "default": ""
                },
                "role": {
                  "type": "string",
                  "maxLength": 80,
                  "default": ""
                },
                "photo": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "bio": {
                  "type": "string",
                  "maxLength": 240,
                  "default": ""
                },
                "socials": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "label": {
                        "type": "string",
                        "maxLength": 40,
                        "default": ""
                      },
                      "href": {
                        "type": "string",
                        "maxLength": 500,
                        "default": ""
                      }
                    },
                    "required": [
                      "label"
                    ],
                    "additionalProperties": false
                  },
                  "maxItems": 5
                }
              },
              "required": [
                "name"
              ],
              "additionalProperties": false
            },
            "maxItems": 24
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "gallery",
      "description": "A responsive image grid (grid/masonry/carousel) with an optional click-to-zoom lightbox. Each item needs a src and alt text.",
      "schema": {
        "type": "object",
        "properties": {
          "layout": {
            "enum": [
              "grid",
              "masonry",
              "carousel"
            ],
            "default": "grid"
          },
          "columns": {
            "type": "integer",
            "enum": [
              2,
              3,
              4
            ],
            "default": 3
          },
          "gap": {
            "enum": [
              "sm",
              "md",
              "lg"
            ],
            "default": "md"
          },
          "lightbox": {
            "type": "boolean",
            "default": true
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "src": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "alt": {
                  "type": "string",
                  "maxLength": 200,
                  "default": ""
                },
                "caption": {
                  "type": "string",
                  "maxLength": 200,
                  "default": ""
                }
              },
              "required": [
                "src",
                "alt"
              ],
              "additionalProperties": false
            },
            "maxItems": 60
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "carousel",
      "description": "A horizontal, swipeable carousel of image slides with optional captions; scrolls natively and can be enhanced with arrows/autoplay.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "src": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "alt": {
                  "type": "string",
                  "maxLength": 200,
                  "default": ""
                },
                "caption": {
                  "type": "string",
                  "maxLength": 200,
                  "default": ""
                }
              },
              "additionalProperties": false
            },
            "maxItems": 20
          },
          "autoplay": {
            "type": "boolean",
            "default": false
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "video",
      "description": "A responsive embedded video from YouTube or Vimeo (by id or URL) or a self-hosted file, with an optional caption.",
      "schema": {
        "type": "object",
        "properties": {
          "provider": {
            "enum": [
              "youtube",
              "vimeo",
              "file"
            ],
            "default": "youtube"
          },
          "src": {
            "type": "string",
            "maxLength": 500,
            "default": ""
          },
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": "Video"
          },
          "poster": {
            "type": "string",
            "maxLength": 500,
            "default": ""
          },
          "caption": {
            "type": "string",
            "maxLength": 200,
            "default": ""
          }
        },
        "required": [
          "src"
        ],
        "additionalProperties": false
      }
    },
    {
      "type": "video-gallery",
      "description": "A grid or carousel of click-to-play video cards (YouTube/Vimeo/file); each loads its player inline on click (a lightweight facade — no heavy iframes up front).",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "layout": {
            "enum": [
              "grid",
              "carousel"
            ],
            "default": "grid"
          },
          "columns": {
            "type": "integer",
            "enum": [
              2,
              3,
              4
            ],
            "default": 3
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "provider": {
                  "enum": [
                    "youtube",
                    "vimeo",
                    "file"
                  ],
                  "default": "youtube"
                },
                "src": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "title": {
                  "type": "string",
                  "maxLength": 160,
                  "default": ""
                },
                "poster": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                }
              },
              "required": [
                "src"
              ],
              "additionalProperties": false
            },
            "maxItems": 24
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "map",
      "description": "An embedded location map for a place or address query, with configurable zoom and height and a link to the full map.",
      "schema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "maxLength": 200,
            "default": ""
          },
          "zoom": {
            "type": "integer",
            "minimum": 1,
            "maximum": 20,
            "default": 14
          },
          "height": {
            "type": "integer",
            "minimum": 160,
            "maximum": 800,
            "default": 360
          },
          "label": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          }
        },
        "required": [
          "query"
        ],
        "additionalProperties": false
      }
    },
    {
      "type": "timeline",
      "description": "A vertical timeline of chronological milestones, each with an optional date, a title, and supporting text.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "date": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                },
                "title": {
                  "type": "string",
                  "maxLength": 120,
                  "default": ""
                },
                "text": {
                  "type": "string",
                  "maxLength": 400,
                  "default": ""
                }
              },
              "required": [
                "title"
              ],
              "additionalProperties": false
            },
            "maxItems": 24
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "tabs",
      "description": "Tabbed content panels that switch with no JavaScript; each tab has a label and a text panel.",
      "schema": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "maxLength": 60,
                  "default": ""
                },
                "text": {
                  "type": "string",
                  "maxLength": 2000,
                  "default": ""
                }
              },
              "required": [
                "label"
              ],
              "additionalProperties": false
            },
            "maxItems": 8
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "accordion",
      "description": "Generic collapsible disclosure panels (native details/summary, no JavaScript); each panel has a heading and body.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "heading": {
                  "type": "string",
                  "maxLength": 200,
                  "default": ""
                },
                "body": {
                  "type": "string",
                  "maxLength": 1200,
                  "default": ""
                }
              },
              "required": [
                "heading"
              ],
              "additionalProperties": false
            },
            "maxItems": 24
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "testimonials",
      "description": "A grid of customer quotes, each with the quote text and an optional author name and role.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "quote": {
                  "type": "string",
                  "maxLength": 400,
                  "default": ""
                },
                "author": {
                  "type": "string",
                  "maxLength": 80,
                  "default": ""
                },
                "role": {
                  "type": "string",
                  "maxLength": 80,
                  "default": ""
                }
              },
              "required": [
                "quote"
              ],
              "additionalProperties": false
            },
            "maxItems": 12
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "reviews",
      "description": "Star-rated customer reviews (1–5 stars) each with an optional author, date, and source (Google, Yelp, …), plus an optional aggregate score. Richer than plain testimonial quotes.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "subtitle": {
            "type": "string",
            "maxLength": 240,
            "default": ""
          },
          "average": {
            "type": "string",
            "maxLength": 8,
            "default": ""
          },
          "count": {
            "type": "string",
            "maxLength": 24,
            "default": ""
          },
          "source": {
            "type": "string",
            "maxLength": 40,
            "default": ""
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "rating": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 5,
                  "default": 5
                },
                "quote": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "author": {
                  "type": "string",
                  "maxLength": 80,
                  "default": ""
                },
                "date": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                },
                "source": {
                  "enum": [
                    "google",
                    "yelp",
                    "facebook",
                    "trustpilot",
                    "tripadvisor",
                    "app-store",
                    "other"
                  ],
                  "default": "other"
                }
              },
              "required": [
                "quote"
              ],
              "additionalProperties": false
            },
            "maxItems": 24
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "faq",
      "description": "An accordion of question/answer pairs. Expands/collapses natively (no JS).",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": "Frequently asked questions"
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "question": {
                  "type": "string",
                  "maxLength": 200,
                  "default": ""
                },
                "answer": {
                  "type": "string",
                  "maxLength": 800,
                  "default": ""
                }
              },
              "required": [
                "question"
              ],
              "additionalProperties": false
            },
            "maxItems": 20
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "chat-thread",
      "description": "A conversation rendered as a thread of rich message bubbles: named participants with avatars or initials, optional per-message times, and typed message bodies that mix text, code, images, lists and quick replies. Static — an authored transcript for showing how an assistant or support team answers, not a live chatbot.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "subtitle": {
            "type": "string",
            "maxLength": 200,
            "default": ""
          },
          "participants": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 40,
                  "default": ""
                },
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 60,
                  "default": ""
                },
                "role": {
                  "enum": [
                    "user",
                    "bot",
                    "agent"
                  ],
                  "default": "bot"
                },
                "avatar": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                }
              },
              "required": [
                "id",
                "name"
              ],
              "additionalProperties": false
            },
            "maxItems": 6
          },
          "messages": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "from": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 40,
                  "default": ""
                },
                "time": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                },
                "body": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "kind": {
                        "enum": [
                          "text",
                          "code",
                          "image",
                          "list",
                          "buttons"
                        ],
                        "default": "text"
                      },
                      "text": {
                        "type": "string",
                        "maxLength": 2000,
                        "default": ""
                      },
                      "lang": {
                        "type": "string",
                        "maxLength": 20,
                        "default": ""
                      },
                      "src": {
                        "type": "string",
                        "maxLength": 500,
                        "default": ""
                      },
                      "alt": {
                        "type": "string",
                        "maxLength": 200,
                        "default": ""
                      },
                      "ordered": {
                        "type": "boolean",
                        "default": false
                      },
                      "items": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "label": {
                              "type": "string",
                              "maxLength": 120,
                              "default": ""
                            },
                            "href": {
                              "type": "string",
                              "maxLength": 500,
                              "default": ""
                            }
                          },
                          "additionalProperties": false
                        },
                        "maxItems": 8
                      }
                    },
                    "additionalProperties": false
                  },
                  "maxItems": 8
                }
              },
              "required": [
                "from"
              ],
              "additionalProperties": false
            },
            "maxItems": 60
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "blog-list",
      "description": "A post index as a grid of cards, each with an optional cover image, tag, date, title, and excerpt linking to the post.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "columns": {
            "type": "integer",
            "enum": [
              2,
              3
            ],
            "default": 3
          },
          "posts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string",
                  "maxLength": 160,
                  "default": ""
                },
                "excerpt": {
                  "type": "string",
                  "maxLength": 280,
                  "default": ""
                },
                "href": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "image": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "date": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                },
                "tag": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                }
              },
              "required": [
                "title"
              ],
              "additionalProperties": false
            },
            "maxItems": 24
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "blog-post",
      "description": "A single article layout with an optional cover, title, author/date, and a typed body (headings, paragraphs, quotes, bullets).",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 200,
            "default": ""
          },
          "date": {
            "type": "string",
            "maxLength": 40,
            "default": ""
          },
          "author": {
            "type": "string",
            "maxLength": 80,
            "default": ""
          },
          "cover": {
            "type": "string",
            "maxLength": 500,
            "default": ""
          },
          "coverAlt": {
            "type": "string",
            "maxLength": 200,
            "default": ""
          },
          "body": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "kind": {
                  "enum": [
                    "heading",
                    "paragraph",
                    "quote",
                    "bullet"
                  ],
                  "default": "paragraph"
                },
                "text": {
                  "type": "string",
                  "maxLength": 2000,
                  "default": ""
                }
              },
              "required": [
                "text"
              ],
              "additionalProperties": false
            },
            "maxItems": 120
          }
        },
        "required": [
          "title"
        ],
        "additionalProperties": false
      }
    },
    {
      "type": "feed",
      "description": "A generic data-driven list of items in a list or card layout, each with a title, optional subtitle/text, badge, image, and link.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "layout": {
            "enum": [
              "list",
              "cards"
            ],
            "default": "list"
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string",
                  "maxLength": 160,
                  "default": ""
                },
                "subtitle": {
                  "type": "string",
                  "maxLength": 120,
                  "default": ""
                },
                "text": {
                  "type": "string",
                  "maxLength": 280,
                  "default": ""
                },
                "href": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "image": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "badge": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                }
              },
              "required": [
                "title"
              ],
              "additionalProperties": false
            },
            "maxItems": 50
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "booking",
      "description": "An appointment/reservation request form (service, date, time, contact) that posts to a host-provided runtime. For booking-driven businesses — salons, clinics, gyms, hotels, events. No raw HTML.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": "Book an appointment"
          },
          "intro": {
            "type": "string",
            "maxLength": 280,
            "default": ""
          },
          "submitLabel": {
            "type": "string",
            "maxLength": 40,
            "default": "Request booking"
          },
          "successMessage": {
            "type": "string",
            "maxLength": 200,
            "default": "Thanks — we'll confirm your booking shortly."
          },
          "serviceLabel": {
            "type": "string",
            "maxLength": 60,
            "default": "Service"
          },
          "services": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "maxLength": 80,
                  "default": "Service"
                },
                "duration": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                },
                "price": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                }
              },
              "required": [
                "name"
              ],
              "additionalProperties": false
            },
            "maxItems": 40
          },
          "askDate": {
            "type": "boolean",
            "default": true
          },
          "askTime": {
            "type": "boolean",
            "default": true
          },
          "askParty": {
            "type": "boolean",
            "default": false
          },
          "askPhone": {
            "type": "boolean",
            "default": true
          },
          "askNotes": {
            "type": "boolean",
            "default": true
          },
          "notesLabel": {
            "type": "string",
            "maxLength": 80,
            "default": "Anything we should know?"
          }
        },
        "additionalProperties": false
      },
      "runtime": {
        "capabilities": [
          "booking.request"
        ]
      }
    },
    {
      "type": "contact-form",
      "description": "A configurable contact form with typed fields (text, email, tel, textarea, select, checkbox) that posts to a host-provided runtime. No raw HTML.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": "Get in touch"
          },
          "intro": {
            "type": "string",
            "maxLength": 280,
            "default": ""
          },
          "submitLabel": {
            "type": "string",
            "maxLength": 40,
            "default": "Send"
          },
          "successMessage": {
            "type": "string",
            "maxLength": 200,
            "default": "Thanks — we'll be in touch."
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "maxLength": 40,
                  "default": "field"
                },
                "label": {
                  "type": "string",
                  "maxLength": 80,
                  "default": "Field"
                },
                "type": {
                  "enum": [
                    "text",
                    "email",
                    "tel",
                    "textarea",
                    "select",
                    "checkbox"
                  ],
                  "default": "text"
                },
                "placeholder": {
                  "type": "string",
                  "maxLength": 80,
                  "default": ""
                },
                "required": {
                  "type": "boolean",
                  "default": false
                },
                "options": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "maxLength": 80,
                    "default": ""
                  },
                  "maxItems": 24
                }
              },
              "required": [
                "name",
                "label"
              ],
              "additionalProperties": false
            },
            "maxItems": 12
          }
        },
        "additionalProperties": false
      },
      "runtime": {
        "capabilities": [
          "contact-form.submit"
        ]
      }
    },
    {
      "type": "newsletter",
      "description": "An email-capture form that posts to a host-provided runtime; renders inert until a runtime is wired.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": "Subscribe to our newsletter"
          },
          "intro": {
            "type": "string",
            "maxLength": 240,
            "default": ""
          },
          "placeholder": {
            "type": "string",
            "maxLength": 80,
            "default": "you@example.com"
          },
          "submitLabel": {
            "type": "string",
            "maxLength": 40,
            "default": "Subscribe"
          },
          "successMessage": {
            "type": "string",
            "maxLength": 200,
            "default": "You're in — check your inbox."
          }
        },
        "additionalProperties": false
      },
      "runtime": {
        "capabilities": [
          "newsletter.subscribe"
        ]
      }
    },
    {
      "type": "search",
      "description": "A site search rendered as a full search bar or a compact expanding icon button; queries a host-provided search runtime.",
      "schema": {
        "type": "object",
        "properties": {
          "layout": {
            "enum": [
              "bar",
              "icon"
            ],
            "default": "bar"
          },
          "placeholder": {
            "type": "string",
            "maxLength": 80,
            "default": "Search…"
          },
          "label": {
            "type": "string",
            "maxLength": 60,
            "default": "Search"
          },
          "buttonLabel": {
            "type": "string",
            "maxLength": 40,
            "default": "Search"
          },
          "name": {
            "type": "string",
            "maxLength": 40,
            "default": "q"
          },
          "align": {
            "enum": [
              "start",
              "center",
              "end"
            ],
            "default": "center"
          }
        },
        "additionalProperties": false
      },
      "runtime": {
        "capabilities": [
          "search.query"
        ]
      }
    },
    {
      "type": "auth",
      "description": "A provider-agnostic sign in / sign up panel: social provider buttons and an optional email form that start auth via a host runtime.",
      "schema": {
        "type": "object",
        "properties": {
          "mode": {
            "enum": [
              "signin",
              "signup"
            ],
            "default": "signin"
          },
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "providers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                },
                "provider": {
                  "type": "string",
                  "maxLength": 40,
                  "default": ""
                }
              },
              "required": [
                "label"
              ],
              "additionalProperties": false
            },
            "maxItems": 6
          },
          "showEmail": {
            "type": "boolean",
            "default": true
          }
        },
        "additionalProperties": false
      },
      "runtime": {
        "capabilities": [
          "auth.start"
        ]
      }
    },
    {
      "type": "cta",
      "description": "A full-width call-to-action band: a headline, optional subheading, and one button. Use near the bottom.",
      "schema": {
        "type": "object",
        "properties": {
          "headline": {
            "type": "string",
            "maxLength": 160,
            "default": "Ready to start?"
          },
          "subhead": {
            "type": "string",
            "maxLength": 240,
            "default": ""
          },
          "background": {
            "enum": [
              "primary",
              "accent",
              "surface"
            ],
            "default": "primary"
          },
          "button": {
            "type": "object",
            "properties": {
              "label": {
                "type": "string",
                "maxLength": 40,
                "default": "Get started"
              },
              "href": {
                "type": "string",
                "maxLength": 300,
                "default": "#"
              }
            },
            "additionalProperties": false
          }
        },
        "required": [
          "headline"
        ],
        "additionalProperties": false
      }
    },
    {
      "type": "social-links",
      "description": "A row or grid of links to social/contact profiles; each link picks a built-in brand icon by platform (or a custom emoji), shown labeled or icon-only.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "layout": {
            "enum": [
              "row",
              "grid"
            ],
            "default": "row"
          },
          "variant": {
            "enum": [
              "labeled",
              "icon"
            ],
            "default": "labeled"
          },
          "align": {
            "enum": [
              "start",
              "center",
              "end"
            ],
            "default": "center"
          },
          "links": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "platform": {
                  "enum": [
                    "x",
                    "twitter",
                    "instagram",
                    "facebook",
                    "linkedin",
                    "youtube",
                    "github",
                    "tiktok",
                    "whatsapp",
                    "telegram",
                    "discord",
                    "mastodon",
                    "rss",
                    "email",
                    "website",
                    "phone",
                    "custom"
                  ],
                  "default": "custom"
                },
                "href": {
                  "type": "string",
                  "maxLength": 500,
                  "default": ""
                },
                "label": {
                  "type": "string",
                  "maxLength": 60,
                  "default": ""
                },
                "icon": {
                  "type": "string",
                  "maxLength": 8,
                  "default": ""
                }
              },
              "required": [
                "href"
              ],
              "additionalProperties": false
            },
            "maxItems": 20
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "contact-details",
      "description": "A contact info block: address, phone, email, and opening hours (each optional). Read-only — no form.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": "Get in touch"
          },
          "address": {
            "type": "string",
            "maxLength": 200,
            "default": ""
          },
          "phone": {
            "type": "string",
            "maxLength": 40,
            "default": ""
          },
          "email": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "hours": {
            "type": "string",
            "maxLength": 160,
            "default": ""
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "hours",
      "description": "Structured weekly opening hours (24h times per day, split shifts allowed) rendered as an accessible table with a live \"open now / closed\" badge. Use for shops, cafés, salons, and clinics.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": "Opening hours"
          },
          "timezone": {
            "type": "string",
            "maxLength": 60,
            "default": ""
          },
          "note": {
            "type": "string",
            "maxLength": 200,
            "default": ""
          },
          "days": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "day": {
                  "enum": [
                    "mon",
                    "tue",
                    "wed",
                    "thu",
                    "fri",
                    "sat",
                    "sun"
                  ],
                  "default": "mon"
                },
                "open": {
                  "type": "string",
                  "maxLength": 5,
                  "default": ""
                },
                "close": {
                  "type": "string",
                  "maxLength": 5,
                  "default": ""
                },
                "closed": {
                  "type": "boolean",
                  "default": false
                }
              },
              "required": [
                "day"
              ],
              "additionalProperties": false
            },
            "maxItems": 21
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "directions",
      "description": "A location card with deep links that open the visitor’s map app (Google/Apple Maps) for directions, from an address, GPS coordinates, or a pasted map link.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "place": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "address": {
            "type": "string",
            "maxLength": 240,
            "default": ""
          },
          "lat": {
            "type": "string",
            "maxLength": 24,
            "default": ""
          },
          "lng": {
            "type": "string",
            "maxLength": 24,
            "default": ""
          },
          "mapUrl": {
            "type": "string",
            "maxLength": 500,
            "default": ""
          },
          "directionsLabel": {
            "type": "string",
            "maxLength": 40,
            "default": "Get directions"
          },
          "appleMaps": {
            "type": "boolean",
            "default": true
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "legal",
      "description": "Policy links (terms, privacy, cookies, …) that open as scrollable, dismissible dialogs; each body is safe Markdown (never raw HTML). No JavaScript.",
      "schema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "align": {
            "enum": [
              "start",
              "center",
              "end"
            ],
            "default": "center"
          },
          "separator": {
            "type": "string",
            "maxLength": 4,
            "default": "·"
          },
          "documents": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "maxLength": 60,
                  "default": ""
                },
                "title": {
                  "type": "string",
                  "maxLength": 120,
                  "default": ""
                },
                "content": {
                  "type": "string",
                  "maxLength": 40000,
                  "default": ""
                }
              },
              "required": [
                "label"
              ],
              "additionalProperties": false
            },
            "maxItems": 8
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "divider",
      "description": "A visual section break rendered as a thin line, a dotted rule, or a gradient bar.",
      "schema": {
        "type": "object",
        "properties": {
          "style": {
            "enum": [
              "line",
              "dots",
              "gradient"
            ],
            "default": "line"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "spacer",
      "description": "Deliberate vertical whitespace between sections, in one of four sizes (sm, md, lg, xl).",
      "schema": {
        "type": "object",
        "properties": {
          "size": {
            "enum": [
              "sm",
              "md",
              "lg",
              "xl"
            ],
            "default": "md"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "copyright",
      "description": "A small copyright bar (© year holder + rights text) for the bottom of a page; the year auto-fills to the current year when left blank.",
      "schema": {
        "type": "object",
        "properties": {
          "holder": {
            "type": "string",
            "maxLength": 120,
            "default": ""
          },
          "year": {
            "type": "string",
            "maxLength": 24,
            "default": ""
          },
          "text": {
            "type": "string",
            "maxLength": 160,
            "default": "All rights reserved."
          },
          "showSymbol": {
            "type": "boolean",
            "default": true
          },
          "align": {
            "enum": [
              "start",
              "center",
              "end"
            ],
            "default": "center"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "type": "credit",
      "description": "A one-line attribution — \"Powered by / Created by / Managed by <name>\" — with an optional logo and an outbound link that opens in a new tab; credits the maker or operator (use `copyright` for ownership).",
      "schema": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string",
            "maxLength": 40,
            "default": "Powered by"
          },
          "name": {
            "type": "string",
            "maxLength": 80,
            "default": ""
          },
          "href": {
            "type": "string",
            "maxLength": 500,
            "default": ""
          },
          "newTab": {
            "type": "boolean",
            "default": true
          },
          "logo": {
            "type": "string",
            "maxLength": 500,
            "default": ""
          },
          "note": {
            "type": "string",
            "maxLength": 160,
            "default": ""
          },
          "variant": {
            "enum": [
              "bar",
              "badge",
              "inline"
            ],
            "default": "bar"
          },
          "align": {
            "enum": [
              "start",
              "center",
              "end"
            ],
            "default": "center"
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      }
    },
    {
      "type": "footer",
      "description": "Page footer: brand, tagline, a row of links, and a copyright line. Place last.",
      "schema": {
        "type": "object",
        "properties": {
          "brand": {
            "type": "string",
            "maxLength": 60,
            "default": ""
          },
          "tagline": {
            "type": "string",
            "maxLength": 160,
            "default": ""
          },
          "links": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "maxLength": 40,
                  "default": "Link"
                },
                "href": {
                  "type": "string",
                  "maxLength": 300,
                  "default": "#"
                }
              },
              "required": [
                "label"
              ],
              "additionalProperties": false
            },
            "maxItems": 12
          },
          "copyright": {
            "type": "string",
            "maxLength": 160,
            "default": ""
          }
        },
        "additionalProperties": false
      }
    }
  ]
}
