# Heading Guides

## Patterns

### Section Heading

When to use:

- a page or panel needs a visible structural title

Composition notes:

- choose `as` from the document outline first
- choose `size` second based on visual rhythm

Trade-offs:

- preserves semantics and visual flexibility
- requires discipline when multiple headings are present

```tsx
import { Heading, Text } from '@vega-ui/react';

export default function DocumentOutline() {
  return (
    <article style={{ display: 'grid', gap: 'var(--spacing-12)', width: '100%', maxWidth: '60ch' }}>
      <div style={{ display: 'grid', gap: 'var(--spacing-3)' }}>
        <Heading as='h1'>Getting started</Heading>
        <Text size={3} style={{ color: 'var(--label-secondary)' }}>Set up your workspace in three steps.</Text>
      </div>
      <div style={{ display: 'grid', gap: 'var(--spacing-3)' }}>
        <Heading as='h2'>Invite your team</Heading>
        <Text size={3}>Members get access to every public project.</Text>
      </div>
      <div style={{ display: 'grid', gap: 'var(--spacing-3)' }}>
        <Heading as='h3'>Roles and permissions</Heading>
        <Text size={3}>Admins manage billing; editors can create projects.</Text>
      </div>
    </article>
  );
}
```

### Compact Hierarchy In Dense Panels

When to use:

- a dense settings page needs smaller visual headings without changing semantic level

Composition notes:

- keep the correct `as`
- reduce `size` only if the hierarchy remains clear

Trade-offs:

- saves space
- can weaken visual hierarchy if overused

```tsx
import { Card, Heading, Text } from '@vega-ui/react';

const keys = [
  { name: 'Production', created: 'Created Jan 12', lastUsed: 'Used 2 minutes ago' },
  { name: 'CI pipeline', created: 'Created Feb 3', lastUsed: 'Used yesterday' },
];

export default function CompactHierarchyInDensePanels() {
  return (
    <Card asChild size='sm' style={{ display: 'grid', gap: 'var(--spacing-6)', width: '100%' }}>
      <section aria-labelledby='api-keys-title'>
        <Heading as='h3' size={4} id='api-keys-title'>API keys</Heading>
        {keys.map((key) => (
          <div key={key.name} style={{ display: 'grid', gap: 'var(--spacing-1)' }}>
            <Heading as='h4' size={3} fontWeight={500}>{key.name}</Heading>
            <Text size={2} style={{ color: 'var(--label-secondary)' }}>{key.created} · {key.lastUsed}</Text>
          </div>
        ))}
      </section>
    </Card>
  );
}
```

### Heading With Supporting Copy

When to use:

- the section title needs a short description

Composition notes:

- keep `Heading` as the title only
- place supporting text in `Text`

Trade-offs:

- clear separation of roles
- requires one extra text element

`<hgroup>` keeps the description tied to the heading without making it part of the heading text.

```tsx
import { Heading, Text } from '@vega-ui/react';
import type { CSSProperties } from 'react';

export default function HeadingWithSupportingCopy() {
  return (
    <hgroup style={{ display: 'grid', gap: 'var(--spacing-2)', width: '100%', margin: 0 }}>
      <Heading as='h2' size={6}>Billing contacts</Heading>
      <Text asChild size={3} style={{ '--t-color': 'var(--label-secondary)' } as CSSProperties}>
        <p>Invoices and payment reminders are sent to these people.</p>
      </Text>
    </hgroup>
  );
}
```

## Comparison

### Quick Decision Rule

Use `Heading` when the text defines document or section structure. Use `Text` for prose and `Label` for form fields.

### `Heading` vs `Text`

- Use `Heading` for navigable section structure.
- Use `Text` for body copy.

### `Heading` vs `Label`

- Use `Heading` for sections or pages.
- Use `Label` for one control.

### `Heading` vs `FieldsetLegend`

- Use `Heading` for document structure.
- Use `FieldsetLegend` for native form group labeling.

### Choose This Component When

- the content should appear in the page or section outline
- visual size and semantic level need to stay independent

### Do Not Choose This Component When

- the text labels a form field
- the content is just descriptive copy

## Troubleshooting

### The UI Looks Structured But Screen Readers Do Not See Headings

#### Symptom

Large styled text appears as section titles visually, but assistive technology does not announce headings.

#### Likely Cause

`Text` or a generic element was used instead of `Heading`.

#### How To Verify

- inspect the rendered element
- confirm it is not `h1` through `h6`

#### Fix

Use `Heading` and choose the correct `as` level.

### The Heading Hierarchy Feels Broken

#### Symptom

Users see headings, but the document outline jumps unpredictably.

#### Likely Cause

Heading levels were chosen by desired font size instead of structure.

#### How To Verify

- read only the heading levels in order
- confirm they form a logical outline

#### Fix

Set `as` from the document hierarchy first, then adjust `size` for visuals.

### Headings And Labels Are Being Mixed

#### Symptom

Form sections and individual fields both use the same heading primitive, making semantics unclear.

#### Likely Cause

`Heading` is being used where `Label` or `FieldsetLegend` should be used.

#### How To Verify

- inspect whether the text names one field or a whole section

#### Fix

Use `Label` for single controls and `FieldsetLegend` for grouped controls.
