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.htmlCTA 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.css → theme.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
compileCssonly touches the first@import url()line so Material Symbols Outlined (loaded second for icon fonts) stays put
Theme blocks
10 blocks for vitrine composition:
| Block | Purpose |
|---|---|
corporate/hero-overlay | Full-bleed hero with image background, eyebrow + title + subtitle + dual CTAs. Flagship home block. |
corporate/hero-split | Two-column hero (image one side, copy + CTAs the other). Sub-pages. |
corporate/services-grid | 3-column card grid — title, description, Material icon. For "Our services" / "Features" sections. |
corporate/cta-banner | Full-width call-to-action band. Title + button. |
corporate/testimonials | Testimonial slider / grid. Variant configurable: "glass" (light, transparent cards) or "primary" (solid coloured panel). |
corporate/trust-bar | Strip of client / partner logos. |
corporate/stats-grid | Number-led stats grid (e.g. "500+ clients", "99.9% uptime"). |
corporate/feature-stack | Vertical list of icon + title + description. |
corporate/contact-info | Address + phone + email + hours + social links. |
corporate/contact-form | Embedded 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 togglecorporate-posts.js— fetches/posts.jsonfor 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
- Editorial / blog: magazine for long-form
- Mixed content / docs: default for versatile reading
- Highly custom layout: install or author your own theme
Continue
- Theme settings — all four tabs
- Theme blocks — corporate block reference
- Pages — static-page home setup
- Default theme / Magazine theme — alternatives