Skip to content

All Sites - Foundation Meta Document

Version: 2.1.0
Date: 2026-01-21
Purpose: Shared configuration, assets, and block library for all company-solution suite sites

Design Philosophy: CICD (Canonical, Idempotent, Commutative, Decomposable)


Static Build Pattern (CRITICAL)

The product-domain retrieval and mutation model now lives under docs/products/.

This shared foundation document should only retain cross-site rules. Product-specific retrieval behavior, product collections, properties, and related mutation patterns should be documented in the product domain.

For current product-domain guidance, see:

  • docs/products/retrieval-intents.md
  • docs/products/mutation-intents.md
  • docs/products/properties.md
  • docs/products/product-collections.md

Deployment Architecture

Decision: Hybrid Path-Based with Independent Apps (Option C)

Adopted: 2026-01-21
Rationale: Best balance of SEO (single domain authority), operational flexibility (independent deploys), and risk containment (isolated failures).

Scope & Intent

This architecture means: - Not one giant runtime app. - Yes one unified web experience under a single host (www.omnivoltaic.com) with independent deployable apps behind it. - Each site remains its own build/deploy unit, but navigation, branding, and governance are shared.

URL Structure

Site Path App Folder Cloudflare Pages Project
Company Hub www.omnivoltaic.com/ apps/isr/company company.omnivoltaic.pages.dev
Off-Grid www.omnivoltaic.com/off-grid apps/isr/off-grid off-grid.omnivoltaic.pages.dev
Cross-Grid www.omnivoltaic.com/cross-grid apps/isr/cross-grid cross-grid.omnivoltaic.pages.dev
Productive Use www.omnivoltaic.com/productive apps/isr/productive productive.omnivoltaic.pages.dev
E-Mobility www.omnivoltaic.com/mobility apps/isr/mobility mobility.omnivoltaic.pages.dev

Architecture Principles

  1. Single Domain: All sites served under www.omnivoltaic.com for consolidated SEO authority
  2. Independent Apps: Each site is a separate Next.js static export with its own Cloudflare Pages project
  3. Path Routing: Cloudflare Workers routes paths to appropriate Pages projects
  4. Independent Deploys: Each app can be deployed/rolled back independently
  5. Shared Design System: All apps import from @dirac/uxi-design-system for brand consistency
  6. Canonical URL Policy: Path URLs are canonical (/off-grid, /cross-grid, etc.); any subdomain aliases must 301 to canonical paths
  7. One-Page-One-Canonical: Every indexable page declares exactly one canonical URL

SEO Governance (Mandatory)

  1. Canonical strategy:
  2. Canonical format: https://www.omnivoltaic.com/<site>/<page>
  3. If aliases exist (for campaigns or migration), enforce permanent redirects to canonical paths.
  4. Search Console ownership:
  5. Maintain Domain property for omnivoltaic.com to track all subdomains and protocols.
  6. Sitemaps:
  7. Keep sitemap index at root host (for example: https://www.omnivoltaic.com/sitemap.xml).
  8. Include each site section sitemap (/off-grid/sitemap.xml, /mobility/sitemap.xml, etc.).
  9. Internal linking:
  10. Cross-site links should point to canonical path URLs, not Pages .pages.dev origins.
  11. Section quality parity:
  12. Every section must meet quality standards; weak sections can be evaluated independently by search systems even under one host.

Operations Governance (Mandatory)

  1. Monorepo build isolation:
  2. Each Pages project should use path-based build triggers (watch paths) to avoid unnecessary full-suite rebuilds.
  3. Rollback isolation:
  4. Roll back the affected site project only; do not roll back unrelated sections.
  5. Current platform boundary:
  6. Cloudflare Pages currently documents a maximum of 5 projects per monorepo.
  7. Current suite already uses 5 projects (company, off-grid, cross-grid, productive, mobility).
  8. Growth plan trigger:
  9. If a 6th site is added, perform architecture review before implementation (split repo strategy or alternative deployment topology).

Next.js Configuration (Per App)

Each ISR app must configure:

// next.config.js
const nextConfig = {
  output: 'export',
  trailingSlash: true,
  images: { unoptimized: true },
  basePath: '/off-grid',  // Set per app (empty for company)
};

basePath values: - company: (empty string - root) - off-grid: /off-grid - cross-grid: /cross-grid - productive: /productive - mobility: /mobility

Cloudflare Workers Router

export default {
  async fetch(request) {
    const url = new URL(request.url);
    const path = url.pathname;

    if (path.startsWith('/off-grid'))   return fetch('https://off-grid.omnivoltaic.pages.dev' + path);
    if (path.startsWith('/mobility'))   return fetch('https://mobility.omnivoltaic.pages.dev' + path);
    if (path.startsWith('/cross-grid')) return fetch('https://cross-grid.omnivoltaic.pages.dev' + path);
    if (path.startsWith('/productive')) return fetch('https://productive.omnivoltaic.pages.dev' + path);

    return fetch('https://company.omnivoltaic.pages.dev' + path); // default: company hub
  }
}

Build Commands

# From monorepo root
pnpm --filter company build      # → apps/isr/company/out/
pnpm --filter off-grid build     # → apps/isr/off-grid/out/
pnpm --filter cross-grid build   # → apps/isr/cross-grid/out/
pnpm --filter productive build   # → apps/isr/productive/out/
pnpm --filter mobility build     # → apps/isr/mobility/out/

Deployment Workflow

  1. Push to GitHub → Triggers Cloudflare Pages auto-build for changed app(s)
  2. Buildpnpm install && pnpm --filter <app> build
  3. Deploy → Static out/ folder deployed to Pages CDN
  4. Route → Cloudflare Worker routes requests to correct Pages project

Cross-Site Navigation

Shared header component must use absolute paths (not relative) for cross-site links:

// ✅ Correct - works across all sites
<a href="/off-grid">Off-Grid Solutions</a>
<a href="/mobility">E-Mobility</a>

// ❌ Wrong - relative paths break across sites
<a href="../off-grid">Off-Grid Solutions</a>

Rejected Alternatives

Option Why Rejected
A: Single Integrated App All-or-nothing deploys; one bug blocks all sites; no independent scaling
B: Subdomain-based Subdomains treated as separate sites by Google; dilutes SEO authority

External References

  • Cloudflare Pages monorepos: https://developers.cloudflare.com/pages/configuration/monorepos/
  • Cloudflare Workers CI/CD monorepo guidance: https://developers.cloudflare.com/workers/ci-cd/builds/advanced-setups/
  • Google Search Console Domain property (domain + subdomains): https://support.google.com/webmasters/answer/10431861?hl=en
  • Google site names behavior (domain/subdomain, not subdirectory): https://developers.google.com/search/docs/appearance/site-names
  • Google site reputation abuse clarification (sections can be treated independently): https://developers.google.com/search/blog/2024/11/site-reputation-abuse

Solution Site Pattern (Canonical and Idempotent)

Philosophy: This pattern is canonical (not derived from other sites) and idempotent (produces consistent results regardless of application history).

Applies To: All solution sites (off-grid, cross-grid, mobility, productive)

Site Structure

Pages (Required): 1. Root (/) → Redirect to /products/ 2. Products grid (/products) 3. Product detail (/products/[slug]) 4. Articles grid (/articles) 5. Article detail (/articles/[slug])

Configuration File: src/config/site.ts

export const SITE_NAME = 'Solution Name';
export const SITE_TAGLINE = 'Brief description';
export const BFF_URL = 'https://dirac-fed-dev.omnivoltaic.com/marketing';
export const PRODUCT_COLLECTIONS = ['collection-key-1', 'collection-key-2'];

export const navigation = [
  { name: 'Products', href: '/products' },
  { name: 'Articles', href: '/articles' },
];

export const footerNavigation = {
  company: [
    { name: 'Company Home', href: 'https://omnivoltaic.com' },
    { name: 'About Us', href: '#' },
    { name: 'Careers', href: '#' },
    { name: 'Press', href: '#' },
    { name: 'Contact', href: 'https://forms.office.com/r/45vCYswcf4' },
  ],
  resources: [
    { name: 'Become a Partner', href: 'https://forms.office.com/r/45vCYswcf4' },
    { name: 'Datasheets', href: '#' },
    { name: 'Knowledge Base', href: '#' },
  ],
  connect: [
    { name: 'LinkedIn', href: 'https://www.linkedin.com/company/omnivoltaic/' },
    { name: 'X / Twitter', href: 'https://x.com/omnivoltaic' },
    { name: 'Facebook', href: 'https://www.facebook.com/omnivoltaic' },
    { name: 'Instagram', href: 'https://www.instagram.com/omnivoltaic' },
  ],
  solutions: [
    { name: 'E-Mobility', href: '/mobility' },
    { name: 'Off-Grid Energy', href: '/off-grid' },
    { name: 'Cross-Grid', href: '/cross-grid' },
    { name: 'Productive Use', href: '/productive' },
  ],
};

Products Grid Page (/products)

Purpose: Multi-collection product showcase with collapsible sections.

Layout: - Dark theme (bg-gray-900) - Header: Logo + navigation (Products, Articles) - Hero section with site name and tagline - Product collections displayed as collapsible sections

Collapsible Sections: - Each collection wrapped in native <details>/<summary> element - First collection open by default (open={index === 0}) - Remaining collections collapsed - Chevron indicator rotates on expand/collapse - Collection heading shows: name + product count

Product Card: - Product image (mainMedia from BFF) - Product name - Collection badge (collection name) - "View Details" link → /products/[productKey]

Grid Layout: - Responsive: 1 col (mobile) → 2 cols (sm) → 3 cols (lg) → 4 cols (xl) - Gap: gap-x-6 gap-y-10

Data Source: BFF getProductCollections query

query GetProductCollections {
  getProductCollections {
    name
    collectionKey
    products {
      name
      productKey
      mainMedia
    }
  }
}

Footer: Default footer (see Default Footer section)

Product Detail Page (/products/[slug])

Purpose: Product details with Bill of Properties (BoP) and Bill of Materials (BoM) hierarchy.

Layout: - Dark theme - Minimal header: Logo + back link - Two-column layout: - Left: Image gallery (mainMedia + additional images) - Right: Product info sections (decomposable)

CICD Pattern: Decomposable sections + composition


Atomic Section: Product Properties (BoP)

Purpose: Always-visible product specifications table

Content: - Section heading: "Product Properties" (cyan #00FFFF) - Hairline divider (border-gray-800) - BoP table: key-value pairs from BFF - Format: Property name (left) | Value (right) - Table style: Tailwind prose tables

Data Source:

bop { key value }

Visual Treatment: - No expand/collapse (always visible for quick scanning) - Clean table layout with alternating row backgrounds - Property keys in gray-400, values in white


Atomic Section: Items Included (BoM)

Purpose: Expandable list of product components

Content: - Hairline divider - Section heading: "Items Included" (cyan #00FFFF) - BoM list as expandable disclosure (<details>/<summary>) - Each item: thumbnail (40x40) + item name + quantity - First item open by default

Data Source:

bom { name quantity thumbnail }

Interaction: - Native <details> element for accessibility - Chevron indicator rotates on expand/collapse - First item open to show affordance


Atomic Section: Product CTAs

Purpose: Download and quote request actions

Content: - Download Datasheet (secondary button) - Request Quote (primary button)

Button Styles: - Secondary: Gray outline, white text, hover → cyan - Primary: Navy bg, cyan border/text (.cta-button-primary)

Links: - Datasheet: /datasheets/[productKey].pdf or Cloudinary URL - Quote: Partnership form https://forms.office.com/r/45vCYswcf4 with pre-filled product name


Composition: Product Detail Page (Full)

Structure: 1. Minimal header (Logo + back link) 2. Two-column layout: - Left: Image gallery - Right: - Product name (h1, cyan) - Product Properties section (atomic, always visible) - Items Included section (atomic, expandable) - Product CTAs section (atomic) 3. Minimal footer (copyright only)

Data Source: BFF getProduct query

query GetProduct($productKey: String!) {
  getProduct(productKey: $productKey) {
    name
    mainMedia
    bop { key value }
    bom { name quantity thumbnail }
  }
}

CICD Properties: - Canonical: Each section self-contained - Idempotent: Same data = same page - Commutative: Section order can be changed (design decision) - Decomposable: Can omit sections (e.g., no BoM if product has none, no CTAs on preview pages)


Articles Grid Page (/articles)

Purpose: Article collection showcase.

Layout: - Dark theme - Header: Logo + navigation (Products, Articles) - Hero section with "Articles" heading - Article grid

Article Card: - Hero image (from article frontmatter) - Category badge (eyebrow-badge class) - Article title - Excerpt (first 150 chars of body) - Published date - Author name - "Read More →" link (secondary-link class)

Grid Layout: - Responsive: 1 col (mobile) → 2 cols (md) → 3 cols (lg) - Gap: gap-8

Data Source: Transitional local article artifacts in oves-sites/docs/articles/*.md - Collection intent currently staged in docs/articles/collections/*.yaml - Parse YAML frontmatter + markdown body - Cleaned article artifacts must be persisted into CMS through the BFF

Footer: Default footer

Article Detail Page (/articles/[slug])

Purpose: Full article view with typography-focused layout.

Layout: - Dark theme - Minimal header: Logo only (no navigation links) - Centered content column (max-w-4xl) - Prose typography (Lato Hairline, weight 100)

Content Structure: - Category badge (eyebrow-badge) - Article title (text-4xl, cyan #00FFFF) - Subtitle (if present) - Metadata bar: Author name, published date - Hero image (full-width, 16:9 aspect) - Article body (markdown → HTML, prose classes) - Feature image (if present, mid-article)

Typography: - Headings: Montserrat, cyan #00FFFF - Body: Lato Hairline (weight 100), light gray - Links: text-indigo-400 (prose-a class) - Code blocks: syntax highlighting

Footer: Minimal footer (copyright only)

Theme & Styling

CSS Import Order (MANDATORY - Cascade Intent)

/**
 * CSS Import Order - CICD Compliance
 * 
 * NOT commutative: Order defines cascade layers
 * Idempotent: Same order = same result on re-application
 * Decomposable: Each layer is atomic, can be reasoned about independently
 * 
 * Intent Labels:
 * - Layers 1-3: Foundation (Tailwind base system)
 * - Layer 4: Accumulative (adds brand tokens without conflicts)
 * - Layer 5: Corrective (overrides for site-specific needs)
 */

/* Layer 1: Reset - Browser defaults → consistent baseline */
@import 'tailwindcss/base';

/* Layer 2: Components - Reusable UI patterns (buttons, cards, forms) */
@import 'tailwindcss/components';

/* Layer 3: Utilities - Atomic classes (text-*, bg-*, flex, grid, etc.) */
@import 'tailwindcss/utilities';

/* Layer 4: Brand Tokens (Accumulative) - Design system colors, typography, spacing */
@import './oves-brand.css';

/* Layer 5: Theme Overrides (Corrective) - Site-specific final say on conflicts */
@import './theme-overrides.css';

Brand Colors: - Primary: Cyan #00FFFF (headings, CTAs, links hover) - Secondary: Navy #002552 (backgrounds, CTA default) - Neutrals: Gray scale (50-950)

Typography: - Headings: Montserrat (sans-serif) - Body: Lato (sans-serif) - Article body: Lato Hairline (weight 100)

Component Classes: - .cta-button-primary — primary CTA button (navy bg, cyan border/text) - .secondary-link — text link with hover (white → cyan) - .eyebrow-badge — category badge (cyan text, subtle ring)

Next.js Configuration

next.config.js:

const nextConfig = {
  output: 'export',              // Static site generation
  trailingSlash: true,           // /products/ not /products
  images: { unoptimized: true }, // Cloudinary handles optimization
  basePath: '/solution-name',    // e.g., '/off-grid', '/mobility'
};

layout.tsx: - Favicon: https://res.cloudinary.com/oves/image/upload/v1657359850/logos/oves_logo_round_h50_jg8h8m.png - Metadata: site name, description, Open Graph tags

Build & Deploy

Static Export:

pnpm --filter solution-site build
# Generates out/ folder with static HTML/CSS/JS

Cloudflare Pages: - One project per site (off-grid.omnivoltaic.pages.dev) - Auto-deploy on Git push - Cloudflare Workers router for path-based routing

Dev Ports: - Company: 3100 - Mobility: 3101 - Off-Grid: 3102 - Cross-Grid: 3103 - Productive: 3104


Pre-Deployment Checklist

Purpose: Comprehensive checklist ensuring all sites are production-ready before deploying to Cloudflare Pages.

Phase 1: Data Sources & Content Governance

Products (BFF Source) - [ ] Product collection intent documented in docs/products/product-collections.md - [ ] Product collection images uploaded to Cloudinary (placeholder URLs replaced with actual images) - [ ] Product collection images added to app code as static/local references (until BFF collections endpoint implemented) - [ ] BFF getProductCollections query tested and returning stable data - [ ] Product slugs normalized (ampersands → "and", lowercased) - [ ] Product images hosted on Cloudinary with proper transformations - [ ] BoP (Bill of Properties) and BoM (Bill of Materials) data complete for all products

Articles (Local → BFF Migration) - [ ] All staged articles in oves-sites/docs/articles/*.md conform to the article-domain contract - [ ] Article collection images uploaded to Cloudinary - [ ] Article slugs normalized per slug rules (ampersands → "and") - [ ] Hero images selected and hosted on Cloudinary - [ ] Feature images selected where applicable - [ ] Article metadata complete: articleKey, title, subtitle, author, publishedAt, categories, tags - [ ] Article collections defined in docs/articles/collections/*.yaml - [ ] Cleaned article artifacts persisted into CMS through BFF - [ ] Local article access code remains scaffold-compatible during transition

Phase 2: Site Implementation & Consistency

Per-Site Checklist (Apply to: company, off-grid, cross-grid, mobility, productive) - [ ] Site spec complete in oves-sites/docs/sites/<site>.md - [ ] next.config.js configured: output: 'export', correct basePath, trailingSlash: true - [ ] src/config/site.ts defines: SITE_NAME, BFF_URL, PRODUCT_COLLECTIONS, navigation, footerNavigation - [ ] Header: logo + nav links only (no CTA buttons) - [ ] Footer: Contact → partnership form URL, Become a Partner → partnership form URL - [ ] Theme CSS imports: tailwindcssoves-brand.csstheme-overrides.css - [ ] Brand colors verified: cyan (#00FFFF), navy (#002552) - [ ] Typography: Montserrat (headings), Lato (body) - [ ] All pages return 200 in dev mode - [ ] pnpm build succeeds with output: 'export' - [ ] Generated out/ folder contains all expected routes

Cross-Site Consistency - [ ] Article detail pages use identical layout across all sites - [ ] Product detail pages use identical BoP/BoM hierarchy across all sites - [ ] Footer widgets match all-sites.md Default Footer spec - [ ] Footer "Solutions" widget present on ALL sites with links to all 4 solution sites (mandatory) - [ ] Company homepage includes 4 solution sections with CTAs to each sub-site (mandatory) - [ ] All site-specific deviations documented in respective docs/sites/<site>.md

Phase 3: Content Quality & Editorial

Articles - [ ] All articles reviewed for technical accuracy - [ ] Spelling and grammar checked - [ ] Product names use correct trademarks (OVES™, LUMN™, ovCamp™, etc.) - [ ] External links verified (no 404s) - [ ] Images have descriptive alt text - [ ] Code blocks have language hints for syntax highlighting - [ ] Frontmatter complete and valid YAML

Visual Assets - [ ] Hero images: 1920x1080 minimum, optimized for web - [ ] Feature images: 800x600 recommended, Cloudinary transformations applied - [ ] Product images: Cloudinary URLs with c_fill transformation - [ ] Logo usage: primary logo in headers, no logo proliferation in content

Phase 4: Technical Readiness

Build & Deploy - [ ] All apps/isr/* apps build successfully: pnpm --filter <app> build - [ ] No out/ folders committed to Git (build artifacts excluded via .gitignore) - [ ] Cloudflare Pages projects created for each app (5 total) - [ ] GitHub integration configured for auto-deploy - [ ] Cloudflare Workers router deployed with path-based routing

SEO & Performance - [ ] Canonical URLs defined for all pages (path-based: /off-grid, /mobility, etc.) - [ ] Sitemap generated for each app - [ ] Meta descriptions written for all pages - [ ] Open Graph images configured - [ ] Lighthouse performance score > 90 (desktop)

Operational - [ ] Session journals updated in dirac-uxi/.session.md and oves-sites/.session.md - [ ] Architecture decisions codified in all-sites.md - [ ] All experiments cleaned up and documented (no "quick and dirty" code in production) - [ ] Deployment runbook created (if not using Cloudflare auto-deploy)


Article Development Strategy

Article-domain guidance no longer belongs in this shared foundation document.

Use these article-domain documents instead:

  • docs/articles/object-intents.md
  • docs/articles/collection-intents.md
  • docs/articles/cms-persistence.md

The key cleanup rule is:

  • local article markdown and local collection YAML are staging artifacts
  • cleaned article-domain artifacts must be persisted into CMS through the BFF
  • current scaffold compatibility may continue temporarily, but should not define long-term authority

Theme System Architecture

Design Workflow (Mandatory)

Two-Stage Process: 1. Design Intent → Document in oves-sites/docs/shared/all-sites.md (this file) 2. Implementation → Code in packages/uxi-design-system/themes/oves-brand.css 3. Application → Apps explicitly import theme via @import "@dirac/uxi-design-system/themes/oves-brand.css"

Implementation Requirements (Mandatory)

❌ NEVER use ad-hoc inline styles or arbitrary Tailwind utilities for themed elements

✅ ALWAYS use designated theme classes:

Element Type Theme Class DON'T Use
Primary CTA Buttons .cta-button-primary bg-indigo-500, hover:bg-indigo-400
Secondary Links .secondary-link text-indigo-400 hover:text-indigo-300
Category/Eyebrow Badges .eyebrow-badge bg-gray-800 px-3 py-1 text-gray-300
Article Body Content .article-body text-gray-300 with inline font-weight
Headings (h1-h6) Auto-applied via theme text-white override
Navigation/Footer Links Auto-applied via theme Custom hover colors

Enforcement: - Code reviews must verify theme class usage - New UI elements → Update this doc → Add to theme CSS → Use class - No exceptions without explicit approval and documentation


Brand Assets

Logos

  • Primary Logo (Header): https://res.cloudinary.com/oves/image/upload/v1657359850/logos/oves_logo_words_h50_w3axpd.png
  • Logo Round/Mark: https://res.cloudinary.com/oves/image/upload/v1657359850/logos/oves_logo_round_h50_jg8h8m.png

Favicon

  • Favicon (All Sites): https://res.cloudinary.com/oves/image/upload/v1657359850/logos/oves_logo_round_h50_jg8h8m.png
  • Format: PNG, 50x50px (scales to standard favicon sizes)
  • Implementation: Add to Next.js layout metadata or HTML <head>

Note: Logo files are hosted on Cloudinary account oves

Brand Colors

  • Primary (Logo Brand Color): Cyan (#00FFFF) - matches OVES logo
  • Secondary: Navy Blue (#002552) - logo background
  • Neutrals: Gray scale (50-950)
  • Accent: Light cyan (#5DFFFF)
  • Dark Mode: Native support required

Note: All title colors, primary CTAs, and brand elements should use the logo cyan color (#00FFFF) for consistency

UI Component Styling

Primary CTA Buttons

Design Intent: - Default State: - Background: Navy Blue (#002552) - Text: Cyan (#00FFFF) - Border: 2px solid Cyan (#00FFFF) - Hover State: - Background: Cyan (#00FFFF) - Text: Navy Blue (#002552) - Border: 2px solid Cyan (#00FFFF) - Transition: 0.3s ease for smooth color toggle - Class Name: .cta-button-primary (for implementation reference)

Design Intent: - Header Navigation Links: On hover → Cyan (#00FFFF) - Footer Links (all sections): On hover → Cyan (#00FFFF) - Principle: Consistent brand highlight color across all interactive text elements

Title/Heading Colors

Design Intent: - All headings (h1-h6): Cyan (#00FFFF) - Footer widget titles (h3): Cyan (#00FFFF) - same as other section titles - Eyebrow labels: Cyan (#00FFFF) - Principle: Logo color used for all prominent text elements to reinforce brand identity

Design Intent: - Appearance: Plain text link (no border, no background) - Default State: White text - Hover State: Cyan (#00FFFF) text - Usage: Non-primary navigation links (e.g., "View Solutions →") - Class Name: .secondary-link (for implementation reference)

Eyebrow Badges

Design Intent: - Appearance: Rounded pill/badge above hero titles - Text: Cyan (#00FFFF) - Background: Transparent or subtle dark - Border: Thin ring in muted color (no hover effect) - Usage: Taglines or category labels (e.g., "Electrify the World!") - Behavior: Static (no hover interaction) - Class Name: .eyebrow-badge (for implementation reference)

Article Body Text

Design Intent: - Font: Lato Hairline (weight 100) for paragraphs and list items - Font Size: Base (16px) - Color: Light gray (rgb(229, 231, 235)) - Line Height: Relaxed for readability - Usage: Article detail page body content - Principle: Ultra-light weight creates elegant reading experience on dark backgrounds


Block Theming Pattern

Purpose: Enable reusable blocks to adapt to light or dark contexts via explicit opt-in props rather than ad-hoc class overrides.

Theme Prop Convention

All themeable blocks MUST support a theme prop with these values:

Value Background Text Primary Text Secondary Accent Color Default
'light' white/gray-50 gray-900 gray-500/600 indigo Yes
'dark' gray-900 white gray-300/400 cyan No

Implementation Rules: 1. Default to 'light' — backward compatible with existing light-mode usages 2. Explicit opt-in — consumers must pass theme="dark" for dark contexts 3. No CSS cascade reliance — theme switching via conditional class application, not parent dark-mode class inheritance 4. Accent color alignment — dark mode uses cyan (#00FFFF) to match brand; light mode uses indigo

Themeable Blocks

Block Theme Support Notes
ProductGridSimple theme?: 'light' \| 'dark' Product listing grid with badge support
ProductDetailExpandable theme?: 'light' \| 'dark' Product detail with expandable sections

Usage Example (dark-mode company site):

<ProductGridSimple products={products} theme="dark" />
<ProductDetailExpandable {...productProps} theme="dark" />

Adding Theme Support to New Blocks: 1. Add theme?: 'light' | 'dark' to props interface 2. Default to 'light' in destructuring 3. Create isDark = theme === 'dark' helper 4. Apply conditional classes: isDark ? 'bg-gray-900 text-white' : 'bg-white text-gray-900' 5. Document in this table above


Collapsible UI Pattern

Purpose: Enable multi-section pages to collapse/expand sections without JavaScript, improving scannability for long lists.

Native HTML Pattern

Use native <details>/<summary> elements — zero JS, fully accessible, keyboard-navigable.

<details open={isFirstSection} className="group">
  <summary className="cursor-pointer list-none flex items-center justify-between">
    <span>Section Title</span>
    <svg className="w-5 h-5 transition-transform group-open:rotate-180" ...>
      <path d="M19 9l-7 7-7-7" />
    </svg>
  </summary>
  {/* Section content */}
</details>

Styling Rules: - list-none — removes default disclosure triangle - group-open:rotate-180 — chevron rotates 180° when open - First section open by default; remaining sections collapsed

Current Usage: - Off-grid products grid — collapsible product collection sections


Contact Information

Social Media

  • LinkedIn: https://www.linkedin.com/company/omnivoltaicglobal
  • Twitter/X: https://x.com/Omnivoltaic
  • Facebook: https://www.facebook.com/OmnivoltaicGlobal
  • Instagram: https://www.instagram.com/omnivoltaicglobal
  • TikTok: https://www.tiktok.com/@omnivoltaic_global

Contact Details

  • Email: team_sales@omnivoltaic.com
  • Phone: (Not publicly listed)
  • Address: Design and R&D in the USA with main distribution centres in China, Philippines, Kenya and Togo
  • Partnership Form: https://forms.office.com/r/45vCYswcf4

Default Components

Default Header

Pattern: Logo + Horizontal Navigation Menu

Structure: - Left: Logo (links to homepage) - Center/Right: Navigation menu (site-specific pages) - Style: Clean, minimal, sticky on scroll - Dark mode: Adaptive colors

Navigation: Each site defines own internal navigation menu

CTA Policy (Mandatory): - No CTA buttons in the header nav bar. The header must remain clean: logo + navigation links only. - Partnership/contact CTAs are served exclusively through the footer: - Footer → Company widget → Contact link → Partnership form (https://forms.office.com/r/45vCYswcf4) - Footer → Resources widget → Become a Partner link → Same partnership form - Hero sections on landing pages may include inline CTA buttons (e.g., "Partner with Us") — these are page content, not navigation chrome.


Company Site: Solution Sections (MANDATORY)

Purpose: The company site (/) serves as the suite's entry point, showcasing all four solution portfolios with prominent CTAs.

Pattern: Hero + Alternating Feature Sections (TailwindUI "Feature section with screenshot on alternating sides")

Structure:

// In apps/isr/company/src/app/page.tsx
const solutions = [
  {
    eyebrow: 'E-Mobility',
    heading: 'Electric Mobility Solutions',
    description: 'Electric mobility solutions for urban transport',
    image: 'https://res.cloudinary.com/oves/image/upload/...',
    ctaLabel: 'Explore E-Mobility',
    ctaLink: '/mobility',  // or http://localhost:3101 in dev
  },
  {
    eyebrow: 'Off-Grid Energy',
    heading: 'Solar Home Systems and Energy Access',
    description: 'Solar home systems and energy access for off-grid communities',
    image: 'https://res.cloudinary.com/oves/image/upload/...',
    ctaLabel: 'Explore Off-Grid',
    ctaLink: '/off-grid',  // or http://localhost:3102 in dev
  },
  {
    eyebrow: 'Cross-Grid',
    heading: 'Hybrid Solar and Grid Solutions',
    description: 'Hybrid solar and grid solutions for reliable power',
    image: 'https://res.cloudinary.com/oves/image/upload/...',
    ctaLabel: 'Explore Cross-Grid',
    ctaLink: '/cross-grid',  // or http://localhost:3103 in dev
  },
  {
    eyebrow: 'Productive Use',
    heading: 'Solar-Powered Tools for Income Generation',
    description: 'Solar-powered tools and equipment for small business empowerment',
    image: 'https://res.cloudinary.com/oves/image/upload/...',
    ctaLabel: 'Explore Productive Use',
    ctaLink: '/productive',  // or http://localhost:3104 in dev
  },
];

Layout: - Alternating left/right image placement (even index = image left, odd = image right) - Large hero images (min 1200px wide) - CTA button using .cta-button-primary class

Purpose: Drive traffic to each solution site, establish company as multi-portfolio provider.


Architecture: 6 independently hydrated zones, props-driven with defaults.

Source of truth: oves-sites/docs/shared/footer-widgets.yaml Implementation: @dirac/uxi-design-system/components/SiteFooter.tsx Presets: @dirac/uxi-design-system/lib/footer-widgets.ts


6-Zone Model

Zone Prop Type Default Preset
Logo column logo? FooterLogoProps { src, alt, description } Omnivoltaic logo + brand description
Widget column 1 widget1? FooterWidget { title, items[] } company_sub (includes "Company Home")
Widget column 2 widget2? FooterWidget { title, items[] } resources
Widget column 3 widget3? FooterWidget { title, items[] } connect
Widget column 4 widget4? FooterWidget { title, items[] } solutions
Copyright bar copyright? FooterCopyrightProps { holder, tagline } Omnivoltaic + "Sustainable Energy for All"

All props are optional. Omitting a prop uses the built-in default.


Widget Presets

company_top -- Company site widget1 (no "Company Home" self-link) - About Us, Careers, Press, Contact

company_sub -- Solution site widget1 default (includes "Company Home") - Company Home → /, About Us, Careers, Press, Contact

resources -- widget2 default - Become a Partner → partnership form, Blog/Articles → /articles, Support, Documentation

connect -- widget3 default - LinkedIn, Twitter/X, Facebook, Instagram

solutions -- widget4 default (MANDATORY on all sites) - E-Mobility → /mobility, Off-Grid Energy → /off-grid, Cross-Grid → /cross-grid, Productive Use → /productive


Per-Site Usage

Company site -- overrides widget1 only:

// src/config/site.ts
import { companyTopWidget } from '@dirac/uxi-design-system/lib/footer-widgets';
export const footerWidget1 = companyTopWidget;

// In page files:
<SiteFooter widget1={footerWidget1} siteName={SITE_NAME} devLabel="Port 3100" />

Solution sites -- all defaults, zero config:

// In page files:
<SiteFooter siteName={SITE_NAME} devLabel="Port XXXX" />


CICD Properties

  • Canonical: Widget presets defined once in design system, derived from YAML source of truth
  • Idempotent: Same props = same footer
  • Commutative: Widget zone order is fixed (columns 1-4), but content is independently swappable
  • Decomposable: Each zone is atomic, can be overridden independently without affecting others

Layout

  • Full Footer: Logo + 4 widget columns + copyright bar (used on: grid pages)
  • Minimal Footer: Copyright only (used on: detail pages)
  • Custom: Override any subset of zones via props
  • Trademark notice: "OVES™ · OMNIVOLTAIC® · LUMN™ · OmniTech™ are trademarks of Omnivoltaic Company"
  • Copyright: "Omnivoltaic © [YEAR] | Sustainable Energy for All"
  • Dev mode indicator: "Development Mode - Port [XXXX]" (development only)

Design Tokens

Typography Scale

  • Display: 6xl (60px)
  • Heading 1: 4xl (36px)
  • Heading 2: 3xl (30px)
  • Heading 3: 2xl (24px)
  • Body Large: xl (20px)
  • Body: base (16px)
  • Small: sm (14px)
  • Tiny: xs (12px)

Spacing Scale

  • Container max-width: 1280px
  • Section padding: py-16 (64px) or py-24 (96px)
  • Element gap: gap-4 (16px) to gap-8 (32px)
  • Card padding: p-6 (24px) or p-8 (32px)

Breakpoints

  • Mobile: < 768px
  • Tablet: 768px - 1024px
  • Desktop: > 1024px
  • Wide: > 1280px

Content Guidelines

Voice & Tone

  • Professional yet approachable
  • Confident but not arrogant
  • Africa-focused and context-aware
  • Solution-oriented rather than feature-focused
  • Impact-driven messaging

Writing Style

  • Short, clear sentences
  • Active voice preferred
  • Benefit-focused descriptions
  • Avoid jargon when possible
  • Provide context for technical terms

Terminology Standards

  • "Omnivoltaic" - Always capitalized, never abbreviated to "OV" in public-facing content
  • "Solutions" - Not "products" at corporate level
  • "Clean energy" - Preferred over "renewable energy"
  • Regional entities - Use full name on first mention: "Omnivoltaic Kenya (OVK)"
  • "Company-solution suite" - Internal development term only

Article Categories

Purpose: Provide a stable, multi-dimensional classification system for articles so that each article can be positioned using a small, curated set of category objects.

Model: - Categories are first-class objects with stable IDs, names, descriptions, and optional media. - An article may reference zero or more category IDs in a categories array. - The inverse view ("which articles belong to this category?") is derived at build or query time.

Category Definitions

ID Name Description
category:technology-and-innovation Technology and Innovation Technical architectures, engineering trade-offs, system design, and innovation-focused content.
category:product-features-and-updates Product Features and Updates Articles about specific OVES solutions, feature announcements, and product-oriented deep dives.
category:sustainability-and-impact Sustainability and Impact Environmental and social impact, SDG alignment, and long-term sustainability narratives.
category:customer-stories-and-field-insights Customer Stories and Field Insights Stories and insights from customers, field deployments, and on-the-ground learnings.
category:events-and-activations Events and Activations Conferences, trade shows, campaigns, and key brand activations.
category:careers-and-culture Careers and Culture Roles, hiring, internal culture, and team-related stories.

Article front-matter pattern (example):

---
articleKey: ART-2026-0001
slug: omnivoltaic-emobility-solutions-ovego
# ...other fields...
categories:
  - category:technology-and-innovation
  - category:product-features-and-updates
---
  • Editors choose from the approved category IDs above.
  • New categories must be added here first, then used in article front-matter.

Collections

Purpose: Define reusable, named selections of articles for specific sites or experiences.

Model: - Collections are first-class objects that live outside individual articles. - Each collection has an id, name, optional scope/site, description, and an articles list of slugs. - Articles do not store collection membership; collections point to articles only.

Initial collections (reference YAML):

collections:
  - id: emobility
    name: e-Mobility
    scope: mobility
    description: Articles used on the e-Mobility site's /articles view and related pages.
    articles:
      - omnivoltaic-emobility-solutions-ovego
      - omnivoltaic-emobility-paving-the-way-for-sustainable-urban-transportation
      - electric-drive-train-heart-and-soul-of-emobility
      - path-to-ev-adoption-the-small-is-the-giant
  - id: off_grid
    name: Off-Grid
    scope: off-grid
    description: Articles used on off-grid power /articles views and related pages.
    articles:
      - oasis-series-offgrid-integrated-acdc-power-solutions
      - offgrid-power-convergence-technologies
      - offgrid-power-basics-omnivoltaics-revolutionary-solar-solutions
      - off-grid-world-electrification-is-hapenning
  - id: cross_grid
    name: Cross-Grid
    scope: cross-grid
    description: Articles focused on grid-interactive and cross-grid topics.
    articles: []
  - id: productive_use
    name: Productive-Use
    scope: off-grid
    description: Articles that focus on productive use of energy.
    articles:
      - solar-productive-use-of-energy-with-omnivoltaic
  - id: omnivoltaic_vision
    name: Omnivoltaic Vision
    scope: omnivoltaic
    description: General, technology-focused, and visionary articles for the corporate site.
    articles:
      - about-omnivoltaic-technologies
      - about-omnivoltaic-markets
      - off-grid-world-electrification-is-hapenning
      - offgrid-power-convergence-technologies
      - omnivoltaics-competitive-edge-a-solar-revolution-beyond-the-ordinary
      - omnivoltaic-broad-product-range
      - omnivoltaic-partnerships

Product Collections

Product collections are a first-class product-domain object.

Their definition and retrieval/mutation intent now belongs in:

  • docs/products/product-collections.md

Site documents should express which collections they use. This shared foundation document should not remain the long-term home of product collection object definitions.

Topic Tags

Purpose: Provide lightweight topical hints for search, discovery, and cross-cutting themes, without the strict governance of categories.

Model: - Tags are defined in a central registry as IDs with human-readable labels and notes. - Articles reference tags via a tags array in front-matter, e.g. tags: [e_mobility, battery]. - Only tags defined in this registry should be used in production content.

Tag Registry (initial set)

ID Label Notes
e_mobility e-mobility Electric mobility topics: motorbikes, scooters, tricycles, boats.
ev_adoption EV adoption Adoption patterns and drivers for electric vehicles.
off_grid Off-Grid Off-grid power systems, solutions, and narratives.
solar Solar Solar products, solar-powered solutions, and solar technology.
productive_use Productive use Productive use of energy (PUE) applications and stories.
training Training Training classes, education, and learning content.
markets Markets Market overviews, regional focus, and go-to-market topics.
technologies Technologies Technology overviews, architectures, and technical capabilities.
partnerships Partnerships Partnerships, channels, and global reach.
battery Battery Battery technology, history, and performance characteristics.
amptorrent AmpTORRENT AmpTORRENT product and battery content.
q_and_a Q&As Question-and-answer style articles and FAQs.
bridgeware BridgeWare BridgeWare™ data and integration topics.
omni_pay Omni-Pay Omni-Pay™ and related SaaS/payment models.
saas SaaS SaaS business models and service structures.
affordability Affordability Affordability, pricing, and access topics.
data Data Data, telemetry, and analytics themes.

Image Guidelines

Image Hosting

  • Platform: Cloudinary
  • Base URL: https://res.cloudinary.com/omnivoltaic/image/upload/
  • Optimization: Automatic format selection (WebP, AVIF)
  • Responsive: Use Cloudinary transformations for different sizes

Image Types

  • Hero images: 1920x1080 minimum
  • Card thumbnails: 600x400 recommended
  • Feature images: 800x600 recommended
  • Logos: SVG preferred
  • Icons: SVG or high-res PNG with transparency

Article Media Aesthetic Requirements

Hero Images (Required) - Dimensions: 1920x1080 minimum (16:9 aspect ratio) - Format: JPEG or WebP (prefer WebP for smaller file size) - Content: High-quality photography showing: - Products in context (e.g., solar lantern illuminating a home) - Real-world use cases (e.g., customer using e-motorcycle) - Environmental context (e.g., rural village, urban street) - Style: - Natural lighting preferred (avoid overly staged/studio shots) - Show people when possible (builds connection) - Avoid stock photos with watermarks or generic corporate imagery - Cloudinary Transformations: - Use c_fill,g_auto for intelligent cropping - Apply q_auto for automatic quality optimization - Example: .../image/upload/c_fill,g_auto,w_1920,h_1080,q_auto/v1234/hero.jpg

Feature Images (Optional) - Dimensions: 800x600 (4:3 aspect ratio) - Purpose: - Mid-article visual break - Detail shots of products - Infographics or diagrams - Technical close-ups (e.g., battery pack internals) - Style: Same natural, authentic aesthetic as hero images - Cloudinary Transformations: - Example: .../image/upload/c_fill,g_center,w_800,h_600,q_auto/v1234/feature.jpg

Grid Thumbnails (Auto-Generated) - Articles grid automatically uses hero image with c_fill,g_auto,w_600,h_400 transformation - No separate thumbnail required

Editorial Guidance: - Prefer: Real customer photos, field deployment shots, authentic product usage - Avoid: Generic stock photos, overly polished marketing shots, studio backdrops - Diversity: Show products serving different markets (urban/rural, different regions) - Brand Consistency: OVES cyan accents in images reinforce brand (but not required)

Alt Text

  • Descriptive and concise
  • Include context when relevant
  • Don't start with "Image of..."

SEO Guidelines

Page Titles

  • Format: "[Page Name] | [Site Name] | Omnivoltaic"
  • Length: 50-60 characters
  • Include primary keyword

Meta Descriptions

  • Length: 150-160 characters
  • Clear value proposition
  • Include call-to-action

Heading Structure

  • One H1 per page (page title)
  • Logical H2-H6 hierarchy
  • No heading level skipping

Accessibility Standards

Minimum Requirements

  • Color contrast ratio: 4.5:1 (text), 3:1 (large text)
  • Focus indicators on interactive elements
  • Keyboard navigation support
  • Alt text for all images
  • Semantic HTML structure
  • ARIA labels where appropriate

Dark Mode

  • All content must support dark mode
  • Maintain contrast ratios in dark mode
  • Smooth color transitions
  • No flash/jarring color switches

Technical Standards

Performance

  • First Contentful Paint: < 1.5s
  • Largest Contentful Paint: < 2.5s
  • Time to Interactive: < 3.5s
  • Images: Lazy loading below fold

Framework

  • Next.js 15.1.7
  • React 19.x
  • Tailwind CSS 4.x
  • TypeScript 5.7.x

Data Fetching

  • BFF pattern for CMS content
  • ISR (Incremental Static Regeneration) for pages
  • Server Components default
  • Client Components only when needed

Development Notes

Using This Document

  1. This document defines defaults and shared resources
  2. Site-specific documents reference blocks and assets from here
  3. If a site overrides a default, it must specify completely (no partial overrides)
  4. All new block types must be added to Block Library section
  5. Keep this document updated as standards evolve

Version Control

  • Update version number on changes
  • Document changes in site-specific files that reference this
  • Communicate breaking changes to team

Change Log

v2.1.0 - 2026-01-21 (Static Build Pattern)

  • Added Static Build Pattern documentation (CRITICAL for production)
  • Problem: BFF getProductCollections returns inconsistent counts (52 → 229 → 170 → 51)
  • Solution: Pre-fetch BFF data → Save to data/products.json → Build from local file
  • Implementation: scripts/fetch-products.js + file-based data loading
  • Benefits: Deterministic builds, no BFF calls during SSG, offline-capable, version-controlled data
  • Troubleshooting: Orphaned JSON cleanup, data refresh procedures
  • BFF Endpoint Analysis:
  • getProduct(productKey): BROKEN - 100% failure rate due to productKey mismatch
  • getProductCollections: WORKING but inconsistent - use with static build pattern
  • Purpose: Ensure reliable static site generation despite BFF instability

v2.0.0 - 2026-01-21 (CICD Refactor)

  • BREAKING: Refactored all patterns to CICD principles (Canonical, Idempotent, Commutative, Decomposable)
  • Added CICD Design Philosophy to document header
  • CSS Import Order: Enhanced with intent documentation
  • Added CICD compliance notes (NOT commutative, idempotent, decomposable)
  • Documented cascade intent: Foundation (layers 1-3) → Accumulative (layer 4) → Corrective (layer 5)
  • Each import has purpose comment explaining role in cascade
  • Fixed typo: tailwindcasstailwindcss
  • Default Footer: Refactored into atomic widgets
  • Created 4 atomic widgets: Company, Resources, Connect, Solutions
  • Each widget self-contained with TypeScript export
  • Composition example shows Full Footer = sum of atomic widgets
  • Added CICD properties documentation (canonical, idempotent, commutative, decomposable)
  • Layout flexibility: Full Footer, Minimal Footer, Custom Composition
  • Removed monolithic structure, replaced with atomic + composition pattern
  • Product Detail Page: Refactored into atomic sections
  • Created 3 atomic sections: Product Properties (BoP), Items Included (BoM), Product CTAs
  • Each section self-contained with purpose, content, data source, visual treatment
  • Composition example shows Full Page = sum of atomic sections
  • Added CICD properties documentation
  • Sections can be omitted (e.g., no BoM if product has none)
  • Section order can be changed (commutative)
  • Purpose: Enable atomic component reuse, support partial implementations, clarify cascade/override intent, align with professional design system practices

v1.9.0 - 2026-01-21

  • Added Solution Site Pattern (Canonical and Idempotent):
  • New section documenting the canonical structure for all solution sites (off-grid, cross-grid, mobility, productive)
  • Philosophy: Pattern is canonical (not derived from other sites) and idempotent (produces consistent results regardless of modification history)
  • Defined 5 required pages: root redirect, products grid, product detail, articles grid, article detail
  • Complete site.ts configuration template with all required exports
  • Products grid specification: collapsible sections, responsive grid, BFF data source
  • Product detail specification: BoP/BoM hierarchy, two-column layout, minimal footer
  • Articles grid specification: card layout, local markdown source, collection filtering
  • Article detail specification: prose typography, minimal header/footer, Lato Hairline body text
  • Theme & styling: CSS import order, brand colors, component classes
  • Next.js configuration: static export, basePath, trailingSlash
  • Build & deploy: dev ports, Cloudflare Pages setup
  • Purpose: Eliminate cross-references between site specs ("same as X"), enable idempotent site rebuilds from single source of truth

v1.8.0 - 2026-01-21

  • Codified cross-site navigation structure:
  • Added "Company Site: Solution Sections (MANDATORY)" section documenting homepage solution showcase pattern
  • Updated Default Footer specification with mandatory "Solutions" widget (Column 4)
  • Added "Company Home" link to Solutions widget — enables navigation back to company homepage from all sub-sites
  • Specified exact links for all 5 navigation targets: Company Home (https://omnivoltaic.com), E-Mobility (/mobility), Off-Grid (/off-grid), Cross-Grid (/cross-grid), Productive Use (/productive)
  • Added TypeScript implementation example for footerNavigation.solutions
  • Documented production vs dev URL patterns (canonical paths vs localhost ports)
  • Updated Pre-Deployment Checklist Phase 2 (Cross-Site Consistency):
  • Added: "Footer 'Solutions' widget present on ALL sites with links to all 4 solution sites (mandatory)"
  • Added: "Company homepage includes 4 solution sections with CTAs to each sub-site (mandatory)"
  • Purpose: Ensure suite-wide discoverability — users can navigate between all solution portfolios from any site entry point, including returning to company homepage

v1.7.0 - 2026-01-21

  • Added collection image requirement:
  • Article collections: image field added to the article-collection staging model now represented under docs/articles/collections/*.yaml
  • Product collections: image field added to Product Collections reference YAML
  • Pre-launch requirement: product collection images must be static/local until BFF collections endpoint implemented
  • Updated Pre-Deployment Checklist Phase 1:
  • Added: "Product collection images uploaded to Cloudinary"
  • Added: "Product collection images added to app code as static/local references"
  • Added: "Article collection images uploaded to Cloudinary"
  • Updated validation script: validate-articles.js now validates collection image fields
  • Updated TypeScript schema: ArticleCollection interface requires image: ImageMeta
  • Updated BFF GraphQL examples: collection queries include image { url alt }

v1.6.0 - 2026-01-21

  • Added Pre-Deployment Checklist (4 phases):
  • Phase 1: Data Sources & Content Governance (products, articles)
  • Phase 2: Site Implementation & Consistency (per-site + cross-site)
  • Phase 3: Content Quality & Editorial (articles, visual assets)
  • Phase 4: Technical Readiness (build, deploy, SEO, operational)
  • Added Article Development Strategy:
  • Local-first workflow with BFF intent
  • Article schema as BFF contract (TypeScript interface → GraphQL schema)
  • Drop-in replacement migration path (local files → BFF GraphQL)
  • ETL workflow: author locally → overhaul → mass-upload → refactor apps
  • Added Article Media Aesthetic Requirements:
  • Hero images: 1920x1080, natural/authentic photography, Cloudinary transformations
  • Feature images: 800x600, technical detail shots
  • Editorial guidance: prefer real customer photos over stock imagery
  • Created docs/contracts/article-schema.ts — TypeScript interface as BFF contract reference

v1.5.0 - 2026-01-21

  • Added Header CTA Policy (Mandatory):
  • No CTA buttons in header nav bar — header is logo + nav links only
  • Partnership/contact CTAs served through footer (Company → Contact, Resources → Become a Partner)
  • Hero section inline CTAs are allowed (page content, not nav chrome)
  • Updated Footer: Contact link now points to partnership form URL
  • Added Collapsible UI Pattern section:
  • Native <details>/<summary> pattern for zero-JS collapsible sections
  • Styling rules for chevron rotation and disclosure triangle removal

v1.4.0 - 2026-01-21

  • Added Product Collections section:
  • Defined featured_products collection with 8 flagship products (2 per portfolio)
  • Products: UBP1K Pro, LUMN Sonic (Off-Grid); CIES-6030, CIES-12060 (Cross-Grid); E-3 Pro, CET-1 (Mobility); Solar TV 32", Town™ 10x5 (Productive)
  • Established model: collections reference BFF products by slug

v1.3.0 - 2026-01-21

  • Added Block Theming Pattern section:
  • Defined theme prop convention ('light' | 'dark')
  • Documented implementation rules (default light, explicit opt-in, no CSS cascade)
  • Listed themeable blocks: ProductGridSimple, ProductDetailExpandable
  • Added usage examples and guidance for new blocks

v1.2.0 - 2026-02-13

  • Expanded Deployment Architecture into policy-level guidance:
  • Added canonical URL governance for path-first architecture
  • Added SEO governance requirements (canonical, sitemaps, internal links)
  • Added Cloudflare monorepo project-limit note and growth trigger
  • Added external references for Cloudflare and Google search behavior

v1.0.0 - 2026-01-19

  • Initial foundation meta document created
  • Defined default header and footer patterns
  • Established block library with 9 core block types
  • Set brand assets, design tokens, and content guidelines
  • Documented technical and accessibility standards

This document serves as the foundation for all company-solution suite sites. Any shared configuration, assets, or patterns should be defined here first, then referenced in site-specific documents.