Skip to content
Vitops
GuidesComponentsPackagesThemeReferenceChangelog

Start here

VitopsInstallationYour design systemYour config

Live preview

Theme previewAnimation libraryIconsPatterns

Components

OverviewCSS classesWeb componentsAstro componentsBricks elements

Packages

@getvitops/cli@getvitops/astro@getvitops/vite@getvitops/generator@getvitops/core@getvitops/utils@getvitops/emdash@getvitops/create

Reference

Config referenceOutput formatsColour systemType & space scalesComponent patternsIconsConsent gateConversion trackingSearchLegal documentsCSS class vocabularyBricks elements

Releases

Changelog

Config reference

Every field of the three-section config — designSystem, organization and site — plus the full design-token schema. Browsable, filterable, and generated from the published JSON Schema.

Generated page. Rendered from this project’sdesign-system.json by @getvitops/generator — the same bundlevitops docs prints against your own config. Don’t edit it by hand.

Generated from config.schema.json and schema.json, the same schemasvitops validate checks against — so they always match validation. Every field is linkable by its dotted path: #site.analytics.clarityId, #colors.palette.

For what belongs in each section and when you need a config at all, start withYour config. Agents should read vitops docs config and vitops docs authoringinstead of this page.

Project config

The three sections of a project config. Token fields live under designSystem and are listed in full below, so this tree stops at the wrapper.

  • designSystemobjectrequired

    The design system: named themes plus the system-wide facts (which theme, which appearance). A bare design system, or a bare theme map, is accepted as shorthand for { themes: … }.

    • themesmaprequired

      Named themes. default is the base; others may extends another and supply a partial patch. Light/dark is NOT a theme — the functional tokens flip per appearance within each one, so default already has both. Only the default theme is built today; multi-theme output and a picker are not wired yet.

    • defaultThemestring

      Which themes entry to use (convention: "default"). Validated against the map; selecting a non-default theme is not wired yet.

    • defaultColorSchemelight | dark | system

      Initial appearance. "system" follows the OS via prefers-color-scheme and is what makes <wc-color-scheme-toggle>'s "System" position resolve to anything — it removes the theme attribute, so without this the page falls through to light. It also gives a no-JS page the OS appearance. Defaults to "light", because switching an existing site to "system" visibly flips it dark for dark-OS visitors.

  • organizationobject

    The company: schema.org Organization details for JSON-LD (name, legalName, logo, tax IDs, sameAs), plus its contact, physical locations, services and public profiles. These stay true across sites — several sites can share one organization and differ only in site.

    • nameone of

      Trading name, as a reader would recognise it (e.g. "Acme"). Localisable.

      • one ofstring
      • one ofmap
    • legalNamestring

      Registered legal name (e.g. "Acme Widgets Inc."). The generated legal documents prefer this over name — a policy is a statement by the legal entity.

    • foundingDatestring

      Date the organization was founded (YYYY-MM-DD).

    • logoone of

      Organization logo → JSON-LD logo.

      • one ofstring
      • one ofobject
        • srcstringrequired
        • altstringrequired
        • widthnumber
        • heightnumber
    • emailstring

      General contact address. Also the last fallback for privacy requests — see contact.

    • phonestring

      General contact telephone number.

    • addressobject

      Registered/mailing address. Its addressRegion and addressCountry are what the governing-law clause of the generated terms of service defaults to.

      • streetAddressstringrequired
      • addressLocalitystringrequired

        City.

      • addressRegionstring

        State / province.

      • postalCodestring
      • addressCountrystringrequired

        Country (ISO 3166-1 alpha-2 preferred).

    • taxIDstring

      Tax identification number.

    • vatIDstring

      VAT identification number.

    • sameAsarray of string

      Profile URLs → JSON-LD sameAs (mirrors links).

    • contactone of

      Primary contact: either a locations key (string reference) or an inline name/email/phone/address object.

      • one ofstring
      • one ofobject
        • namestring
        • emailstring
        • phonestring
        • addressobject

          schema.org PostalAddress field names, so JSON-LD generation is lossless.

          • streetAddressstringrequired
          • addressLocalitystringrequired

            City.

          • addressRegionstring

            State / province.

          • postalCodestring
          • addressCountrystringrequired

            Country (ISO 3166-1 alpha-2 preferred).

    • primaryLocationstring

      The main locations key (for JSON-LD and defaults).

    • locationsmap

      Physical locations (schema.org LocalBusiness): address, geo, opening hours, service area.

      • <name>object
        • slugone of

          A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

          • one ofstring
          • one ofmap
        • nameone ofrequired

          A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

          • one ofstring
          • one ofmap
        • emailstring
        • phonestring
        • addressobject

          schema.org PostalAddress field names, so JSON-LD generation is lossless.

          • streetAddressstringrequired
          • addressLocalitystringrequired

            City.

          • addressRegionstring

            State / province.

          • postalCodestring
          • addressCountrystringrequired

            Country (ISO 3166-1 alpha-2 preferred).

        • geoobject
          • latitudenumberrequired
          • longitudenumberrequired
        • hoursarray
          • [items]object
            • dayOfWeekarray of Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sundayrequired
            • opensstringrequired
            • closesstringrequired
        • hoursSpecialarray

          Holiday/temporary hours, as dated deviations from the recurring hours — distinct from it because these carry a date range rather than a weekday.

          • [items]object
            • validFromstringrequired
            • validThroughstring
            • opensstring
            • closesstring
        • typeLocalBusiness | Store | Restaurant | CafeOrCoffeeShop | ProfessionalService | MedicalBusiness | HealthAndBeautyBusiness | HomeAndConstructionBusiness | AutomotiveBusiness | FinancialService | LegalService | RealEstateAgent | Organization
        • descriptionone of

          A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

          • one ofstring
          • one ofmap
        • areaServedarray of string
        • priceRangestring
        • paymentAcceptedarray of string
        • currenciesAcceptedstring
        • knowsLanguagearray of string
        • photosarray

          Location photos (logo, storefront, interior, …) → JSON-LD image. Every listing platform (GBP, Bing Places, Apple Business Connect) wants these; none can derive them.

          • [items]one of
            • one ofstring
            • one ofobject
              • srcstringrequired
              • altstringrequired
              • widthnumber
              • heightnumber
        • sameAsarray of string

          This location's own profile URLs (its Google Business Profile, Bing Places listing, Apple Business Connect location, Facebook page, …) → JSON-LD sameAs. Distinct from organization.sameAs, which is the company overall — a multi-location org's locations do not share one GBP listing.

        • listingsmap

          External listing IDs for this location, keyed by platform — the Google Business Profile location id, the Bing Places business id, the Apple Business Connect location id. Not consumed by the generator today; recorded here so a future sync has a stable id to match against instead of risking a duplicate listing.

    • servicesmap

      Services offered (schema.org Service/Offer): name, description, slug, price offers.

      • <name>object
        • nameone ofrequired

          A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

          • one ofstring
          • one ofmap
        • descriptionone of

          A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

          • one ofstring
          • one ofmap
        • slugone of

          A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

          • one ofstring
          • one ofmap
        • offersarray
          • [items]object
            • nameone of

              A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

              • one ofstring
              • one ofmap
            • pricestring | number
            • priceCurrencystring
            • availabilitystring
            • urlstring
            • validFromstring
            • priceValidUntilstring
    • linksobject

      Public profile URLs (also feed JSON-LD sameAs via organization.sameAs).

      • googleMapsstring
      • instagramstring
      • facebookstring
      • xstring
      • linkedinstring
      • youtubestring
      • githubstring
  • siteobjectrequired

    This published site: locales, domains, environments, content templates, SEO, analytics, legal documents, icons, favicon and deployment. Facts about a presentation of the organization rather than the organization itself.

    • defaultLocalestringrequired

      The locale used when none is specified; must be a locales key.

    • localesmaprequired

      Locales the site is published in, keyed by BCP 47 tag (e.g. "en", "fr").

      • <name>object
        • namestringrequired

          Display name of the locale (e.g. "English").

        • taglinestring

          Site tagline in this locale.

        • basePathstring

          URL prefix for this locale (e.g. "/fr").

    • domainsobject

      Canonical domain + redirecting aliases.

      • canonicalstringrequired

        The canonical origin used for absolute URLs and SEO.

      • aliasesarray

        Alias domains and how they redirect to the canonical one.

        • [items]object
          • domainstringrequired
          • redirectTypenumber | number | number | numberrequired
          • redirectTostringrequired
          • environmentstring
    • dnsmap

      Desired DNS state per domain (provider, nameservers, records) — declarative reference, not applied automatically.

      • <name>object
        • providerstring
        • nameserversarray of string
        • recordsarray
          • [items]object
            • typeA | AAAA | CNAME | TXT | MX | NS | SRV | CAA | PTR | SOArequired
            • namestring
            • valuestringrequired
            • ttlinteger
            • proxiedboolean
    • cloudflaremap

      Deliberate escape hatch for provider-specific Cloudflare settings — out of scope to model here.

    • googleobject

      This site's Google Cloud project. Not a secret — the credentials stay in the environment.

      • projectstringrequired

        Google Cloud project id that API usage is attributed to (quota and billing). One project per site keeps usage separate — Search Console today, Maps and anything else later. Sent as x-goog-user-project, which is required when the credential is a user one (an ADC login from gcloud auth application-default login, or VITOPS_GOOGLE_*): those use a shared OAuth client that carries no project of its own. A service-account credential belongs to a project already, so this is not needed for it. The identity must hold serviceusage.services.use on the project, and the APIs being called must be enabled there.

    • searchConsolemap

      Domains to onboard as Google Search Console domain properties via vitops search setup, keyed by bare hostname (mirrors dns). Credentials come from the environment (CLOUDFLARE_API_TOKEN + the Google OAuth vars) — never in this file. Set google.project when using a user credential.

      • <name>object
        • delegatedOwnersarray of string

          Emails added as verification owners on the Site Verification web resource. Automated via the API — additive and idempotent, never removes an existing owner.

        • fullUserGroupstring

          A Google Group to grant Full-User access in Search Console. SURFACED AS A REMINDER only: Search Console exposes no user/permission API, so this step stays manual by design.

    • environmentsmaprequired

      Deploy environments (production, dev, …): URL, API origin, analytics toggle, robots policy, active A/B variant.

      • <name>object
        • urlstringrequired

          Public origin of this environment.

        • apistring

          API origin, when different from url.

        • analyticsboolean

          Whether analytics fire in this environment.

        • adsboolean

          Whether site.ads pixels fire in this environment. Defaults to analytics, then true — a preview deployment sending pageviews is survivable, one firing conversion pixels is not, so this can be turned off on its own.

        • robotsstring

          Robots policy (e.g. "noindex,nofollow" for dev).

        • variantstring

          Active abTesting.variants key for this environment.

    • abTestingobject

      A/B testing: cookie-based split plus named variants whose overrides patch the config per environment.

      • enabledbooleanrequired
      • cookieNamestring
      • cookieMaxAgeinteger

        Seconds.

      • splitRationumber

        Fraction of traffic sent to the variant (0–1).

      • variantsmap

        Named variants; each targets an environment and may deep-merge config overrides.

        • <name>object
          • environmentstringrequired
          • descriptionstring
          • overridesmap
    • fontsarray

      Font LOADING (a serialisable projection of the Astro Fonts API: provider, weights, subsets, preload). Font TOKENS live in designSystem.themes.<theme>.fonts and reference the same cssVariable.

      • [items]object
        • namestringrequired
        • providergoogle | fontsource | adobe | bunny | fontshare | googleicons | npm | localrequired
        • cssVariablestringrequired
        • weightsarray
          • [items]number | string
        • stylesarray of normal | italic
        • subsetsarray of string
        • fallbacksarray of string
        • optimizedFallbacksboolean
        • displayauto | block | swap | fallback | optional
        • formatsarray of string
        • unicodeRangearray of string
        • variantsarray
          • [items]object
            • srcarray of stringrequired
            • weightnumber | string
            • stylenormal | italic
            • unicodeRangearray of string
            • displayauto | block | swap | fallback | optional
        • preloadone of

          Emit <Font preload /> for this family (true, or a list of weight/style faces).

          • one ofboolean
          • one ofarray
            • [items]object
              • weightnumber | stringrequired
              • stylenormal | italic
    • tagsmap

      Free-form content-tag taxonomy (site-specific; not interpreted by the generator).

    • postTypesmap

      Free-form content-type definitions (site-specific; not interpreted by the generator).

    • galleriesmap

      Named image galleries (title, tags, images with localisable alt/caption).

      • <name>object
        • titleone of

          A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

          • one ofstring
          • one ofmap
        • tagsarray of string
        • imagesarrayrequired
          • [items]object
            • srcstringrequired
            • altone ofrequired

              A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

              • one ofstring
              • one ofmap
            • captionone of

              A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

              • one ofstring
              • one ofmap
    • testimonialsmap

      Named testimonial groups (quote, name, role, rating, date).

      • <name>object
        • titleone of

          A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

          • one ofstring
          • one ofmap
        • itemsarrayrequired
          • [items]object
            • quoteone ofrequired

              A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

              • one ofstring
              • one ofmap
            • namestringrequired
            • rolestring
            • ratingnumber
            • datestring
    • templatesmap

      Named content templates rendered at SSR time: nav (menu trees), form (field lists + submit), or nodes (raw element trees).

      • <name>one of
        • one ofobject
          • typestringrequired
          • tagsarray of string
          • presentmap
          • itemsarray
        • one ofobject
          • typestringrequired
          • tagsarray of string
          • presentmap
          • actionstring
          • methodget | post
          • fieldsarray
            • [items]object
              • namestringrequired
              • typetext | email | tel | url | number | password | textarea | select | checkbox | radio | date | file | hiddenrequired
              • labelone of

                A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

                • one ofstring
                • one ofmap
              • requiredboolean
              • validationstring
              • optionsone of
                • one ofstring
                • one ofarray
                  • [items]object
                    • labelstringrequired
                    • valuestringrequired
              • attrsmap
                • <name>string | number | boolean
          • submitmap
            • <name>string | number | boolean
          • honeypotboolean
        • one ofobject
          • typestringrequired
          • tagsarray of string
          • nodesarray
    • navigationobject

      Site navigation settings (which nav template renders where).

      • activeTemplateobject

        Which nav template is active, optionally per breakpoint.

        • defaultstring

          A templates key.

        • breakpointsmap

          Breakpoint name → templates key overrides.

    • seoobject

      SEO defaults: title/description templates, robots policy, verification tokens, Open Graph + Twitter cards, and post-deploy indexing notification.

      • titleTemplatestring

        Page-title pattern (e.g. "%s · Acme").

      • descriptionTemplatestring
      • robotsstring

        e.g. "index,follow" / "noindex,nofollow".

      • googleSiteVerificationstring
      • bingSiteVerificationstring
      • openGraphobject
        • typestring
        • siteNamestring
        • titleone of

          A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

          • one ofstring
          • one ofmap
        • descriptionone of

          A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

          • one ofstring
          • one ofmap
        • imageone of
          • one ofstring
          • one ofobject
            • srcstringrequired
            • altstringrequired
            • widthnumber
            • heightnumber
        • localestring
      • twitterobject
        • cardsummary | summary_large_image | app | player
        • sitestring
        • creatorstring
        • titleone of

          A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

          • one ofstring
          • one ofmap
        • descriptionone of

          A string, or a per-locale map of strings ({ en: "…", fr: "…" }).

          • one ofstring
          • one ofmap
        • imageone of
          • one ofstring
          • one ofobject
            • srcstringrequired
            • altstringrequired
            • widthnumber
            • heightnumber
      • indexingobject

        How vitops search notify tells search engines about a deploy: which sitemap, IndexNow key, Search Console property, and which pages to verify afterwards.

        • sitemapUrlstring

          The sitemap to submit and to diff for changed URLs. Defaults to <canonical>/sitemap-index.xml.

        • indexNowobject

          IndexNow submission (Bing, Yandex, Naver, Seznam, Yep — not Google). Omit to skip the channel.

          • keystringrequired

            IndexNow key (8–128 chars, hex is conventional). NOT a secret — it is served publicly at keyLocation so the engine can verify you own the host. Generate one with vitops search notify --new-key.

          • keyLocationstring

            Absolute URL of the key file. Defaults to <canonical>/<key>.txt; set it only when the file lives elsewhere.

          • endpointstring

            IndexNow endpoint (default https://api.indexnow.org/indexnow). Any participating engine shares submissions with the rest, so one is normally enough.

        • searchConsoleobject

          Google Search Console property. Needs a credential at run time — either a service account in VITOPS_GSC_SERVICE_ACCOUNT / GOOGLE_APPLICATION_CREDENTIALS, or the user OAuth credential vitops search setup uses (VITOPS_GOOGLE_CLIENT_ID / _CLIENT_SECRET / _REFRESH_TOKEN). The service account wins when both are set. Never put a key in this file.

          • siteUrlstringrequired

            The property exactly as Search Console identifies it — sc-domain:acme.ca for a domain property, or the URL-prefix form https://acme.ca/. A mismatch here is a 403, not a "not found".

          • resubmitSitemapboolean

            Re-submit the sitemap through the Search Console API on each notify (default true when searchConsole is set). This is the automated equivalent of the manual resubmit in the UI.

        • priorityUrlsarray of string

          The pages whose indexing actually matters. vitops search notify --check inspects these and exits non-zero if Google has not indexed one. Kept explicit because URL Inspection is quota-bound (2000/day), so checking every page is neither affordable nor informative.

    • analyticsobject

      Analytics provider IDs (gated per environment via environments.<env>.analytics). Which provider is set is also what the generated privacy policy and cookie notice disclose — see legal.

      • googleAnalyticsIdstring
      • plausibleDomainstring
      • googleTagManagerIdstring
      • clarityIdstring

        Microsoft Clarity project ID.

      • matomoobject

        Matomo instance.

        • urlstringrequired

          Instance base URL (self-hosted, or *.matomo.cloud).

        • siteIdstringrequired

          Site ID within that instance.

        • cookiesboolean

          Default false — Matomo runs cookieless (disableCookies), which is what lets the cookie notice state positively that it sets none.

    • notificationsobject

      Where site notifications (form submissions, tracked calls) are sent. TODO: sms and persist channels — only email is implemented.

      • emailone of

        Where conversion notifications are e-mailed. A bare address is shorthand for { provider: "cloudflare", to }.

        • one ofstring
        • one ofobject
          • providerstringrequired

            Delivery provider. Only Cloudflare Email Sending is implemented; the field is stated so adding another is additive.

          • tostring

            Recipient. Defaults to the primary location’s email, then the first location that has one.

          • fromstring

            Sender. Defaults to noreply@<domains.canonical>. Its domain must be onboarded (wrangler email sending enable <domain>) or every send fails.

          • fromNamestring

            Display name on the From header. Defaults to organization.name.

          • replyTostring

            Reply-To header.

          • bindingstring

            Workers send_email binding name (default EMAIL). Set it when using a restricted binding.

    • trackingobject

      Ad-click attribution for conversion tracking.

      • enabledboolean

        Capture ad click IDs and UTMs from the landing URL into the _ac cookie, for attributing conversions.

      • categorymarketing | analytics

        Consent category the _ac cookie waits on (default marketing). It is a 90-day identifier tying a visitor to the ad that brought them, so it is only written once this category is granted — and asking for it is what raises the banner.

      • platformsarray of string

        Informational list of ad platforms in use. Capture recognises every known click-ID parameter regardless.

    • adsmap

      Ad properties this site is linked to, keyed by platform. Read by vitops ads setup (ensure the DNS verification record), vitops ads tags (emit the consent-gated pixel), and the generated cookie notice (disclose what each pixel stores). Credentials never live here — the DNS write uses CLOUDFLARE_API_TOKEN from the environment.

      • <name>object
        • accountIdstring

          The advertising account as the platform shows it — Google Ads customer ID, Meta ad account, LinkedIn partner ID, Reddit advertiser ID. For LinkedIn this is also the Insight Tag id; everywhere else the tag id is pixelId.

        • pixelIdstring

          The tag/pixel ID the browser snippet initialises — Meta pixel, TikTok pixel, Reddit pixel, Microsoft UET tag ID, Pinterest tag ID, Snap pixel, or the Google Ads conversion ID (AW-…, which is NOT the customer ID).

        • conversionLabelstring

          Google Ads only: the conversion action label paired with the AW-… conversion ID.

        • domainstring

          Bare hostname to verify with this platform. Defaults to the host of domains.canonical — set it only when the ad account is verified against a different domain.

        • domainVerificationstring

          The verification token from the platform UI, for the platforms that verify by DNS TXT (Meta, TikTok, Pinterest, Snapchat). vitops ads setup prompts for it and writes it here on first run. NOT a secret — it is published in DNS, and the platform fetching it back is the ownership proof, exactly like the IndexNow key. A value containing = is used as the whole record, which is the escape hatch if a platform changes its prefix.

        • categorymarketing | analytics

          Consent category the tag waits on (default marketing). An ad pixel is advertising by default; analytics is for a site using one purely for its own measurement.

        • enabledboolean

          Set false to keep the property on record without emitting its tag.

    • securityobject

      Security integrations (bot protection).

      • turnstileobject
        • siteKeystring

          Cloudflare Turnstile site key (public).

    • legalobject

      Legal pages: which documents exist, where they live, and the facts the generated prose asserts.

      • jurisdictionca

        Which legal template set the generated documents use. Default ca.

      • privacyPolicyobject
        • enabledbooleanrequired
        • urlstring
        • lastUpdatedstring
        • privacyOfficerone of

          Who privacy requests go to. Falls back to contact, then primaryLocation.

          • one ofstring
          • one ofobject
            • namestring
            • emailstring
            • phonestring
            • addressobject

              schema.org PostalAddress field names, so JSON-LD generation is lossless.

              • streetAddressstringrequired
              • addressLocalitystringrequired

                City.

              • addressRegionstring

                State / province.

              • postalCodestring
              • addressCountrystringrequired

                Country (ISO 3166-1 alpha-2 preferred).

        • retentionstring

          How long personal information is kept, in prose (e.g. "24 months after last contact").

        • processorsarray

          Third parties that receive personal information and cannot be inferred from the rest of the config (payment processors, CRMs, mail senders). Known providers implied by analytics, security and deployment are added automatically — list only the rest.

          • [items]object
            • namestringrequired

              The provider, as a reader would recognise it (e.g. "Stripe").

            • purposestringrequired

              Why they receive it, as a noun phrase that reads after "for" (e.g. "payment processing").

            • countrystring

              Shorthand for the common case where one country is both where they store it and whose laws reach it: asserts BOTH storage: [{ country }] AND operatorCountry. Reads inside a sentence (e.g. "the United States"). When the two differ — a Canadian region operated by a US company — state storage and operatorCountry instead; setting this alongside either is rejected.

            • storagearray

              Where the information actually rests. Feeds the "stored or processed outside of <jurisdiction>" disclosure and nothing else. Several entries are allowed, each optionally scoped to a category of information — which is what makes a Canadian-region tenant holding identity data in the US expressible.

              • [items]object
                • countrystringrequired

                  A country or bloc where this provider stores or processes the information, as it should read in a sentence (e.g. "Canada", "the United States", "the European Union"). Naming the jurisdiction the policy is written for is meaningful: it says this information does not leave it.

                • scopestring

                  Which information is held there, as a noun phrase that reads after "in the case of" (e.g. "account and sign-in information", "mailbox contents"). Omit when this location holds everything the provider receives — a scoped entry claims LESS than an unscoped one, so omitting it is the safe default.

            • operatorCountrystring

              The jurisdiction that can compel this provider to hand the information over — where it is established, or from which it is controlled. Reads after "the laws of" (e.g. "the United States"); a bloc is acceptable. A SEPARATE fact from storage, because privacy law cares about foreign access, not only foreign storage: a Canadian-region service run by a US company is storage: [{ country: "Canada" }] with operatorCountry: "the United States".

            • privacyUrlstring
      • termsOfServiceobject
        • enabledbooleanrequired
        • urlstring
        • lastUpdatedstring | null
        • governingLawstring

          Governing-law clause, in prose (e.g. "the Province of Ontario"). Defaults from the contact address.

      • cookieConsentobject
        • enabledbooleanrequired
        • typeopt-in | opt-out

          Consent model.

        • positiontop | bottom | center
        • categoriesarray of string
    • iconsmap

      Icon sets and the specific icons to bundle from each (keys are iconify collection names).

      • uistring

        Icon set used for UI chrome (e.g. "lucide", "ph").

      • brandstring

        Icon set used for brand marks.

      • weightstring

        Weight for suffix-weighted sets like Phosphor ("regular" | "bold" | "duotone" | "fill" | "light" | "thin"). Ignored by sets that split weights across collections, e.g. Font Awesome.

      • spriteboolean

        Emit an SVG sprite (icons.svg) alongside the stylesheet, for consumers that cannot run an icon integration (Bricks/WordPress, EmDash renderers).

      • semanticarray of string

        Named semantic icons to include.

      • fa7-solidarray of string
      • fa7-regulararray of string
      • fa7-lightarray of string
      • fa7-thinarray of string
      • fa7-brandsarray of string
      • simple-iconsarray of string
      • material-symbolsarray of string
      • lucidearray of string
      • pharray of string
    • faviconobject

      Favicon/PWA asset generation (consumed by @getvitops/utils favicon tooling).

      • sourcestringrequired

        Source image (SVG/PNG) the favicon set is generated from.

      • lowResSourcestring

        Alternate source for small raster sizes (16/32px) when the main source scales down poorly.

      • namestring

        App name for the generated web manifest. Setting this AND themeColor is what makes the site installable: together they emit site.webmanifest (with display: "standalone") and link it. Neither alone does anything. A marketing site that does not want a browser offering to install it should leave one of them unset.

      • themeColorstring

        Browser UI colour, emitted as <meta name="theme-color"> on every page — so it applies with or without a manifest. Note it is also half the manifest switch: see name.

      • backgroundColorstring

        Background composited under the OPAQUE generated icons — apple-touch-icon.png and the maskable icon-mask.png — which are produced whether or not there is a manifest. Defaults to white, so a dark logo on a transparent source needs this set. It is also the manifest background_color when one is emitted, but it is not manifest-only.

    • deploymentobject

      How the site is built and deployed (platform, commands, output directory) — informational for tooling.

      • platformstring
      • buildCommandstring
      • deployCommandstring
      • outputDirectorystring
      • typestring

Design tokens

Every field of a design system — what designSystem.themes.<name> holds, and what a standalone design-system.json contains on its own.

  • metaobject

    Brand identity for agent-facing output. Consumed only by the design format (DESIGN.md); it emits no CSS and no tokens.

    • namestring

      Brand/system name. Used as the name field and <h1> of the design format's DESIGN.md. Defaults to "Design System".

    • descriptionstring

      One or two sentences on the brand personality and the feeling the UI should evoke — what an agent needs when no token answers the question. Becomes the DESIGN.md description field and opens its Overview section; if omitted, a generic description of the system's mechanics is used instead.

  • colorsobjectrequired

    The colour system (the only required section): palette hues become generated OKLCH scales; roles map semantic roles onto those hues, from which all role tokens and dark mode derive.

    • palettemaprequired

      Palette hues by name. Each becomes an 11-step numeric OKLCH scale (--color-<hue>-50…950). Every ramp shares one fixed lightness ladder, so a step means the same lightness in every hue; only chroma and hue vary. Beyond the outermost authored colour the chroma decays towards a small endpoint value (0.008 light / 0.015 dark) so the near-white and near-black ends keep a whisper of the hue — but that is a ceiling, not a target, so a low-chroma seed stays low and a chroma-0 seed gives a true neutral rather than a tinted one. The ladder is also enforced: if pinned colours leave a ramp non-monotonic (some step darker than the one below it), the build fails rather than shipping a scale whose hover states run backwards.

      • <name>one of

        A palette hue, authored one of two ways: { seed, anchors? } generates an 11-step numeric OKLCH scale (50…950) from the seed, or { tones } supplies a fixed brand kit used verbatim.

        • one ofobject

          Seeded hue: the 11-step scale is GENERATED in OKLCH from seed (anchors pin specific steps).

          • seedstringrequired

            Seed colour (hex or oklch()). An 11-step numeric scale (50…950, tinted near-white → tinted near-black) is generated in OKLCH from it; the seed is preserved at its natural step.

          • anchorsmap

            Step → colour overrides (hex or oklch()) pinned VERBATIM at those steps. Every other step takes its lightness from the shared ladder, with chroma and hue interpolated between the anchors — so an anchor is reproduced exactly and is the only step allowed off the ladder. An explicit anchor overrides the seed at that step; two anchors that resolve to the same step are an error.

        • one ofobject

          Fixed hue: authored brand tones used verbatim; no generation.

          • tonesone ofrequired

            Fixed brand kit: authored tones placed verbatim at their nearest steps plus tinted off-white/off-black endpoints; no interpolation. Either an ordered light → dark array or a step → colour map.

            • one ofarray of string
            • one ofmap
    • rolesmaprequired

      Maps semantic role names onto palette hues. Role names are ARBITRARY — add a key and the generator emits that role's token set (--color-<target>-<role>[-<variant>] for target bg/text/icon/border), its dark-mode flip and its utility classes. A value is either a hue name ("danger": "rust") or { "hue": …, "kind": "surface" | "chromatic" }. The kind decides the shape of the token set. chromatic (the default, and what the bare-string form means) is a signal colour: its backgrounds split into tints (bg-<role>-x-muted/-muted) and solids (bg-<role>-solid[-bold|-x-bold]), with deliberately no bare bg-<role> — "how loud?" is a question the author answers. surface is a page/panel colour: it has a bare bg-<role> plus the full emphasis range and text scale. Dark mode flips automatically; there is no per-appearance scheme grammar. The solid family and its computed text-on-<role> foreground stay mode-stable so a filled button keeps its identity. Six roles are a required core, because the shipped framework CSS references them with no fallback: brand-primary, danger, neutral, surface, ui-primary, warning. Conventional additions are ui-secondary/accent, brand-secondary, info and success.

      • <name>one of
        • one ofstring

          A palette hue name. Shorthand for { hue, kind: "chromatic" }.

        • one ofobject
          • huestringrequired

            The palette hue this role resolves to.

          • kindsurface | chromatic

            surface — a page/panel colour: gets a bare bg-<role> plus the full emphasis range and text scale. chromatic (default) — a signal colour: tints and solids only, no bare bg-<role>.

    • utilitiesarray of bg | text | icon | border | outline | fill | stroke

      Which colour utility-class families to emit (bg-*, text-*, icon-*, border-*, outline-*, fill-*, stroke-*). Defaults to bg, text, icon, border. icon is a separate non-text tier (a glyph may run more vivid than text); outline/fill/stroke have no tokens of their own and alias the border and icon tiers.

  • shadowsmap

    Named shadows → --shadow-<name> tokens and .drop-shadow-<name> utilities. Values are shadow parameter lists (offset/blur/colour). Each token feeds two consumers with different grammars — box-shadow (pattern geometry, via the --ds-* group aliases) and filter: drop-shadow(…) (the utilities and the shadow: state shortcut) — so values must stay in the intersection: one layer, no spread radius, no inset. drop-shadow() rejects all three, and rejecting them invalidates the whole filter, so the shadow vanishes rather than degrading.

  • fontsmap

    Raw font stacks by name, emitted as --font-<name> tokens (referenced by typography.families). Stacks only — vitops does not load webfonts. A value here is a font-family list and nothing more: it emits no @font-face, no preload, and no metrics-matched fallback. If a family needs loading, declare it in Astro's fonts: config (astro.config, or the site config's fonts array) and point the token at the family's cssVariable — "display": "var(--font-league-spartan), sans-serif". Installing a @fontsource* package and importing its CSS also works but gives up subsetting, preload and size-adjust/ascent-override fallbacks, so it regresses CLS.

  • typeScaleobject

    Fluid modular TYPE scale → --text-<name> tokens, consumed by typography roles and text-size utilities.

    • basestringrequired

      Anchor size (a CSS length, e.g. "1rem") — the value at baseStep.

    • rationumberrequired

      Modular ratio between adjacent steps at large viewports.

    • stepsnumber

      Token count when names is absent (steps are then named 1..steps).

    • namesarray of string

      Step names, smallest → largest (e.g. ["xs","sm","md",…]); each becomes a token suffix.

    • baseStepnumber

      1-based index of the step whose value is base.

    • baselinestring

      Named step used as the fluid pivot / GUI scale centre (defaults to baseStep).

    • fluidobject

      Makes the scale fluid: each step compiles to a clamp() that interpolates from minRatio at minVw to ratio at maxVw.

      • minVwstringrequired

        Viewport width (CSS length) where fluid scaling bottoms out.

      • maxVwstringrequired

        Viewport width (CSS length) where fluid scaling tops out.

      • minRationumberrequired

        Modular ratio at/below minVw (usually < ratio).

  • spaceScaleobject

    Fluid modular SPACE scale → --space-<name> tokens, consumed by spacing/gap utilities and vertical rhythm.

    • basestringrequired

      Anchor size (a CSS length, e.g. "1rem") — the value at baseStep.

    • rationumberrequired

      Modular ratio between adjacent steps at large viewports.

    • stepsnumber

      Token count when names is absent (steps are then named 1..steps).

    • namesarray of string

      Step names, smallest → largest (e.g. ["xs","sm","md",…]); each becomes a token suffix.

    • baseStepnumber

      1-based index of the step whose value is base.

    • baselinestring

      Named step used as the fluid pivot / GUI scale centre (defaults to baseStep).

    • fluidobject

      Makes the scale fluid: each step compiles to a clamp() that interpolates from minRatio at minVw to ratio at maxVw.

      • minVwstringrequired

        Viewport width (CSS length) where fluid scaling bottoms out.

      • maxVwstringrequired

        Viewport width (CSS length) where fluid scaling tops out.

      • minRationumberrequired

        Modular ratio at/below minVw (usually < ratio).

  • patternsobject

    Component patterns and their token cascade: defaults → groups → per-pattern overrides, plus shape (radii) and z-index primitives.

    • defaultsmap

      Cascade-wide fallback tokens, emitted as --<prop>-default.

    • radiimap

      Shape primitives, emitted as --br-<name> (referenced by pattern bases).

    • groupsmap

      Group-level tokens, emitted as --<prop>-<group>; patterns opt in via their group key.

      • <name>map

        A CSS declaration block: property → value. Values stay strings (they can be hex, var(), clamp(), keywords, …); the generator, not the schema, interprets them.

    • zmap

      Z-index tiers → --z-tier-<name>.

    • itemsmap

      The component patterns to emit, keyed by name.

      • <name>object

        One component pattern (button, link, badge, card, …): base declarations + interaction states + semantic role variants, resolved through the pattern token cascade.

        • groupstring

          Token-cascade group this pattern belongs to (e.g. tag / control / panel); base declarations resolve through --<prop>-<group> before --<prop>-default.

        • overridesmap

          Per-pattern token overrides, emitted as --<prop>-<name>-group values.

        • elementstring

          Style at element level via zero-specificity :where(<element>) (instead of, or alongside, a class).

        • classstring

          Class name to emit (defaults to the pattern's key when no element is set). Combined with element, the pattern emits one zero-specificity :where(<element>, .<class>) rule so the class works on any tag and any explicit class overrides it.

        • fillboolean

          Whether this pattern is colour-filled (states/roles drive background-color + on-solid text) or text-coloured (they drive color). Defaults to true when base declares a background.

        • default_rolestring

          Semantic colour role applied to the bare/default variant.

        • basemap

          Base CSS declarations. Geometry properties (padding, border-radius, border, box-shadow, font-size) are wrapped in per-pattern override hooks (--p-<name>, --br-<name>, --b-<name>, --ds-<name>, --fs-<name>) so consumers can restyle one pattern by setting one variable.

        • statesmap

          Interaction states (hover / active / focus-visible), each a map of shortcuts: step (intensify the fill or text by n rungs — bg-<role>-solid → -solid-bold, text-<role> → -bold), scale (transform scale), lift (translateY + shadow), shadow (a shadow name → drop-shadow(var(--shadow-<name>)), or true → lift shadow), ring (focus ring), or raw css declarations. Hover rules are wrapped in @media (hover: hover).

        • rolesarray of string

          Semantic colour role variants to emit as <pattern>-<role> classes (fills use the role solid / on-solid tokens).

  • typographyobject

    Typography: family aliases, semantic type roles (→ font-<role> classes), and the bare-element → role mapping.

    • familiesmap

      Role-facing family aliases → CSS font values, usually referencing the top-level fonts tokens (e.g. "var(--font-display)").

    • rolesmap

      Semantic type roles (display, title, heading, body, quote, caption, eyebrow, code, lead, footnote, tag, …), each emitted as a font-<role> class.

      • <name>map

        A bag of CSS-ish keys, each mapped to a declaration plus a --<role>-<sfx> override hook. The recognised set is closed: family, size, weight, style, line-height, tracking (→ letter-spacing), text-transform, text-decoration, text-wrap, color. Note the last four are spelled with their full CSS property names — transform and decoration are NOT accepted. Anything unrecognised is ignored, not passed through, so the generator warns rather than emitting it: a silently-dropped transform: uppercase is how title-case navigation reaches production. Note also that style, text-transform, text-decoration and text-wrap are emitted on every role at their identity value (normal/none/none/wrap) whether declared or not, so applying one role class over another fully resets it — which means omitting text-wrap is not "inherit": it emits text-wrap: wrap and cancels the pretty the role would otherwise inherit from a pretty ancestor such as a body-mapped role. Declare it on every role — balance for heading-like roles, pretty for copy, wrap for short single-line labels.

        • <name>string | number
    • headingsmap

      Maps bare elements to type roles so unclassed markup picks up role styling — { "h1": "display", "h2": "heading" }. The key is used verbatim as a selector, so it is not limited to h1…h6: map "body" to your prose role to bind base page typography to the role rather than hand-writing it. That binding is what makes the role editable — a stylesheet that re-states font-family/line-height as literals on body shadows --<role>-ff/--<role>-lh, and the live theme editor then appears to do nothing.

  • animationsobject

    Animation effect + journey classes (pure value layers). The animation engine itself — keyframes, drivers, floats, utilities — is static framework CSS, not configured here.

    • effectsmap

      Effect classes to emit (.fade-in, .reveal-left, …), keyed by class name.

      • <name>object

        A named animation effect class — a pure value layer (--_anim + --<prop>-from/-to) over the static keyframe engine.

        • kfstringrequired

          Keyframe family driving the effect: composite (transform/opacity), paint, or layout.

        • cssmap

          Extra literal declarations merged into the effect class as-is.

          • <name>string | number
        • varsmap

          Effect endpoint variables (--<key>: <value>, e.g. opacity-from, translate-y-to) that override the keyframe defaults.

          • <name>string | number
    • journeysobject

      Multi-part journey classes composed from base building blocks.

      • basemap

        Named journey building blocks: part name → var map.

      • composearray of array

        Combinations of base parts, each emitted as a .<parts>-journey class.

Built with the design system it documents.

@getvitops on npm