Components Typography

Petal Pro is the full SaaS app this is built for

Auth, billing, admin, and Claude Code integration included. One purchase, unlimited projects.

Typography

Typography is the cheapest way to make an app look finished, and the easiest thing to get subtly wrong. Petal Components ships the whole type scale with that work already done: headings, body, lead, blockquote, inline code, lists, text helpers and a divider, all on consistent emphasis tiers with vertical rhythm built in. Drop them into a page and it reads the way a designed page should, in light and dark, with no manual spacing. To render raw HTML such as converted markdown, use Prose.
The Petal Components type scale rendered side by side in light and dark mode
One page, the same components, in light and dark. Everything below is rendered live.

In context

Every element composing together with no manual spacing. Drop the components in and the vertical rhythm just works, in light and dark.

The quiet power of Phoenix

A considered type scale does more for "looks finished" than any single component. Here is every element, in the kind of context you would actually ship.

Petal Components ships a refined set of headings, body copy and inline elements. Run mix deps.get, import the styles, and it already matches.

Built for reading

Body text uses a comfortable line height and a sensible measure, so paragraphs are pleasant to read rather than cramped. Headings carry tight tracking and a balanced weight.

"We shipped our marketing site in a weekend. The defaults just look right."

What you get

  • Headings from h1 through h5
  • Lead, body, blockquote and inline code
  • Muted, large and small text helpers

The joke tax

Even a table reads cleanly, with the data set brighter than its header so figures scan at a glance.

Joke tier Tax
Puns 5 gold coins
Jokes 10 gold coins
One-liners 20 gold coins

Headings

Heading 1

The Lighthouse at the Edge of the Map

heex
Copy
<.h1>The Lighthouse at the Edge of the Map</.h1>
Heading 2

Where the ferries stopped running

heex
Copy
<.h2>Where the ferries stopped running</.h2>
Heading 3

A keeper and her lamp

heex
Copy
<.h3>A keeper and her lamp</.h3>
Heading 4

The night the fog rolled in

heex
Copy
<.h4>The night the fog rolled in</.h4>
Heading 5
Notes from the harbour master
heex
Copy
<.h5>Notes from the harbour master</.h5>
Custom colour

The blue hour

heex
Copy
<.h2 class="text-sky-500 dark:text-sky-400">The blue hour</.h2>
Gradient

A light that never dims

heex
Copy
<.h1>
  <span class="text-transparent bg-clip-text bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500">
    A light that never dims
  </span>
</.h1>
Heading properties
elixir
Copy
            # <.h1>, <.h2>, <.h3>, <.h4>, <.h5>
  attr(:class, :string, default: "", doc: "CSS class")
  attr(:label, :string, default: nil, doc: "label your heading")
  attr(:no_margin, :boolean, default: nil, doc: "removes margin from headings")
  attr(:underline, :boolean, default: false, doc: "underlines a heading")
  attr(:color_class, :string, default: nil, doc: "adds a color class")
  attr(:rest, :global)
  slot(:inner_block, required: false)

        

Paragraphs

Here is a paragraph

heex
Copy
<.p>Here is a paragraph</.p>
Paragraph properties
elixir
Copy
            # <.p>
  attr(:class, :string, default: "", doc: "CSS class")
  attr(:no_margin, :boolean, default: nil, doc: "removes the bottom margin")
  attr(:rest, :global)
  slot(:inner_block, required: false)

        

Lead

A larger, muted introductory paragraph for the top of a page or section.

Petal Components is a set of HEEx components for Phoenix, built to look finished out of the box.

heex
Copy
<.lead>Petal Components is a set of HEEx components for Phoenix.</.lead>

Blockquote

"The defaults just look right, so we shipped the marketing site in a weekend."
heex
Copy
<.blockquote>"The defaults just look right."</.blockquote>

Inline code

For code snippets within a sentence.

Install the dependency with mix deps.get and you are ready to go.

heex
Copy
<.p>Install with <.inline_code>mix deps.get</.inline_code> to begin.</.p>

Text helpers

Emphasis and secondary copy: text_large, text_muted and text_small.
Large: an emphasised line of body text.

Muted: captions, hints and metadata.

Small: tight label text.
heex
Copy
<.text_large>Emphasised body text.</.text_large>
<.text_muted>Captions, hints and metadata.</.text_muted>
<.text_small>Tight label text.</.text_small>

Lists

  • List item 1
  • List item 2
  • List item 3
  1. List item 1
  2. List item 2
  3. List item 3
heex
Copy
<.ul>
  <li>List item 1</li>
  <li>List item 2</li>
  <li>List item 3</li>
</.ul>

<.ol class="mt-5">
  <li>List item 1</li>
  <li>List item 2</li>
  <li>List item 3</li>
</.ol>
List properties
elixir
Copy
            # <.ul, <.ol>
  attr(:class, :string, default: "", doc: "CSS class")
  attr(:rest, :global)
  slot(:inner_block, required: false)

        

Divider

A horizontal rule with sensible vertical spacing.

Above the divider.


Below the divider.

heex
Copy
<.hr />

Prose

Title

Here is a paragraph

Here is a another paragraph

  • List item 1
  • List item 2
heex
Copy
<.prose>
  <h1>Title</h1>
  <p>Here is a paragraph</p>
  <p>Here is a another paragraph</p>
  <ul>
    <li>List item 1</li>
    <li>List item 2</li>
  </ul>
</.prose>
Prose properties
elixir
Copy
            # <.prose>
  attr(:class, :string, default: "", doc: "CSS class")
  attr(:rest, :global)
  slot(:inner_block, required: false)