Skip to content

Marketing

ISection ​

The band a page section sits in. Handles the four things every section on a marketing page repeats — vertical rhythm, an optional tint, an optional top rule, and a centred heading block — so the page itself is left holding only its content.

vue
<ISection
  id="pricing"
  heading="One price, whatever you invoice"
  description="No percentage of what you bill."
  tone="muted"
  bordered
>
  <div class="grid gap-4 lg:grid-cols-3">
    <ICard v-for="plan in plans" :key="plan.name">…</ICard>
  </div>
</ISection>

ISection includes an IContainer. Put the section's content directly inside it; do not add another container.

That split is the whole layout model: tone, bordered and padding belong to the full-width band, and size controls the content container inside it.

Heading ​

eyebrow, heading and description are all optional, and each has a matching slot for markup. The heading renders as an h2 — a page section sits under the page's own h1.

Features

Everything the money side needs

Not a general ledger. The part of it that decides whether you get paid this month.

Leave all three out and no heading block renders at all — no empty element, and no gap above the body.

Alignment ​

center is the default, and caps the heading block at max-w-2xl so a description never runs the full width of a wide page. start left-aligns it and caps the description alone, so the heading is free to run wider than the line under it.

Aligned to the start

For a section whose body is left-aligned too.

Centred

The default.

Tone and the top rule ​

tone="muted" tints the band so it separates from the sections either side, and bordered draws a rule along the top edge. They are separate props because a rule without a tint is a common way to close a page.

Default

Muted, bordered

Bordered only

Alternating default and muted down a page is what gives a marketing site its banding, and it costs one prop per section rather than a class each time.

Rhythm ​

padding sets the vertical rhythm through a small scale rather than a raw number. Each step is responsive — md is py-20 on a phone and py-24 from sm — so the rhythm scales down on small screens.

paddingSpace
noneNone; you take it over
smpy-12 sm:py-16
mdpy-20 sm:py-24 (default)
lgpy-24 sm:py-32

The gap between the heading block and the body is fixed at mt-12, and disappears with the heading block.

Width ​

size goes straight through to the container. A section of prose or an accordion reads better narrowed:

vue
<ISection size="md" heading="Questions people ask first">
  <IAccordion :items="questions" />
</ISection>

Props ​

PropTypeDefaultDescription
eyebrowstring—Small line above the heading
headingstring—Rendered as an h2
descriptionstring—Paragraph under the heading
tone'default' | 'muted''default'Tint of the band
borderedbooleanfalseRule along the top edge
align'start' | 'center''center'Heading block alignment
padding'none' | 'sm' | 'md' | 'lg''md'Vertical rhythm
size'sm' | 'md' | 'lg' | 'xl' | 'full''xl'Container width
asstring'section'Element to render
unstyledboolean—Drop built-in classes
classstring—Merged with the built-in classes
ui{ root?, container?, header?, eyebrow?, heading?, description?, body? }—Per-element class overrides

The default section is the semantic element a page section wants. Reach for as when the surrounding document structure needs something else.

Slots ​

When both a prop and its matching slot are given, the slot wins.

SlotDescription
defaultThe section's body
eyebrowReplaces the eyebrow prop
headingReplaces the heading prop
descriptionReplaces the description prop