CtaSplit
apps/www/src/sections/CtaSplit.astro · 50 lines · group Call to action
CtaSplit — a call to action with a picture beside it: the hero's shape used mid-page, where it asks for the next step rather than opening the site mid-page.
In the fleet
Used on 1 site built with this engine.
Samples 1
Try it for one seasonSend it back if it does not earn its place.
One station, one gateway, the full dashboard. No installation fee and no contract for the first season.

MDX of this sample
<CtaSplit
title="Try it for one season"
highlight="Send it back if it does not earn its place."
description="One station, one gateway, the full dashboard. No installation fee and no contract for the first season."
image="product-02.jpg"
primaryText="Start the season"
primaryHref="/trial/"
secondaryText="What it costs"
secondaryHref="/pricing/"
/>Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| id | string | |||
| title | string | yes | ||
| highlight | string | accent line rendered in the brand gradient under the title | ||
| description | string | |||
| image | string | |||
| imageSide | 'left' | 'right' | 'right' | ||
| theme | Theme | 'dark' | ||
| primaryText | string | |||
| primaryHref | string | '#' | ||
| secondaryText | string | |||
| secondaryHref | string | '#' |
Source apps/www/src/sections/CtaSplit.astro @ gitt.one
---
/**
* CtaSplit — a call to action with a picture beside it: the hero's shape used
* mid-page, where it asks for the next step rather than opening the site
* mid-page.
*/
import { Image } from 'astro:assets';
import { resolveImage } from '../lib/images';
import Section from './_Section.astro';
import type { Theme } from './_Section.astro';
import Button from './_Button.astro';
interface Props {
id?: string;
title: string;
/** accent line rendered in the brand gradient under the title */
highlight?: string;
description?: string;
image?: string;
imageSide?: 'left' | 'right';
theme?: Theme;
primaryText?: string;
primaryHref?: string;
secondaryText?: string;
secondaryHref?: string;
}
const { id, title, highlight, description, image, imageSide = 'right', theme = 'dark', primaryText, primaryHref = '#', secondaryText, secondaryHref = '#' } = Astro.props;
const left = imageSide === 'left';
const img = image ? await resolveImage(image) : undefined;
---
<Section id={id} theme={theme}>
<div class="lg:grid lg:grid-cols-2 lg:items-center lg:gap-12">
<div class:list={[left && 'lg:order-2']}>
<h2 class="text-3xl font-extrabold tracking-tight sm:text-4xl">
{title}
{highlight && <span class="block bg-gradient-to-r from-primary-300 to-primary-alt-400 bg-clip-text text-transparent [.bg-white_&]:from-primary-500 [.bg-white_&]:to-primary-alt-600">{highlight}</span>}
</h2>
{description && <p class="mt-6 text-xl text-primary-100 [.bg-white_&]:text-gray-500 [.bg-gray-50_&]:text-gray-500">{description}</p>}
{(primaryText || secondaryText) && (
<div class="mt-8 flex flex-wrap gap-4">
{primaryText && <Button href={primaryHref}>{primaryText}</Button>}
{secondaryText && <Button href={secondaryHref} kind="secondary" onDark={theme !== 'light' && theme !== 'muted'}>{secondaryText}</Button>}
</div>
)}
</div>
{img && <Image src={img} alt="" widths={[400, 840, 1280]} class:list={['mt-10 w-full max-h-[26rem] object-contain lg:mt-0', left && 'lg:order-1']} />}
</div>
</Section>Source links point to engine-astro@38c294d9. Samples are demo content: the components are the real ones, the copy and the pictures are made up.