Contact Us

Primitive Components

Visual showcase of core primitive components. Each section demonstrates variants, sizes, and states.

Heading

Semantic headings with visual size decoupling. The level prop sets the HTML element; size overrides visual styling.

h2 styled as 3xl

h2 (default)

h2 styled as xl

h3 (default)

h4 (default)

h5 (default)
h6 (default)
Show code
<Heading level={2} size="3xl">h2 styled as 3xl</Heading>
<Heading level={2}>h2 (default)</Heading>
<Heading level={2} size="xl">h2 styled as xl</Heading>
<Heading level={3}>h3 (default)</Heading>
<Heading level={4}>h4 (default)</Heading>
<Heading level={5}>h5 (default)</Heading>
<Heading level={6}>h6 (default)</Heading>

PageHeading

Lightweight page heading band for route subheaders. Use instead of Hero when no actions, images, or complex layout are needed.

With Subheading

Documentation

Browse docs and showcase pages by topic, type, and audience.

Heading Only

REQ-00042

Show code
{/* With subheading */}
<PageHeading
  heading="Documentation"
  subheading="Browse docs and showcase pages by topic, type, and audience."
/>

{/* Heading only */}
<PageHeading heading="REQ-00042" />

Button

Polymorphic button/link. Renders <a> when href is provided, <button> otherwise. Eleven variants × three sizes.

Standard Variants

Show code
<Button variant="primary">Primary</Button>
<Button variant="outline">Outline</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="secondary-outline">Secondary Outline</Button>
<Button variant="tertiary">Tertiary</Button>
<Button variant="tertiary-outline">Tertiary Outline</Button>
<Button variant="neutral">Neutral</Button>

Sizes

Show code
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>

Border Radius (utility classes)

Border radius is controlled via Tailwind utility classes on class, not a dedicated prop. The Button default radius comes from the component stylesheet; override with utilities as needed.

Show code
<Button class="rounded-none">rounded-none</Button>
<Button class="rounded-sm">rounded-sm</Button>
<Button class="rounded-md">rounded-md</Button>
<Button class="rounded-lg">rounded-lg</Button>
<Button class="rounded-full">rounded-full</Button>

States

Show code
<Button disabled>Disabled</Button>
<Button fullWidth>Full Width</Button>

As Link

Show code
<Button href="#button">Link Button (primary)</Button>
<Button href="#button" variant="outline">Link Button (outline)</Button>

on-primary (on primary surface)

on-secondary (on secondary surface)

on-tertiary (on tertiary surface)

Show contextual code
{/* Place on matching brand surface */}
<LayoutSection background="primary">
  <Button variant="on-primary">On Primary</Button>
</LayoutSection>
<LayoutSection background="secondary">
  <Button variant="on-secondary">On Secondary</Button>
</LayoutSection>
<LayoutSection background="tertiary">
  <Button variant="on-tertiary">On Tertiary</Button>
</LayoutSection>

inverted (on contrast surface)

inverted (on inverted surface)

Show inverted code
<LayoutSection background="contrast">
  <Button variant="inverted">Inverted</Button>
</LayoutSection>
<LayoutSection background="inverted">
  <Button variant="inverted">Inverted</Button>
</LayoutSection>

Token Override (escape hatch)

For rare one-off treatments not covered by the named variants, use tokenOverrides with semantic token references. This example uses status tokens to create an error/destructive action — a case that the eleven named variants do not cover.

Show code
{/* Exceptional: uses tokenOverrides for a destructive action */}
<Button
  tokenOverrides={{
    bg: "var(--st-color-status-error)",
    fg: "var(--st-color-on-status-error)",
    border: "var(--st-color-status-error)",
    bgHover: "var(--st-color-status-error-subtle)",
    fgHover: "var(--st-color-on-status-error)",
  }}
>
  Delete Account
</Button>

LayoutSection

Compositional wrapper that renders a semantic <section> with eight background variants.

Background Variants

default — canvas background

soft — subtle background

strong — emphasized background

contrast — dark background with light text

inverted — fully inverted colors

primary — brand primary

secondary — brand secondary

tertiary — brand tertiary

Show code
<LayoutSection background="default">...</LayoutSection>
<LayoutSection background="soft">...</LayoutSection>
<LayoutSection background="strong">...</LayoutSection>
<LayoutSection background="contrast">...</LayoutSection>
<LayoutSection background="inverted">...</LayoutSection>
<LayoutSection background="primary">...</LayoutSection>
<LayoutSection background="secondary">...</LayoutSection>
<LayoutSection background="tertiary">...</LayoutSection>

SurfaceBox

Lightweight styled <div> with rounded corners and padding. Shares the same background variants as LayoutSection. Use for callouts, panels, and highlighted regions within content flow.

Border Radius

none
xs
sm
md
lg
full
Show code
<SurfaceBox background="strong" class="p-md">none</SurfaceBox>
<SurfaceBox background="strong" class="rounded-xs p-md">xs</SurfaceBox>
<SurfaceBox background="strong" class="rounded-sm p-md">sm</SurfaceBox>
<SurfaceBox background="strong" class="rounded-md p-md">md</SurfaceBox>
<SurfaceBox background="strong" class="rounded-lg p-md">lg</SurfaceBox>
<SurfaceBox background="strong" class="rounded-full p-md">full</SurfaceBox>

Callout Example

A SurfaceBox sits inline with surrounding content.

Callout

This panel uses background="soft" and class="rounded-lg p-md".

Show code
<SurfaceBox background="soft" class="rounded-lg p-md">
  <Heading level={4}>Callout</Heading>
  <p>Your content here.</p>
</SurfaceBox>

Container Size Variants

Resize the browser to see how each container constrains its content at different viewport widths.

content — max-width: var(--pt-layout-content-max) — narrowest, for reading
content-wide — max-width: var(--pt-layout-content-wide-max) — wider content
wide — max-width: var(--pt-layout-container-max) — default for most layouts
full — max-width: 100% — edge-to-edge
Show code
<Container size="content">...</Container>
<Container size="content-wide">...</Container>
<Container size="wide">...</Container>
<Container size="full">...</Container>

Background Contrast

Compare section background variants while keeping the same inner layout framing.

background="soft" — subtle surface treatment for low-emphasis grouping

background="contrast" — high-emphasis surface for callouts and key transitions

Spacing Heights

verticalPadding comparison: same content, different verticalPadding values.

verticalPadding="none" — no padding

verticalPadding="sm" — small

verticalPadding="md" — medium

verticalPadding="lg" — large

verticalPadding="xl" — extra large

verticalPadding="2xl" — 2x large

verticalPadding="3xl" — 3x large

Icon

Inline SVG icons with name-based resolution. Icons inherit currentColor and scale with the size prop.

Utility Icons

bars chevron-down envelope envelope-open external-link
Show code
<Icon name="bars" size="1.5em" />
<Icon name="chevron-down" size="1.5em" />
<Icon name="envelope" size="1.5em" />
<Icon name="envelope-open" size="1.5em" />
<Icon name="external-link" size="1.5em" />

Social Icons

facebook youtube linkedin instagram
Show code
<Icon name="facebook" size="1.5em" />
<Icon name="youtube" size="1.5em" />
<Icon name="linkedin" size="1.5em" />
<Icon name="instagram" size="1.5em" />

Sizes

1em 1.5em 2em 3em
Show code
<Icon name="envelope" size="1em" />
<Icon name="envelope" size="1.5em" />
<Icon name="envelope" size="2em" />
<Icon name="envelope" size="3em" />

Color Inheritance

primary fg secondary fg error
Show code
<span style="color: var(--st-color-brand-primary-fg);">
  <Icon name="envelope" size="2em" />
</span>
<span style="color: var(--st-color-brand-secondary-fg);">
  <Icon name="envelope" size="2em" />
</span>
<span style="color: var(--st-color-status-error);">
  <Icon name="envelope" size="2em" />
</span>

Link for internal navigation, ExternalLink for external URLs with security defaults.

Internal Link

Visit the home page or the design tokens showcase .

Show code
<Link href="/">home page</Link>
<Link href="/theme-docs/showcase/showcase-tokens/">design tokens showcase</Link>

External Link

Learn more at Astro (external link) (default behavior).

Opens in new tab: Astro (external link, opens in new tab) .

Without icon: Astro (external link) .

Show code
{/* default — opens in same tab, shows icon */}
<ExternalLink href="https://astro.build">Astro</ExternalLink>

{/* opens in new tab */}
<ExternalLink href="https://astro.build" target="_blank">Astro</ExternalLink>

{/* without icon */}
<ExternalLink href="https://astro.build" showIcon={false}>Astro</ExternalLink>

Badge

Metadata badges with status-aligned color variants and two sizes.

Variants (md)

Default Success Warning Error Info Primary Secondary Tertiary
Show code
<Badge variant="default">Default</Badge>
<Badge variant="success">Success</Badge>
<Badge variant="warning">Warning</Badge>
<Badge variant="error">Error</Badge>
<Badge variant="info">Info</Badge>
<Badge variant="brand-primary">Primary</Badge>
<Badge variant="brand-secondary">Secondary</Badge>
<Badge variant="brand-tertiary">Tertiary</Badge>

Outline

Outline mode works with high-contrast variants (error, info, brand). Status variants with light backgrounds (default, success, warning) do not meet AA contrast in outline mode.

Error Info Primary Secondary Tertiary
Show code
<Badge variant="error" outline>Error</Badge>
<Badge variant="info" outline>Info</Badge>
<Badge variant="brand-primary" outline>Primary</Badge>
<Badge variant="brand-secondary" outline>Secondary</Badge>
<Badge variant="brand-tertiary" outline>Tertiary</Badge>

Sizes

Small Medium
Show code
<Badge size="sm" variant="info">Small</Badge>
<Badge size="md" variant="info">Medium</Badge>

Outline Sizes

Small Medium

FormatDate

Date formatting with Intl.DateTimeFormat. Renders a semantic <time> element.

short:

long:

iso:

custom:

from string:

Show code
const sampleDate = new Date("2026-03-01");

<FormatDate date={sampleDate} format="short" />
<FormatDate date={sampleDate} format="long" />
<FormatDate date={sampleDate} format="iso" />
<FormatDate
  date={sampleDate}
  options={{ weekday: "long", month: "long", day: "numeric" }}
/>
<FormatDate date="2026-03-01" format="long" />

Vanilla JS dropdown with keyboard navigation and ARIA disclosure semantics.

Show code
<Dropdown label="Actions">
  <button type="button" class="dropdown-item">New post</button>
  <button type="button" class="dropdown-item">Edit</button>
  <button type="button" class="dropdown-item">Duplicate</button>
  <button type="button" class="dropdown-item" disabled>Delete</button>
</Dropdown>

<Dropdown label="Align right" position="bottom-end">
  <button type="button" class="dropdown-item">Option A</button>
  <button type="button" class="dropdown-item">Option B</button>
  <button type="button" class="dropdown-item">Option C</button>
</Dropdown>

Separator

Styled horizontal rule or vertical divider with visual variants.

Variants

default


dotted


dashed


strong


wide (extends beyond content padding)


Show code
<Separator />
<Separator variant="dotted" />
<Separator variant="dashed" />
<Separator variant="strong" />
<Separator variant="wide" />

Vertical

Left Middle Right
Show code
<div class="flex items-center gap-md" style="height: 3rem;">
  <span>Left</span>
  <Separator orientation="vertical" />
  <span>Middle</span>
  <Separator orientation="vertical" variant="dashed" />
  <span>Right</span>
</div>

ButtonGroup

Flex wrapper for grouping multiple Button components with configurable direction, alignment, and gap.

Row (default)

Show code
<ButtonGroup>
  <Button variant="primary">Save</Button>
  <Button variant="outline">Cancel</Button>
  <Button variant="secondary">Reset</Button>
</ButtonGroup>

Column

Show code
<ButtonGroup direction="column" gap="sm">
  <Button variant="primary">Sign Up</Button>
  <Button variant="outline">Learn More</Button>
</ButtonGroup>

Center Aligned

Show code
<ButtonGroup align="center">
  <Button variant="primary">Confirm</Button>
  <Button variant="outline">Cancel</Button>
</ButtonGroup>

Search

Search across pages and articles. Use arrow keys to navigate results.

Search across pages and articles.

Loading search...

Search is unavailable. Please try again later.

    No results for ""

    Try different keywords or fewer words.