# Makeway — prepare my complete website

## Before you send this to your AI

1. Open your existing project chat or start a new AI chat.
2. Attach this markdown file. If you already have an image you want to use, attach that image to the same AI chat too. Include any logo, artwork, photo, or screenshot you want on your website. Images are not included inside this markdown file.
3. Paste the prompt from Makeway into that chat and send it with your attachments.

## Instructions for the AI

Return a downloadable makeway-site.json file containing one JSON object matching the exact schema below. Keep Markdown fences and commentary out of that JSON. Any image files or instructions belong separately. This is website content and design configuration, not executable code or a token deployment.

Use the project context already in this conversation, together with the content and notes below. Do not ask me to repeat information you already have. If this is a new chat with no project context, ask a few concise questions together about what the project is, who it is for, and its real story or capabilities, then wait for my answers before creating the JSON. If some context exists, ask only for essential missing facts. Never ask me to choose a template, palette, font, or page structure. Make those design decisions yourself. Never invent partnerships, audits, users, revenue, or completed milestones.

## Choose the site structure from my project

Choose mode yourself: narrative for a character, story, artwork or community; technical for a real software product or tool. The current mode, design, fonts and palette are provisional editor defaults, not preferences. You may replace them. Choose based on the existing conversation, not just the project name.

### If you choose narrative

This is a story-led site. Write it as the story of the project: who it is for and why it exists.

- hero.heading and hero.description carry the premise. Be literal enough that someone arriving cold understands it.
- story is the longer version, if there is one: two or three short paragraphs. Leave it empty rather than padding it out.
- Artwork belongs in image slots. Say what each image should show in its alt text.
- features stays empty and howItWorks stays null. A narrative site does not use either.
- roadmap is what you are making or organising next — artwork, chapters, events, contribution packs. Never growth targets, exchange listings or price milestones.
- faq answers what a newcomer actually asks: what this is, how to take part, where to find official project information, and which links are official.

Never present fiction as verified fact. Do not invent utility, partnerships, a roadmap, or any claim the project has not made.

### If you choose technical

This is a software site. Explain what the product does, how it works, and where its limits are.

- hero.heading and hero.description state the job plainly: do [task] so you get [output]. Avoid "an AI-powered ecosystem for the future".
- story explains who it is for and what changes for them.
- features are real user-facing capabilities, one per feature. Three real ones beat six padded ones.
- howItWorks carries the mechanism: a plain-language summary, what is needed before starting, the ordered steps, what happens underneath, and what the product cannot do or does not control. Leave any part empty rather than guessing.
- Screenshots belong in image slots. Say what each should show in its alt text.
- roadmap distinguishes what is available now from what is planned, with deliverables someone could actually inspect.
- faq answers access, cost, compatibility, data and support questions.

Prepare marketing copy only. Do not write the product's code, invent its APIs or architecture, or claim capabilities it does not have. Never invent privacy claims, availability promises or audit badges.

## Which pages exist

Choose which pages this project actually needs; the editor’s current page switches are not requirements.

- pages.roadmap, pages.faq and pages.howItWorks are switches. Set one to true only when you are supplying real content for it; an enabled page with nothing on it is worse than no page. Set it to false otherwise.
- Leave pages.*.title and pages.*.description empty unless a page needs a more specific heading than its section name.
- The homepage draws its roadmap and FAQ previews from the same records as those pages, so write each item once.

## Your settings

- mode: choose narrative or technical from the project context.
- design: choose the best visual template below. Do not default to warm for every project.
- design must be one of: warm, crisp, terminal, gallery, editorial
- headingFont / bodyFont must be one of: manrope, outfit, azeret-mono, bricolage-grotesque, space-grotesk, sora, syne, fraunces, dm-serif-display, bodoni-moda, archivo-black, bebas-neue, space-mono, ibm-plex-mono, caveat
- palette must be one of: paper, graphite, emerald, midnight, porcelain, butter, rose, custom

## Art direction — make the choices for me

- warm: floating capsule navigation, loose scrapbook layout, gentle artwork entrances. Suits expressive characters and friendly stories.
- crisp: sticky product navigation, wide screenshot stage and structured features. Suits products that need a clear explanation.
- terminal: command-bar navigation, square edges, ruled sections and stepped entrances. Suits developer tools and source-oriented projects.
- gallery: poster headings and an asymmetric image collection. Suits projects whose artwork should lead.
- editorial: publication masthead, quiet motion and long reading layouts. Suits journals and detailed stories.

The template supplies its own navigation, layout and animations; select its ID, never provide executable code. Pair distinct heading and body fonts intentionally. Keep body copy readable; reserve condensed, display and handwritten faces for headings.

- manrope: Sans serif; Quiet, precise, versatile
- outfit: Sans serif; Round and geometric
- azeret-mono: Monospace; Geometric and precise
- bricolage-grotesque: Display; Playful, expressive, human
- space-grotesk: Sans serif; Engineered with personality
- sora: Sans serif; Wide, clear, contemporary
- syne: Display; Wide and unconventional
- fraunces: Serif; Soft, characterful editorial
- dm-serif-display: Serif; Elegant, high-contrast headlines
- bodoni-moda: Serif; Fashion and publication
- archivo-black: Display; Heavy poster lettering
- bebas-neue: Display; Tall, condensed capitals
- space-mono: Monospace; Retro computing
- ibm-plex-mono: Monospace; Readable technical detail
- caveat: Handwritten; Loose, personal, handwritten

## Custom colour themes

Choose a preset or set theme.palette to "custom" and supply theme.customColors with all six roles: bg (page background), ink (body text), accent (links and primary buttons), panel (cards), line (borders), accentInk (text on accent buttons). Use #RRGGBB hex values; line may also use #RRGGBBAA for transparency. No CSS expressions or colour names.

Example: "theme": { "headingFont": "space-grotesk", "bodyFont": "manrope", "palette": "custom", "customColors": { "bg": "#F5F3EA", "ink": "#182C26", "accent": "#315E46", "panel": "#E3E8DC", "line": "#182C2633", "accentInk": "#FFFFFF" } }

Make the palette fit this project; the example is not a default to copy. Keep at least 4.5:1 contrast for ink on bg, ink on panel, accentInk on accent, and accent on bg. Omit customColors if you select a preset. Custom colours are shared by every page, navigation, artwork placeholders and the exported website.

## Names and headlines that fit

Keep project.name as the full project name. For a long name, supply project.shortName with a recognizable existing abbreviation or natural shortened form for the navigation and footer. Aim for 8–16 characters including spaces; the maximum is 24. Omit it if the full name already works. Do not rename the project or change the token name merely to fit the navigation. For example, a project called "Shaquille O'Meal" could use "Shaq O'Meal" as its shortName.

Write hero.heading as a concise headline: aim for 3–7 words, roughly 20–40 characters including spaces, and one or two balanced lines. For Gallery and wide display fonts such as Archivo Black, favour the shorter end of that range. Avoid long ALL-CAPS sentences: uppercase and wide letters take more space. Use the actual character count and word lengths as a guide, not just the schema's 120-character maximum. Put the extra explanation in hero.description. A sentence such as "THE BIGGEST COMBO IN THE GAME." could become "Big appetite. Bigger game."

Choose the font and wording together. Consider both a narrow phone and a desktop layout; do not assume a headline that fits on desktop will fit on mobile. Prefer natural wrapping, or at most one intentional newline between meaningful phrases. The renderer balances and resizes headlines toward two lines, but very long text or explicit line breaks may need more lines to stay readable. Never promise an exact line count based on characters alone.

## Website and token copy — write for the whole launch

The creator chose WEBSITE + TOKEN through Makeway. The intended order is prepare both, publish the website, then launch the token. This choice is intent, not proof a token exists. Do not ask again whether they want a token. Supply token.description as a separate, nonempty field, up to 500 characters. It is used for permanent token metadata and the Explore listing; project.description is used for the website. Write a concise identity and purpose for the token, not a progress update. Makeway appends its own attribution; do not add it yourself.

Write evergreen project.description, hero copy, story, page descriptions and FAQ answers that stay accurate before and after a token launch. Do not bake temporary token status into prose: avoid "not live yet", "token coming soon", "planned meme-token", "pre-launch", and "launching tomorrow". Do not replace these with unsupported claims such as "live now" or "buy now". Keep genuine product limitations and confirmed future product plans; evergreen does not mean pretending unfinished work is complete.

For example, replace "A planned meme-token project built around Shaquille O'Meal. The token is not live yet." with "Shaquille O'Meal brings a larger-than-life burger character, fries on the side, and a familiar grin to internet culture." A separate token.description could be "OMEAL is the meme token for Shaquille O'Meal, a larger-than-life burger character with fries on the side." This describes identity without claiming trading has started or promising utility.

Makeway shows a creator-supplied contract address only when one is added; Netlify live admin can update that address. It does not rewrite website prose, infer launch status from the blockchain, or update already published token metadata. Omit time-sensitive token-status FAQs and launch milestones from permanent copy. Review existing draft wording too: do not preserve stale status language merely because it appears below.

## Ranked ticker ideas

Return exactly five distinct options in project.tickerOptions, ranked best first. Each object has ticker (1–12 uppercase letters or numbers, no $) and reason (a short explanation of the name fit). Set project.ticker to the first option so it is preselected. The creator can pick another option from a dropdown or type their own. Rank for relevance, memorability, and readability, never expected price or returns. Do not claim a ticker is available or unique on-chain. On a revision, preserve an explicitly chosen ticker as the first option.

## Images — offer a square profile image and a wide hero

Before finalizing the JSON, proactively offer the two useful launch images. Unless I have already made my preference clear, ask: "Would you like me to create a matching square profile/token image and a wide hero image, or use your existing images as they are?" Bundle this with any other essential questions and wait for my answer. Ask even when I have attached an image: it may be a reference, not a finished asset. Do not decide that no additional images are needed just because an attachment exists.

If I say I need images and that you can use or reuse my attachment, treat that as a request to create the matching pair from that reference. If I already ask for both images, create both without making me ask again. If I request only one, create only that one. If I explicitly say to use my files unchanged or not to generate images, respect that choice and do not ask again. Attaching an image or saying "use this" alone is not permission to recreate it; ask the image-choice question first. Preserve original files and save any approved new versions separately.

When I choose to create both, complete both image files as part of this task, then finalize the JSON to match them. Do not stop at the JSON and wait for a separate image-generation prompt. Create two separate, coordinated files, not a contact sheet or a combined mockup:

- logo.png: a square 1:1 profile/token image, ideally 1024 × 1024. Keep the subject centered and recognizable at avatar size. Avoid small lettering. Assign it to the logo slot, which is also used in navigation and the footer. A profile image can have a background; do not force transparency. For a technical brand mark, a transparent PNG or SVG may be more appropriate.
- hero-artwork.png: a wide website hero, ideally 16:9. Match the square image's subject, colours, and visual style. Keep the important details within the composition and avoid duplicating a long website headline inside the image. Assign it to hero-artwork. Use the closest supported dimensions if the image tool cannot produce the exact ratio.

Use any supplied image as the reference for an approved recreation. Preserve the core character and project identity. A screenshot or chat capture is a reference, not the final asset: omit chat bubbles, app chrome, and unrelated overlays from the newly created images. Keep the original attachment unchanged. Never invent a real product screenshot; technical projects should use actual interface captures in product-screenshot, with generated brand artwork clearly treated as illustration.

If I choose to keep existing images, map those files to their intended slots without modifying them. A brand logo is required before Makeway lets the user continue, including for website-only projects. Always include a logo image slot and identify the file to upload there. The same supplied image may be assigned to both logo and hero if the user wants their originals unchanged; a separate hero is optional. If no usable logo exists, ask the user to attach one or approve creating one. Do not add filler slots or describe an opaque image as transparent. Choose a template and palette that suit the artwork. Hero images retain their full composition on desktop and mobile.

Outside the JSON, list every final filename and the image-slot ID where I should upload it. Include slots and accurate alt text for the agreed assets. Keep new assetRef values null even when images were generated or attached in this chat: Makeway assigns references on upload. Preserve existing assetRef values on unchanged slots. Do not embed images in JSON or add a filename-mapping field. Supply new files separately; I can upload unchanged originals directly without renaming or downloading them again.

If image generation is unavailable, say so clearly and provide a ready-to-use generation prompt for each requested image, including its purpose, aspect ratio, and reference instructions. You may still return the JSON with the intended image slots unassigned. Never claim an image file exists unless you actually created and attached it.

## Rules

Preserve stable roadmap and image-slot IDs on updates. Set new image assetRef values to null; never invent references, fetch images, or embed base64 data. Keep the assetRef values I supply. Image and roadmap IDs must be unique within their array. Links must be HTTPS without embedded credentials, and an X Community URL must look like https://x.com/i/communities/123456789.

Do not add HTML, CSS, scripts, contract addresses, wallet details, fees, or launch settings. Follow the website/token choice above; token.description is descriptive content, not a deployment setting. Keep the JSON under 256 KB.

## Exact JSON Schema

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "schemaVersion": {
      "type": "number",
      "const": 3
    },
    "mode": {
      "type": "string",
      "enum": [
        "narrative",
        "technical"
      ]
    },
    "design": {
      "type": "string",
      "enum": [
        "warm",
        "crisp",
        "terminal",
        "gallery",
        "editorial"
      ]
    },
    "theme": {
      "type": "object",
      "properties": {
        "headingFont": {
          "type": "string",
          "enum": [
            "manrope",
            "outfit",
            "azeret-mono",
            "bricolage-grotesque",
            "space-grotesk",
            "sora",
            "syne",
            "fraunces",
            "dm-serif-display",
            "bodoni-moda",
            "archivo-black",
            "bebas-neue",
            "space-mono",
            "ibm-plex-mono",
            "caveat"
          ]
        },
        "bodyFont": {
          "type": "string",
          "enum": [
            "manrope",
            "outfit",
            "azeret-mono",
            "bricolage-grotesque",
            "space-grotesk",
            "sora",
            "syne",
            "fraunces",
            "dm-serif-display",
            "bodoni-moda",
            "archivo-black",
            "bebas-neue",
            "space-mono",
            "ibm-plex-mono",
            "caveat"
          ]
        },
        "palette": {
          "type": "string",
          "enum": [
            "paper",
            "graphite",
            "emerald",
            "midnight",
            "porcelain",
            "butter",
            "rose",
            "custom"
          ]
        },
        "customColors": {
          "description": "Required when palette is custom. Omit when using a preset palette.",
          "type": "object",
          "properties": {
            "bg": {
              "type": "string",
              "pattern": "^#[0-9a-fA-F]{6}$",
              "description": "Page background"
            },
            "ink": {
              "type": "string",
              "pattern": "^#[0-9a-fA-F]{6}$",
              "description": "Text colour"
            },
            "accent": {
              "type": "string",
              "pattern": "^#[0-9a-fA-F]{6}$",
              "description": "Links and primary buttons"
            },
            "panel": {
              "type": "string",
              "pattern": "^#[0-9a-fA-F]{6}$",
              "description": "Cards and alternate surfaces"
            },
            "line": {
              "type": "string",
              "pattern": "^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$"
            },
            "accentInk": {
              "type": "string",
              "pattern": "^#[0-9a-fA-F]{6}$",
              "description": "Text on accent buttons"
            }
          },
          "required": [
            "bg",
            "ink",
            "accent",
            "panel",
            "line",
            "accentInk"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "headingFont",
        "bodyFont",
        "palette"
      ],
      "additionalProperties": false
    },
    "project": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 80,
          "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
        },
        "shortName": {
          "description": "Optional recognizable short name for navigation and footer. Keep the full project name unchanged.",
          "type": "string",
          "minLength": 0,
          "maxLength": 24,
          "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
        },
        "ticker": {
          "type": "string",
          "maxLength": 12,
          "pattern": "^[A-Z0-9]*$"
        },
        "description": {
          "type": "string",
          "minLength": 1,
          "maxLength": 240,
          "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
        },
        "tickerOptions": {
          "description": "Five unique ticker ideas ordered best first; project.ticker starts with the first choice.",
          "minItems": 5,
          "maxItems": 5,
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "ticker": {
                "type": "string",
                "minLength": 1,
                "maxLength": 12,
                "pattern": "^[A-Z0-9]+$"
              },
              "reason": {
                "type": "string",
                "minLength": 1,
                "maxLength": 160,
                "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
              }
            },
            "required": [
              "ticker",
              "reason"
            ],
            "additionalProperties": false
          }
        }
      },
      "required": [
        "name",
        "ticker",
        "description"
      ],
      "additionalProperties": false
    },
    "hero": {
      "type": "object",
      "properties": {
        "heading": {
          "type": "string",
          "minLength": 1,
          "maxLength": 120,
          "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
        },
        "description": {
          "type": "string",
          "minLength": 0,
          "maxLength": 600,
          "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
        },
        "primaryLink": {
          "type": "object",
          "properties": {
            "label": {
              "type": "string",
              "minLength": 0,
              "maxLength": 40,
              "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
            },
            "url": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 2048,
                  "pattern": "^https:\\/\\/[^\\s]+$"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "required": [
            "label",
            "url"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "heading",
        "description",
        "primaryLink"
      ],
      "additionalProperties": false
    },
    "token": {
      "description": "Supply for a token project; null for website-only. Optional so older JSON files still import.",
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "description": {
              "type": "string",
              "minLength": 0,
              "maxLength": 500,
              "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$",
              "description": "Evergreen token metadata, separate from website copy. Describe identity and purpose without launch-status wording or Makeway attribution."
            }
          },
          "required": [
            "description"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ]
    },
    "story": {
      "type": "string",
      "minLength": 0,
      "maxLength": 3000,
      "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
    },
    "features": {
      "maxItems": 6,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
          },
          "body": {
            "type": "string",
            "minLength": 0,
            "maxLength": 500,
            "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
          }
        },
        "required": [
          "title",
          "body"
        ],
        "additionalProperties": false
      }
    },
    "howItWorks": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "summary": {
              "type": "string",
              "minLength": 0,
              "maxLength": 800,
              "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
            },
            "prerequisites": {
              "maxItems": 6,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80,
                    "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
                  },
                  "body": {
                    "type": "string",
                    "minLength": 0,
                    "maxLength": 400,
                    "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
                  }
                },
                "required": [
                  "title",
                  "body"
                ],
                "additionalProperties": false
              }
            },
            "steps": {
              "maxItems": 8,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80,
                    "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
                  },
                  "body": {
                    "type": "string",
                    "minLength": 0,
                    "maxLength": 500,
                    "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
                  }
                },
                "required": [
                  "title",
                  "body"
                ],
                "additionalProperties": false
              }
            },
            "mechanism": {
              "type": "string",
              "minLength": 0,
              "maxLength": 2000,
              "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
            },
            "limitations": {
              "type": "string",
              "minLength": 0,
              "maxLength": 1500,
              "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
            }
          },
          "required": [
            "summary",
            "prerequisites",
            "steps",
            "mechanism",
            "limitations"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ]
    },
    "roadmap": {
      "maxItems": 6,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40,
            "pattern": "^[a-z0-9][a-z0-9-]*$"
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
          },
          "period": {
            "type": "string",
            "minLength": 0,
            "maxLength": 80,
            "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
          },
          "description": {
            "type": "string",
            "minLength": 0,
            "maxLength": 500,
            "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
          },
          "status": {
            "type": "string",
            "enum": [
              "planned",
              "in_progress",
              "complete"
            ]
          }
        },
        "required": [
          "id",
          "title",
          "period",
          "description",
          "status"
        ],
        "additionalProperties": false
      }
    },
    "faq": {
      "maxItems": 8,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160,
            "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
          },
          "answer": {
            "type": "string",
            "minLength": 0,
            "maxLength": 1000,
            "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
          }
        },
        "required": [
          "question",
          "answer"
        ],
        "additionalProperties": false
      }
    },
    "socials": {
      "type": "object",
      "properties": {
        "x": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 2048,
              "pattern": "^https:\\/\\/[^\\s]+$"
            },
            {
              "type": "null"
            }
          ]
        },
        "xCommunity": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 2048,
              "pattern": "^https:\\/\\/[^\\s]+$"
            },
            {
              "type": "null"
            }
          ]
        },
        "telegram": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 2048,
              "pattern": "^https:\\/\\/[^\\s]+$"
            },
            {
              "type": "null"
            }
          ]
        },
        "discord": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 2048,
              "pattern": "^https:\\/\\/[^\\s]+$"
            },
            {
              "type": "null"
            }
          ]
        },
        "github": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 2048,
              "pattern": "^https:\\/\\/[^\\s]+$"
            },
            {
              "type": "null"
            }
          ]
        },
        "docs": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 2048,
              "pattern": "^https:\\/\\/[^\\s]+$"
            },
            {
              "type": "null"
            }
          ]
        }
      },
      "required": [
        "x",
        "xCommunity",
        "telegram",
        "discord",
        "github",
        "docs"
      ],
      "additionalProperties": false
    },
    "imageSlots": {
      "maxItems": 10,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40,
            "pattern": "^[a-z0-9][a-z0-9-]*$"
          },
          "alt": {
            "type": "string",
            "minLength": 0,
            "maxLength": 200,
            "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
          },
          "assetRef": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80,
                "pattern": "^[a-zA-Z0-9-]+$"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "alt",
          "assetRef"
        ],
        "additionalProperties": false
      }
    },
    "pages": {
      "type": "object",
      "properties": {
        "roadmap": {
          "type": "object",
          "properties": {
            "enabled": {
              "type": "boolean"
            },
            "title": {
              "type": "string",
              "minLength": 0,
              "maxLength": 80,
              "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
            },
            "description": {
              "type": "string",
              "minLength": 0,
              "maxLength": 240,
              "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
            }
          },
          "required": [
            "enabled",
            "title",
            "description"
          ],
          "additionalProperties": false
        },
        "faq": {
          "type": "object",
          "properties": {
            "enabled": {
              "type": "boolean"
            },
            "title": {
              "type": "string",
              "minLength": 0,
              "maxLength": 80,
              "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
            },
            "description": {
              "type": "string",
              "minLength": 0,
              "maxLength": 240,
              "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
            }
          },
          "required": [
            "enabled",
            "title",
            "description"
          ],
          "additionalProperties": false
        },
        "howItWorks": {
          "type": "object",
          "properties": {
            "enabled": {
              "type": "boolean"
            },
            "title": {
              "type": "string",
              "minLength": 0,
              "maxLength": 80,
              "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
            },
            "description": {
              "type": "string",
              "minLength": 0,
              "maxLength": 240,
              "pattern": "^(?![\\s\\S]*<\\/?[a-zA-Z][^>]*>)[\\s\\S]*$"
            }
          },
          "required": [
            "enabled",
            "title",
            "description"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "roadmap",
        "faq",
        "howItWorks"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "schemaVersion",
    "mode",
    "design",
    "theme",
    "project",
    "hero",
    "story",
    "features",
    "howItWorks",
    "roadmap",
    "faq",
    "socials",
    "imageSlots",
    "pages"
  ],
  "additionalProperties": false
}
```

If I return validation errors, fix those fields and return the entire JSON object. Preserve my other content.
