---
title: "Patterns"
description: "Patterns, recipes, and working examples."
---

import { getFolder } from '../../lib/content';
import FinderLink from '../../components/FinderLink.astro';

export const folder = await getFolder('patterns');
export const groupedPatterns = folder.folders.map(sub => ({
    slug: sub.slug,
    label: sub.frontmatter.title,
    items: sub.files.map(f => ({
        title: f.frontmatter.title,
        url: f.url,
        description: f.frontmatter.description,
        icon: f.frontmatter.icon || '',
        soon: f.frontmatter.soon || false,
    })),
}));

<div class="not-prose">
    {groupedPatterns.map(group => (
        <section class="mt-10 first:mt-4">
            <h2 id={group.slug} class="flex items-baseline gap-2.5 mb-3 scroll-mt-[calc(var(--header-height)+var(--construction-banner-height,0px)+2rem)]">
                <a href={`#${group.slug}`} class="text-base font-semibold text-neutral-800 dark:text-neutral-100 no-underline interact:underline">
                    {group.label}
                </a>
            </h2>
            <div class="flex flex-col gap-0.5">
                {group.items.map(item => (
                    <FinderLink href={item.soon ? undefined : item.url} data-disabled={item.soon ? '' : undefined} class={item.soon ? 'cursor-not-allowed pointer-events-none opacity-50' : ''}>
                        {item.icon && <i class={`${item.icon} size-5 shrink-0 -translate-y-px group-interact/link:text-white dark:group-interact/link:text-black transition`}></i>}
                        <div class="flex flex-col sm:flex-row sm:items-center gap-1 sm:gap-5 flex-1 min-w-0">
                            <span class="text-sm font-medium sm:min-w-[16ch]">{item.title}</span>
                            {item.description && (
                                <span class="text-sm text-neutral-650 dark:text-neutral-350 group-interact/link:text-white dark:group-interact/link:text-black transition">{item.description}</span>
                            )}
                        </div>
                        {item.soon && (
                            <span class="text-[9px] px-1.5 py-0.5 shrink-0 self-start sm:self-center rounded bg-yellow-300/5 text-yellow-700 dark:text-yellow-300 border border-yellow-600/50 dark:border-yellow-300 font-medium uppercase tracking-wide">Soon</span>
                        )}
                    </FinderLink>
                ))}
            </div>
        </section>
    ))}
</div>
