1 GitHub star = 1 new component.

Star the repo
Heroes

Hero Showcase Split

Dynamic two-column hero with interactive dashboard mockup and theme toggles.

sectionsherolandingshowcasesplit
Live Preview
NEW: ASTRO 5 PRODUCTION SUITE

Craft stunning web apps at lightspeed

A cohesive collection of 150+ dark-mode first, accessible Astro components. Zero dependencies, pure vanilla CSS, full TypeScript support.

$npm install astro-component-kit
astrocomponents.dev/preview
โšก

Production SSR Ready

Zero JavaScript hydration overhead by default.

Score100
A11yAA
Speed0.2s

Usage

Copy and paste this code into your React component:

tsx
import { HeroShowcaseSplit } from 'react-component-kit-ui/sections';

<HeroShowcaseSplit />

Manual Installation

If you are not using the npm package, create a new file and paste the following code: src/components/sections/HeroShowcaseSplit.tsx + HeroShowcaseSplit.css:

HeroShowcaseSplit.tsx
'use client';

import type { ReactNode } from 'react';
import './HeroShowcaseSplit.css';

/**
 * HeroShowcaseSplit โ€” Two-column modern landing hero section with install command, action CTAs, and interactive preview widget.
 * 
 * @param {string} badge - Header lead badge. Default is 'NEW: ASTRO 5 SUITE'.
 * @param {string} title - Primary headline string.
 * @param {string} subtitle - Subtitle paragraph text.
 * @param {string} primaryCtaText - Primary CTA button text.
 * @param {string} primaryCtaHref - Primary CTA link.
 * @param {string} secondaryCtaText - Secondary button text.
 * @param {string} secondaryCtaHref - Secondary link.
 */
export interface HeroShowcaseSplitProps {
  badge?: string;
  title?: string;
  subtitle?: string;
  primaryCtaText?: string;
  primaryCtaHref?: string;
  secondaryCtaText?: string;
  secondaryCtaHref?: string;
  children?: ReactNode;
}

export function HeroShowcaseSplit({
  badge = 'NEW: ASTRO 5 PRODUCTION SUITE',
  title = 'Craft stunning web apps at lightspeed',
  subtitle = 'A cohesive collection of 150+ dark-mode first, accessible Astro components. Zero dependencies, pure vanilla CSS, full TypeScript support.',
  primaryCtaText = 'Explore Components',
  primaryCtaHref = '/docs/glass-button',
  secondaryCtaText = 'View on GitHub',
  secondaryCtaHref = 'https://github.com/konstantinWDK/astro-components',
  children
}: HeroShowcaseSplitProps) {
  return (
    <>
      <div className="cq-hero-showcase-split-cq" data-rk-723e29="">
      <section className="split-hero" data-rk-723e29="">
        <div className="split-hero__inner" data-rk-723e29="">
          <div className="split-hero__content" data-rk-723e29="">
            <div className="split-hero__badge" data-rk-723e29="">
              <span className="dot" data-rk-723e29=""></span>
              <span data-rk-723e29="">{badge}</span>
            </div>
      
            <h1 className="split-hero__title" data-rk-723e29="">{title}</h1>
            <p className="split-hero__subtitle" data-rk-723e29="">{subtitle}</p>
      
            <div className="split-hero__actions" data-rk-723e29="">
              <a href={primaryCtaHref} className="btn btn--primary" data-rk-723e29="">
                {primaryCtaText}
                <span aria-hidden="true" data-rk-723e29="">โ†’</span>
              </a>
              <a href={secondaryCtaHref} target="_blank" rel="noopener" className="btn btn--secondary" data-rk-723e29="">
                {secondaryCtaText}
              </a>
            </div>
      
            <div className="split-hero__install" data-rk-723e29="">
              <span className="prompt" data-rk-723e29="">$</span>
              <code data-rk-723e29="">npm install astro-component-kit</code>
            </div>
          </div>
      
          <div className="split-hero__visual" data-rk-723e29="">
            <div className="glass-device" data-rk-723e29="">
              <div className="glass-device__bar" data-rk-723e29="">
                <span className="d-dot d-dot--red" data-rk-723e29=""></span>
                <span className="d-dot d-dot--yellow" data-rk-723e29=""></span>
                <span className="d-dot d-dot--green" data-rk-723e29=""></span>
                <span className="glass-device__url" data-rk-723e29="">astrocomponents.dev/preview</span>
              </div>
              <div className="glass-device__body" data-rk-723e29="">
                {children ?? (<>
                  <div className="mock-widget" data-rk-723e29="">
                    <span className="mock-icon" data-rk-723e29="">โšก</span>
                    <h4 data-rk-723e29="">Production SSR Ready</h4>
                    <p data-rk-723e29="">Zero JavaScript hydration overhead by default.</p>
                    <div className="mock-metrics" data-rk-723e29="">
                      <div data-rk-723e29=""><span data-rk-723e29="">Score</span><strong data-rk-723e29="">100</strong></div>
                      <div data-rk-723e29=""><span data-rk-723e29="">A11y</span><strong data-rk-723e29="">AA</strong></div>
                      <div data-rk-723e29=""><span data-rk-723e29="">Speed</span><strong data-rk-723e29="">0.2s</strong></div>
                    </div>
                  </div>
                </>)}
              </div>
            </div>
          </div>
        </div>
      </section>
      </div>
    </>
  );
}

export default HeroShowcaseSplit;
HeroShowcaseSplit.css
/* HeroShowcaseSplit โ€” ported from astro-component-kit (sections/HeroShowcaseSplit.astro) */

.cq-hero-showcase-split-cq:where([data-rk-723e29]) { container-type: inline-size; }
.split-hero:where([data-rk-723e29]) {
  position: relative;
  padding: 6rem 1.5rem;
  width: 100%;
  overflow: hidden;
  font-family: var(--font-sans, system-ui, sans-serif);
}

.split-hero__inner:where([data-rk-723e29]) {
  max-width: 1240px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 4rem;
  align-items: center;
}

.split-hero__content:where([data-rk-723e29]) {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.split-hero__badge:where([data-rk-723e29]) {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0.35rem 0.85rem;
  background: color-mix(in srgb, var(--c-primary, #b8860b) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--c-primary, #b8860b) 35%, transparent);
  border-radius: var(--r-full, 9999px);
  font-size: 0.75rem;
  font-weight: 800;
  color: var(--c-accent, #fef3c7);
  margin-bottom: 1.5rem;
  letter-spacing: 0.05em;
}

.split-hero__badge:where([data-rk-723e29]) .dot:where([data-rk-723e29]) {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #d4a017;
  box-shadow: 0 0 8px #d4a017;
}

.split-hero__title:where([data-rk-723e29]) {
  font-size: clamp(2.4rem, 5vw, 3.8rem);
  font-weight: 900;
  line-height: 1.1;
  letter-spacing: -0.04em;
  color: var(--c-text-1, #ffffff);
  margin: 0 0 1.25rem 0;
}

.split-hero__subtitle:where([data-rk-723e29]) {
  font-size: 1.05rem;
  color: var(--c-text-2, #a3a3a3);
  line-height: 1.65;
  margin: 0 0 2rem 0;
  max-width: 540px;
}

.split-hero__actions:where([data-rk-723e29]) {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 2rem;
}

.btn:where([data-rk-723e29]) {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0.85rem 1.8rem;
  font-size: 0.92rem;
  font-weight: 700;
  border-radius: var(--r-md, 12px);
  text-decoration: none;
  transition: all 0.25s ease;
}

.btn--primary:where([data-rk-723e29]) {
  background: linear-gradient(135deg, #d4a017, #b8860b);
  color: #050505;
  box-shadow: 0 4px 20px color-mix(in srgb, var(--c-primary, #b8860b) 35%, transparent);
}
.btn--primary:hover:where([data-rk-723e29]) {
  transform: translateY(-2px);
  box-shadow: 0 8px 30px color-mix(in srgb, var(--c-primary, #b8860b) 50%, transparent);
}

.btn--secondary:where([data-rk-723e29]) {
  background: rgb(var(--ink-rgb, 255 255 255) / 0.04);
  backdrop-filter: blur(12px);
  border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.1);
  color: var(--c-text-1, #ffffff);
}
.btn--secondary:hover:where([data-rk-723e29]) {
  background: rgb(var(--ink-rgb, 255 255 255) / 0.08);
  border-color: rgb(var(--ink-rgb, 255 255 255) / 0.2);
  transform: translateY(-2px);
}

.split-hero__install:where([data-rk-723e29]) {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 0.6rem 1.1rem;
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.08);
  border-radius: var(--r-md, 10px);
  font-family: var(--font-mono, monospace);
  font-size: 0.85rem;
  color: var(--c-primary-light, #d4a017);
}

.split-hero__install:where([data-rk-723e29]) .prompt:where([data-rk-723e29]) {
  color: var(--c-text-3, #737373);
}

/* Visual mock preview container */
.glass-device:where([data-rk-723e29]) {
  background: rgba(14, 14, 18, 0.85);
  backdrop-filter: blur(24px);
  border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.12);
  border-radius: var(--r-xl, 24px);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6);
  overflow: hidden;
}

.glass-device__bar:where([data-rk-723e29]) {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0.8rem 1rem;
  background: rgba(0, 0, 0, 0.3);
  border-bottom: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.06);
}

.d-dot:where([data-rk-723e29]) { width: 10px; height: 10px; border-radius: 50%; }
.d-dot--red:where([data-rk-723e29]) { background: #ef4444; }
.d-dot--yellow:where([data-rk-723e29]) { background: #f59e0b; }
.d-dot--green:where([data-rk-723e29]) { background: #10b981; }

.glass-device__url:where([data-rk-723e29]) {
  margin-left: auto;
  font-size: 0.75rem;
  color: var(--c-text-3, #737373);
  font-family: var(--font-mono, monospace);
}

.glass-device__body:where([data-rk-723e29]) {
  padding: 2.5rem;
}

.mock-widget:where([data-rk-723e29]) {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.mock-icon:where([data-rk-723e29]) {
  font-size: 2.5rem;
  background: color-mix(in srgb, var(--c-primary, #b8860b) 15%, transparent);
  border: 1px solid color-mix(in srgb, var(--c-primary, #b8860b) 30%, transparent);
  width: 64px;
  height: 64px;
  border-radius: 50%;
  display: grid;
  place-items: center;
}

.mock-widget:where([data-rk-723e29]) h4:where([data-rk-723e29]) {
  font-size: 1.25rem;
  font-weight: 800;
  color: var(--c-text-1, #ffffff);
  margin: 0;
}

.mock-widget:where([data-rk-723e29]) p:where([data-rk-723e29]) {
  font-size: 0.85rem;
  color: var(--c-text-2, #a3a3a3);
  margin: 0;
  max-width: 280px;
}

.mock-metrics:where([data-rk-723e29]) {
  display: flex;
  gap: 24px;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.08);
  width: 100%;
  justify-content: center;
}

.mock-metrics:where([data-rk-723e29]) div:where([data-rk-723e29]) {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.mock-metrics:where([data-rk-723e29]) span:where([data-rk-723e29]) { font-size: 0.7rem; color: var(--c-text-3, #737373); text-transform: uppercase; }
.mock-metrics:where([data-rk-723e29]) strong:where([data-rk-723e29]) { font-size: 1.1rem; color: var(--c-primary-light, #d4a017); }

@container (max-width: 900px) {
  .split-hero__inner:where([data-rk-723e29]) {
    grid-template-columns: 1fr;
    gap: 3rem;
  }
}