The full-bleed loud block: eyebrow, statement, meta, and one red action, on the surface that contrasts most with the page.
Light
Today · 6:30 pm
Adult karate
Check inDark
Today · 6:30 pm
Adult karate
Check inSource:
Hero.tsx. Where a screen gets one, and where it must not: tab-home.
When to use it
- On a tab home where there is usually one obviously-next thing for this person: tonight's class on Train, the class you are teaching on Teach.
- Once per screen. It is the screen's loud block, so the screen spends nothing else on volume.
Not on a screen people came to browse — Social, Learn — where it would be a wall in front of the index. Not with a photograph: the block carries type, so it works for a dojo that has never uploaded an image.
Anatomy
| Part | Token |
|---|---|
| Block | surface.hero, full bleed (cancels spacing.page and repaints it as padding), radius 0 |
| Padding | spacing.page 20 horizontal, spacing.section 24 vertical |
| Eyebrow | typography.eyebrow 11/800 caps, accent.onHero, spacing.s8 below |
| Statement | typography.statement 46/900 caps, Archivo ExtraCondensed, text.onHero |
| Meta | typography.body 15/400, text.onHeroMuted, spacing.s12 above |
| CTA | brand.red pill, 48 floor, typography.rowTitle in caps, brand.onRed, arrow glyph, spacing.s20 above |
surface.hero inverts by theme — near-black in light, near-white in dark — so the text tokens
on it invert too. Never paint the block brand.ink: in dark it vanishes into the page.
States
Light
CTA pressed
Today · 6:30 pm
Kids
Check inCTA focus · the ring flips to border.focusOnHero
Today · 6:30 pm
Kids
Check inDark
CTA pressed
Today · 6:30 pm
Kids
Check inCTA focus · the ring flips to border.focusOnHero
Today · 6:30 pm
Kids
Check in- Long statement: reflows to three lines of
statement, then steps down totypography.display34/800 by measuring itself. It never truncates. - CTA pressed:
opacity.pressed0.85. - CTA focus: the ring flips to
border.focusOnHero, because a ring drawn inside the ink block inborder.focusfails —border.focusonsurface.herois 1.14:1.border.focusOnHeroonsurface.herois 16.86:1. - No CTA: legal. The block is then pure information.
- Disabled, loading, error: none of its own. While the next class is loading, render nothing in its place rather than an empty ink block.
Content
- The eyebrow is a time or a category, three words at most: "Today · 6:30 pm".
- The statement is the thing's name — a class, an event — not a sentence. Pass it in sentence case; the component uppercases it.
- Meta is one quiet line: who, where, when.
- The CTA is a verb: "Check in", "Start class".
Accessibility
- The block is not pressable. Only the CTA navigates — a pressable block behind a CTA would put the same destination in one viewport twice.
- The CTA is role
buttonand needs atestID; passaccessibilityLabelwhen the label alone is a fragment ("Check in to Adult karate"). - Red text on the block is
accent.onHero, neveraccent.redorbrand.red:brand.redonsurface.herois 3.77:1 and fails for text.
Do and don't
Saturday
Belt test
Open testDo
One block, one action. The block itself is not pressable.
Saturday
Belt test
Open testShareDon’t
Two filled actions on one block. Nothing is loud when everything is.
Code
import { Hero } from '../../components/ui';
<Hero
eyebrow="Today · 6:30 pm"
statement="Adult karate"
meta="Sensei Marcus · Main mat · in 4 hours"
cta={{ label: 'Check in', onPress: checkIn, testID: 'train-hero-check-in' }}
testID="train-hero"
/>
It only reaches the screen edges inside a container padded by exactly spacing.page.