<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Aster — Projects and writing, built with Astro</title><description>A minimal Astro template for independent designers and developers, combining project case studies with long-form writing.</description><link>https://astro-template-aster.prosefly.dev/</link><item><title>A Tour of Prosefly&apos;s Astro Components</title><link>https://astro-template-aster.prosefly.dev/blog/astro-components-tour/</link><guid isPermaLink="true">https://astro-template-aster.prosefly.dev/blog/astro-components-tour/</guid><description>A practical tour of every public component, rendered together in one real MDX article.</description><pubDate>Thu, 01 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;@prosefly/astro-components&lt;/code&gt; is the shared MDX layer used by Lotus and Dahlia. It exists because
technical articles regularly need more structure than Markdown provides, but that structure should
not tie the writing to one documentation theme.&lt;/p&gt;
&lt;p&gt;This page renders every public component from version 0.7.1 inside Aster. It is both a tour and a
portability test: Aster supplies its own layouts, typography, colors, and spacing while the package
supplies content structure and focused interactions.&lt;/p&gt;
&lt;div class=&quot;pf-callout&quot; data-has-title=&quot;true&quot; data-type=&quot;note&quot; role=&quot;note&quot; data-astro-cid-yxo7o45t&gt;&lt;span class=&quot;pf-callout__icon&quot; aria-hidden=&quot;true&quot; data-astro-cid-yxo7o45t&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-astro-cid-yxo7o45t=&quot;true&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;/&gt;&lt;path d=&quot;M12 16v-4m0-4h.01&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;div class=&quot;pf-callout__content&quot; data-astro-cid-yxo7o45t&gt;&lt;p class=&quot;pf-callout__title&quot; data-astro-cid-yxo7o45t&gt;One integration&lt;/p&gt;&lt;div class=&quot;pf-callout__slot&quot; data-astro-cid-yxo7o45t&gt;&lt;p&gt;Aster registers &lt;code&gt;proseflyComponents()&lt;/code&gt; once. The integration supplies shared
Markdown transforms, gallery assets, and Iconify preloading.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The examples stay inside one article on purpose. A component can look convincing in an isolated
catalog and still feel too heavy when surrounded by real headings, paragraphs, and code. Seeing the
whole set in sequence makes the intended hierarchy clearer.&lt;/p&gt;
&lt;h2 id=&quot;badges-icons-and-callouts&quot;&gt;Badges, icons, and callouts&lt;/h2&gt;
&lt;p&gt;Badges carry short metadata without interrupting a paragraph:&lt;/p&gt;
&lt;span class=&quot;pf-badge&quot; data-color=&quot;neutral&quot; data-variant=&quot;soft&quot; data-astro-cid-k4cvekrn&gt;Astro 7&lt;/span&gt;
&lt;span class=&quot;pf-badge&quot; data-color=&quot;accent&quot; data-variant=&quot;soft&quot; data-astro-cid-k4cvekrn&gt;MDX&lt;/span&gt;
&lt;span class=&quot;pf-badge&quot; data-color=&quot;success&quot; data-variant=&quot;soft&quot; data-astro-cid-k4cvekrn&gt;Stable&lt;/span&gt;
&lt;span class=&quot;pf-badge&quot; data-color=&quot;warning&quot; data-variant=&quot;soft&quot; data-astro-cid-k4cvekrn&gt;Private&lt;/span&gt;
&lt;p&gt;Icons can be decorative or carry an accessible title. &lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594zM20 2v4m2-2h-4&quot;/&gt;&lt;circle cx=&quot;4&quot; cy=&quot;20&quot; r=&quot;2&quot;/&gt;&lt;/g&gt;&lt;/svg&gt; This icon is
decorative; &lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; focusable=&quot;false&quot; role=&quot;img&quot; data-astro-cid-af3dxg6y&gt;&lt;title&gt;Warning&lt;/title&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m21.73 18l-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3M12 9v4m0 4h.01&quot;/&gt;&lt;/svg&gt; this one announces its meaning.&lt;/p&gt;
&lt;div class=&quot;pf-callout&quot; data-has-title=&quot;true&quot; data-type=&quot;tip&quot; role=&quot;note&quot; data-astro-cid-yxo7o45t&gt;&lt;span class=&quot;pf-callout__icon&quot; aria-hidden=&quot;true&quot; data-astro-cid-yxo7o45t&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-astro-cid-yxo7o45t=&quot;true&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5c1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5c.7.7 1.3 1.5 1.5 2.5m0 4h6m-5 4h4&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;div class=&quot;pf-callout__content&quot; data-astro-cid-yxo7o45t&gt;&lt;p class=&quot;pf-callout__title&quot; data-astro-cid-yxo7o45t&gt;Use the lightest component that explains the idea&lt;/p&gt;&lt;div class=&quot;pf-callout__slot&quot; data-astro-cid-yxo7o45t&gt;&lt;p&gt;A badge labels, an icon cues, and a callout interrupts. Choosing between them
is part of writing the page.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;cards-and-steps&quot;&gt;Cards and steps&lt;/h2&gt;
&lt;div class=&quot;pf-card-grid&quot; data-astro-cid-fydxx5rk&gt;&lt;a class=&quot;pf-card&quot; data-external=&quot;true&quot; data-link=&quot;true&quot; href=&quot;https://astro-theme-lotus.prosefly.dev/&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-card__icon&quot; data-astro-cid-j3hiwsr2&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-astro-cid-j3hiwsr2=&quot;true&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;rect width=&quot;18&quot; height=&quot;18&quot; x=&quot;3&quot; y=&quot;3&quot; rx=&quot;2&quot;/&gt;&lt;path d=&quot;M3 9h18M9 21V9&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Lotus&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;A complete documentation shell with navigation, search, and configurable
design tokens.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;a class=&quot;pf-card&quot; data-external=&quot;true&quot; data-link=&quot;true&quot; href=&quot;https://astro-theme-dahlia.prosefly.dev/&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-card__icon&quot; data-astro-cid-j3hiwsr2&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-astro-cid-j3hiwsr2=&quot;true&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M12 5a3 3 0 1 1 3 3m-3-3a3 3 0 1 0-3 3m3-3v1M9 8a3 3 0 1 0 3 3M9 8h1m5 0a3 3 0 1 1-3 3m3-3h-1m-2 3v-1&quot;/&gt;&lt;circle cx=&quot;12&quot; cy=&quot;8&quot; r=&quot;2&quot;/&gt;&lt;path d=&quot;M12 10v12m0 0c4.2 0 7-1.667 7-5c-4.2 0-7 1.667-7 5m0 0c-4.2 0-7-1.667-7-5c4.2 0 7 1.667 7 5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Dahlia&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;A minimal, content-first theme built on the same component layer.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ol role=&quot;list&quot; class=&quot;pf-steps&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install the package.&lt;/strong&gt;&lt;/p&gt;
&lt;section class=&quot;pf-tabs pf-package-manager-tabs&quot; data-pf-tabs=&quot;&quot; data-sync-key=&quot;package-manager&quot;&gt;&lt;div class=&quot;pf-tabs__header&quot;&gt;&lt;div aria-hidden=&quot;true&quot; class=&quot;pf-tabs__active-icons&quot;&gt;&lt;span class=&quot;pf-tabs__active-icon&quot; data-pf-tabs-icon-for=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-0&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y=&quot;&quot;&gt;&lt;path fill=&quot;currentColor&quot; d=&quot;M0 0v7.5h7.5V0zm8.25 0v7.5h7.498V0zm8.25 0v7.5H24V0zM2 2h3.5v3.5H2zm8.25 0h3.498v3.5H10.25zm8.25 0H22v3.5h-3.5zM8.25 8.25v7.5h7.498v-7.5zm8.25 0v7.5H24v-7.5zm2 2H22v3.5h-3.5zM0 16.5V24h7.5v-7.5zm8.25 0V24h7.498v-7.5zm8.25 0V24H24v-7.5z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-tabs__active-icon&quot; data-pf-tabs-icon-for=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-1&quot; hidden&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y=&quot;&quot;&gt;&lt;path fill=&quot;currentColor&quot; d=&quot;M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l13.837.019l-.009 13.836h-3.464l.01-10.382h-3.456L12.04 19.17H5.113z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-tabs__active-icon&quot; data-pf-tabs-icon-for=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-2&quot; hidden&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y=&quot;&quot;&gt;&lt;path fill=&quot;currentColor&quot; d=&quot;M12 0C5.375 0 0 5.375 0 12s5.375 12 12 12s12-5.375 12-12S18.625 0 12 0m.768 4.105c.183 0 .363.053.525.157c.125.083.287.185.755 1.154c.31-.088.468-.042.551-.019c.204.056.366.19.463.375c.477.917.542 2.553.334 3.605c-.241 1.232-.755 2.029-1.131 2.576c.324.329.778.899 1.117 1.825c.278.774.31 1.478.273 2.015a6 6 0 0 0 .602-.329c.593-.366 1.487-.917 2.553-.931c.714-.009 1.269.445 1.353 1.103a1.23 1.23 0 0 1-.945 1.362c-.649.158-.95.278-1.821.843c-1.232.797-2.539 1.242-3.012 1.39a1.7 1.7 0 0 1-.704.343c-.737.181-3.266.315-3.466.315h-.046c-.783 0-1.214-.241-1.45-.491c-.658.329-1.51.19-2.122-.134a1.08 1.08 0 0 1-.58-1.153a1.2 1.2 0 0 1-.153-.195c-.162-.25-.528-.936-.454-1.946c.056-.723.556-1.367.88-1.71a5.5 5.5 0 0 1 .408-2.256c.306-.727.885-1.348 1.32-1.737c-.32-.537-.644-1.367-.329-2.21c.227-.602.412-.936.82-1.08h-.005c.199-.074.389-.153.486-.259a3.42 3.42 0 0 1 2.298-1.103q.056-.138.125-.283c.31-.658.639-1.029 1.024-1.168a1 1 0 0 1 .328-.06zm.006.7c-.507.016-1.001 1.519-1.001 1.519s-1.27-.204-2.266.871c-.199.218-.468.334-.746.44c-.079.028-.176.023-.417.672c-.371.991.625 2.094.625 2.094s-1.186.839-1.626 1.881c-.486 1.144-.338 2.261-.338 2.261s-.843.732-.899 1.487c-.051.663.139 1.2.343 1.515c.227.343.51.176.51.176s-.561.653-.037.931c.477.25 1.283.394 1.71-.037c.31-.31.371-1.001.486-1.283c.028-.065.12.111.209.199c.097.093.264.195.264.195s-.755.324-.445 1.066c.102.246.468.403 1.066.398c.222-.005 2.664-.139 3.313-.296c.375-.088.505-.283.505-.283s1.566-.431 2.998-1.357c.917-.598 1.293-.76 2.034-.936c.612-.148.57-1.098-.241-1.084c-.839.009-1.575.44-2.196.825c-1.163.718-1.742.672-1.742.672l-.018-.032c-.079-.13.371-1.293-.134-2.678c-.547-1.515-1.413-1.881-1.344-1.997c.297-.5 1.038-1.297 1.334-2.78c.176-.899.13-2.377-.269-3.151c-.074-.144-.732.241-.732.241s-.616-1.371-.788-1.483a.27.27 0 0 0-.157-.046z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-tabs__active-icon&quot; data-pf-tabs-icon-for=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-3&quot; hidden&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y=&quot;&quot;&gt;&lt;path fill=&quot;currentColor&quot; d=&quot;M12 22.596c6.628 0 12-4.338 12-9.688c0-3.318-2.057-6.248-5.219-7.986c-1.286-.715-2.297-1.357-3.139-1.89C14.058 2.025 13.08 1.404 12 1.404c-1.097 0-2.334.785-3.966 1.821a50 50 0 0 1-2.816 1.697C2.057 6.66 0 9.59 0 12.908c0 5.35 5.372 9.687 12 9.687zM10.599 4.715c.334-.759.503-1.58.498-2.409c0-.145.202-.187.23-.029c.658 2.783-.902 4.162-2.057 4.624c-.124.048-.199-.121-.103-.209a5.8 5.8 0 0 0 1.432-1.977m2.058-.102a5.8 5.8 0 0 0-.782-2.306v-.016c-.069-.123.086-.263.185-.172c1.962 2.111 1.307 4.067.556 5.051c-.082.103-.23-.003-.189-.126a5.85 5.85 0 0 0 .23-2.431m1.776-.561a5.7 5.7 0 0 0-1.612-1.806v-.014c-.112-.085-.024-.274.114-.218c2.595 1.087 2.774 3.18 2.459 4.407a.12.12 0 0 1-.049.071a.11.11 0 0 1-.153-.026a.12.12 0 0 1-.022-.083a5.9 5.9 0 0 0-.737-2.331m-5.087.561c-.617.546-1.282.76-2.063 1c-.117 0-.195-.078-.156-.181c1.752-.909 2.376-1.649 2.999-2.778c0 0 .155-.118.188.085c0 .304-.349 1.329-.968 1.874m4.945 11.237a2.96 2.96 0 0 1-.937 1.553c-.346.346-.8.565-1.286.62a2.18 2.18 0 0 1-1.327-.62a2.96 2.96 0 0 1-.925-1.553a.24.24 0 0 1 .064-.198a.23.23 0 0 1 .193-.069h3.965a.23.23 0 0 1 .19.07c.05.053.073.125.063.197m-5.458-2.176a1.86 1.86 0 0 1-2.384-.245a1.98 1.98 0 0 1-.233-2.447c.207-.319.503-.566.848-.713a1.84 1.84 0 0 1 1.092-.11c.366.075.703.261.967.531a1.98 1.98 0 0 1 .408 2.114a1.93 1.93 0 0 1-.698.869zm8.495.005a1.86 1.86 0 0 1-2.381-.253a1.96 1.96 0 0 1-.547-1.366c0-.384.11-.76.32-1.079c.207-.319.503-.567.849-.713a1.84 1.84 0 0 1 1.093-.108c.367.076.704.262.968.534a1.98 1.98 0 0 1 .4 2.117a1.93 1.93 0 0 1-.702.868&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/div&gt;&lt;div aria-label=&quot;Tabs&quot; class=&quot;pf-tabs__list&quot; role=&quot;tablist&quot;&gt;&lt;button aria-controls=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-0&quot; aria-selected=&quot;true&quot; class=&quot;pf-tabs__trigger&quot; data-pf-tabs-trigger=&quot;&quot; data-tab-label=&quot;pnpm&quot; data-tab-panel=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-0&quot; data-tab-value=&quot;pnpm&quot; id=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-tab-0&quot; role=&quot;tab&quot; tabindex=&quot;0&quot; type=&quot;button&quot;&gt;pnpm&lt;/button&gt;&lt;button aria-controls=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-1&quot; aria-selected=&quot;false&quot; class=&quot;pf-tabs__trigger&quot; data-pf-tabs-trigger=&quot;&quot; data-tab-label=&quot;npm&quot; data-tab-panel=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-1&quot; data-tab-value=&quot;npm&quot; id=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-tab-1&quot; role=&quot;tab&quot; tabindex=&quot;-1&quot; type=&quot;button&quot;&gt;npm&lt;/button&gt;&lt;button aria-controls=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-2&quot; aria-selected=&quot;false&quot; class=&quot;pf-tabs__trigger&quot; data-pf-tabs-trigger=&quot;&quot; data-tab-label=&quot;yarn&quot; data-tab-panel=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-2&quot; data-tab-value=&quot;yarn&quot; id=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-tab-2&quot; role=&quot;tab&quot; tabindex=&quot;-1&quot; type=&quot;button&quot;&gt;yarn&lt;/button&gt;&lt;button aria-controls=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-3&quot; aria-selected=&quot;false&quot; class=&quot;pf-tabs__trigger&quot; data-pf-tabs-trigger=&quot;&quot; data-tab-label=&quot;bun&quot; data-tab-panel=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-3&quot; data-tab-value=&quot;bun&quot; id=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-tab-3&quot; role=&quot;tab&quot; tabindex=&quot;-1&quot; type=&quot;button&quot;&gt;bun&lt;/button&gt;&lt;/div&gt;&lt;button aria-label=&quot;Copy code&quot; class=&quot;pf-tabs__copy&quot; data-pf-tabs-copy=&quot;&quot; title=&quot;Copy code&quot; type=&quot;button&quot;&gt;&lt;span class=&quot;pf-tabs__copy-icon&quot; data-pf-tabs-copy-icon=&quot;copy&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y=&quot;&quot;&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;rect width=&quot;14&quot; height=&quot;14&quot; x=&quot;8&quot; y=&quot;8&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-tabs__copy-icon&quot; data-pf-tabs-copy-icon=&quot;check&quot; hidden&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y=&quot;&quot;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M20 6L9 17l-5-5&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;&lt;/div&gt;&lt;div class=&quot;pf-tabs__panels&quot;&gt;&lt;div aria-labelledby=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-tab-0&quot; class=&quot;pf-tabs__panel&quot; id=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-0&quot; role=&quot;tabpanel&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#6F42C1;--shiki-dark:#B392F0&quot;&gt;pnpm&lt;/span&gt;&lt;span style=&quot;--shiki-light:#032F62;--shiki-dark:#9ECBFF&quot;&gt; add&lt;/span&gt;&lt;span style=&quot;--shiki-light:#032F62;--shiki-dark:#9ECBFF&quot;&gt; @prosefly/astro-components&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div aria-labelledby=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-tab-1&quot; class=&quot;pf-tabs__panel&quot; hidden id=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-1&quot; role=&quot;tabpanel&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#6F42C1;--shiki-dark:#B392F0&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;--shiki-light:#032F62;--shiki-dark:#9ECBFF&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;--shiki-light:#032F62;--shiki-dark:#9ECBFF&quot;&gt; @prosefly/astro-components&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div aria-labelledby=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-tab-2&quot; class=&quot;pf-tabs__panel&quot; hidden id=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-2&quot; role=&quot;tabpanel&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#6F42C1;--shiki-dark:#B392F0&quot;&gt;yarn&lt;/span&gt;&lt;span style=&quot;--shiki-light:#032F62;--shiki-dark:#9ECBFF&quot;&gt; add&lt;/span&gt;&lt;span style=&quot;--shiki-light:#032F62;--shiki-dark:#9ECBFF&quot;&gt; @prosefly/astro-components&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div aria-labelledby=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-tab-3&quot; class=&quot;pf-tabs__panel&quot; hidden id=&quot;pf-tabs-74421bf6-9fc6-46c7-9eb2-01516663aa3d-panel-3&quot; role=&quot;tabpanel&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#6F42C1;--shiki-dark:#B392F0&quot;&gt;bun&lt;/span&gt;&lt;span style=&quot;--shiki-light:#032F62;--shiki-dark:#9ECBFF&quot;&gt; add&lt;/span&gt;&lt;span style=&quot;--shiki-light:#032F62;--shiki-dark:#9ECBFF&quot;&gt; @prosefly/astro-components&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Register the integration.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Add &lt;code&gt;proseflyComponents()&lt;/code&gt; to &lt;code&gt;astro.config.mjs&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Import components in MDX.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Keep ordinary prose in Markdown and reach for components only when structure helps.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;tabs-and-accordions&quot;&gt;Tabs and accordions&lt;/h2&gt;
&lt;p&gt;Tabs work well when several commands complete the same task.&lt;/p&gt;
&lt;section class=&quot;pf-tabs&quot; data-pf-tabs data-sync-key=&quot;install-components&quot;&gt;&lt;div class=&quot;pf-tabs__header&quot;&gt;&lt;div aria-hidden=&quot;true&quot; class=&quot;pf-tabs__active-icons&quot;&gt;&lt;span class=&quot;pf-tabs__active-icon&quot; data-pf-tabs-icon-for=&quot;pf-tabs-0bb6c7dc-1b34-4766-8264-2a193b4c3c83-panel-0&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;currentColor&quot; d=&quot;M0 0v7.5h7.5V0zm8.25 0v7.5h7.498V0zm8.25 0v7.5H24V0zM2 2h3.5v3.5H2zm8.25 0h3.498v3.5H10.25zm8.25 0H22v3.5h-3.5zM8.25 8.25v7.5h7.498v-7.5zm8.25 0v7.5H24v-7.5zm2 2H22v3.5h-3.5zM0 16.5V24h7.5v-7.5zm8.25 0V24h7.498v-7.5zm8.25 0V24H24v-7.5z&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-tabs__active-icon&quot; data-pf-tabs-icon-for=&quot;pf-tabs-0bb6c7dc-1b34-4766-8264-2a193b4c3c83-panel-1&quot; hidden&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;currentColor&quot; d=&quot;M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l13.837.019l-.009 13.836h-3.464l.01-10.382h-3.456L12.04 19.17H5.113z&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/div&gt;&lt;div aria-label=&quot;Tabs&quot; class=&quot;pf-tabs__list&quot; role=&quot;tablist&quot;&gt;&lt;button aria-controls=&quot;pf-tabs-0bb6c7dc-1b34-4766-8264-2a193b4c3c83-panel-0&quot; aria-selected=&quot;true&quot; class=&quot;pf-tabs__trigger&quot; data-pf-tabs-trigger data-tab-label=&quot;pnpm&quot; data-tab-panel=&quot;pf-tabs-0bb6c7dc-1b34-4766-8264-2a193b4c3c83-panel-0&quot; data-tab-value=&quot;pnpm&quot; id=&quot;pf-tabs-0bb6c7dc-1b34-4766-8264-2a193b4c3c83-tab-0&quot; role=&quot;tab&quot; tabindex=&quot;0&quot; type=&quot;button&quot;&gt;pnpm&lt;/button&gt;&lt;button aria-controls=&quot;pf-tabs-0bb6c7dc-1b34-4766-8264-2a193b4c3c83-panel-1&quot; aria-selected=&quot;false&quot; class=&quot;pf-tabs__trigger&quot; data-pf-tabs-trigger data-tab-label=&quot;npm&quot; data-tab-panel=&quot;pf-tabs-0bb6c7dc-1b34-4766-8264-2a193b4c3c83-panel-1&quot; data-tab-value=&quot;npm&quot; id=&quot;pf-tabs-0bb6c7dc-1b34-4766-8264-2a193b4c3c83-tab-1&quot; role=&quot;tab&quot; tabindex=&quot;-1&quot; type=&quot;button&quot;&gt;npm&lt;/button&gt;&lt;/div&gt;&lt;button aria-label=&quot;Copy code&quot; class=&quot;pf-tabs__copy&quot; data-pf-tabs-copy title=&quot;Copy code&quot; type=&quot;button&quot;&gt;&lt;span class=&quot;pf-tabs__copy-icon&quot; data-pf-tabs-copy-icon=&quot;copy&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;rect width=&quot;14&quot; height=&quot;14&quot; x=&quot;8&quot; y=&quot;8&quot; rx=&quot;2&quot; ry=&quot;2&quot;/&gt;&lt;path d=&quot;M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-tabs__copy-icon&quot; data-pf-tabs-copy-icon=&quot;check&quot; hidden&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M20 6L9 17l-5-5&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;&lt;/div&gt;&lt;div class=&quot;pf-tabs__panels&quot;&gt;&lt;div aria-labelledby=&quot;pf-tabs-0bb6c7dc-1b34-4766-8264-2a193b4c3c83-tab-0&quot; class=&quot;pf-tabs__panel&quot; id=&quot;pf-tabs-0bb6c7dc-1b34-4766-8264-2a193b4c3c83-panel-0&quot; role=&quot;tabpanel&quot; tabindex=&quot;0&quot;&gt;&lt;pre&gt;&lt;code&gt;pnpm add @prosefly/astro-components&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div aria-labelledby=&quot;pf-tabs-0bb6c7dc-1b34-4766-8264-2a193b4c3c83-tab-1&quot; class=&quot;pf-tabs__panel&quot; hidden id=&quot;pf-tabs-0bb6c7dc-1b34-4766-8264-2a193b4c3c83-panel-1&quot; role=&quot;tabpanel&quot; tabindex=&quot;0&quot;&gt;&lt;pre&gt;&lt;code&gt;npm install @prosefly/astro-components&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;
&lt;p&gt;Accordions keep optional answers available without lengthening the main path.&lt;/p&gt;
&lt;div class=&quot;pf-accordions&quot; data-default-values=&quot;[]&quot; data-pf-accordions&gt;&lt;details class=&quot;pf-accordion&quot; data-pf-accordion data-value=&quot;Can the components work without Lotus or Dahlia?&quot;&gt;&lt;summary class=&quot;pf-accordion__trigger&quot; data-pf-accordion-trigger&gt;&lt;span class=&quot;pf-accordion__title&quot;&gt;Can the components work without Lotus or Dahlia?&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-accordion__chevron&quot;&gt;&lt;svg fill=&quot;none&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; width=&quot;16&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/summary&gt;&lt;div class=&quot;pf-accordion__content&quot;&gt;&lt;p&gt;Yes. Register the shared integration and map the semantic Prosefly CSS
properties to the surrounding site’s design tokens.&lt;/p&gt;&lt;/div&gt;&lt;/details&gt;&lt;details class=&quot;pf-accordion&quot; data-pf-accordion data-value=&quot;Do Prosefly themes need extra setup?&quot;&gt;&lt;summary class=&quot;pf-accordion__trigger&quot; data-pf-accordion-trigger&gt;&lt;span class=&quot;pf-accordion__title&quot;&gt;Do Prosefly themes need extra setup?&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-accordion__chevron&quot;&gt;&lt;svg fill=&quot;none&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; width=&quot;16&quot;&gt;&lt;path d=&quot;m6 9 6 6 6-6&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/summary&gt;&lt;div class=&quot;pf-accordion__content&quot;&gt;&lt;p&gt;No. Lotus and Dahlia already register the integration and expose the shared
components to their MDX content.&lt;/p&gt;&lt;/div&gt;&lt;/details&gt;&lt;/div&gt;
&lt;h2 id=&quot;file-trees&quot;&gt;File trees&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;FileTree&lt;/code&gt; turns a single Markdown list into an expandable project map.&lt;/p&gt;
&lt;ul class=&quot;pf-file-tree&quot; data-icon-set=&quot;lucide&quot; role=&quot;list&quot;&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;directory&quot;&gt;&lt;details class=&quot;pf-file-tree__details&quot; open&gt;&lt;summary class=&quot;pf-file-tree__summary&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__chevron&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m9 18l6-6l-6-6&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;directory&quot;&gt;&lt;span class=&quot;pf-file-tree__icon-closed&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__icon-open&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m6 14l1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;&lt;span class=&quot;pf-file-tree__sr-only&quot;&gt;Directory &lt;/span&gt;src&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/summary&gt;&lt;ul class=&quot;pf-file-tree__list&quot; role=&quot;list&quot;&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;directory&quot;&gt;&lt;details class=&quot;pf-file-tree__details&quot; open&gt;&lt;summary class=&quot;pf-file-tree__summary&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__chevron&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m9 18l6-6l-6-6&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;directory&quot;&gt;&lt;span class=&quot;pf-file-tree__icon-closed&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__icon-open&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m6 14l1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;&lt;span class=&quot;pf-file-tree__sr-only&quot;&gt;Directory &lt;/span&gt;content&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/summary&gt;&lt;ul class=&quot;pf-file-tree__list&quot; role=&quot;list&quot;&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;directory&quot;&gt;&lt;details class=&quot;pf-file-tree__details&quot; open&gt;&lt;summary class=&quot;pf-file-tree__summary&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__chevron&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m9 18l6-6l-6-6&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;directory&quot;&gt;&lt;span class=&quot;pf-file-tree__icon-closed&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__icon-open&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m6 14l1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;&lt;span class=&quot;pf-file-tree__sr-only&quot;&gt;Directory &lt;/span&gt;blog&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/summary&gt;&lt;ul class=&quot;pf-file-tree__list&quot; role=&quot;list&quot;&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot; data-highlighted=&quot;true&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot; data-highlighted=&quot;true&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;text&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5M10 9H8m8 4H8m8 4H8&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;&lt;strong&gt;astro-components-tour.mdx&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/details&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;file&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;projects&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/details&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;code&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5m-10 4.5L8 15l2 2.5m4-5l2 2.5l-2 2.5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;content.config.ts&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;file&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;pages&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/details&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;config&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 8a1 1 0 0 1-1-1V2a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8zm5 0v12a2 2 0 0 1-2 2h-4.182M3.305 19.53l.923-.382M4 10.592V4a2 2 0 0 1 2-2h8M4.228 16.852l-.924-.383m2.548-1.241l-.383-.923m.383 6.467l-.383.924m2.679-6.468l.383-.923m-.001 7.391l-.382-.924m1.625-3.92l.922-.383m-.922 2.679l.922.383&quot;/&gt;&lt;circle cx=&quot;7&quot; cy=&quot;18&quot; r=&quot;3&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;astro.config.mjs&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;config&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 8a1 1 0 0 1-1-1V2a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8zm5 0v12a2 2 0 0 1-2 2h-4.182M3.305 19.53l.923-.382M4 10.592V4a2 2 0 0 1 2-2h8M4.228 16.852l-.924-.383m2.548-1.241l-.383-.923m.383 6.467l-.383.924m2.679-6.468l.383-.923m-.001 7.391l-.382-.924m1.625-3.92l.922-.383m-.922 2.679l.922.383&quot;/&gt;&lt;circle cx=&quot;7&quot; cy=&quot;18&quot; r=&quot;3&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;package.json&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id=&quot;image-galleries&quot;&gt;Image galleries&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ImageGallery&lt;/code&gt; keeps related screenshots together and owns its responsive browser behavior.&lt;/p&gt;
&lt;figure class=&quot;pf-image-gallery&quot; data-image-count=&quot;2&quot; data-astro-cid-jrbjkjkd&gt;&lt;pf-image-gallery data-astro-cid-jrbjkjkd=&quot;true&quot;&gt;&lt;div class=&quot;pf-image-gallery__track&quot; data-pf-image-gallery-track data-astro-cid-jrbjkjkd&gt;&lt;span class=&quot;pf-image-gallery__item&quot; data-astro-cid-jrbjkjkd&gt;&lt;img src=&quot;https://raw.githubusercontent.com/prosefly/astro-theme-lotus/main/.github/assets/light-dark.png&quot; alt=&quot;Lotus documentation theme shown in light and dark
modes&quot;&gt;&lt;/span&gt;&lt;span class=&quot;pf-image-gallery__item&quot; data-astro-cid-jrbjkjkd&gt;&lt;img src=&quot;https://raw.githubusercontent.com/prosefly/astro-theme-dahlia/main/public/images/og.jpg&quot; alt=&quot;Dahlia documentation theme social
preview&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;pf-image-gallery__footer&quot; data-astro-cid-jrbjkjkd&gt;&lt;span aria-live=&quot;polite&quot; aria-atomic=&quot;true&quot; class=&quot;pf-image-gallery__caption&quot; data-pf-image-gallery-caption data-astro-cid-jrbjkjkd&gt;Lotus documentation theme shown in light and dark
modes&lt;/span&gt;&lt;div class=&quot;pf-image-gallery__navigation&quot; data-astro-cid-jrbjkjkd&gt;&lt;button aria-label=&quot;Previous image&quot; class=&quot;pf-image-gallery__button&quot; data-pf-image-gallery-button=&quot;previous&quot; disabled type=&quot;button&quot; data-astro-cid-jrbjkjkd&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-astro-cid-jrbjkjkd=&quot;true&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m12 19l-7-7l7-7m7 7H5&quot;/&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button aria-label=&quot;Next image&quot; class=&quot;pf-image-gallery__button&quot; data-pf-image-gallery-button=&quot;next&quot; type=&quot;button&quot; data-astro-cid-jrbjkjkd&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-astro-cid-jrbjkjkd=&quot;true&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M5 12h14m-7-7l7 7l-7 7&quot;/&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pf-image-gallery&gt;&lt;/figure&gt;
&lt;h2 id=&quot;rich-links-and-audio&quot;&gt;Rich links and audio&lt;/h2&gt;
&lt;p&gt;Supplying complete metadata lets &lt;code&gt;Embed&lt;/code&gt; render a link card without fetching the destination
during the build.&lt;/p&gt;
&lt;figure class=&quot;pf-embed&quot; data-pf-embed-kind=&quot;link&quot; data-pf-embed-source=&quot;props&quot;&gt;&lt;a class=&quot;pf-embed__card&quot; href=&quot;https://astro-theme-lotus.prosefly.dev/&quot; rel=&quot;noreferrer&quot; target=&quot;_blank&quot;&gt;&lt;div class=&quot;pf-embed__image&quot;&gt;&lt;img alt=&quot;&quot; decoding=&quot;async&quot; loading=&quot;lazy&quot; src=&quot;https://astro-theme-lotus.prosefly.dev/images/og.png&quot;&gt;&lt;/div&gt;&lt;div class=&quot;pf-embed__body&quot;&gt;&lt;div class=&quot;pf-embed__eyebrow&quot;&gt;Prosefly&lt;/div&gt;&lt;p class=&quot;pf-embed__title&quot;&gt;Astro Theme Lotus&lt;/p&gt;&lt;p class=&quot;pf-embed__description&quot;&gt;An installable documentation theme for Astro v7, Tailwind CSS v4, and MDX.&lt;/p&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;code&gt;AudioPlayer&lt;/code&gt; enhances the native audio element with metadata, seeking, playback speed, mute, and
Media Session support where the browser provides it.&lt;/p&gt;
&lt;pf-audio-player role=&quot;group&quot; aria-label=&quot;STS-133 Mission Status Briefing&quot; data-pf-audio-album=&quot;NASA mission audio&quot; data-pf-audio-artist=&quot;NASA&quot; data-pf-audio-duration=&quot;11:06&quot; data-pf-audio-title=&quot;STS-133 Mission Status Briefing&quot; class=&quot;pf-audio-player&quot;&gt;&lt;div class=&quot;pf-audio-player__body&quot;&gt;&lt;div class=&quot;pf-audio-player__metadata&quot;&gt;&lt;div class=&quot;pf-audio-player__marquee&quot; data-pf-audio-marquee&gt;&lt;span class=&quot;pf-audio-player__title&quot; data-pf-audio-marquee-content&gt;STS-133 Mission Status Briefing&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;pf-audio-player__marquee&quot; data-pf-audio-marquee&gt;&lt;span class=&quot;pf-audio-player__byline&quot; data-pf-audio-marquee-content&gt;NASA mission audio&lt;span aria-hidden=&quot;true&quot;&gt; - &lt;/span&gt;NASA&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;audio src=&quot;https://shikwasa.js.org/assets/STS-133_FD11_Mission_Status_Briefing.mp3&quot; aria-label=&quot;STS-133 Mission Status Briefing&quot; class=&quot;pf-audio-player__audio&quot; controls preload=&quot;metadata&quot;&gt;Your browser does not support the audio element.&lt;/audio&gt;&lt;div class=&quot;pf-audio-player__progress&quot;&gt;&lt;time class=&quot;pf-audio-player__time&quot; data-pf-audio-current-time&gt;00:00&lt;/time&gt;&lt;input aria-label=&quot;Seek&quot; class=&quot;pf-audio-player__seek&quot; data-pf-audio-seek disabled max=&quot;100&quot; min=&quot;0&quot; step=&quot;0.1&quot; type=&quot;range&quot; value=&quot;0&quot;&gt;&lt;time class=&quot;pf-audio-player__time&quot; data-pf-audio-duration&gt;11:06&lt;/time&gt;&lt;/div&gt;&lt;div aria-label=&quot;Audio controls&quot; class=&quot;pf-audio-player__controls&quot; role=&quot;group&quot;&gt;&lt;button aria-label=&quot;Change playback speed&quot; class=&quot;pf-audio-player__speed&quot; data-pf-audio-rate type=&quot;button&quot;&gt;1.0x&lt;/button&gt;&lt;div class=&quot;pf-audio-player__transport&quot;&gt;&lt;button aria-label=&quot;Replay 15 seconds&quot; class=&quot;pf-audio-player__button&quot; data-pf-audio-seek-by=&quot;-15&quot; type=&quot;button&quot;&gt;&lt;svg class=&quot;pf-icon pf-audio-player__icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;currentColor&quot; d=&quot;M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12h2a8 8 0 1 0 1.385-4.5H8v2H2v-6h2V6a9.99 9.99 0 0 1 8-4M8.5 15.5v-7H10v7zm3.5-7h4.75V10H13.5v1.25h1.375a2.125 2.125 0 0 1 0 4.25H12V14h2.875a.625.625 0 1 0 0-1.25H12z&quot;/&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button aria-label=&quot;Play&quot; class=&quot;pf-audio-player__button pf-audio-player__play&quot; data-pf-audio-play type=&quot;button&quot;&gt;&lt;svg class=&quot;pf-icon pf-audio-player__icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-pf-audio-icon=&quot;play&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;currentColor&quot; d=&quot;M19.376 12.416L8.777 19.482A.5.5 0 0 1 8 19.066V4.934a.5.5 0 0 1 .777-.416l10.599 7.066a.5.5 0 0 1 0 .832&quot;/&gt;&lt;/svg&gt;&lt;svg class=&quot;pf-icon pf-audio-player__icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-pf-audio-icon=&quot;pause&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;currentColor&quot; d=&quot;M6 5h2v14H6zm10 0h2v14h-2z&quot;/&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button aria-label=&quot;Forward 30 seconds&quot; class=&quot;pf-audio-player__button&quot; data-pf-audio-seek-by=&quot;30&quot; type=&quot;button&quot;&gt;&lt;svg class=&quot;pf-icon pf-audio-player__icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;currentColor&quot; d=&quot;M2 12C2 6.477 6.477 2 12 2a9.99 9.99 0 0 1 8 4V3.5h2v6h-4.834c.212.368.334.795.334 1.25v2.5a2.5 2.5 0 0 1-5 0v-2.5A2.5 2.5 0 0 1 16 8.458V7.5h2.616A8 8 0 1 0 20 12h2c0 5.523-4.477 10-10 10S2 17.523 2 12m13-2.25a1 1 0 0 0-1 1v2.5a1 1 0 1 0 2 0v-2.5a1 1 0 0 0-1-1m-5.625 3a.625.625 0 1 1 0 1.25H6.75v1.5h2.625a2.125 2.125 0 0 0 1.62-3.5a2.125 2.125 0 0 0-1.62-3.5H6.75V10h2.625a.625.625 0 1 1 0 1.25H7.5v1.5z&quot;/&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;button aria-label=&quot;Mute&quot; class=&quot;pf-audio-player__mute pf-audio-player__button&quot; data-pf-audio-mute type=&quot;button&quot;&gt;&lt;svg class=&quot;pf-icon pf-audio-player__icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-pf-audio-icon=&quot;volume-up&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;currentColor&quot; d=&quot;M2 16h3.889l5.294 4.332a.5.5 0 0 0 .817-.387V4.055a.5.5 0 0 0-.817-.387L5.89 8H2a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1m21-4c0 3.292-1.446 6.246-3.738 8.262l-1.418-1.418A8.98 8.98 0 0 0 21 12a8.98 8.98 0 0 0-3.155-6.844l1.417-1.418A10.97 10.97 0 0 1 23 12m-5 0a5.99 5.99 0 0 0-2.287-4.713l-1.429 1.429A4 4 0 0 1 16 12c0 1.36-.679 2.561-1.716 3.284l1.43 1.43A5.99 5.99 0 0 0 18 12&quot;/&gt;&lt;/svg&gt;&lt;svg class=&quot;pf-icon pf-audio-player__icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-pf-audio-icon=&quot;volume-mute&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;currentColor&quot; d=&quot;M5.889 16H2a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h3.889l5.294-4.332a.5.5 0 0 1 .817.387v15.89a.5.5 0 0 1-.817.387zm14.525-4l3.536 3.536l-1.415 1.414L19 13.414l-3.536 3.536l-1.414-1.414L17.586 12L14.05 8.465l1.414-1.415L19 10.586l3.535-3.536l1.415 1.415z&quot;/&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pf-audio-player&gt;
&lt;h2 id=&quot;choosing-the-smallest-useful-component&quot;&gt;Choosing the smallest useful component&lt;/h2&gt;
&lt;p&gt;The package is not meant to replace ordinary Markdown. Most sentences, lists, links, images, and
code blocks should remain native content. A component earns its place when it adds a relationship or
behavior that Markdown cannot express clearly.&lt;/p&gt;
&lt;div class=&quot;pf-card-grid&quot; data-astro-cid-fydxx5rk&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Label&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;Use a badge for compact status or category metadata that belongs beside the
prose.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Interrupt&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;Use a callout when a note, warning, or recommendation should change how the
reader interprets the surrounding section.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Organize&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;Use cards, steps, tabs, accordions, or a file tree when the relationship
between several pieces is the point.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Enhance media&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;Use a gallery, embed, or audio player when native media needs grouping,
metadata, or focused controls.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;/div&gt;
&lt;p&gt;That restraint keeps an MDX page readable in source form and makes the component API easier to
maintain. The important boundary is unchanged across every example: components supply structure and
behavior, while the host site supplies the visual system.&lt;/p&gt;</content:encoded></item><item><title>One Component Layer, Two Astro Themes</title><link>https://astro-template-aster.prosefly.dev/blog/one-component-layer-two-themes/</link><guid isPermaLink="true">https://astro-template-aster.prosefly.dev/blog/one-component-layer-two-themes/</guid><description>How Lotus and Dahlia share an MDX contract without collapsing into one configurable theme.</description><pubDate>Tue, 22 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Lotus and Dahlia solve the same broad problem: turn an Astro content collection into a complete
documentation site. Authors should not have to relearn how to write a callout or set of tabs when
they move between them. Readers, however, should be able to feel that the themes make different
choices.&lt;/p&gt;
&lt;p&gt;That tension led to a simple boundary: share the author-facing component layer, but let each theme
own its shell and visual system.&lt;/p&gt;
&lt;h2 id=&quot;extract-the-stable-vocabulary&quot;&gt;Extract the stable vocabulary&lt;/h2&gt;
&lt;p&gt;The shared &lt;code&gt;@prosefly/astro-components&lt;/code&gt; package owns structures whose meaning does not change with
the page layout.&lt;/p&gt;
&lt;div class=&quot;pf-card-grid&quot; data-astro-cid-fydxx5rk&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Shared contract&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;MDX component APIs, accessible interaction behavior, Markdown transforms,
icon loading, and semantic style hooks.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Theme-owned expression&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;Typography, spacing, color, header, sidebar, table of contents, search UI,
and responsive page composition.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;/div&gt;
&lt;p&gt;A tab still represents parallel choices in either theme. A callout still interrupts the prose with
important context. Those semantics belong with the content. How much space they occupy and how they
fit the surrounding article belong with the theme.&lt;/p&gt;
&lt;ul class=&quot;pf-file-tree&quot; data-icon-set=&quot;lucide&quot; role=&quot;list&quot;&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;directory&quot;&gt;&lt;details class=&quot;pf-file-tree__details&quot; open&gt;&lt;summary class=&quot;pf-file-tree__summary&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__chevron&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m9 18l6-6l-6-6&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;directory&quot;&gt;&lt;span class=&quot;pf-file-tree__icon-closed&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__icon-open&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m6 14l1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;&lt;span class=&quot;pf-file-tree__sr-only&quot;&gt;Directory &lt;/span&gt;@prosefly/astro-components&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/summary&gt;&lt;ul class=&quot;pf-file-tree__list&quot; role=&quot;list&quot;&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;file&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;MDX&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__comment&quot;&gt;components&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;file&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;client&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__comment&quot;&gt;behavior&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;file&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;Markdown&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__comment&quot;&gt;transforms&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;file&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;semantic&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__comment&quot;&gt;CSS properties&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/details&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;directory&quot;&gt;&lt;details class=&quot;pf-file-tree__details&quot; open&gt;&lt;summary class=&quot;pf-file-tree__summary&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__chevron&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m9 18l6-6l-6-6&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;directory&quot;&gt;&lt;span class=&quot;pf-file-tree__icon-closed&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__icon-open&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m6 14l1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;&lt;span class=&quot;pf-file-tree__sr-only&quot;&gt;Directory &lt;/span&gt;@prosefly/astro-theme-lotus&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/summary&gt;&lt;ul class=&quot;pf-file-tree__list&quot; role=&quot;list&quot;&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;file&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;Lotus&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__comment&quot;&gt;shell&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;file&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;Lotus&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__comment&quot;&gt;tokens&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;file&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;Lotus&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__comment&quot;&gt;configuration&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/details&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;directory&quot;&gt;&lt;details class=&quot;pf-file-tree__details&quot; open&gt;&lt;summary class=&quot;pf-file-tree__summary&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__chevron&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m9 18l6-6l-6-6&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;directory&quot;&gt;&lt;span class=&quot;pf-file-tree__icon-closed&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__icon-open&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m6 14l1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;&lt;span class=&quot;pf-file-tree__sr-only&quot;&gt;Directory &lt;/span&gt;@prosefly/astro-theme-dahlia&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/summary&gt;&lt;ul class=&quot;pf-file-tree__list&quot; role=&quot;list&quot;&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;file&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;Dahlia&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__comment&quot;&gt;shell&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;file&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;Dahlia&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__comment&quot;&gt;tokens&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;file&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;Dahlia&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__comment&quot;&gt;configuration&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/details&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id=&quot;keep-the-dependency-direction-visible&quot;&gt;Keep the dependency direction visible&lt;/h2&gt;
&lt;p&gt;Both themes depend on the component package. The component package does not import either theme,
inspect a theme name, or carry theme-specific branches.&lt;/p&gt;
&lt;p&gt;That direction matters more than where the files live. If the shared layer needs to know whether it
is inside Lotus or Dahlia, it has stopped being shared infrastructure and become a hidden base
theme.&lt;/p&gt;
&lt;p&gt;Instead, components expose semantic &lt;code&gt;--pf-*&lt;/code&gt; properties with useful fallbacks. Each theme maps
those roles into its own tokens. A standalone site such as Aster can do the same without adopting a
documentation shell.&lt;/p&gt;
&lt;div class=&quot;pf-callout&quot; data-has-title=&quot;true&quot; data-type=&quot;note&quot; role=&quot;note&quot; data-astro-cid-yxo7o45t&gt;&lt;span class=&quot;pf-callout__icon&quot; aria-hidden=&quot;true&quot; data-astro-cid-yxo7o45t&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-astro-cid-yxo7o45t=&quot;true&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;/&gt;&lt;path d=&quot;M12 16v-4m0-4h.01&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;div class=&quot;pf-callout__content&quot; data-astro-cid-yxo7o45t&gt;&lt;p class=&quot;pf-callout__title&quot; data-astro-cid-yxo7o45t&gt;The practical result&lt;/p&gt;&lt;div class=&quot;pf-callout__slot&quot; data-astro-cid-yxo7o45t&gt;&lt;p&gt;An article can move between Lotus, Dahlia, and Aster without rewriting every
callout, card, tab, step, or file tree.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;why-not-build-one-theme-with-two-presets&quot;&gt;Why not build one theme with two presets?&lt;/h2&gt;
&lt;p&gt;Presets work when the difference is mostly color and typography. Lotus and Dahlia differ in page
composition, navigation density, spacing, and the relationship between the article and its
surrounding controls.&lt;/p&gt;
&lt;p&gt;Putting both behind one tree of conditions would make every shell change answer two questions:
what does this feature do, and which preset is currently active? Separate theme packages keep that
reasoning local. Shared content behavior is still fixed once in the component layer.&lt;/p&gt;
&lt;p&gt;The cost is that some shell logic exists twice. That is acceptable when the duplicated code
represents genuinely different products rather than an overlooked abstraction.&lt;/p&gt;
&lt;h2 id=&quot;use-portability-as-a-design-test&quot;&gt;Use portability as a design test&lt;/h2&gt;
&lt;p&gt;Before adding a feature to the shared layer, we ask whether its meaning belongs to the document or
to the shell. Before adding a theme-specific component, we ask whether an author would expect the
same content to work elsewhere.&lt;/p&gt;
&lt;p&gt;This does not produce a perfectly generic component library. It produces a focused one with a clear
consumer: technical content written in Astro and MDX. That narrower contract is what lets the two
themes keep distinct identities without forking the writing experience.&lt;/p&gt;</content:encoded></item><item><title>Building Dahlia Without Forking Lotus</title><link>https://astro-template-aster.prosefly.dev/blog/building-dahlia-without-forking-lotus/</link><guid isPermaLink="true">https://astro-template-aster.prosefly.dev/blog/building-dahlia-without-forking-lotus/</guid><description>What stayed shared—and what deliberately changed—when Prosefly added a second documentation theme.</description><pubDate>Tue, 15 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The easiest way to create a second theme is to copy the first one, change the colors, and promise to
clean up the duplication later. That works until a shared feature changes. Then every improvement
has to be rediscovered in both codebases, while the two themes slowly develop incompatible content
APIs.&lt;/p&gt;
&lt;p&gt;Dahlia took a different path. It shares the content vocabulary and infrastructure that authors rely
on, but owns the parts that make a theme feel like a product: page composition, navigation rhythm,
typography, spacing, and visual hierarchy.&lt;/p&gt;
&lt;h2 id=&quot;begin-with-the-reason-for-a-second-theme&quot;&gt;Begin with the reason for a second theme&lt;/h2&gt;
&lt;p&gt;Lotus is a broad documentation shell with compact navigation and a configurable product surface.
Dahlia explores a quieter, content-first composition: persistent navigation on the left, a centered
article, and a table of contents that supports the page without enclosing it in heavier chrome.&lt;/p&gt;
&lt;p&gt;If the difference had been only an accent color, a preset would have been enough. The second package
became worthwhile because the layout and reading rhythm were meaningfully different.&lt;/p&gt;
&lt;div class=&quot;pf-card-grid&quot; data-astro-cid-fydxx5rk&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Keep shared&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;The docs collection contract, MDX component APIs, icon loading, Markdown
transforms, code behavior, and accessible interactive primitives.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Let Dahlia own&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;Header and sidebar composition, article width, table of contents, search
presentation, responsive transitions, typography, and palette.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;/div&gt;
&lt;h2 id=&quot;move-the-author-contract-below-both-themes&quot;&gt;Move the author contract below both themes&lt;/h2&gt;
&lt;p&gt;Callouts, cards, steps, tabs, accordions, file trees, and galleries moved into
&lt;code&gt;@prosefly/astro-components&lt;/code&gt;. The package exposes semantic CSS properties rather than importing a
theme stylesheet.&lt;/p&gt;
&lt;p&gt;Both themes depend on that package and map the same roles into their own tokens. The dependency only
points one way: shared components never branch on a theme name.&lt;/p&gt;
&lt;div class=&quot;pf-callout&quot; data-has-title=&quot;true&quot; data-type=&quot;note&quot; role=&quot;note&quot; data-astro-cid-yxo7o45t&gt;&lt;span class=&quot;pf-callout__icon&quot; aria-hidden=&quot;true&quot; data-astro-cid-yxo7o45t&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-astro-cid-yxo7o45t=&quot;true&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;/&gt;&lt;path d=&quot;M12 16v-4m0-4h.01&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;div class=&quot;pf-callout__content&quot; data-astro-cid-yxo7o45t&gt;&lt;p class=&quot;pf-callout__title&quot; data-astro-cid-yxo7o45t&gt;A useful constraint&lt;/p&gt;&lt;div class=&quot;pf-callout__slot&quot; data-astro-cid-yxo7o45t&gt;&lt;p&gt;If a shared component needs to know which theme is rendering it, the boundary
is probably in the wrong place.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;rebuild-the-shell-from-its-own-priorities&quot;&gt;Rebuild the shell from its own priorities&lt;/h2&gt;
&lt;p&gt;Rather than copying Lotus layouts and deleting pieces, Dahlia assembled its page around the reading
experience it wanted.&lt;/p&gt;
&lt;ol role=&quot;list&quot; class=&quot;pf-steps&quot;&gt;
&lt;li&gt;Establish the article measure and vertical rhythm.&lt;/li&gt;
&lt;li&gt;Place navigation and the table of contents around that article.&lt;/li&gt;
&lt;li&gt;Add mobile transitions that preserve the same information hierarchy.&lt;/li&gt;
&lt;li&gt;Map shared content components into Dahlia’s tokens.&lt;/li&gt;
&lt;li&gt;Add search, i18n, code rendering, Mermaid, and theme controls as parts of the shell.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This order made the visual difference structural. It also made duplicated shell code honest: Lotus
and Dahlia each own their navigation because their navigation is not the same component wearing a
different class name.&lt;/p&gt;
&lt;h2 id=&quot;test-portability-with-real-documents&quot;&gt;Test portability with real documents&lt;/h2&gt;
&lt;p&gt;A shared contract matters only if existing content can use it. Guides containing callouts, tabs,
steps, code examples, and file trees were rendered in both themes. Problems that appeared in both
belonged to the shared package. Problems caused by one page composition stayed with that theme.&lt;/p&gt;
&lt;p&gt;The result is not zero duplication. It is duplication at the product layer and reuse at the author
layer—a trade that keeps each theme understandable while preserving the durable content.&lt;/p&gt;
&lt;p&gt;Dahlia can now evolve as its own design without asking authors to rewrite the documentation that
already works in Lotus.&lt;/p&gt;</content:encoded></item><item><title>Treating OpenAPI as Astro Content</title><link>https://astro-template-aster.prosefly.dev/blog/openapi-as-astro-content/</link><guid isPermaLink="true">https://astro-template-aster.prosefly.dev/blog/openapi-as-astro-content/</guid><description>Why Astro OpenAPI produces a bounded content model and leaves routes to the documentation site.</description><pubDate>Tue, 08 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;span class=&quot;pf-badge&quot; data-color=&quot;warning&quot; data-variant=&quot;soft&quot; data-astro-cid-k4cvekrn&gt;Private package&lt;/span&gt;
&lt;p&gt;An OpenAPI document looks like content, but it rarely behaves like a normal article. Operations
share schemas, schemas refer back to one another, security rules apply at several levels, and a
single endpoint may carry examples for multiple request and response media types.&lt;/p&gt;
&lt;p&gt;Astro OpenAPI handles that complexity before the page template sees it. The package reads a
specification and produces an introduction, operation entries, webhook entries, navigation, and a
bounded schema model. The consuming Astro site decides what URLs to generate and how those entries
fit beside the rest of its documentation.&lt;/p&gt;
&lt;h2 id=&quot;separate-the-reference-model-from-the-shell&quot;&gt;Separate the reference model from the shell&lt;/h2&gt;
&lt;ol role=&quot;list&quot; class=&quot;pf-steps&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Resolve configured sources.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Most sites load one local file. Products with several APIs can define named sources, each with a
distinct base path.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Normalize author input.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;OpenAPI objects become predictable operation and webhook entries with consistent method, path,
security, parameter, body, response, and example data.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Bound recursive structures.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Configurable budgets limit schema depth, array items, object entries, and total nodes so the data
stored in Astro’s content layer remains finite and JSON-safe.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Render inside the owning theme.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The site chooses routes and layouts, then uses API-specific components for requests, responses,
security, schemas, snippets, and aside navigation.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The content collection setup remains recognizably Astro:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;ts&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { defineCollection } &lt;/span&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--shiki-light:#032F62;--shiki-dark:#9ECBFF&quot;&gt; &amp;#39;astro:content&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { openApiLoader, openApiSchema } &lt;/span&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--shiki-light:#032F62;--shiki-dark:#9ECBFF&quot;&gt; &amp;#39;@prosefly-pro/astro-openapi&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;--shiki-light:#005CC5;--shiki-dark:#79B8FF&quot;&gt; api&lt;/span&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#6F42C1;--shiki-dark:#B392F0&quot;&gt; defineCollection&lt;/span&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  loader: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#6F42C1;--shiki-dark:#B392F0&quot;&gt;openApiLoader&lt;/span&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  schema: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#6F42C1;--shiki-dark:#B392F0&quot;&gt;openApiSchema&lt;/span&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt; const&lt;/span&gt;&lt;span style=&quot;--shiki-light:#005CC5;--shiki-dark:#79B8FF&quot;&gt; collections&lt;/span&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { api }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;route-ownership-stays-with-the-site&quot;&gt;Route ownership stays with the site&lt;/h2&gt;
&lt;p&gt;Astro OpenAPI intentionally does not inject endpoint pages. A loader can serve several routing
strategies; a router embedded in the package would make every consumer inherit the same URL and
layout assumptions.&lt;/p&gt;
&lt;div class=&quot;pf-card-grid&quot; data-astro-cid-fydxx5rk&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Loader responsibility&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;Produce stable, validated entries and the navigation information needed to
find them.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Theme responsibility&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;Decide where entries live, how they are grouped, and how the reference sits
beside guides and conceptual documentation.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;/div&gt;
&lt;p&gt;Lotus, for example, can place operation pages inside its existing documentation shell and combine
generated API navigation with hand-authored groups. Another Astro site can choose a different base
path or page composition without changing the loader.&lt;/p&gt;
&lt;h2 id=&quot;recursive-schemas-need-an-explicit-budget&quot;&gt;Recursive schemas need an explicit budget&lt;/h2&gt;
&lt;p&gt;Dereferencing an OpenAPI document can produce cycles or extremely large object graphs. Passing that
graph directly to a content entry makes build time and output size depend on accidental details of
the source specification.&lt;/p&gt;
&lt;p&gt;Astro OpenAPI stores a bounded display model instead. Defaults work for typical references, while
projects with unusual schemas can adjust &lt;code&gt;maxDepth&lt;/code&gt;, &lt;code&gt;maxArrayItems&lt;/code&gt;, &lt;code&gt;maxObjectEntries&lt;/code&gt;, and
&lt;code&gt;maxNodes&lt;/code&gt;. Hitting a budget is a visible product decision, not an unbounded traversal hidden inside
a component render.&lt;/p&gt;
&lt;div class=&quot;pf-callout&quot; data-has-title=&quot;true&quot; data-type=&quot;tip&quot; role=&quot;note&quot; data-astro-cid-yxo7o45t&gt;&lt;span class=&quot;pf-callout__icon&quot; aria-hidden=&quot;true&quot; data-astro-cid-yxo7o45t&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-astro-cid-yxo7o45t=&quot;true&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5c1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5c.7.7 1.3 1.5 1.5 2.5m0 4h6m-5 4h4&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;div class=&quot;pf-callout__content&quot; data-astro-cid-yxo7o45t&gt;&lt;p class=&quot;pf-callout__title&quot; data-astro-cid-yxo7o45t&gt;Why the boundary matters&lt;/p&gt;&lt;div class=&quot;pf-callout__slot&quot; data-astro-cid-yxo7o45t&gt;&lt;p&gt;Normalization makes the reference predictable. Route ownership keeps it
composable. The schema budget keeps it safe to place in Astro’s content layer.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;components-complete-the-model-without-owning-the-page&quot;&gt;Components complete the model without owning the page&lt;/h2&gt;
&lt;p&gt;The package exports focused components for authentication, request bodies, response examples,
schemas, webhooks, code snippets, and reference asides. Interactive pieces enhance their local
section; the surrounding document remains statically rendered.&lt;/p&gt;
&lt;p&gt;This is the useful end state: generated API reference behaves like one of the site’s content
sources, not like a separate application mounted beside the documentation.&lt;/p&gt;</content:encoded></item><item><title>Keeping Documentation in Astro Collections</title><link>https://astro-template-aster.prosefly.dev/blog/content-collections-source-of-truth/</link><guid isPermaLink="true">https://astro-template-aster.prosefly.dev/blog/content-collections-source-of-truth/</guid><description>A practical boundary between durable content and a replaceable documentation shell.</description><pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A documentation theme makes dozens of useful decisions: where navigation lives, how search opens,
what an active page looks like, and how a long article behaves on a small screen. Those decisions
should be easy to adopt. They should not become the only place the documentation can exist.&lt;/p&gt;
&lt;p&gt;Prosefly themes keep source documents in Astro content collections. The theme generates routes,
navigation, search metadata, and page chrome around them, but Markdown and MDX remain ordinary
project files.&lt;/p&gt;
&lt;ul class=&quot;pf-file-tree&quot; data-icon-set=&quot;lucide&quot; role=&quot;list&quot;&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;directory&quot;&gt;&lt;details class=&quot;pf-file-tree__details&quot; open&gt;&lt;summary class=&quot;pf-file-tree__summary&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__chevron&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m9 18l6-6l-6-6&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;directory&quot;&gt;&lt;span class=&quot;pf-file-tree__icon-closed&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__icon-open&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m6 14l1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;&lt;span class=&quot;pf-file-tree__sr-only&quot;&gt;Directory &lt;/span&gt;src&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/summary&gt;&lt;ul class=&quot;pf-file-tree__list&quot; role=&quot;list&quot;&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;directory&quot;&gt;&lt;details class=&quot;pf-file-tree__details&quot; open&gt;&lt;summary class=&quot;pf-file-tree__summary&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__chevron&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m9 18l6-6l-6-6&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;directory&quot;&gt;&lt;span class=&quot;pf-file-tree__icon-closed&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__icon-open&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m6 14l1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;&lt;span class=&quot;pf-file-tree__sr-only&quot;&gt;Directory &lt;/span&gt;content&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/summary&gt;&lt;ul class=&quot;pf-file-tree__list&quot; role=&quot;list&quot;&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;directory&quot;&gt;&lt;details class=&quot;pf-file-tree__details&quot; open&gt;&lt;summary class=&quot;pf-file-tree__summary&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__chevron&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m9 18l6-6l-6-6&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;directory&quot;&gt;&lt;span class=&quot;pf-file-tree__icon-closed&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__icon-open&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m6 14l1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;&lt;span class=&quot;pf-file-tree__sr-only&quot;&gt;Directory &lt;/span&gt;docs&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/summary&gt;&lt;ul class=&quot;pf-file-tree__list&quot; role=&quot;list&quot;&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;text&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5M10 9H8m8 4H8m8 4H8&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;index.mdx&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;text&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5M10 9H8m8 4H8m8 4H8&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;installation.mdx&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;directory&quot;&gt;&lt;details class=&quot;pf-file-tree__details&quot; open&gt;&lt;summary class=&quot;pf-file-tree__summary&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__chevron&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m9 18l6-6l-6-6&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;directory&quot;&gt;&lt;span class=&quot;pf-file-tree__icon-closed&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__icon-open&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m6 14l1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;&lt;span class=&quot;pf-file-tree__sr-only&quot;&gt;Directory &lt;/span&gt;configuration&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/summary&gt;&lt;ul class=&quot;pf-file-tree__list&quot; role=&quot;list&quot;&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;text&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5M10 9H8m8 4H8m8 4H8&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;navigation.mdx&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/details&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/details&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/details&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;code&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5m-10 4.5L8 15l2 2.5m4-5l2 2.5l-2 2.5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;content.config.ts&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/details&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;code&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z&quot;/&gt;&lt;path d=&quot;M14 2v5a1 1 0 0 0 1 1h5m-10 4.5L8 15l2 2.5m4-5l2 2.5l-2 2.5&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;astro.config.ts&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;pf-file-tree__item&quot; data-entry-type=&quot;file&quot;&gt;&lt;span class=&quot;pf-file-tree__entry&quot;&gt;&lt;span class=&quot;pf-file-tree__target&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;pf-file-tree__icon&quot; data-kind=&quot;config&quot;&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 8a1 1 0 0 1-1-1V2a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8zm5 0v12a2 2 0 0 1-2 2h-4.182M3.305 19.53l.923-.382M4 10.592V4a2 2 0 0 1 2-2h8M4.228 16.852l-.924-.383m2.548-1.241l-.383-.923m.383 6.467l-.383.924m2.679-6.468l.383-.923m-.001 7.391l-.382-.924m1.625-3.92l.922-.383m-.922 2.679l.922.383&quot;/&gt;&lt;circle cx=&quot;7&quot; cy=&quot;18&quot; r=&quot;3&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;pf-file-tree__name&quot;&gt;theme.config.json&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id=&quot;give-each-layer-one-kind-of-decision&quot;&gt;Give each layer one kind of decision&lt;/h2&gt;
&lt;p&gt;The arrangement works because three files answer three different questions.&lt;/p&gt;
&lt;div class=&quot;pf-card-grid&quot; data-astro-cid-fydxx5rk&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Content collection&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;What fields make a valid page, where the source files live, and how Astro
loads them.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Theme configuration&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;What the product is called, how navigation is grouped, which search provider
is active, and how the shell is branded.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;Markdown and MDX&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;What the reader needs to know, including prose, examples, and structured
content components.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;/div&gt;
&lt;p&gt;In Lotus, the collection boundary is explicit:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;ts&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { defineCollection } &lt;/span&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--shiki-light:#032F62;--shiki-dark:#9ECBFF&quot;&gt; &amp;#39;astro:content&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { docsLoader, docsSchema } &lt;/span&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--shiki-light:#032F62;--shiki-dark:#9ECBFF&quot;&gt; &amp;#39;@prosefly/astro-theme-lotus/content&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;--shiki-light:#005CC5;--shiki-dark:#79B8FF&quot;&gt; docs&lt;/span&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#6F42C1;--shiki-dark:#B392F0&quot;&gt; defineCollection&lt;/span&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  loader: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#6F42C1;--shiki-dark:#B392F0&quot;&gt;docsLoader&lt;/span&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  schema: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#6F42C1;--shiki-dark:#B392F0&quot;&gt;docsSchema&lt;/span&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt; const&lt;/span&gt;&lt;span style=&quot;--shiki-light:#005CC5;--shiki-dark:#79B8FF&quot;&gt; collections&lt;/span&gt;&lt;span style=&quot;--shiki-light:#D73A49;--shiki-dark:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { docs }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The schema catches invalid frontmatter early. The loader gives the theme a predictable set of
entries. Neither needs to hide the original document.&lt;/p&gt;
&lt;h2 id=&quot;let-configuration-describe-the-shell&quot;&gt;Let configuration describe the shell&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;theme.config.json&lt;/code&gt; contains product identity and navigation because those values describe how the
site presents the collection. A page title and description belong to the page; the site’s logo,
sidebar groups, and social links do not.&lt;/p&gt;
&lt;p&gt;This separation keeps reviews legible. A writing change looks like a writing change. A navigation
reorganization appears in one configuration diff. A visual change stays in tokens or component
overrides instead of being mixed into dozens of MDX files.&lt;/p&gt;
&lt;div class=&quot;pf-callout&quot; data-has-title=&quot;true&quot; data-type=&quot;note&quot; role=&quot;note&quot; data-astro-cid-yxo7o45t&gt;&lt;span class=&quot;pf-callout__icon&quot; aria-hidden=&quot;true&quot; data-astro-cid-yxo7o45t&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-astro-cid-yxo7o45t=&quot;true&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot;/&gt;&lt;path d=&quot;M12 16v-4m0-4h.01&quot;/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt;&lt;div class=&quot;pf-callout__content&quot; data-astro-cid-yxo7o45t&gt;&lt;p class=&quot;pf-callout__title&quot; data-astro-cid-yxo7o45t&gt;Own the durable part&lt;/p&gt;&lt;div class=&quot;pf-callout__slot&quot; data-astro-cid-yxo7o45t&gt;&lt;p&gt;A theme can change. The content, URLs, and information architecture should be
able to survive that change with as little rewriting as possible.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;test-the-boundary-with-a-migration-exercise&quot;&gt;Test the boundary with a migration exercise&lt;/h2&gt;
&lt;p&gt;The simplest way to evaluate content ownership is to imagine replacing the theme.&lt;/p&gt;
&lt;ol role=&quot;list&quot; class=&quot;pf-steps&quot;&gt;
&lt;li&gt;Point a new Astro collection at the existing &lt;code&gt;src/content/docs/&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;Map the existing frontmatter fields into the new shell.&lt;/li&gt;
&lt;li&gt;Recreate navigation from configuration or directory structure.&lt;/li&gt;
&lt;li&gt;Render the same Markdown and MDX through the new layouts.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Some component imports may need mapping, and shell configuration will certainly change. The article
bodies, examples, headings, and Git history should not need to be exported from anywhere.&lt;/p&gt;
&lt;h2 id=&quot;portability-still-needs-a-contract&quot;&gt;Portability still needs a contract&lt;/h2&gt;
&lt;p&gt;Keeping files in the repository does not make content automatically portable. A theme can still
leak implementation details through proprietary frontmatter, layout imports, or components that
only work inside one CSS environment.&lt;/p&gt;
&lt;p&gt;That is why Prosefly pairs collections with a shared component package and semantic design tokens.
The collection preserves the source; the shared author-facing contract reduces the amount that must
change when the surrounding shell does.&lt;/p&gt;
&lt;p&gt;The goal is not a perfectly theme-neutral document. It is a clean, visible boundary where the
product-specific choices begin.&lt;/p&gt;</content:encoded></item><item><title>Defaults With an Exit</title><link>https://astro-template-aster.prosefly.dev/blog/defaults-with-an-exit/</link><guid isPermaLink="true">https://astro-template-aster.prosefly.dev/blog/defaults-with-an-exit/</guid><description>Good theme defaults shorten the first week without limiting what the site can become.</description><pubDate>Fri, 14 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A documentation theme earns its place by resolving repetitive work: page structure, navigation,
search, readable prose, responsive behavior, and accessible interaction states. A new project
should feel coherent before it has a custom design system.&lt;/p&gt;
&lt;p&gt;The same theme becomes a liability when those early decisions harden into permanent constraints.
Real products eventually need their own type, color, density, navigation, and component behavior.
The question is not whether a theme has opinions. It is whether the product can outgrow them without
rewriting its content.&lt;/p&gt;
&lt;h2 id=&quot;start-complete&quot;&gt;Start complete&lt;/h2&gt;
&lt;p&gt;Defaults are most useful when they form a system rather than a collection of placeholders.&lt;/p&gt;
&lt;div class=&quot;pf-card-grid&quot; data-astro-cid-fydxx5rk&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;A readable page&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;Type scale, line length, heading rhythm, code treatment, and focus states
should work together on day one.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;A navigable site&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;Desktop and mobile navigation, search, current-page state, and table of
contents should already agree about the information architecture.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;article class=&quot;pf-card&quot; data-astro-cid-j3hiwsr2=&quot;true&quot;&gt;&lt;div class=&quot;pf-card__layout&quot; data-astro-cid-j3hiwsr2&gt;&lt;div class=&quot;pf-card__body&quot; data-astro-cid-j3hiwsr2&gt;&lt;p class=&quot;pf-card__title&quot; data-astro-cid-j3hiwsr2&gt;A responsive shell&lt;/p&gt;&lt;div class=&quot;pf-card__content&quot; data-astro-cid-j3hiwsr2&gt;&lt;p&gt;The theme should decide how those parts collapse before every project
invents a different set of breakpoints.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;&lt;/div&gt;
&lt;p&gt;An incomplete default shifts design work back to the adopter while still asking them to learn the
theme’s abstractions. A considered default lets the team begin with content and discover which parts
actually need to become distinctive.&lt;/p&gt;
&lt;h2 id=&quot;put-exits-at-meaningful-layers&quot;&gt;Put exits at meaningful layers&lt;/h2&gt;
&lt;p&gt;Not every CSS value needs a configuration option. Useful escape routes correspond to decisions a
product team can name.&lt;/p&gt;
&lt;ol role=&quot;list&quot; class=&quot;pf-steps&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tokens change the visual language.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Accent, neutrals, fonts, radius, spacing roles, and status colors establish identity without
changing component structure.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configuration changes product behavior.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Navigation, search, locale, social links, and page metadata belong to the site rather than the
theme’s source code.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Component overrides change composition.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When the product genuinely needs different navigation or footer behavior, a documented component
boundary is clearer than a growing collection of selectors.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Content ownership makes replacement possible.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Markdown, MDX, and Astro collections remain useful even if the shell is eventually replaced.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;pf-callout&quot; data-has-title=&quot;true&quot; data-type=&quot;tip&quot; role=&quot;note&quot; data-astro-cid-yxo7o45t&gt;&lt;span class=&quot;pf-callout__icon&quot; aria-hidden=&quot;true&quot; data-astro-cid-yxo7o45t&gt;&lt;svg class=&quot;pf-icon&quot; width=&quot;1em&quot; height=&quot;1em&quot; viewBox=&quot;0 0 24 24&quot; data-astro-cid-yxo7o45t=&quot;true&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot; data-astro-cid-af3dxg6y&gt;&lt;path fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M15 14c.2-1 .7-1.7 1.5-2.5c1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5c.7.7 1.3 1.5 1.5 2.5m0 4h6m-5 4h4&quot;/&gt;&lt;/svg&gt;&lt;/span&gt;&lt;div class=&quot;pf-callout__content&quot; data-astro-cid-yxo7o45t&gt;&lt;p class=&quot;pf-callout__title&quot; data-astro-cid-yxo7o45t&gt;A useful test&lt;/p&gt;&lt;div class=&quot;pf-callout__slot&quot; data-astro-cid-yxo7o45t&gt;&lt;p&gt;Can a team begin with the theme, grow into its own visual system, and keep the
same content throughout the transition?&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;avoid-the-other-extreme&quot;&gt;Avoid the other extreme&lt;/h2&gt;
&lt;p&gt;An exit does not mean exposing every internal variable. A configuration surface with hundreds of
unrelated values is another kind of lock-in: adopters must understand the implementation before
they can make a safe change.&lt;/p&gt;
&lt;p&gt;Semantic choices are more durable. “Accent color” expresses intent; “third link hover border”
describes an accident of the current markup. A small set of roles can be applied consistently and
survive component refactors.&lt;/p&gt;
&lt;p&gt;The same rule applies to overrides. Replacing a search control is a meaningful boundary. Overriding
the wrapper around every icon usually means the underlying component contract is missing the right
token or prop.&lt;/p&gt;
&lt;h2 id=&quot;the-exit-makes-the-default-more-trustworthy&quot;&gt;The exit makes the default more trustworthy&lt;/h2&gt;
&lt;p&gt;Aster exposes centralized configuration, semantic color tokens, shared content components, and
content that stays in ordinary Astro collections. Most projects will not replace every default.
That is precisely why the boundaries matter: authors can begin with the complete template without
betting that their needs will never change.&lt;/p&gt;
&lt;p&gt;A strong default should feel like a useful starting point, not a decision the project is afraid to
revisit.&lt;/p&gt;</content:encoded></item></channel></rss>