# Design my CARTT store

> **To Claude:** this brief is from CARTT (cartt.ai), an ecommerce platform. The person who gave it to you wants to plan their online store with you before they build it in CARTT. Follow the steps below. At the end you will produce one file, `cartt-site-spec.json`, which CARTT imports to build the store.

## How to work

1. **Interview first, briefly.** Ask about the business, what it sells, who buys, how it should feel, and any sites they admire. Ask a few questions at a time, not a questionnaire. If they share a logo, photos or an existing site, use them for colours and tone.
2. **Propose a plan.** Suggest a palette, a font pairing, a category tree and a short list of pages, each with its sections in order. Explain your choices in a sentence each. Revise until they are happy.
3. **Write the copy.** Write every heading, paragraph and button in the brand voice you agreed. Keep it specific to this business: no filler, no superlatives it cannot back up.
4. **Produce the spec.** Output `cartt-site-spec.json` as a downloadable file that matches the format below exactly. Check it against the rules before you hand it over.
5. **Tell them what is next:** "Create your store at cartt.ai, then open **Site Builder > Design with Claude** and upload this file."

## What CARTT builds, and what you design

- **You design:** the theme (colours and fonts), the brand voice, the category tree, and the body of the home page and up to 11 other content pages (about, story, FAQ, shipping info, and so on).
- **CARTT supplies, so do not design them:** the header, menus and footer, product pages, category pages, search, cart, checkout and customer accounts, and the legal policies (CARTT has a policy wizard). These follow the theme automatically.
- **No products yet.** Products are added in CARTT. Product and category grids fill themselves once they exist.
- **No images before sign-up.** Images come from the store's media library after sign-up. Leave image fields out. Every section still looks finished without one.
- **Testimonials must be real.** Only include quotes the merchant has actually received, with their permission. Never invent reviews.
- **Plain text only.** No HTML or markdown inside any field. Separate paragraphs with a blank line (`\n\n`).
- **Links** are same-site paths such as `/candles` (a category, lower-case with hyphens), `/our-story` (a page slug), `/search` or `/contact`, or full `https://` addresses.

## Section types

Every page is a list of sections, top to bottom. A good home page opens with a `hero`, shows products early, and ends with a `newsletter` or `cta`. Three to seven sections is plenty.

### `hero`: Hero

The opening band: one headline, one line of support, one or two buttons. Use once, at the top of the home page.

| Field | Required | Notes |
|---|---|---|
| `heading` | yes | The headline. Becomes the page's h1. Up to 90 characters. |
| `subheading` |  | One or two sentences under it. Up to 240 characters. |
| `button_text` |  | Main button label, e.g. "Shop the range". Up to 30 characters. |
| `button_url` |  | Where it goes, e.g. a category "/candles" or "/search". |
| `secondary_button_text` |  | Optional second button. Up to 30 characters. |
| `secondary_button_url` |  | Second button link. |
| `image` |  | Background image from the store's media library (/media/...). Leave out before sign-up. |
| `tone` |  | Band colour: "brand" (primary colour), "dark" or "light". One of: `brand`, `dark`, `light`. Default `"brand"`. |

### `rich_text`: Text

A heading and paragraphs. Separate paragraphs with a blank line. Plain text only, no HTML or markdown.

| Field | Required | Notes |
|---|---|---|
| `heading` |  | Section heading. Up to 90 characters. |
| `body` | yes | Paragraphs, separated by a blank line. Up to 3000 characters. |
| `align` |  | Text alignment. One of: `left`, `center`. Default `"left"`. |

### `image_text`: Image and text

A story block: text beside an image. Without an image it renders as text alone, so it is safe to use before sign-up.

| Field | Required | Notes |
|---|---|---|
| `heading` | yes | Section heading. Up to 90 characters. |
| `body` | yes | Paragraphs, separated by a blank line. Up to 1500 characters. |
| `image` |  | Image from the media library (/media/...). Leave out before sign-up. |
| `image_alt` |  | What the image shows, for screen readers. Up to 125 characters. |
| `image_side` |  | Which side the image sits on. One of: `left`, `right`. Default `"right"`. |
| `button_text` |  | Optional button label. Up to 30 characters. |
| `button_url` |  | Button link. |

### `features`: Features

Three to six short reasons to buy (free shipping, handmade, local), each with an icon.

| Field | Required | Notes |
|---|---|---|
| `heading` |  | Section heading. Up to 90 characters. |
| `subheading` |  | Line under the heading. Up to 200 characters. |
| `items` | yes | The features. Up to 6 items. |
| `items[].icon` |  | A Lucide icon name, e.g. "truck", "leaf", "shield-check", "gift", "heart", "recycle". |
| `items[].title` | yes | Short title. Up to 50 characters. |
| `items[].description` | yes | One sentence. Up to 200 characters. |

### `product_grid`: Product grid

Live products from the shop, drawn with CARTT's product card. Fills itself once products are added.

| Field | Required | Notes |
|---|---|---|
| `heading` |  | Section heading, e.g. "Best sellers". Up to 90 characters. |
| `source` |  | Which products to show. One of: `bestsellers`, `new_arrivals`. Default `"bestsellers"`. |
| `count` |  | How many. Whole number 4 to 12. Default `8`. |

### `category_grid`: Category grid

Tiles linking to the shop's categories.

| Field | Required | Notes |
|---|---|---|
| `heading` |  | Section heading, e.g. "Shop by range". Up to 90 characters. |
| `count` |  | Most categories to show. Whole number 2 to 12. Default `8`. |

### `testimonials`: Testimonials

Quotes from real customers. Only include quotes the merchant has actually received; never invent them.

| Field | Required | Notes |
|---|---|---|
| `heading` |  | Section heading. Up to 90 characters. |
| `subheading` |  | Line under the heading. Up to 200 characters. |
| `items` | yes | The quotes. Up to 6 items. |
| `items[].quote` | yes | The customer's words. Up to 400 characters. |
| `items[].author` | yes | Name as they agreed to be shown. Up to 60 characters. |
| `items[].role` |  | Optional, e.g. "Brisbane". Up to 60 characters. |
| `items[].rating` |  | Star rating, if they gave one. Whole number 1 to 5. |

### `faq`: FAQ

Questions and answers in an accordion.

| Field | Required | Notes |
|---|---|---|
| `heading` |  | Section heading. Up to 90 characters. |
| `subheading` |  | Line under the heading. Up to 200 characters. |
| `items` | yes | The questions. Up to 15 items. |
| `items[].question` | yes | The question. Up to 160 characters. |
| `items[].answer` | yes | The answer, plain text. Up to 800 characters. |

### `cta`: Call to action

A closing band with a heading and one button.

| Field | Required | Notes |
|---|---|---|
| `heading` | yes | The ask. Up to 90 characters. |
| `subheading` |  | Line under it. Up to 200 characters. |
| `button_text` | yes | Button label. Up to 30 characters. |
| `button_url` | yes | Button link. |

### `newsletter`: Newsletter sign-up

An email sign-up band, wired to CARTT's email marketing.

| Field | Required | Notes |
|---|---|---|
| `heading` | yes | The offer, e.g. "10% off your first order". Up to 90 characters. |
| `subheading` |  | Line under it. Up to 200 characters. |
| `button_text` |  | Button label. Up to 30 characters. Default `"Subscribe"`. |

## The rest of the file

| Field | Required | Notes |
|---|---|---|
| `spec` | yes | Always "cartt-site-spec/1". One of: `cartt-site-spec/1`. |
| `store` | yes | Who the store is. |
| `store.name` | yes | Store name as customers see it. Up to 80 characters. |
| `store.tagline` |  | One short line under the name. Up to 120 characters. |
| `store.description` |  | What the store sells and why it exists, in two or three sentences. CARTT's AI writing tools use it when brand_voice.description is left out. Up to 600 characters. |
| `theme` |  | Colours and fonts. Leave out to keep CARTT's default theme. |
| `theme.colors` |  | Six-digit hex colours, e.g. "#1f4d3a". |
| `theme.colors.primary` | yes | Main brand colour: buttons, links, the hero band. |
| `theme.colors.accent` |  | Second colour for highlights and badges. |
| `theme.colors.background` |  | Page background. Keep it light unless the brand is genuinely dark. |
| `theme.colors.surface` |  | Alternate band background (a near-neutral tint). |
| `theme.colors.text` |  | Body text. Must read clearly on the background (4.5:1 contrast or better). |
| `theme.colors.muted_text` |  | Secondary text such as captions. |
| `theme.fonts` |  | Fonts CARTT hosts. Pick from the list in the brief; any other name is rejected. |
| `theme.fonts.heading` |  | Font for headings. |
| `theme.fonts.body` |  | Font for body text. A plain, readable sans or serif. |
| `brand_voice` |  | How the store writes. CARTT's AI writing tools use this for product descriptions, emails and pages. |
| `brand_voice.description` |  | The business in the owner's own words. Up to 600 characters. |
| `brand_voice.audience` |  | Who buys, and what they care about. Up to 400 characters. |
| `brand_voice.selling_points` |  | Why customers choose this store. Up to 6 items. |
| `brand_voice.perspective` |  | "we" (a team), "i" (a maker or sole trader) or "they" (the brand in third person). One of: `we`, `i`, `they`. Default `"we"`. |
| `brand_voice.formality` |  | Register of the copy. One of: `casual`, `conversational`, `professional`, `formal`. Default `"conversational"`. |
| `brand_voice.enthusiasm` |  | 1 is understated, 5 is exuberant. Whole number 1 to 5. Default `3`. |
| `brand_voice.humour` |  | Whether light humour suits the brand. `true` or `false`. Default `false`. |
| `brand_voice.spelling` |  | English spelling to write in. One of: `AU`, `NZ`, `UK`, `US`, `CA`. Default `"AU"`. |
| `brand_voice.brand_words` |  | Words the brand likes to use. Up to 20 items. |
| `brand_voice.avoid_phrases` |  | Words and phrases the brand never uses. Up to 20 items. |
| `categories` |  | The shop's category tree, at most two levels deep. Products are added in CARTT later. Up to 40 items. |
| `categories[].name` | yes | Category name. Up to 60 characters. |
| `categories[].description` |  | Short intro shown at the top of the category page. Up to 400 characters. |
| `categories[].children` |  | Sub-categories (one level only). Up to 12 items. |
| `categories[].children[].name` | yes | Sub-category name. Up to 60 characters. |
| `categories[].children[].description` |  | Short intro. Up to 400 characters. |
| `pages` | yes | The page bodies. CARTT draws the header, footer, menus, product pages, cart and checkout itself. Up to 12 items. |
| `pages[].kind` | yes | "home" for the home page (at most one), "page" for any other content page. One of: `home`, `page`. |
| `pages[].title` | yes | Page title (browser tab and admin list). Up to 80 characters. |
| `pages[].slug` |  | URL for a "page", e.g. "about" becomes /about. Required for kind "page"; ignored for home. |
| `pages[].meta_description` |  | Search-result snippet, 150 characters or so. Up to 160 characters. |
| `pages[].sections` | yes | The page body, top to bottom. Each entry is one of the section types below. Up to 14 items. |

## Fonts CARTT hosts

- **Sans-serif:** Inter, Roboto, Open Sans, Lato, Montserrat, Poppins, Nunito, Raleway, Work Sans, Quicksand, Karla, Josefin Sans, Source Sans Pro, Source Sans 3, Nunito Sans, PT Sans, Cabin, Ubuntu, Oxygen, Hind, Mulish, DM Sans, Outfit, Plus Jakarta Sans, Manrope, Space Grotesk, Barlow, Rubik, Cantarell, Archivo, Figtree, Lexend, Sora, Albert Sans, Andika, Pontano Sans, Quattrocento Sans, Fira Sans, IBM Plex Sans, Hanken Grotesk, Bricolage Grotesque, Gabarito, Geist, Atkinson Hyperlegible, Instrument Sans, Public Sans, Familjen Grotesk, Jost, Schibsted Grotesk, Fredoka, Zen Kaku Gothic New, Sofia Sans, Chivo
- **Serif:** Playfair Display, Merriweather, Lora, Libre Baskerville, Source Serif Pro, Crimson Text, Cormorant Garamond, EB Garamond, Spectral, Cardo, Alice, Quattrocento, Fanwood Text, Lustria, Proza Libre, Halant, Fauna One, Ledger, PT Serif, Noto Serif, Bitter, Vollkorn, Literata, Newsreader, Slabo 27px, Young Serif, Gloock, DM Serif Display, Bodoni Moda
- **Display:** Abril Fatface, Oswald, Fjalla One, Yeseva One, Cinzel, Roboto Condensed, Bebas Neue, Ultra, Unica One, Philosopher, Nixie One, Stint Ultra Expanded, Arvo, Alfa Slab One, Anton, Paytone One, Righteous, Permanent Marker, Staatliches, Fraunces, Unbounded, Bowlby One, Barlow Condensed, Bagel Fat One, Rubik Mono One, Sofia Sans Condensed, Big Shoulders Display
- **Script:** Sacramento, Pacifico, Dancing Script, Great Vibes, Satisfy, Caveat, Kalam, Amatic SC, Shadows Into Light, Indie Flower
- **Monospace:** Fira Code, JetBrains Mono, Source Code Pro, Roboto Mono, IBM Plex Mono, Inconsolata, Space Mono, Courier Prime, Chivo Mono, Fragment Mono

## Example

```json
{
    "spec": "cartt-site-spec/1",
    "store": {
        "name": "Saltbush Candle Co.",
        "tagline": "Small-batch soy candles, poured in Fremantle",
        "description": "Hand-poured soy candles scented with Australian botanicals. Every candle is made in our Fremantle studio in batches of forty."
    },
    "theme": {
        "colors": {
            "primary": "#2f5d50",
            "accent": "#c8873a",
            "background": "#fbf8f3",
            "surface": "#f1ebe1",
            "text": "#1f2421",
            "muted_text": "#5d6560"
        },
        "fonts": {
            "heading": "Cormorant Garamond",
            "body": "Karla"
        }
    },
    "brand_voice": {
        "description": "Two of us, a shed full of wax, and a love of the bush after rain.",
        "audience": "People buying a considered gift, and regulars who burn a candle every night.",
        "selling_points": [
            "Poured by hand in small batches",
            "Australian botanical scents",
            "Refillable glass vessels"
        ],
        "perspective": "we",
        "formality": "conversational",
        "enthusiasm": 3,
        "humour": false,
        "spelling": "AU",
        "brand_words": [
            "poured",
            "slow",
            "botanical"
        ],
        "avoid_phrases": [
            "luxury",
            "game-changer"
        ]
    },
    "categories": [
        {
            "name": "Candles",
            "description": "Our signature soy candles.",
            "children": [
                {
                    "name": "Classic"
                },
                {
                    "name": "Travel tins"
                }
            ]
        },
        {
            "name": "Refills"
        },
        {
            "name": "Gift sets"
        }
    ],
    "pages": [
        {
            "kind": "home",
            "title": "Saltbush Candle Co.",
            "meta_description": "Hand-poured soy candles scented with Australian botanicals, made in small batches in Fremantle.",
            "sections": [
                {
                    "type": "hero",
                    "heading": "The bush after rain, in a jar",
                    "subheading": "Small-batch soy candles scented with native botanicals.",
                    "button_text": "Shop candles",
                    "button_url": "/candles",
                    "tone": "brand"
                },
                {
                    "type": "product_grid",
                    "heading": "Best sellers",
                    "source": "bestsellers",
                    "count": 8
                },
                {
                    "type": "features",
                    "heading": "Made slowly, on purpose",
                    "items": [
                        {
                            "icon": "leaf",
                            "title": "Native botanicals",
                            "description": "Lemon myrtle, saltbush and sandalwood, blended in our studio."
                        },
                        {
                            "icon": "recycle",
                            "title": "Refill, don't replace",
                            "description": "Send the glass back and we pour it again."
                        },
                        {
                            "icon": "truck",
                            "title": "Free shipping over $80",
                            "description": "Anywhere in Australia."
                        }
                    ]
                },
                {
                    "type": "category_grid",
                    "heading": "Shop by range",
                    "count": 3
                },
                {
                    "type": "newsletter",
                    "heading": "10% off your first order",
                    "subheading": "New scents and studio news, once a month."
                }
            ]
        },
        {
            "kind": "page",
            "title": "Our story",
            "slug": "our-story",
            "meta_description": "How two friends and a shed full of wax started Saltbush Candle Co.",
            "sections": [
                {
                    "type": "image_text",
                    "heading": "It started in a shed",
                    "body": "We poured our first candle in 2019, for a friend's wedding.\n\nForty candles later we had a business."
                },
                {
                    "type": "faq",
                    "heading": "Questions",
                    "items": [
                        {
                            "question": "How long does a candle burn?",
                            "answer": "Around 50 hours. Trim the wick to 5mm before each burn."
                        },
                        {
                            "question": "Do you ship overseas?",
                            "answer": "Not yet. We ship anywhere in Australia."
                        }
                    ]
                },
                {
                    "type": "cta",
                    "heading": "Find your scent",
                    "button_text": "Shop candles",
                    "button_url": "/candles"
                }
            ]
        }
    ]
}
```

## JSON Schema

The file must validate against this schema. CARTT checks it on import and explains anything it rejects.

```json
{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://cartt.ai/design-with-claude/cartt-site-spec-1.schema.json","title":"CARTT site spec","type":"object","properties":{"spec":{"type":"string","enum":["cartt-site-spec/1"],"description":"Always \"cartt-site-spec/1\"."},"store":{"type":"object","properties":{"name":{"type":"string","maxLength":80,"description":"Store name as customers see it."},"tagline":{"type":"string","maxLength":120,"description":"One short line under the name."},"description":{"type":"string","maxLength":600,"description":"What the store sells and why it exists, in two or three sentences. CARTT's AI writing tools use it when brand_voice.description is left out."}},"required":["name"],"additionalProperties":false,"description":"Who the store is."},"theme":{"type":"object","properties":{"colors":{"type":"object","properties":{"primary":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Main brand colour: buttons, links, the hero band."},"accent":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Second colour for highlights and badges."},"background":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Page background. Keep it light unless the brand is genuinely dark."},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Alternate band background (a near-neutral tint)."},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Body text. Must read clearly on the background (4.5:1 contrast or better)."},"muted_text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Secondary text such as captions."}},"required":["primary"],"additionalProperties":false,"description":"Six-digit hex colours, e.g. \"#1f4d3a\"."},"fonts":{"type":"object","properties":{"heading":{"$ref":"#/$defs/font","description":"Font for headings."},"body":{"$ref":"#/$defs/font","description":"Font for body text. A plain, readable sans or serif."}},"additionalProperties":false,"description":"Fonts CARTT hosts. Pick from the list in the brief; any other name is rejected."}},"additionalProperties":false,"description":"Colours and fonts. Leave out to keep CARTT's default theme."},"brand_voice":{"type":"object","properties":{"description":{"type":"string","maxLength":600,"description":"The business in the owner's own words."},"audience":{"type":"string","maxLength":400,"description":"Who buys, and what they care about."},"selling_points":{"type":"array","maxItems":6,"items":{"type":"string","maxLength":160},"description":"Why customers choose this store."},"perspective":{"type":"string","enum":["we","i","they"],"description":"\"we\" (a team), \"i\" (a maker or sole trader) or \"they\" (the brand in third person).","default":"we"},"formality":{"type":"string","enum":["casual","conversational","professional","formal"],"description":"Register of the copy.","default":"conversational"},"enthusiasm":{"type":"integer","minimum":1,"maximum":5,"description":"1 is understated, 5 is exuberant.","default":3},"humour":{"type":"boolean","description":"Whether light humour suits the brand.","default":false},"spelling":{"type":"string","enum":["AU","NZ","UK","US","CA"],"description":"English spelling to write in.","default":"AU"},"brand_words":{"type":"array","maxItems":20,"items":{"type":"string","maxLength":40},"description":"Words the brand likes to use."},"avoid_phrases":{"type":"array","maxItems":20,"items":{"type":"string","maxLength":60},"description":"Words and phrases the brand never uses."}},"additionalProperties":false,"description":"How the store writes. CARTT's AI writing tools use this for product descriptions, emails and pages."},"categories":{"type":"array","maxItems":40,"items":{"type":"object","properties":{"name":{"type":"string","maxLength":60,"description":"Category name."},"description":{"type":"string","maxLength":400,"description":"Short intro shown at the top of the category page."},"children":{"type":"array","maxItems":12,"items":{"type":"object","properties":{"name":{"type":"string","maxLength":60,"description":"Sub-category name."},"description":{"type":"string","maxLength":400,"description":"Short intro."}},"required":["name"],"additionalProperties":false},"description":"Sub-categories (one level only)."}},"required":["name"],"additionalProperties":false},"description":"The shop's category tree, at most two levels deep. Products are added in CARTT later."},"pages":{"type":"array","minItems":1,"maxItems":12,"items":{"type":"object","properties":{"kind":{"type":"string","enum":["home","page"],"description":"\"home\" for the home page (at most one), \"page\" for any other content page."},"title":{"type":"string","maxLength":80,"description":"Page title (browser tab and admin list)."},"slug":{"type":"string","maxLength":60,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"URL for a \"page\", e.g. \"about\" becomes /about. Required for kind \"page\"; ignored for home."},"meta_description":{"type":"string","maxLength":160,"description":"Search-result snippet, 150 characters or so."},"sections":{"type":"array","minItems":1,"maxItems":14,"items":{"$ref":"#/$defs/section"},"description":"The page body, top to bottom. Each entry is one of the section types below."}},"required":["kind","title","sections"],"additionalProperties":false},"description":"The page bodies. CARTT draws the header, footer, menus, product pages, cart and checkout itself."}},"required":["spec","store","pages"],"additionalProperties":false,"$defs":{"section":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["hero"],"description":"Hero"},"heading":{"type":"string","maxLength":90,"description":"The headline. Becomes the page's h1."},"subheading":{"type":"string","maxLength":240,"description":"One or two sentences under it."},"button_text":{"type":"string","maxLength":30,"description":"Main button label, e.g. \"Shop the range\"."},"button_url":{"type":"string","maxLength":300,"pattern":"^(?:/(?!/)[^\\s<>\"'`]*|#[A-Za-z0-9_-]+|https://[^\\s<>\"'`]+|mailto:[^\\s<>\"'`]+|tel:[+0-9 ()-]+)$","description":"Where it goes, e.g. a category \"/candles\" or \"/search\"."},"secondary_button_text":{"type":"string","maxLength":30,"description":"Optional second button."},"secondary_button_url":{"type":"string","maxLength":300,"pattern":"^(?:/(?!/)[^\\s<>\"'`]*|#[A-Za-z0-9_-]+|https://[^\\s<>\"'`]+|mailto:[^\\s<>\"'`]+|tel:[+0-9 ()-]+)$","description":"Second button link."},"image":{"type":"string","maxLength":300,"pattern":"^/media/[A-Za-z0-9/_.-]+\\.(?:[jJ][pP][eE]?[gG]|[pP][nN][gG]|[wW][eE][bB][pP]|[aA][vV][iI][fF]|[gG][iI][fF])$","description":"Background image from the store's media library (/media/...). Leave out before sign-up."},"tone":{"type":"string","enum":["brand","dark","light"],"description":"Band colour: \"brand\" (primary colour), \"dark\" or \"light\".","default":"brand"}},"required":["type","heading"],"additionalProperties":false,"description":"The opening band: one headline, one line of support, one or two buttons. Use once, at the top of the home page."},{"type":"object","properties":{"type":{"type":"string","enum":["rich_text"],"description":"Text"},"heading":{"type":"string","maxLength":90,"description":"Section heading."},"body":{"type":"string","maxLength":3000,"description":"Paragraphs, separated by a blank line."},"align":{"type":"string","enum":["left","center"],"description":"Text alignment.","default":"left"}},"required":["type","body"],"additionalProperties":false,"description":"A heading and paragraphs. Separate paragraphs with a blank line. Plain text only, no HTML or markdown."},{"type":"object","properties":{"type":{"type":"string","enum":["image_text"],"description":"Image and text"},"heading":{"type":"string","maxLength":90,"description":"Section heading."},"body":{"type":"string","maxLength":1500,"description":"Paragraphs, separated by a blank line."},"image":{"type":"string","maxLength":300,"pattern":"^/media/[A-Za-z0-9/_.-]+\\.(?:[jJ][pP][eE]?[gG]|[pP][nN][gG]|[wW][eE][bB][pP]|[aA][vV][iI][fF]|[gG][iI][fF])$","description":"Image from the media library (/media/...). Leave out before sign-up."},"image_alt":{"type":"string","maxLength":125,"description":"What the image shows, for screen readers."},"image_side":{"type":"string","enum":["left","right"],"description":"Which side the image sits on.","default":"right"},"button_text":{"type":"string","maxLength":30,"description":"Optional button label."},"button_url":{"type":"string","maxLength":300,"pattern":"^(?:/(?!/)[^\\s<>\"'`]*|#[A-Za-z0-9_-]+|https://[^\\s<>\"'`]+|mailto:[^\\s<>\"'`]+|tel:[+0-9 ()-]+)$","description":"Button link."}},"required":["type","heading","body"],"additionalProperties":false,"description":"A story block: text beside an image. Without an image it renders as text alone, so it is safe to use before sign-up."},{"type":"object","properties":{"type":{"type":"string","enum":["features"],"description":"Features"},"heading":{"type":"string","maxLength":90,"description":"Section heading."},"subheading":{"type":"string","maxLength":200,"description":"Line under the heading."},"items":{"type":"array","minItems":2,"maxItems":6,"items":{"type":"object","properties":{"icon":{"type":"string","maxLength":48,"pattern":"^[a-z0-9-]+$","description":"A Lucide icon name, e.g. \"truck\", \"leaf\", \"shield-check\", \"gift\", \"heart\", \"recycle\"."},"title":{"type":"string","maxLength":50,"description":"Short title."},"description":{"type":"string","maxLength":200,"description":"One sentence."}},"required":["title","description"],"additionalProperties":false},"description":"The features."}},"required":["type","items"],"additionalProperties":false,"description":"Three to six short reasons to buy (free shipping, handmade, local), each with an icon."},{"type":"object","properties":{"type":{"type":"string","enum":["product_grid"],"description":"Product grid"},"heading":{"type":"string","maxLength":90,"description":"Section heading, e.g. \"Best sellers\"."},"source":{"type":"string","enum":["bestsellers","new_arrivals"],"description":"Which products to show.","default":"bestsellers"},"count":{"type":"integer","minimum":4,"maximum":12,"description":"How many.","default":8}},"required":["type"],"additionalProperties":false,"description":"Live products from the shop, drawn with CARTT's product card. Fills itself once products are added."},{"type":"object","properties":{"type":{"type":"string","enum":["category_grid"],"description":"Category grid"},"heading":{"type":"string","maxLength":90,"description":"Section heading, e.g. \"Shop by range\"."},"count":{"type":"integer","minimum":2,"maximum":12,"description":"Most categories to show.","default":8}},"required":["type"],"additionalProperties":false,"description":"Tiles linking to the shop's categories."},{"type":"object","properties":{"type":{"type":"string","enum":["testimonials"],"description":"Testimonials"},"heading":{"type":"string","maxLength":90,"description":"Section heading."},"subheading":{"type":"string","maxLength":200,"description":"Line under the heading."},"items":{"type":"array","minItems":1,"maxItems":6,"items":{"type":"object","properties":{"quote":{"type":"string","maxLength":400,"description":"The customer's words."},"author":{"type":"string","maxLength":60,"description":"Name as they agreed to be shown."},"role":{"type":"string","maxLength":60,"description":"Optional, e.g. \"Brisbane\"."},"rating":{"type":"integer","minimum":1,"maximum":5,"description":"Star rating, if they gave one."}},"required":["quote","author"],"additionalProperties":false},"description":"The quotes."}},"required":["type","items"],"additionalProperties":false,"description":"Quotes from real customers. Only include quotes the merchant has actually received; never invent them."},{"type":"object","properties":{"type":{"type":"string","enum":["faq"],"description":"FAQ"},"heading":{"type":"string","maxLength":90,"description":"Section heading."},"subheading":{"type":"string","maxLength":200,"description":"Line under the heading."},"items":{"type":"array","minItems":2,"maxItems":15,"items":{"type":"object","properties":{"question":{"type":"string","maxLength":160,"description":"The question."},"answer":{"type":"string","maxLength":800,"description":"The answer, plain text."}},"required":["question","answer"],"additionalProperties":false},"description":"The questions."}},"required":["type","items"],"additionalProperties":false,"description":"Questions and answers in an accordion."},{"type":"object","properties":{"type":{"type":"string","enum":["cta"],"description":"Call to action"},"heading":{"type":"string","maxLength":90,"description":"The ask."},"subheading":{"type":"string","maxLength":200,"description":"Line under it."},"button_text":{"type":"string","maxLength":30,"description":"Button label."},"button_url":{"type":"string","maxLength":300,"pattern":"^(?:/(?!/)[^\\s<>\"'`]*|#[A-Za-z0-9_-]+|https://[^\\s<>\"'`]+|mailto:[^\\s<>\"'`]+|tel:[+0-9 ()-]+)$","description":"Button link."}},"required":["type","heading","button_text","button_url"],"additionalProperties":false,"description":"A closing band with a heading and one button."},{"type":"object","properties":{"type":{"type":"string","enum":["newsletter"],"description":"Newsletter sign-up"},"heading":{"type":"string","maxLength":90,"description":"The offer, e.g. \"10% off your first order\"."},"subheading":{"type":"string","maxLength":200,"description":"Line under it."},"button_text":{"type":"string","maxLength":30,"description":"Button label.","default":"Subscribe"}},"required":["type","heading"],"additionalProperties":false,"description":"An email sign-up band, wired to CARTT's email marketing."}]},"font":{"type":"string","enum":["Inter","Roboto","Open Sans","Lato","Montserrat","Poppins","Nunito","Raleway","Work Sans","Quicksand","Karla","Josefin Sans","Source Sans Pro","Source Sans 3","Nunito Sans","PT Sans","Cabin","Ubuntu","Oxygen","Hind","Mulish","DM Sans","Outfit","Plus Jakarta Sans","Manrope","Space Grotesk","Barlow","Rubik","Cantarell","Archivo","Figtree","Lexend","Sora","Albert Sans","Andika","Pontano Sans","Quattrocento Sans","Fira Sans","IBM Plex Sans","Hanken Grotesk","Bricolage Grotesque","Gabarito","Geist","Atkinson Hyperlegible","Instrument Sans","Public Sans","Familjen Grotesk","Jost","Schibsted Grotesk","Fredoka","Zen Kaku Gothic New","Sofia Sans","Chivo","Playfair Display","Merriweather","Lora","Libre Baskerville","Source Serif Pro","Crimson Text","Cormorant Garamond","EB Garamond","Spectral","Cardo","Alice","Quattrocento","Fanwood Text","Lustria","Proza Libre","Halant","Fauna One","Ledger","PT Serif","Noto Serif","Bitter","Vollkorn","Literata","Newsreader","Slabo 27px","Young Serif","Gloock","DM Serif Display","Bodoni Moda","Abril Fatface","Oswald","Fjalla One","Yeseva One","Cinzel","Roboto Condensed","Bebas Neue","Ultra","Unica One","Philosopher","Nixie One","Stint Ultra Expanded","Arvo","Alfa Slab One","Anton","Paytone One","Righteous","Permanent Marker","Staatliches","Fraunces","Unbounded","Bowlby One","Barlow Condensed","Bagel Fat One","Rubik Mono One","Sofia Sans Condensed","Big Shoulders Display","Sacramento","Pacifico","Dancing Script","Great Vibes","Satisfy","Caveat","Kalam","Amatic SC","Shadows Into Light","Indie Flower","Fira Code","JetBrains Mono","Source Code Pro","Roboto Mono","IBM Plex Mono","Inconsolata","Space Mono","Courier Prime","Chivo Mono","Fragment Mono"]}}}
```
