# Lead paragraph

> The introductory paragraph under a page title or hero headline: one p set a step above body copy, on a measure set in em so it holds about sixty characters at either size. Inherits font and colour.

- ID: `cmp_lead_paragraph_01`
- Slug: `lead-paragraph-01`
- Version: `1.0.0` (current)
- Status: published
- Published: 2026-10-01T08:06:10Z
- Updated: 2026-10-01
- Available versions: `1.0.0`
- Kind: control
- Primary category: `typography`
- Detail page: https://pagesugar.com/components/lead-paragraph-01?variant=default
- Preview: https://pagesugar.com/preview/lead-paragraph-01

## Variants

| Variant | Label | Default | Artifact digest |
| --- | --- | --- | --- |
| `default` | Inherited colour | yes | `sha256-7130b6fd8aee1cede2987217856a96f84e0b63bf590a7f8b2c501332ba78fbcc` |

## Runtime and compatibility

- Runtime: svelte
- Svelte: 5
- SvelteKit required: no (portable Svelte component)
- Tailwind CSS: 4
- SSR: supported
- Requires client-side JavaScript: no
- Integration level: presentational
- Appearance modes: light
- Suggested directory: `src/lib/components/lead-paragraph-01`

## Dependencies

No third-party runtime packages.

## Services

No external services required.

## Usage

Put the lead copy in as children, directly after your heading; choose size, alignment and tone through props. It renders one p and nothing else. It does not render the heading above it, add a drop cap, truncate long copy or set a font family.

Required props: `children`

```svelte
<script lang="ts">
	import LeadParagraph from '$lib/components/lead-paragraph-01/LeadParagraph.svelte';
</script>

<h1 class="text-4xl font-semibold tracking-tight">Bring clients into the plan</h1>
<LeadParagraph class="mt-5">
	Guests can read the roadmap, comment on milestones and follow the dates that affect them.
</LeadParagraph>

<LeadParagraph size="xl" align="center" class="mt-6">
	Boards, milestones and dependencies share one timeline.
</LeadParagraph>
```

Limitations:

- No margins are set: the space above and below the lead depends on the heading and copy around it, so pass them through class (mt-4 to mt-6 under a title is typical).
- The measure is 28em, about sixty Inter characters. A wider or narrower face changes the count; set --lead-paragraph-measure to adjust.
- No font family is set. Leading and tracking are tuned for a neo-grotesque such as Inter and may want adjusting for a serif.
- Colour is inherited from the surrounding text; there is no separate dark mode because the lead follows whatever colour its container sets.
- text-wrap: pretty and balance and word-break: auto-phrase are progressive: browsers without them wrap normally.

## Usage guide

### Lead paragraph

The paragraph that opens a page, an article or a hero, set one step above the body copy and
softer than the heading above it. It is always a `<p>`: the emphasis is visual and never
enters the outline.

```svelte
<script lang="ts">
	import LeadParagraph from '$lib/components/lead-paragraph-01/LeadParagraph.svelte';
</script>

<h1 class="text-4xl font-semibold tracking-tight">Bring clients into the plan</h1>
<LeadParagraph class="mt-5">
	Guests can read the roadmap, comment on milestones and follow the dates that affect them.
</LeadParagraph>
```

#### Sizes

| Size | Base       | From `sm`  | Tracking           | Use                          |
| ---- | ---------- | ---------- | ------------------ | ---------------------------- |
| `lg` | 18 / 28 px | 20 / 32 px | −0.011 → −0.013 em | page and section intros      |
| `xl` | 20 / 32 px | 24 / 36 px | −0.013 → −0.017 em | under a 48 px+ hero headline |

Both keep a 28em measure, about sixty characters, so the line length does not change when the
size does. Set `--lead-paragraph-measure` (in em) to change it.

#### Centred under a hero

`align="center"` centres the text and the measure and balances the lines. Keep it to two or
three lines; a longer lead reads better start-aligned.

```svelte
<LeadParagraph size="xl" align="center" class="mt-6">
	Boards, milestones and dependencies share one timeline, so a slipped date moves everything that
	waits on it.
</LeadParagraph>
```

#### Colour

The lead takes the surrounding text colour, and the default muted tone is a 72% mix of it. On a
dark band, set the band's text colour and leave the tokens alone. To tint it:

```svelte
<div style="--lead-paragraph-muted: #6b4a33">
	<LeadParagraph>Order by Thursday evening and we will hold your loaf until 11.</LeadParagraph>
</div>
```

## Props

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `size` | 'lg' \| 'xl' | no | `'lg'` | Emphasis step. lg is 18 px, rising to 20 px from the sm breakpoint; xl is 20 px rising to 24 px, for a hero. |
| `align` | 'start' \| 'center' | no | `'start'` | Alignment. start uses text-start, so it flips in right-to-left text; center also centres the measure and balances the lines. Keep centred leads to two or three lines. |
| `tone` | 'default' \| 'muted' | no | `'muted'` | Colour role. muted is a softer mix of the surrounding text colour; default is the surrounding text colour itself. |
| `id` | `string` | no |  | Id on the paragraph, for aria-describedby on a section or dialog. |
| `class` | `string` | no |  | Extra classes on the paragraph. Use it for margins; the measure is set through --lead-paragraph-measure. |
| `children` | `Snippet` | yes |  | The lead copy: text and inline elements such as a link or em. |

## Customization

Choose size, alignment and tone through props; retone with --lead-paragraph-ink and --lead-paragraph-muted, or leave both to inherit the surrounding text colour; change the line length with --lead-paragraph-measure. Edit the SIZES map in the source to change the scale.

- Colour: by default the lead takes the surrounding text colour, and the muted tone is a 72% mix of it, so it reads on white, on a dark band and on a tinted page without changes. Set --lead-paragraph-muted (or --lead-paragraph-ink for tone="default") on the lead or any ancestor for a brand tone.
- Dark or tinted page: set the container's text colour (for example text-zinc-50 on bg-zinc-950) and leave the tokens alone. On a cream page, a warm brown such as #6b4a33 for --lead-paragraph-muted keeps 4.5:1 and sits better than grey.
- Sharing a body-text tone: if your site defines a muted body colour, point the lead at it once, for example style="--lead-paragraph-muted: var(--body-text-muted)" on the page root.
- Spacing: the lead sets no margins. Under a title use mt-4 to mt-6; before a row of actions leave 32 px (mt-8) on the next element.
- Measure: the line length is --lead-paragraph-measure, 28em by default, about sixty characters at both sizes. Set it in em on the lead or any ancestor (style="--lead-paragraph-measure: 26em" for a shorter hero subhead, or none inside a column that already bounds it). A max-w-\* class does not override it.
- Scale: the SIZES map at the top of the script holds each step's size, leading and tracking as complete Tailwind classes. Keep the leading on whole four-pixel lines and the tracking tightening as the size grows.

| Token | Public CSS variable |
| --- | --- |
| `ink` | `--lead-paragraph-ink` |
| `muted` | `--lead-paragraph-muted` |
| `measure` | `--lead-paragraph-measure` |

## Accessibility

- Renders one native p. The emphasis is visual only: no role, aria-level or heading element is added, so it never enters the document outline.
- Place it directly after the heading it introduces. To have a section or dialog described by it, pass id and point aria-describedby at it.
- Sizes are in rem and the measure in em, so browser text zoom scales the type and the line length together.
- The muted tone mixes the surrounding text colour at 72%: about 8:1 for zinc-950 on white and 10:1 for zinc-50 on zinc-950. Re-check 4.5:1 if you set --lead-paragraph-muted or --lead-paragraph-ink.
- Long words and addresses wrap with overflow-wrap: anywhere, so a lead never forces horizontal scrolling at 320 px.
- Letter-spacing is removed under dir="rtl" and for Chinese, Japanese and Korean; text-start flips the alignment for right-to-left text, and the default measure tightens to 24em there because Arabic and Hebrew set more characters to the em.

Known limitations:

- Contrast is not checked by the component; it follows the colour of the surrounding text or the tokens you set.

## License

- Declared source: MIT
- Default license approval is pending. See https://pagesugar.com/docs/license.

## Source

- Palette: Inherited colour (`default`)
- Entry: `LeadParagraph.svelte`
- Suggested directory: `src/lib/components/lead-paragraph-01`
- Files: 1
- Artifact digest: `sha256-7130b6fd8aee1cede2987217856a96f84e0b63bf590a7f8b2c501332ba78fbcc`

Paths below are relative to the suggested directory. Copy the files as they are;
they import nothing from this site.

#### `LeadParagraph.svelte`

Role: entry · 3661 bytes · SHA-256 `85bb531b23490e69dcf25a05dc59179ebe1310e797b652aa5ad994c3e76dad01`

```svelte
<script lang="ts" module>
	export type LeadParagraphSize = 'lg' | 'xl';
	export type LeadParagraphAlign = 'start' | 'center';
	export type LeadParagraphTone = 'default' | 'muted';
</script>

<script lang="ts">
	import type { Snippet } from 'svelte';

	interface Props {
		/** Emphasis step. lg is 18 px rising to 20 px; xl is 20 px rising to 24 px. */
		size?: LeadParagraphSize;
		/** Text alignment. Centre also centres the measure and balances the lines. */
		align?: LeadParagraphAlign;
		/** Colour role: the surrounding text colour, or a softer mix of it. */
		tone?: LeadParagraphTone;
		/** Id on the paragraph, for aria-describedby. */
		id?: string;
		/** Extra classes on the paragraph. Use it for margins. */
		class?: string;
		/** The lead copy. */
		children: Snippet;
	}

	let {
		size = 'lg',
		align = 'start',
		tone = 'muted',
		id,
		class: className,
		children
	}: Props = $props();

	/*
	 * Each step steps up once at the sm breakpoint. Leading lands on whole four-pixel lines (28,
	 * 32, 36 px) and tracking tightens a touch as the size grows. Complete class names only.
	 */
	const SIZES: Record<LeadParagraphSize, string> = {
		lg: 'text-lg/7 tracking-[-0.011em] sm:text-xl/8 sm:tracking-[-0.013em]',
		xl: 'text-xl/8 tracking-[-0.013em] sm:text-2xl/9 sm:tracking-[-0.017em]'
	};

	/*
	 * The measure is set in em (--lead-paragraph-measure, 28em by default), so it holds about
	 * sixty characters at every size and breakpoint rather than growing wider as the type does.
	 * Centred leads are balanced, so a two-line subhead under a hero splits evenly; start-aligned
	 * ones avoid a lone last word.
	 */
	const ALIGNS: Record<LeadParagraphAlign, string> = {
		start: 'text-start text-pretty',
		center: 'mx-auto text-center text-balance'
	};

	const TONES: Record<LeadParagraphTone, string> = {
		default: 'text-(--_ink)',
		muted: 'text-(--_muted)'
	};
</script>

<p
	{id}
	class={[
		'lead-paragraph max-w-(--_measure) font-normal [overflow-wrap:anywhere]',
		SIZES[size] ?? SIZES.lg,
		ALIGNS[align] ?? ALIGNS.start,
		TONES[tone] ?? TONES.muted,
		className
	]}
>
	{@render children()}
</p>

<style>
	/*
	 * Public tokens: set --lead-paragraph-ink or --lead-paragraph-muted on the paragraph or any
	 * ancestor. By default the lead takes the surrounding text colour, and the muted tone a
	 * softer mix of it, so it reads on a white page, a dark band or a tinted card unchanged.
	 * --lead-paragraph-measure changes the line length; keep it in em so it follows the size.
	 */
	.lead-paragraph {
		--_measure: var(--lead-paragraph-measure, 28em);
		--_ink: var(--lead-paragraph-ink, currentColor);
		--_muted: var(--lead-paragraph-muted, color-mix(in srgb, currentColor 72%, transparent));
	}

	/*
	 * Arabic and Hebrew set more characters to the em than Latin, so the default measure
	 * tightens to keep right-to-left lines near sixty characters. A set token still wins.
	 */
	.lead-paragraph:dir(rtl) {
		--_measure: var(--lead-paragraph-measure, 24em);
	}

	/*
	 * Other scripts. The Latin tracking comes off for right-to-left scripts and for Chinese,
	 * Japanese and Korean. CJK lines break strictly; Korean keeps its words whole and Japanese
	 * breaks at phrase boundaries where the browser can find them.
	 */
	.lead-paragraph:dir(rtl),
	.lead-paragraph:lang(zh),
	.lead-paragraph:lang(ja),
	.lead-paragraph:lang(ko) {
		letter-spacing: 0;
	}

	.lead-paragraph:lang(zh),
	.lead-paragraph:lang(ja),
	.lead-paragraph:lang(ko) {
		line-break: strict;
	}

	.lead-paragraph:lang(ko) {
		word-break: keep-all;
	}

	@supports (word-break: auto-phrase) {
		.lead-paragraph:lang(ja) {
			word-break: auto-phrase;
		}
	}
</style>
```

## Artifacts

### Inherited colour (`default`) (default)

- Artifact digest: `sha256-7130b6fd8aee1cede2987217856a96f84e0b63bf590a7f8b2c501332ba78fbcc`
- Entry: `LeadParagraph.svelte`
- Receipt: https://pagesugar.com/artifacts/cmp_lead_paragraph_01/1.0.0/default/sha256-7130b6fd8aee1cede2987217856a96f84e0b63bf590a7f8b2c501332ba78fbcc/manifest.json
- Bundle: https://pagesugar.com/artifacts/cmp_lead_paragraph_01/1.0.0/default/sha256-7130b6fd8aee1cede2987217856a96f84e0b63bf590a7f8b2c501332ba78fbcc/bundle.zip (4172 bytes, sha256 `a3da80e819507ed1eb26b2497e2a92c23b279ad1cea31193601fbf9a84097382`)

Files:

- `LeadParagraph.svelte` (entry, 3661 bytes): https://pagesugar.com/artifacts/cmp_lead_paragraph_01/1.0.0/default/sha256-7130b6fd8aee1cede2987217856a96f84e0b63bf590a7f8b2c501332ba78fbcc/source/LeadParagraph.svelte
