Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Avelero/avelero/llms.txt

Use this file to discover all available pages before exploring further.

Avelero’s theming system lets you create digital product passports that match your brand identity. Customize colors, typography, logos, navigation, and content sections to deliver a consistent brand experience.

Theme architecture

The theme system separates styles from configuration:

Theme styles

Visual design elements that control how passports look:
  • Design tokens (colors, typography scales)
  • Component style overrides
  • Custom fonts (Google Fonts or self-hosted)
  • Custom CSS stylesheets

Theme configuration

Content and behavior settings:
  • Branding assets (logos, images)
  • Navigation menus (primary and secondary)
  • CTA banner content and visibility
  • Social media links
  • Section visibility toggles
  • Carousel configuration
This separation allows you to change visual design without affecting content, and vice versa. Theme changes apply to all passports immediately without republishing.

Design tokens

Design tokens are the foundation of your theme’s visual system.

Color tokens

Define your brand’s color palette:
{
  "colors": {
    "background": "#FFFFFF",
    "foreground": "#000000",
    "muted": "#F5F5F5",
    "mutedForeground": "#737373",
    "accent": "#0066CC",
    "accentForeground": "#FFFFFF",
    "card": "#FFFFFF",
    "cardForeground": "#000000",
    "primary": "#1A1A1A",
    "primaryForeground": "#FFFFFF",
    "destructive": "#DC2626",
    "destructiveForeground": "#FFFFFF",
    "success": "#16A34A",
    "successForeground": "#FFFFFF",
    "border": "#E5E5E5",
    "link": "#0066CC"
  }
}
Token usage:
  • Colors cascade to all components automatically
  • Change primary once, updates all buttons, headers, and accents
  • Ensures visual consistency across passport pages

Typography tokens

Define text styles for different content types:
{
  "typography": {
    "h1": {
      "fontSize": "2.25rem",
      "fontWeight": 700,
      "lineHeight": 1.2,
      "letterSpacing": "-0.02em"
    },
    "h2": {
      "fontSize": "1.875rem",
      "fontWeight": 600,
      "lineHeight": 1.3
    },
    "body": {
      "fontSize": "1rem",
      "fontWeight": 400,
      "lineHeight": 1.5
    },
    "body-sm": {
      "fontSize": "0.875rem",
      "lineHeight": 1.4
    }
  }
}
Available scales:
  • h1, h2, h3, h4, h5, h6 - Heading levels
  • body - Default body text
  • body-sm - Smaller text (captions, labels)
  • body-xs - Extra small text (metadata, fine print)

Component style overrides

Customize individual components beyond design tokens.

Override structure

Each component class can override specific CSS properties:
Component override example
{
  "product__title": {
    "fontSize": "2rem",
    "fontWeight": 600,
    "color": "$primary",
    "marginBottom": 16
  }
}

Color values in overrides

Component colors can reference tokens or use explicit values: Token reference (recommended):
{
  "banner__button": {
    "backgroundColor": "$primary",
    "color": "$primaryForeground"
  }
}
Outputs: background-color: var(--primary) Explicit hex value:
{
  "banner__button": {
    "backgroundColor": "#FF6B00",
    "color": "#FFFFFF"
  }
}
Outputs: background-color: #FF6B00
Use token references ($primary) when you want changes to design tokens to cascade. Use explicit hex values (#FF6B00) for one-off overrides that shouldn’t change.

Component class reference

  • header - Main header container
  • header__text-logo - Text logo styling when no image logo is used
  • product__image - Main product image
  • product__title - Product name heading
  • product__description - Product description text
  • product__brand - Brand name display
  • product__show-more - Expand/collapse button for long descriptions
  • product-details - Details section container (border color inherited by rows)
  • product-details__label - Detail row labels
  • product-details__value - Detail row values
  • impact-card - Environmental impact card container
  • impact-card__title - Impact metric name
  • impact-card__type - Impact type label
  • impact-card__value - Numeric value
  • impact-card__unit - Unit of measurement
  • impact-card__icon - Impact category icon
  • materials-card - Material card container
  • materials-card__title - Material name
  • materials-card__percentage - Material percentage
  • materials-card__type - Material type/category
  • materials-card__certification - Certification badge
  • materials-card__certification-icon - Checkmark icon for certified materials
  • materials-card__certification-text - Certification name text
  • materials-card__origin - Material origin/source
  • journey-card - Supply chain step card
  • journey-card__title - Step name
  • journey-card__line - Visual connector line between steps
  • journey-card__type - Process type
  • journey-card__operator - Operator/facility name

Typescale selection

Apply a typography scale to a component:
Using typescale
{
  "carousel__title": {
    "typescale": "h2"
  }
}
This applies all properties from the h2 typography token (fontSize, fontWeight, lineHeight, letterSpacing).

Custom fonts

Google Fonts

Use any font from Google Fonts:
1

Browse Google Fonts

Visit fonts.google.com and select fonts.
2

Copy embed URL

Click “View selected families” and copy the <link> href:
https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap
3

Add to theme

In theme settings, paste the Google Fonts URL into the Google Fonts URL field.
4

Apply in typography tokens

Set fontFamily in typography tokens:
{
  "typography": {
    "body": {
      "fontFamily": "'Inter', sans-serif"
    }
  }
}

Self-hosted custom fonts

Use your brand’s proprietary fonts:
1

Upload font files

Upload .woff2 font files to your file assets in Avelero.
2

Get CDN URLs

Copy the public CDN URL for each font file.
3

Define custom fonts

Add to theme styles:
{
  "customFonts": [
    {
      "fontFamily": "Brand Sans",
      "src": "https://cdn.avelero.com/fonts/brand-sans-regular.woff2",
      "fontWeight": 400,
      "fontStyle": "normal",
      "fontDisplay": "swap"
    },
    {
      "fontFamily": "Brand Sans",
      "src": "https://cdn.avelero.com/fonts/brand-sans-bold.woff2",
      "fontWeight": 700,
      "fontStyle": "normal",
      "fontDisplay": "swap"
    }
  ]
}
4

Apply in tokens

Reference the font family in typography:
{
  "typography": {
    "body": {
      "fontFamily": "'Brand Sans', sans-serif"
    }
  }
}
  • Format: .woff2 (best compression and browser support)
  • Fallback: Include system font fallback (e.g., sans-serif)
  • Licensing: Ensure font license allows web embedding
  • Optimization: Subset fonts to reduce file size

Custom CSS stylesheets

For advanced styling beyond component overrides:
1

Create stylesheet

Write custom CSS targeting passport components or adding new styles.
2

Upload stylesheet

Upload .css file to Avelero file assets.
3

Link in theme

Copy the CDN URL and set as Custom stylesheet URL in theme settings.
Custom CSS example:
Custom styles
/* Add subtle animation to buttons */
.banner__button {
  transition: transform 0.2s ease;
}

.banner__button:hover {
  transform: scale(1.05);
}

/* Add custom section divider */
.section-divider {
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--border),
    transparent
  );
  margin: 48px 0;
}

/* Customize product image aspect ratio */
.product__image {
  aspect-ratio: 1 / 1;
  object-fit: cover;
}
Custom CSS is loaded after default styles. Use higher specificity or !important if needed to override defaults. Test thoroughly across different screen sizes.

Theme configuration

Branding assets

Set your brand logo:
Branding config
{
  "branding": {
    "headerLogoUrl": "https://cdn.avelero.com/brands/logo.svg"
  }
}
Logo requirements:
  • Format: SVG, PNG, or JPG
  • Recommended: SVG for scalability
  • Max width: Auto-sized to fit header
  • Transparent background recommended for PNG
Configure primary and secondary menus:
Menu config
{
  "menus": {
    "primary": [
      { "label": "Shop", "url": "https://yourbrand.com/shop" },
      { "label": "Sustainability", "url": "https://yourbrand.com/sustainability" },
      { "label": "About", "url": "https://yourbrand.com/about" }
    ],
    "secondary": [
      { "label": "Privacy Policy", "url": "https://yourbrand.com/privacy" },
      { "label": "Terms", "url": "https://yourbrand.com/terms" },
      { "label": "Contact", "url": "https://yourbrand.com/contact" }
    ]
  }
}
Menu behavior:
  • Primary menu: Displayed in header or expandable menu
  • Secondary menu: Displayed in footer
  • All links open in current window (add target="_blank" in custom CSS if needed)

CTA banner

Add call-to-action banners to passports:
CTA config
{
  "cta": {
    "bannerBackgroundImage": "https://cdn.avelero.com/banners/sustainability.jpg",
    "bannerHeadline": "Committed to Sustainability",
    "bannerSubline": "Learn about our journey to carbon neutrality",
    "bannerCTAText": "Read Our Story",
    "bannerCTAUrl": "https://yourbrand.com/sustainability",
    "showHeadline": true,
    "showSubline": true,
    "showButton": true
  }
}
Visibility toggles:
  • showHeadline, showSubline, showButton - Control which elements appear
  • Useful for A/B testing or seasonal campaigns
  • Banner hidden automatically if sections.showCTABanner is false
Connect passports to social profiles:
Social config
{
  "social": {
    "showInstagram": true,
    "showFacebook": false,
    "showTwitter": true,
    "showPinterest": false,
    "showTiktok": true,
    "showLinkedin": false,
    "instagramUrl": "https://instagram.com/yourbrand",
    "twitterUrl": "https://twitter.com/yourbrand",
    "tiktokUrl": "https://tiktok.com/@yourbrand"
  }
}
Supported platforms: Instagram, Facebook, Twitter/X, Pinterest, TikTok, LinkedIn

Section visibility

Control which sections appear on passports:
Section visibility
{
  "sections": {
    "showProductDetails": true,
    "showPrimaryMenu": true,
    "showSecondaryMenu": true,
    "showImpact": true,
    "showMaterials": true,
    "showJourney": true,
    "showSimilarProducts": true,
    "showCTABanner": false
  }
}
Sections with no data are hidden automatically, even if visibility is enabled. For example, if a product has no environmental impact data, the impact section won’t display.

Materials section options

Customize materials display:
Materials config
{
  "materials": {
    "showCertificationCheckIcon": true
  }
}
Certification icon:
  • When enabled, shows checkmark icon next to certified materials
  • Visually emphasizes sustainable material choices
  • Disable for minimal design aesthetic
Customize the similar products carousel:
Carousel config
{
  "carousel": {
    "productCount": 6,
    "showPrice": true,
    "showTitle": true,
    "roundPrice": false,
    "includeIds": [],
    "excludeIds": [],
    "filter": {
      "tags": ["featured", "bestseller"]
    }
  }
}
Options:
  • productCount - Number of products to show (default: 6)
  • showPrice, showTitle - Toggle product info visibility
  • roundPrice - Round prices (49.9949.99 → 50)
  • includeIds - Specific product IDs to show
  • excludeIds - Product IDs to exclude
  • filter - Filter criteria (tags, category, season, etc.)

Editing themes

Via dashboard

1

Navigate to theme editor

Go to SettingsBrand settingsTheme.
2

Edit styles

Switch to Styles tab to edit colors, typography, and component overrides.
3

Edit configuration

Switch to Configuration tab to edit menus, banners, and visibility.
4

Save changes

Click Save to apply changes to all passports immediately.

Via API

Update theme programmatically:
Update config
import { trpc } from '@/lib/trpc';

const result = await trpc.brand.theme.update.mutate({
  config: {
    menus: {
      primary: [
        { label: 'Shop', url: 'https://yourbrand.com/shop' }
      ]
    },
    sections: {
      showCTABanner: false
    }
  }
});
API methods:
  • brand.theme.get - Fetch current theme (styles + config)
  • brand.theme.update - Update theme configuration
Theme styles are updated separately via the dashboard. API updates are for programmatic config changes (e.g., enabling/disabling sections based on data availability).

Theme preview

Test theme changes before publishing:
1

Enable preview mode

Click Preview in theme editor.
2

Select product

Choose a product to preview with your theme.
3

Test responsiveness

Preview on different screen sizes (mobile, tablet, desktop).
4

Iterate

Make adjustments and preview again until satisfied.
Preview limitations:
  • Preview uses draft theme (not yet saved)
  • Only you can see preview (not public)
  • Preview expires after session ends

Theme revalidation

When theme changes are saved:
  1. Database update - Theme config/styles saved to brand_theme table
  2. Cache invalidation - Passport pages revalidated automatically
  3. Immediate effect - Changes apply to all passports within seconds
Revalidation implementation:
Automatic revalidation
// After theme update
const brand = await db.query.brands.findFirst({
  where: eq(brands.id, brandId)
});

if (brand?.slug) {
  // Revalidates all passport pages for this brand
  await revalidateBrand(brand.slug);
}
You don’t need to republish passports when updating themes. Changes propagate automatically.

Best practices

Use design tokens

Define colors and typography once in tokens, reference them in components. Makes global changes easier.

Test with real data

Preview theme with products that have varying data completeness to ensure graceful degradation.

Maintain accessibility

Ensure color contrast ratios meet WCAG AA (4.5:1 for body text, 3:1 for large text).

Optimize assets

Compress images and fonts. Use modern formats (WebP, WOFF2) for better performance.

Accessibility checklist

  • Body text: 4.5:1 contrast ratio minimum
  • Large text (18pt+): 3:1 contrast ratio minimum
  • Use tools like WebAIM Contrast Checker
  • Body text: Minimum 16px (1rem)
  • Small text: Minimum 14px (0.875rem)
  • Ensure text is readable on mobile devices
  • Interactive elements must have visible focus indicators
  • Don’t remove default outline without replacing
  • Test keyboard navigation (Tab key)
  • Ensure decorative images don’t convey critical info
  • Product images have alt text from product data
  • Logos use brand name as alt text

Database schema

Theme data is stored in the brand_theme table:
brandId
uuid
Primary key. One theme per brand.
themeStyles
jsonb
Theme styles object (design tokens, component overrides, custom fonts)
themeConfig
jsonb
Theme configuration object (menus, banners, visibility, social links)
googleFontsUrl
string
Google Fonts embed URL (if using Google Fonts)
stylesheetPath
string
CDN path to custom CSS stylesheet (if uploaded)

Next steps

Custom domains

Serve passports from your own domain to strengthen branding.

Brand customization

Learn more about brand-wide customization features.

Build docs developers (and LLMs) love