Panels
# PanelSection
Panels group short facts, notes, contact information or a call to action. Use them directly, in a data-driven grid or as nested rich-text blocks.
<script>
import { PanelSection } from '@page-sections/svelte';
</script>
<PanelSection
section={{
id: 'profile',
title: 'Profile',
headline: 'At a glance',
tone: 'muted',
blocks: [{ type: 'paragraph', text: 'Design and development in Germany.' }],
actions: [
{ label: 'Contact', href: 'mailto:hello@example.com', variant: 'primary' }
]
}}
/> PanelSection props
Required section: Omit<PanelSectionData, 'type'>. Shared SectionDefinition fields apply; additional fields are blocks: RichTextBlock[] (required), tone: standard/muted (default muted), actions: ContentAction[] (optional). The data discriminator is panel. The section headline is rendered once inside the panel and labels the section. Nested panels/text follow the inherited heading hierarchy.
tone selects the panel surface independently of background.color,
which paints the surrounding section. standard uses --ps-section-standard; muted uses --ps-section-muted.
Both follow the active theme. For example, a standard section with a muted panel provides a
distinct inset surface. This API already exists in 0.2.
ContentPanel props
ContentPanel is the lower-level wrapper without a section or registry entry. Optional props: title, titleId, headingLevel (inherited; standalone h2), tone (muted), actions and children: Snippet. Its title increments the level inherited by nested panels. Padding follows the active grid gap; radius, colors and borders follow the theme.
Actions props
Actions accepts optional actions: ContentAction[]. An empty/omitted list renders nothing. Each action has label, href and optional variant: primary/secondary/text (default text). Primary uses accent and onAccent; secondary uses the standard surface. URLs pass through safeHref. Actions are ordinary anchors, available in SSR, and introduce no router or icon-library dependency.
Related: Structured text, Themes, Data models.