Skip to main content

Corporate theme

The corporate theme is built for vitrine / lead-generation / SaaS sites — company landings, agency portfolios, product marketing pages. The home is typically a static page composed of theme blocks (hero, services, testimonials, CTA) rather than a list of latest posts.

Visual style

  • Static-page home by default — composed of theme blocks: corporate/hero-overlay + corporate/services-grid + corporate/testimonials + corporate/cta-banner
  • Single-post layout — body in a narrow reading column + sidebar with author bio + popular articles + CTA card
  • Dual-mode header — inline horizontal nav (md+) and burger overlay menu (every viewport)
  • Hardcoded /contact.html CTA in the header — admins should typically have a contact page at that URL (or override the CTA via theme settings)
  • Single-font system — Inter by default, swappable via theme settings
  • Indigo + navy palette — Material 3 colour tokens stored as RGB triplets

CSS pipeline

Same as magazine: Tailwind. scripts/build-theme-tailwind.mjs compiles tailwind.config.cjs + theme.csstheme.compiled.css at prebuild. Manifest ?inline-imports the compiled CSS. compileCss(config) hook regenerates with overrides at upload time.

The corporate Tailwind config's content glob includes .js files (for menu-loader.js and posts-loader.js that contribute class names to runtime-rendered widgets). Without that, Tailwind's purge would strip used classes:

// src/themes/corporate/tailwind.config.cjs
module.exports = {
content: [
"src/themes/corporate/**/*.{ts,tsx,html,js}", // ← .js included
],
// ...
};

If you author a custom theme that ships runtime JS contributing class names to the DOM, mirror this convention.

Settings page

Four tabs: General + Single + Logo + Style.

General tab

  • Header sticky on scroll — toggle (default: true)
  • Header transparent over hero — toggle (default: true on home, false otherwise)

Single tab

Single-post sidebar configuration:

  • Show author bio card — toggle (default: false). When on, renders a card with avatar + name + title + bio + socials.
  • Show popular articles card — toggle (default: true). Renders a card with most-read posts (data from /posts.json).
    • Title — customisable (default "Popular articles" in the active locale)
    • Count — how many posts to show (default 3)
  • Show CTA card — toggle (default: true). The navy "Get Started" callout in the sidebar.
    • Title — text (default: site title or localised "Get started")
    • Button label — text (default: localised "Get started")
    • Button URL — link target (default: /contact.html)

Logo tab

  • Logo image — picker (uploads /theme-assets/corporate-logo.webp)
  • Logo enabled — toggle

Style tab

Single-font system + 22 tokens (Surfaces / Foreground / Outlines / Accent / Spacing / Radius / Typography):

  • Font — single sans family. Picker offers Inter, Plus Jakarta Sans, Outfit, Manrope, DM Sans, Work Sans, IBM Plex Sans
  • The font swap regex in compileCss only touches the first @import url() line so Material Symbols Outlined (loaded second for icon fonts) stays put

Theme blocks

10 blocks for vitrine composition:

BlockPurpose
corporate/hero-overlayFull-bleed hero with image background, eyebrow + title + subtitle + dual CTAs. Flagship home block.
corporate/hero-splitTwo-column hero (image one side, copy + CTAs the other). Sub-pages.
corporate/services-grid3-column card grid — title, description, Material icon. For "Our services" / "Features" sections.
corporate/cta-bannerFull-width call-to-action band. Title + button.
corporate/testimonialsTestimonial slider / grid. Variant configurable: "glass" (light, transparent cards) or "primary" (solid coloured panel).
corporate/trust-barStrip of client / partner logos.
corporate/stats-gridNumber-led stats grid (e.g. "500+ clients", "99.9% uptime").
corporate/feature-stackVertical list of icon + title + description.
corporate/contact-infoAddress + phone + email + hours + social links.
corporate/contact-formEmbedded contact form with formspree-or-mailto submit.

→ See Theme blocks (in the editor) for editing UX.

Contact form runtime

The corporate/contact-form block emits HTML with [data-cms-form] / [data-cms-form-endpoint] / [data-cms-form-mailto] hooks. The runtime corporate-posts.js's wireContactForms() intercepts submit:

  • If a Formspree-compatible endpoint is configured, POSTs urlencoded form data with Accept: application/json. Shows success / error message via [data-cms-form-success] / [data-cms-form-error] siblings.
  • If only a mailto target is configured, opens the user's email client with form values pre-filled.

Floating-label CSS sync (.is-filled class) is also wired so autofill / back-button restore keep labels raised correctly.

Templates

Six templates in src/themes/corporate/templates/:

  • BaseLayout — header (logo + inline nav md+ + burger every viewport + CTA button), footer with company info, body-end sentinel for plugin scripts
  • HomeTemplate — when homeMode: "static-page", renders the chosen page's body verbatim. Otherwise (rare for corporate), falls back to a latest-posts grid.
  • SingleTemplate — full-bleed hero image + meta strip + h1 + 8/4 grid (body + sidebar with author bio / popular / CTA cards)
  • CategoryTemplate — header with description + posts grid (no sidebar)
  • AuthorTemplate — author hero + posts grid
  • NotFoundTemplate — branded 404 with home button

Header — two menus

The corporate header includes two menu hosts:

<!-- Inline horizontal nav (visible md+) -->
<nav data-cms-menu-inline>...</nav>

<!-- Burger overlay menu (every viewport) -->
<nav data-cms-menu="header">...</nav>

The shared menu-loader.js reads the data-cms-menu-inline flag and emits flat <a> links for that host (no <ul>/<li> wrapper) — same /menu.json, two visual presentations.

This means one menu in the admin's Menus page drives both the inline nav and the overlay menu — you don't manage them separately.

Image variants

imageFormats: {
inputFormats: [".jpg", ".jpeg", ".png", ".webp"],
outputFormat: "webp",
quality: 80,
formats: {
small: { width: 480, height: 480, fit: "cover" },
medium: { width: 800, height: 800, fit: "cover" },
large: { width: 1600, height: 900, fit: "cover" },
avatar: { width: 200, height: 200, fit: "cover" },
},
defaultFormat: "medium",
}

The avatar variant (200×200 square) is used for author bio cards in the single-post sidebar.

Companion JS

  • corporate-menu.js — fetches /menu.json, fills [data-cms-menu] AND [data-cms-menu-inline] containers, wires the burger toggle
  • corporate-posts.js — fetches /posts.json for popular-articles cards + wires contact forms

When to use it

  • Company landing pages — hero + value props + testimonials
  • SaaS marketing sites — features grid + CTA banners + lead-gen forms
  • Agency portfolios — services + case studies + contact
  • Product launches — hero with strong CTA + feature explanations + social proof

When to pick a different theme

Continue