Hero

apps/www/src/sections/Hero.astro · 101 lines · group Hero

Hero — the first screen of a landing. variant="cover" full-bleed photo under a dark multiply overlay (posexpert) variant="split" text left, picture right (or imageSide="left") variant="plain" text only, centered Accepts the gatsby-era skattedosan `Hero` props (subtitle, text, imageName, primaryButtonTitle/Link, brightName) as a migration shim; new content uses the canonical names.

Used by

Live sites: posexpert.se.

Samples 1

posexpert.se/

Custom POS solutions

We develop software for POS terminals, cash registers, and other payment processing devices. We build custom integrations with payment processors, inventory systems, or e-commerce platforms

MDX of this sample
<Hero
  variant="cover"
  image="hero.jpg"
  title="Custom POS solutions"
  description="We develop software for POS terminals, cash registers, and other payment processing devices. We build custom integrations with payment processors, inventory systems, or e-commerce platforms"
  primaryText="Contact us"
  primaryHref="/#contacts"
/>

Props

NameTypeRequiredDefaultDescription
titlestringyes
highlightstringaccent line rendered in the brand gradient under the title
descriptionstring
imagestring
imageSide'left' | 'right'
variant'cover' | 'split' | 'plain'
primaryTextstring
primaryHrefstring
secondaryTextstring
secondaryHrefstring
subtitlestring--- legacy skattedosan props (shim) ---
textstring
imageNamestring
brightNamestring
primaryButtonTitlestring
primaryButtonLinkstring
secondaryButtonTitlestring
secondaryButtonLinkstring

Source apps/www/src/sections/Hero.astro @ gitt.one

---
/**
 * Hero — the first screen of a landing.
 *
 * variant="cover"  full-bleed photo under a dark multiply overlay (posexpert)
 * variant="split"  text left, picture right (or imageSide="left")
 * variant="plain"  text only, centered
 *
 * Accepts the gatsby-era skattedosan `Hero` props (subtitle, text, imageName,
 * primaryButtonTitle/Link, brightName) as a migration shim; new content uses
 * the canonical names.
 */
import { Image } from 'astro:assets';
import { resolveImage } from '../lib/images';
import Button from './_Button.astro';

interface Props {
  title: string;
  /** accent line rendered in the brand gradient under the title */
  highlight?: string;
  description?: string;
  image?: string;
  imageSide?: 'left' | 'right';
  variant?: 'cover' | 'split' | 'plain';
  primaryText?: string;
  primaryHref?: string;
  secondaryText?: string;
  secondaryHref?: string;
  // --- legacy skattedosan props (shim) ---
  subtitle?: string;
  text?: string;
  imageName?: string;
  brightName?: string;
  primaryButtonTitle?: string;
  primaryButtonLink?: string;
  secondaryButtonTitle?: string;
  secondaryButtonLink?: string;
}

const p = Astro.props;
const title = p.title;
const highlight = p.highlight ?? p.subtitle;
const description = p.description ?? p.text;
const imageName = p.image ?? p.imageName;
const variant = p.variant ?? (p.imageName ? 'split' : imageName ? 'cover' : 'plain');
const imageSide = p.imageSide ?? 'right';
const primaryText = p.primaryText ?? p.primaryButtonTitle;
const primaryHref = p.primaryHref ?? p.primaryButtonLink ?? '#';
const secondaryText = p.secondaryText ?? p.secondaryButtonTitle;
const secondaryHref = p.secondaryHref ?? p.secondaryButtonLink ?? '#';

const image = imageName ? await resolveImage(imageName) : undefined;
---

{
  variant === 'cover' ? (
    <section class="relative bg-stone-800 pb-32">
      {image && (
        <div class="absolute inset-0">
          <Image src={image} alt="" widths={[400, 840, 1280, 1680]} loading="eager" fetchpriority="high" class="h-full w-full object-cover" />
          <div class="absolute inset-0 bg-stone-800 mix-blend-multiply" aria-hidden="true" />
        </div>
      )}
      <div class="relative mx-auto max-w-7xl px-4 py-24 sm:px-6 sm:py-32 lg:px-8">
        <h1 class="text-4xl font-extrabold tracking-tight text-white md:text-5xl lg:text-6xl">
          {title}
          {highlight && <span class="block bg-gradient-to-r from-primary-300 to-primary-alt-400 bg-clip-text text-transparent">{highlight}</span>}
        </h1>
        {description && <p class="mt-6 max-w-3xl text-xl text-primary-100">{description}</p>}
        {(primaryText || secondaryText) && (
          <div class="mt-10 flex flex-wrap gap-4">
            {primaryText && <Button href={primaryHref}>{primaryText}</Button>}
            {secondaryText && <Button href={secondaryHref} kind="secondary" onDark>{secondaryText}</Button>}
          </div>
        )}
      </div>
    </section>
  ) : (
    <section class="bg-white px-4 py-16 sm:px-6 sm:py-24 lg:px-8">
      <div class:list={['mx-auto max-w-7xl', variant === 'split' && image ? 'grid items-center gap-12 lg:grid-cols-2' : 'max-w-3xl text-center']}>
        <div class:list={[imageSide === 'left' && 'lg:order-2']}>
          <h1 class="text-4xl font-extrabold tracking-tight text-gray-900 sm:text-5xl lg:text-6xl">
            {title}
            {highlight && <span class="block bg-gradient-to-r from-primary-500 to-primary-alt-600 bg-clip-text text-transparent">{highlight}</span>}
          </h1>
          {description && <p class="mt-6 text-xl text-gray-500">{description}</p>}
          {(primaryText || secondaryText) && (
            <div class:list={['mt-10 flex flex-wrap gap-4', variant === 'plain' && 'justify-center']}>
              {primaryText && <Button href={primaryHref}>{primaryText}</Button>}
              {secondaryText && <Button href={secondaryHref} kind="secondary">{secondaryText}</Button>}
            </div>
          )}
        </div>
        {variant === 'split' && image && (
          <Image src={image} alt="" widths={[400, 840, 1280]} loading="eager" fetchpriority="high" class:list={['w-full rounded-2xl shadow-xl', imageSide === 'left' && 'lg:order-1']} />
        )}
      </div>
    </section>
  )
}

Source links point to engine-astro@e857a859. Samples are cut from the sites' own content by scripts/gallery-extract.mjs; nothing is merged or removed yet.