Compose a feature-card grid
Use a container with display.layout set to grid, then put canonical card blocks in its children. This is a static composition: the grid owns placement while each card owns its title, description, and optional footer copy.
Copy this complete tree and adapt the IDs and card copy. display.columns: 3 is the grid mechanism, display.gap: 24 sets the spacing, and display.full_width: true is required to emit w-full.
{ "blocks": [ { "id": "feature-grid", "type": "container", "display": { "layout": "grid", "columns": 3, "gap": 24, "full_width": true }, "style": { "class": "px-6 py-12" }, "blocks": [ { "id": "feature-model", "type": "card", "content": { "title": "Model your work", "description": "Describe the records and fields your team needs.", "footer": "Data model" } }, { "id": "feature-page", "type": "card", "content": { "title": "Compose pages", "description": "Arrange reusable blocks into clear customer flows.", "footer": "Page builder" } }, { "id": "feature-publish", "type": "card", "content": { "title": "Publish confidently", "description": "Ship a consistent experience with governed access.", "footer": "Delivery" } } ] } ]}Grid rules
Section titled “Grid rules”Pick one column mechanism. display.columns emits an inline grid-template-columns, so it wins over any md:grid-cols-N in style.class; a container uses one mechanism, not both. Use display.columns for this static, deterministic grid and reserve style.class for non-competing utilities such as padding, margins, or typography.
The gap mapping divides numeric pixels by four: gap: 24 becomes gap-6. Named values map as xs to 1, sm to 2, md to 4, lg to 6, xl to 8, and 2xl to 12. display.full_width: true is required for w-full; it is intentionally not the default.
Variations
Section titled “Variations”Pricing tiers
Section titled “Pricing tiers”Keep this same grid-and-card composition and replace each card’s title, description, and footer with tier name, price, and billing or action copy. Do not use the table block for pricing: TableBlock.svelte:10-11,30-35 renders display.rows placeholder rows whose every cell is the literal {header} {row}, so it cannot represent authored plan features. A Markdown table is also unsuitable because it renders as preformatted text.
Use one accordion block instead of a grid when the visitor needs expandable answers. Its content.items is an array of {title, content} objects, and display.type is either single or multiple. Item content is plain text: it does not render Markdown.
{ "blocks": [ { "id": "pricing-faq", "type": "accordion", "content": { "items": [ { "title": "Can I change plans later?", "content": "Yes. Choose the plan that fits today and update it when your needs change." }, { "title": "Is onboarding included?", "content": "Every plan includes guided setup and product documentation." } ] }, "display": { "type": "single" } } ]}