Section card
A contained content section: header row with title, supporting description and a status badge, body copy with a feature list, and a footer pairing meta text with a call-to-action.
Installation
Blocks are copied source, not library calls — the generator writes this
exact template into app/views/blocks/
and from there it's yours to edit. The preview below renders the same
source the copy-in produces.
bin/rails g poetry:block section-card
Default
Usage-based billing
Pay for what the workspace actually uses. Metering runs hourly and the invoice line items match the usage dashboard.
- Per-request API metering
- Storage billed by the gigabyte-hour
- Spend alerts before every threshold
<%# Page framing: a section keeps its container + breathing room when it is
the page's subject - a bare card at the viewport origin reads cramped
(a judged-run lesson). Drop the wrapper only when composing into an
already-padded frame like the app-shell content area. %>
<div class="mx-auto max-w-md p-6">
<%= poetry_card do |card| %>
<% card.with_title { "Usage-based billing" } %>
<% card.with_description { "Meter API calls and storage, invoiced monthly." } %>
<% card.with_action do %>
<%= poetry_badge(variant: :secondary) { "Beta" } %>
<% end %>
<% card.with_footer do %>
<div class="flex w-full items-center justify-between gap-4">
<span class="text-xs text-muted-foreground">Updated 2 days ago</span>
<%# The CTA reads as interactive (v1.1): always-underlined with a
trailing arrow - the affordance the judged card pairs kept
rewarding. %>
<%= poetry_link(href: "/docs/billing", underline: :always, class: "inline-flex items-center gap-1") do %>
Learn more <%= poetry_icon(name: :"arrow-right", class: "size-3.5") %>
<% end %>
</div>
<% end %>
<div class="space-y-3 text-sm">
<p>Pay for what the workspace actually uses. Metering runs hourly and the invoice line items match the usage dashboard.</p>
<ul class="space-y-2">
<li class="flex items-center gap-2">
<%= poetry_icon(name: :check, class: "size-4 text-muted-foreground") %>
<span>Per-request API metering</span>
</li>
<li class="flex items-center gap-2">
<%= poetry_icon(name: :check, class: "size-4 text-muted-foreground") %>
<span>Storage billed by the gigabyte-hour</span>
</li>
<li class="flex items-center gap-2">
<%= poetry_icon(name: :check, class: "size-4 text-muted-foreground") %>
<span>Spend alerts before every threshold</span>
</li>
</ul>
</div>
<% end %>
</div>
Styling
A block has no styling surface of its own — every element in the copied
template is a Poetry component carrying its usual
data-slot parts, and because you own
the source, utility classes can be edited directly in place. Per-part
contracts live on the composed components' pages: