# Page Layouts

Build custom Astro pages with Dahlia layout exports.

import { Badge } from '@prosefly/astro-components';

Dahlia exports page-level layout primitives from
`@prosefly/astro-theme-dahlia/layouts`. Use them for custom Astro routes such as
pricing pages, changelogs, landing pages, legal pages, and other pages that
should share the same theme shell without using the docs sidebar layout.

## Exports

| Export | Purpose |
| --- | --- |
| `BaseLayout` | Document shell with Dahlia styles, appearance attributes, metadata, favicon, JSON-LD, and assistant widget support. |
| `SiteHeader` | Shared site header with brand, search, navbar, socials, language selector, and responsive mobile menu. |
| `SiteFooter` | Footer shell using the configured brand, copyright, credits, and footer links. |
| `PageContainer` | Responsive max-width container with Dahlia horizontal page padding. |
| `PageSection` | Page section wrapper with configurable vertical spacing and optional container. |
| `SplashLayout` | Complete splash page layout with site header, hero area, content section, and footer. |
| `TextLayout` | Complete centered prose layout for terms, privacy, and other plain text pages. |

The `/docs/` route uses an internal documentation shell with its own rail,
sub-navigation, table of contents, and responsive behavior. That shell is not
part of the public layout export surface.

## Header Controls

`SiteHeader` is a standalone shell header for custom pages. It accepts
page-level switches for pages that share Dahlia branding and navigation but do
not need the full docs header behavior.

```astro
<SiteHeader
  currentPath="/blog/"
  search={false}
  assistant={false}
  showLanguage={false}
  showSocials={false}
/>
```

Use these props for template pages such as blogs, marketing pages, and custom
dashboards. They do not change the global Dahlia config.

Theme mode is intentionally rendered once by `SiteFooter` as a segmented control
so the header stays focused on navigation and page actions.

## Pricing Page

Use `BaseLayout` when the page needs a custom composition:

```astro title="src/pages/pricing.astro"
---
import {
  BaseLayout,
  PageSection,
  SiteFooter,
  SiteHeader,
} from '@prosefly/astro-theme-dahlia/layouts';
import { Card, CardGrid } from '@prosefly/astro-components';
---

<BaseLayout title="Pricing" description="Choose a plan for your team.">
  <SiteHeader currentPath="/pricing/" />

  <main>
    <PageSection class="text-center" size="lg">
      <p class="text-sm font-medium text-(--dahlia-accent)">Pricing</p>
      <h1 class="mt-3 text-4xl font-semibold text-(--dahlia-text-strong)">
        Plans for every documentation team
      </h1>
      <p class="mx-auto mt-4 max-w-2xl text-(--dahlia-text-muted)">
        Start with the free plan and upgrade when your docs need more workflow.
      </p>
    </PageSection>

    <PageSection padding="md" size="lg">
      <CardGrid>
        <Card icon="lucide:sparkles" title="Starter">
          Publish a polished documentation site with the default Dahlia shell.
        </Card>
        <Card icon="lucide:building-2" title="Team">
          Add search, page actions, contributors, and custom navigation.
        </Card>
      </CardGrid>
    </PageSection>
  </main>

  <SiteFooter />
</BaseLayout>
```

## Splash Page

Use `SplashLayout` when the page matches the built-in hero plus content shape:

```astro
---
import { SplashLayout } from '@prosefly/astro-theme-dahlia/layouts';
---

<SplashLayout
  title="Pricing"
  description="Plans for teams and builders."
  hero={{
    title: 'Pricing',
    tagline: 'Choose the right plan for your docs.',
    actions: [
      { text: 'Get started', link: '/docs/overview/', variant: 'primary' },
    ],
  }}
>
  <p>Use normal Astro, Markdown, or MDX content here.</p>
</SplashLayout>
```

## Text Page

Use `TextLayout` for standalone prose:

```astro
---
import { TextLayout } from '@prosefly/astro-theme-dahlia/layouts';
---

<TextLayout title="Terms" description="Terms for using this service.">
  <p>Terms content goes here.</p>
</TextLayout>
```

## Blog Pages

<Badge variant="subtle" color="warning">New in 0.3.0</Badge>

Blog collections belong in your project, not in Dahlia config. Use Dahlia layouts
and the exported `Prose` component to keep posts visually consistent with docs
pages.

```astro title="src/pages/blog/[...slug].astro"
---
import { getCollection, render } from 'astro:content';
import {
  BaseLayout,
  PageContainer,
  SiteFooter,
  SiteHeader,
} from '@prosefly/astro-theme-dahlia/layouts';
import { Prose } from '@prosefly/astro-theme-dahlia/components';

export async function getStaticPaths() {
  const posts = await getCollection('blog');

  return posts.map((post) => ({
    params: { slug: post.id.replace(/\.mdx?$/, '') },
    props: { post },
  }));
}

const { post } = Astro.props;
const { Content } = await render(post);
---

<BaseLayout title={post.data.title} description={post.data.description}>
  <SiteHeader currentPath="/blog/" search={false} assistant={false} />

  <main class="py-16">
    <PageContainer size="md">
      <header class="mb-10">
        <p class="text-sm font-medium text-(--dahlia-text-muted)">
          {post.data.date.toLocaleDateString()}
        </p>
        <h1 class="mt-3 text-4xl font-semibold text-(--dahlia-text-strong)">
          {post.data.title}
        </h1>
        {post.data.description && (
          <p class="mt-4 text-lg text-(--dahlia-text-muted)">
            {post.data.description}
          </p>
        )}
      </header>

      <Prose>
        <Content />
      </Prose>
    </PageContainer>
  </main>

  <SiteFooter />
</BaseLayout>
```
