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

sample

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

NameTypeRequiredDefaultDescription
idstring
titlestringyes
highlightstringaccent line rendered in the brand gradient under the title
descriptionstring
imagestring
imageSide'left' | 'right''right'
themeTheme'dark'
primaryTextstring
primaryHrefstring'#'
secondaryTextstring
secondaryHrefstring'#'

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.