Components Guide. Complete reference for all available components and patterns

Modular Block Components

Themes are built using modular, reusable components that can be mixed and matched across pages. Each block component can be easily imported and customized.

Wrapper

The Wrapper component is a layout utility that standardizes spacing and typography for sections across your site.
It ensures consistent width and styling without having to repeat long Tailwind class strings.

Location: src/components/fundations/containers/Wrapper.astro

Basic Usage

astro
---
import Wrapper from "@/components/fundations/containers/Wrapper.astro";
---

<Wrapper>
  <h2>About Ælen</h2>
  <p>This is a simple section wrapped in the standard layout container.</p>
</Wrapper>

Variants

The component supports a variant prop to switch between different styles:

  • standard (default) → max-width container with padding.
  • prose → Tailwind Typography styles for rich text (e.g., blog posts, docs).
astro
<Wrapper variant="default">
  <h2>Standard Section</h2>
  <p>This uses the default layout wrapper with spacing applied.</p>
</Wrapper>

<Wrapper variant="prose">
  <h2>Prose Section</h2>
  <p>This section uses typography utilities for styled content like <strong>headings</strong>, <a href="#">links</a>, and lists.</p>
</Wrapper>

Additional Props

  • class → Add extra classes to customize spacing or background.
  • id → Assign an ID for anchor links or section navigation.
astro
<Wrapper id="features" class="bg-gray-50 py-12">
  <h2>Features</h2>
  <p>Extend the wrapper with your own utilities.</p>
</Wrapper>

Use the Wrapper whenever you want consistent section layouts, typography, or spacing across your theme.

Button

The Button component provides a flexible, accessible button with support for multiple variants, sizes, icons, and custom styling. It maintains consistency across your theme while offering extensive customization options.

Location: src/components/fundations/elements/Button.astro

Basic Usage

astro
---
import Button from "@/components/fundations/elements/Button.astro";
---

<Button>Click Me</Button>

Props Reference

Prop Type Default Description
variant 'default' | 'muted' | 'none' 'default' Button style variant
size 'xs' | 'sm' | 'base' | 'md' | 'lg' | 'xl' 'base' Button size
gap 'xs' | 'sm' | 'base' | 'md' | 'lg' - Spacing between icons and text
onlyIconSize string - Special sizing for icon-only buttons
class string - Additional CSS classes

Variants

Choose from three pre-built visual styles:

astro
<!-- Default: Black background, white text -->
<Button variant="default">Default Button</Button>

<!-- Muted: White background, black text -->
<Button variant="muted">Muted Button</Button>

<!-- None: No predefined styles (completely customizable) -->
<Button variant="none" class="bg-blue-500 text-background px-4 py-2">
  Custom Styled
</Button>

Sizes

Six size options provide flexible button scaling:

astro
<Button size="xs">Extra Small (h-8)</Button>
<Button size="sm">Small (h-9)</Button>
<Button size="base">Base (h-10)</Button>
<Button size="md">Medium (h-11)</Button>
<Button size="lg">Large (h-12)</Button>
<Button size="xl">Extra Large (h-14)</Button>

Size Details:

  • xs: 32px height, text-xs, px-4 py-2
  • sm: 36px height, text-sm, px-4 py-2
  • base: 40px height, text-base, px-6 py-3
  • md: 44px height, text-base, px-6 py-3
  • lg: 48px height, text-lg, px-6 py-3
  • xl: 56px height, text-xl, px-6 py-3

Using Icons

Add icons before or after button text using named slots:

astro
---
import { ChevronRight, Download, Plus } from "lucide-astro";
---

<!-- Left icon -->
<Button variant="default" size="base" gap="sm">
  <Plus slot="left-icon" size={16} />
  Add Item
</Button>

<!-- Right icon -->
<Button variant="muted" size="md" gap="sm">
  Download
  <Download slot="right-icon" size={18} />
</Button>

<!-- Both icons -->
<Button variant="default" size="lg" gap="base">
  <Plus slot="left-icon" size={20} />
  Create New
  <ChevronRight slot="right-icon" size={20} />
</Button>

Icon Spacing

Control the gap between icons and text with the gap prop:

astro
<Button gap="xs">Tight spacing</Button>    <!-- gap-2 -->
<Button gap="sm">Small spacing</Button>    <!-- gap-4 -->
<Button gap="base">Base spacing</Button>   <!-- gap-8 -->
<Button gap="md">Medium spacing</Button>   <!-- gap-10 -->
<Button gap="lg">Large spacing</Button>    <!-- gap-12 -->

Icon-Only Buttons

For buttons containing only icons, use the onlyIconSize prop:

astro
<Button variant="default" onlyIconSize="w-10 h-10">
  <Plus slot="left-icon" size={20} />
</Button>

Custom Styling

Extend or completely customize button appearance:

astro
<!-- Adding custom classes -->
<Button variant="default" class="shadow-lg hover:shadow-xl">
  Enhanced Button
</Button>

<!-- Complete custom styling with variant="none" -->

<!-- Custom focus styles -->
<Button
  variant="default"
  class="focus:ring-blue-500 focus:ring-4"
>
  Custom Focus
</Button>

Full HTML Button Attributes

The component passes through all standard button attributes:

astro
<Button
  variant="default"
  size="md"
  type="submit"
  disabled={isLoading}
  onclick="handleClick()"
  aria-label="Submit form"
>
  Submit
</Button>

Usage Examples

Call-to-action buttons:

astro
<Button variant="default" size="lg" gap="sm">
  <ChevronRight slot="right-icon" size={20} />
  Get Started
</Button>

Form buttons:

astro
<div class="flex gap-4">
  <Button variant="muted" size="md" type="button">
    Cancel
  </Button>
  <Button variant="default" size="md" type="submit">
    Save Changes
  </Button>
</div>

Icon buttons:

astro
<Button variant="none" class="p-2 hover:bg-gray-100 rounded-full">
  <Heart slot="left-icon" size={20} />
</Button>

Accessibility Notes

The Button component includes built-in accessibility features:

  • Proper focus management with focus:ring-2 and focus:outline-none
  • Keyboard navigation support
  • Screen reader compatibility
  • All standard button ARIA attributes are supported

Always provide meaningful text or aria-label attributes for icon-only buttons to ensure accessibility.

The Link component provides a versatile anchor element that can render as either a styled button-like link or a minimal text link. It shares most of the same props and styling options as the Button component but generates an <a> tag for navigation.

Location: src/components/fundations/elements/Link.astro

Basic Usage

astro
---
import Link from "@/components/fundations/elements/Link.astro";
---

<!-- Simple text link -->
<Button  variant="link" href="/about">About Us</Link>

<!-- Button-styled link -->
<Button  variant="default" href="/contact">Contact</Link>

Props Reference

Prop Type Default Description
href string required URL or path to navigate to
variant 'default' | 'muted' | 'link' 'link' Link style variant
size 'xs' | 'sm' | 'base' | 'md' | 'lg' | 'xl' 'base' Size (only applies to button variants)
gap 'xs' | 'sm' | 'base' | 'md' | 'lg' - Spacing between icons and text
onlyIconSize string - Special sizing for icon-only links
class string - Additional CSS classes

Variants

The Link component offers three distinct styling approaches:

astro
<!-- Link: Minimal text link styling -->
<Button  variant="link" href="/blog">
  Read our blog
</Link>

<!-- Default: Button-like link with dark background -->
<Button  variant="default" href="/signup">
  Sign Up Now
</Link>

<!-- Muted: Button-like link with light background -->
<Button  variant="muted" href="/learn-more">
  Learn More
</Link>

Variant Details:

  • link: Minimal styling with focus:ring-0, perfect for inline text links
  • default: Full button styling (black bg, white text) - identical to Button component
  • muted: Light button styling (white bg, black text) - identical to Button component

The component behaves differently based on the variant:

Text Links (variant="link"):

astro
<!-- Simple, minimal styling -->
<Button  variant="link" href="/home" class="text-blue-600 hover:underline">
  Go Home
</Link>

<!-- In paragraph text -->
<p>
  Visit our <Button  variant="link" href="/features">features page</Link>
  to learn more about what we offer.
</p>

Button-Style Links (variant="default" or variant="muted"):

astro
<!-- Full button styling with sizes -->
<Button  variant="default" size="lg" href="/get-started">
  Get Started
</Link>

<!-- With icons like buttons -->
<Button  variant="muted" size="md" gap="sm" href="/download">
  <Download slot="left-icon" size={18} />
  Download App
</Link>

Sizes (Button Variants Only)

When using default or muted variants, all button sizes are available:

astro
<Button  variant="default" size="xs" href="/quick-action">Quick</Link>
<Button  variant="default" size="sm" href="/small-cta">Small CTA</Link>
<Button  variant="default" size="base" href="/standard">Standard</Link>
<Button  variant="default" size="md" href="/medium">Medium</Link>
<Button  variant="default" size="lg" href="/large-cta">Large CTA</Link>
<Button  variant="default" size="xl" href="/hero-cta">Hero CTA</Link>

Note: The size prop has no effect when variant="link" is used.

Using Icons

Icons work identically to the Button component:

astro
---
import { ExternalLink, ArrowRight, Home } from "lucide-astro";
---

<!-- Text link with icon -->
<Button  variant="link" href="https://example.com" gap="xs">
  External Site
  <ExternalLink slot="right-icon" size={16} />
</Link>

<!-- Button-style link with icons -->
<Button  variant="default" size="md" gap="sm" href="/dashboard">
  <Home slot="left-icon" size={18} />
  Dashboard
  <ArrowRight slot="right-icon" size={18} />
</Link>

<!-- Icon-only link -->
<Button  variant="muted" onlyIconSize="w-10 h-10" href="/profile">
  <User slot="left-icon" size={20} />
</Link>

Internal Navigation:

astro
<!-- Page navigation -->
<Button  variant="link" href="/about">About</Link>
<Button  variant="link" href="/services">Services</Link>
<Button  variant="link" href="/contact">Contact</Link>

<!-- Section navigation -->
<Button  variant="link" href="#features">Jump to Features</Link>

External Links:

astro
<!-- External website -->
<Button  variant="link" href="https://example.com" target="_blank" rel="noopener">
  Visit Example.com
  <ExternalLink slot="right-icon" size={14} />
</Link>

<!-- Social media -->
<Button  variant="muted" size="sm" href="https://twitter.com/yourhandle" target="_blank">
  Follow on Twitter
</Link>

Call-to-Action Links:

astro
<!-- Primary CTA -->
<Button  variant="default" size="lg" href="/signup" gap="sm">
  Start Free Trial
  <ArrowRight slot="right-icon" size={20} />
</Link>

<!-- Secondary CTA -->
<Button  variant="muted" size="md" href="/demo">
  Watch Demo
</Link>

Custom Styling

Extend styling for both variants:

astro
<!-- Custom text link -->
<Button
  variant="link"
  href="/special"
  class="text-purple-600 hover:text-purple-800 font-semibold"
>
  Special Link
</Link>

<!-- Custom button-style link -->
<Button
  variant="default"
  href="/premium"
  class="bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700"
>
  Go Premium
</Link>

HTML Anchor Attributes

All standard anchor attributes are supported:

astro
<Button
  variant="default"
  href="/download"
  download="filename.pdf"
  target="_blank"
  rel="noopener noreferrer"
  title="Download our guide"
>
  Download Guide
</Link>

Usage Guidelines

Use variant="link" for:

  • Inline text links within paragraphs
  • Navigation menus
  • Footer links
  • When you want minimal styling

Use variant="default" or variant="muted" for:

  • Primary call-to-action links
  • Button-like navigation elements
  • When you need consistent button styling
  • Links that should stand out prominently

Accessibility Notes

The Link component maintains excellent accessibility:

  • Proper focus management for all variants
  • Keyboard navigation support
  • Screen reader compatibility
  • All standard anchor ARIA attributes supported
  • External links should include appropriate target and rel attributes

Button

Unified button and link component. Renders an <a> when href is set, otherwise a <button type="button">.

Location: src/components/fundations/elements/Button.tsx

Basic Usage

astro
---
import { Button } from "@/components/fundations/elements/Button";
---

<Button label="Click me" />
<Button href="/contact" label="Contact us" />

Props Reference

Prop Type Default Description
href string - Renders as <a> when set
variant 'solid' | 'solid-light' | 'brand' | 'muted' | 'outline' | 'outline-light' | 'ghost' 'solid' Visual style variant
size 'xs' | 'sm' | 'base' | 'lg' | 'icon' 'base' Element size
block boolean false Full width; label left, optional arrow right
arrow boolean false Show down-right arrow
external boolean false Opens link in a new tab
label string - Button text (or pass children)
className string - Additional CSS classes (use className in Astro, not class)
astro
<!-- Renders <button> -->
<Button variant="solid" size="base">
  Submit form
</Button>

<!-- Renders <a> -->
<Button variant="brand" size="sm" href="/pricing">
  Full access
</Button>

Variants

astro
<Button variant="solid">Solid</Button>
<Button variant="solid-light">Solid light</Button>
<Button variant="brand">Brand</Button>
<Button variant="muted">Muted</Button>
<Button variant="outline">Outline</Button>
<Button variant="outline-light">Outline light</Button>
<Button variant="ghost">Ghost</Button>

Variant details:

  • solid: bg-dark-background text-background — dark ink on light canvas
  • solid-light: bg-background text-foreground — white fill on dark panels
  • brand: bg-brand-light text-white hover:bg-brand-dark — primary brand CTA
  • muted: bg-muted-surface text-foreground — secondary action beside a solid CTA
  • outline: hairline border on light backgrounds
  • outline-light: hairline border on dark or colored panels
  • ghost: quiet toolbar actions; call sites set active colors

Sizes

Five size options:

astro
<Button size="xs">Extra small</Button>
<Button size="sm">Small</Button>
<Button size="base">Base</Button>
<Button size="lg">Large</Button>
<Button size="icon" aria-label="Close">×</Button>

Use size="icon" for square icon-only buttons.

Text

The Text component is a versatile typography utility that provides consistent text styling across your site. It supports multiple HTML tags, responsive font sizes, and semantic markup while maintaining design consistency.

Location: src/components/fundations/elements/Text.astro

Basic Usage

astro
---
import Text from "@/components/fundations/elements/Text.astro";
---

<Text>This is a basic paragraph with default styling.</Text>
<Text variant="textLG">This is larger text.</Text>
<Text tag="h2" variant="displayMD">This is a heading.</Text>

Props Reference

Prop Type Default Description
tag 'a' | 'p' | 'em' | 'span' | 'small' | 'strong' | 'blockquote' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' 'p' HTML element to render
variant See Variants 'textBase' Typography style variant
class string - Additional CSS classes
id string - Element ID attribute
href string - Link URL (only when tag="a")
title string - Title attribute (primarily for links)
ariaLabel string - Aria-label for accessibility
style string - Inline CSS styles

Variants

The Text component offers two categories of variants: Display (large, responsive sizes) and Text (standard body text sizes).

Display Variants (Large, Responsive Typography)

Perfect for headlines, hero text, and major section titles:

astro
<!-- Extra large displays (responsive scaling) -->
<Text tag="h1" variant="display6XL">Hero Title</Text>
<Text tag="h1" variant="display5XL">Main Headline</Text>
<Text tag="h2" variant="display4XL">Section Hero</Text>

<!-- Large displays -->
<Text tag="h2" variant="display3XL">Page Title</Text>
<Text tag="h2" variant="display2XL">Major Heading</Text>
<Text tag="h3" variant="displayXL">Section Title</Text>

<!-- Medium displays -->
<Text tag="h3" variant="displayLG">Subsection Title</Text>
<Text tag="h4" variant="displayMD">Card Title</Text>

<!-- Small displays -->
<Text tag="h4" variant="displaySM">Component Title</Text>
<Text tag="h5" variant="displayXS">Small Heading</Text>

Display Variant Sizes:

  • display6XL: text-6xl sm:text-7xl md:text-9xl lg:text-[12rem]
  • display5XL: text-5xl sm:text-7xl md:text-8xl lg:text-[10rem]
  • display4XL: text-4xl sm:text-7xl md:text-8xl lg:text-9xl
  • display3XL: text-4xl sm:text-6xl md:text-7xl lg:text-8xl
  • display2XL: text-5xl sm:text-5xl md:text-6xl lg:text-7xl
  • displayXL: text-4xl sm:text-4xl md:text-5xl lg:text-6xl
  • displayLG: text-3xl sm:text-3xl md:text-4xl lg:text-5xl
  • displayMD: text-2xl sm:text-2xl md:text-3xl lg:text-4xl
  • displaySM: text-lg sm:text-xl md:text-2xl lg:text-3xl
  • displayXS: text-base sm:text-lg md:text-xl lg:text-2xl

Text Variants (Standard Body Text)

Ideal for body content, UI text, and smaller elements:

astro
<!-- Standard body text -->
<Text variant="textXL">Large body text</Text>
<Text variant="textLG">Medium-large body text</Text>
<Text variant="textBase">Standard body text</Text>

<!-- Smaller text -->
<Text variant="textSM">Small text</Text>
<Text variant="textXS">Extra small text</Text>

Text Variant Sizes:

  • textXL: text-lg sm:text-xl md:text-2xl (responsive)
  • textLG: text-base sm:text-lg md:text-xl (responsive)
  • textBase: text-base (16px baseline)
  • textSM: text-sm (14px)
  • textXS: text-xs (12px)

HTML Tag Options

Choose the appropriate semantic HTML element:

astro
<!-- Headings -->
<Text tag="h1" variant="display4XL">Page Title</Text>
<Text tag="h2" variant="display2XL">Section Title</Text>
<Text tag="h3" variant="displayMD">Subsection</Text>

<!-- Body text -->
<Text tag="p" variant="textBase">Paragraph content</Text>
<Text tag="span" variant="textSM">Inline text</Text>

<!-- Semantic text -->
<Text tag="strong" variant="textBase">Important text</Text>
<Text tag="em" variant="textBase">Emphasized text</Text>
<Text tag="small" variant="textXS">Fine print</Text>

<!-- Quotes -->
<Text tag="blockquote" variant="textLG" class="border-l-4 border-gray-300 pl-4">
  "This is a styled blockquote with proper semantic markup."
</Text>

<!-- Links -->
<Text tag="a" variant="textBase" href="/about" class="text-blue-600 hover:underline">
  About Us
</Text>

Using Icons

The Text component supports icons just like Button and Link components:

astro
---
import IconName from "@/components/fundations/icons/IconName.astro";
---

<!-- Text with left icon -->
<Text variant="textLG" class="flex items-center gap-2">
  <Star  size={20} />
  Featured content
</Text>

<!-- Text with right icon -->
<Text tag="a" variant="textBase" href="/learn-more" class="inline-flex items-center gap-1">
  Learn more
  <ArrowRight slot="right-icon" size={16} />
</Text>

<!-- Text with both icons -->
<Text variant="displaySM" class="flex items-center justify-center gap-3">
  <Info size={24} />
  Important Notice
  <Info  size={24} />
</Text>

Responsive Typography Examples

Leverage the responsive variants for optimal reading experience:

astro
<!-- Hero section -->
<Text tag="h1" variant="display5XL" class="font-bold text-center">
  Welcome to Our Platform
</Text>
<Text tag="p" variant="textXL" class="text-center text-gray-600 mt-4">
  Building amazing experiences for everyone
</Text>

<!-- Article content -->
<Text tag="h2" variant="display2XL" class="font-semibold mb-6">
  Article Title
</Text>
<Text tag="p" variant="textLG" class="mb-4">
  This paragraph uses responsive text sizing that adapts beautifully
  across different screen sizes.
</Text>

Custom Styling

Combine variants with additional classes for enhanced styling:

astro
<!-- Styled headings -->
<Text
  tag="h1"
  variant="display3XL"
  class="font-bold text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-purple-600"
>
  Gradient Heading
</Text>

<!-- Styled body text -->
<Text
  variant="textBase"
  class="text-gray-700 leading-relaxed max-w-prose"
>
  Optimized reading experience with custom line height and max width.
</Text>

<!-- Custom link styling -->
<Text
  tag="a"
  variant="textLG"
  href="/contact"
  class="text-blue-600 hover:text-blue-800 underline decoration-2 underline-offset-4"
>
  Contact Us
</Text>

Common Use Cases

Landing Page Hero:

astro
<Text tag="h1" variant="display6XL" class="font-bold text-center">
  Innovation
</Text>
<Text tag="p" variant="textXL" class="text-center text-gray-600 mt-6">
  Transforming ideas into reality
</Text>

Article Layout:

astro
<Text tag="h1" variant="display3XL" class="font-bold mb-4">
  Article Title
</Text>
<Text tag="p" variant="textSM" class="text-gray-500 mb-8">
  Published on March 15, 2024
</Text>
<Text tag="p" variant="textBase" class="mb-6">
  Article introduction paragraph...
</Text>

Card Components:

astro
<Text tag="h3" variant="displaySM" class="font-semibold mb-2">
  Card Title
</Text>
<Text variant="textSM" class="text-gray-600">
  Card description text
</Text>

Navigation Items:

astro
<Text tag="a" variant="textBase" href="/services" class="hover:text-blue-600">
  Services
</Text>

Accessibility Best Practices

  • Use appropriate heading hierarchy (h1h2h3, etc.)
  • Provide ariaLabel for links when text alone isn’t descriptive enough
  • Use semantic HTML tags (strong, em, blockquote) for proper meaning
  • Ensure sufficient color contrast for all text variants
  • Test responsive text sizes across different devices
astro
<!-- Good heading hierarchy -->
<Text tag="h1" variant="display4XL">Page Title</Text>
<Text tag="h2" variant="display2XL">Main Section</Text>
<Text tag="h3" variant="displayLG">Subsection</Text>

<!-- Accessible link -->
<Text
  tag="a"
  variant="textBase"
  href="/download/report.pdf"
  ariaLabel="Download the annual report PDF"
>
  Download Report
</Text>

Data-Driven Components

For sections like cards, pricing tables, or feature lists, components accept data arrays while preserving customization options:

javascript
const included = [
  {
    title: "No subscription required",
    description: "One-time purchase with lifetime access to updates.",
  },
  {
    title: "Full source code",
    description: "Complete access to all theme files and components.",
  },
  // More items...
];
html
<ul
  class="pt-6 mt-6 border-t grid grid-cols-1 gap-4 lg:gap-12 border-zinc-50 lg:grid-cols-3"
>
  {included.map((item) => (
  <li class="space-y-2">
    <h3 class="font-medium text-foreground">{item.title}</h3>
    <p class="text-zinc-600 text-sm">{item.description}</p>
  </li>
  ))}
</ul>