Page intro
StableThe top of a kit page: an eyebrow, the page’s h1, a lead and a row of facts, over film grain and a soft ceiling light.
PageIntro opens a page, and its title is the page’s <h1>, so it appears once, at the top. KitPage is the root that goes around the whole page: it paints the surface and arms the scroll arrivals and pointer light for everything inside, including the staggered entrance of the intro itself.
Updated View source
On a demo page
import { ButtonLink, delay } from '@rchursin/home/ui'import { KitPage, PageIntro, Section } from '@rchursin/product/shell/layout'
const parts: [string, string][] = [ ['Eyebrow', 'A mono label that says where you are.'], ['Title', 'The page’s one <h1>, arriving out of a soft blur.'], ['Lead', 'Two or three sentences on what the page is for.'], ['Facts', 'Optional big numbers in a row, as a description list.'],]
/** * A whole demo page: KitPage arms the arrivals, PageIntro renders the page's <h1>, * and Sections follow below on alternating grounds. */export default function PageIntroKitPage() { return ( <KitPage> <main> <PageIntro eyebrow="Demo page · Layout"Usage
import { KitPage, PageIntro } from '@rchursin/product/shell/layout'<KitPage> <main> <PageIntro eyebrow="Product kit · Timer" title="Timers that keep honest time." lead="…" facts={[['Timers', '3']]} /> </main></KitPage>API
Page intro props
| Prop | Type | Default | Description |
|---|---|---|---|
eyebrowrequired | string | – | The mono label above the title, e.g. "Product kit · Tasks". |
titlerequired | ReactNode | – | The page’s <h1>. Keep it to one line on a desktop. |
leadrequired | ReactNode | – | Two or three sentences under the title, up to 672 pixels wide. |
facts | [string, string][] | – | A row of short facts as [label, value] pairs, e.g. [["Components", "14"]]. Rendered as a <dl>. |
children | ReactNode | – | Anything after the facts, inside the same column: actions, a note. Add your own top margin. |
KitPage props
| Prop | Type | Default | Description |
|---|---|---|---|
childrenrequired | ReactNode | – | The whole page. Put <main> inside it yourself. |
className | string | – | Extra classes on the root (it already has bg-surface text-fg antialiased). |
Accessibility
- PageIntro hard-codes an <h1> for its title, inside a <section>. Use it once per page and put no other <h1> on that page.
- Facts are a description list: each label is a <dt> and each value its <dd>, so screen readers keep them paired.
- The ceiling light is aria-hidden. The hairline at the bottom is an <hr>, which some screen readers announce as a separator.
- KitPage adds no landmark of its own: it is a <div>. Wrap the content in <main>, as the example does.
- Arrivals only start hidden when motion is allowed and the script has run; with reduced motion, or before hydration, everything is visible at once.
Guidelines
Do
- Write the title as a short sentence that says what the page gives people.
- Use facts for true numbers about the page’s subject, three or four at most.
- Wrap the page in KitPage so the arrivals inside PageIntro and Section run.
Don’t
- Don’t use PageIntro twice on a page: each one is an <h1>.
- Don’t put sentences in facts; each is a short label and a value.
- Don’t use it inside a card or a dialog; it is the top of a page.
In use
Used on this site
Related
- SectionA page band with an eyebrow, an h2 and a lead, on a plain or sunken ground. SectionHeading is the heading block alone.
- ContainerA centred page column with a max width and side gutters. Container serves the home pages, Wrap the kit pages.
- Scroll arrivalsContent that fades and rises in as it scrolls into view, bars that grow, stamps that land and a frame that draws itself.
- Light & grainA ceiling halo for heroes, film grain for flat grounds, a fade for product shots and a shadow that follows torn paper.
Source
The component’s own files, exactly as they run on this site.
/** * Layout pieces for the kit pages: an intro, numbered sections, specimens (one component on a * card with a caption), a keyboard table and a short list of rules. * They share the site's finishing layer: arrivals (lux-reveal), hairlines, grain, the halo. */import type { ReactNode } from "react"import { cx } from "../../components/cx"import { useLuxe } from "../../components/motion"import { delay } from "../../home/ui"import { KeyCombo } from "../ui/button"
export function KitPage({ children, className }: { children: ReactNode; className?: string }) { const root = useLuxe<HTMLDivElement>() return ( <div ref={root} className={cx("bg-surface text-fg antialiased", className)}> {children} </div> )}