A card hero introducing a transaction or recipient — avatar, title, separator, label-value row and description, on a brand or default surface.
4368:12856 as Detail Hero, with Surface = Brand | Default and the email = yes | no boolean retired. Layer naming is complete across both variants — Title, SenderDetails, Label, Value and Description, every one matching between surfaces so each exposes as a single text property. The avatar placeholder is a deliberate swap target, the single metadata row is the intended scope, the spacer instances are a system-wide annotation convention, the typeface split against Page Banner is a decision rather than drift, and the hero is static by design. It stays filed with the header family because that is where designers look for it, even though by anatomy it is a card hero. All four DS Health traits pass; the only item still open is Code Connect, blocked until the native library exists.Detail Hero appears at the top of transaction detail screens and recipient profile cards — introducing the person or transaction below the app bar.
Add Label Here
Add description here.
Add description here.
email boolean removed the transaction-specific coupling, and the single metadata row is confirmed as the intended scope rather than a limitation.Placeholder is a deliberate swap target for consumer content rather than an unfinished avatar, so nothing external is required to render.Surface axis and brand fill, and renamed onto the §3 vocabulary — Title · Label · Value · Description, identical in both variants, with the duplicate #text and the legacy # prefix both gone.| State | iOS | Android | Figma Property | Notes |
|---|---|---|---|---|
| Default (Brand) | Yes | Yes | Surface=Brand | White title and description on the brand surface. |
| Default (Default) | Yes | Yes | Surface=Default | Dark title and description on the default white surface. |
| Pressed / Disabled | N/A | N/A | — | Static — no interactive states. |
- Code Connect mappings not registered. Blocked — no native library exists yet. The schema is otherwise settled: a single
Surfaceenum over a swap target, a title, one label-value pair and a description. C7 · Code Connect Linkability
- Renamed to Detail Hero and moved out of the Header family. v2.0: Rebuilt on node
4368:12856in the 2026 Working File. The previous assessment’s central call — that this is not a header — is settled: it has no navigation role and no title-only scope, and its anatomy is a card hero (avatar, title, separator, label-value, description). The name now says so, which also frees it from being read as a sibling of the three components that genuinely are headers. (C1 · Rename) C1 · Layer Structure & Naming -
Surface = Brand | Defaultexposed. v2.0: The same axis Page Banner and Brand App Bar landed on, so all three read consistently, and a detail hero on a settings screen can use the default surface instead of being forced onto brand blue. PascalCase per §1, Title Case values per §5, and the brand fill#1972F9matches Page Banner’s exactly. (C2 · Property) C2 · Variant & Property Naming -
email = yes | noboolean retired. v2.0: The property that hardcoded one specific metadata field into the component’s schema is gone. The API no longer claims this component is about email addresses. (C2 · Property) C2 · Variant & Property Naming - Separator alpha treatment settled. v2.1: The separator is
#F6F9FDat 24% on brand and#E5EBF4on default — the same treatment as Page Banner’s border, which the owner has confirmed as intentional and token-bound. Recorded here as covered by that decision rather than reopened per-component. (C3 · Token) C3 · Token Coverage - Layer naming pass complete across both variants. v2.2: Verified on the live node.
#title→Title,sender-details→SenderDetails, the two siblings that both read#text→LabelandValue, and#description→Description— the last of these landing in v2.3, which cleared the final cross-variant mismatch. Every text layer now carries the same name inSurface=BrandandSurface=Default, so each exposes as a single text property, and all four follow the §3 vocabulary. The legacy#prefix is gone from the component entirely. (C1 · Rename) C1 · Layer Structure & Naming - Avatar placeholder confirmed intentional. v2.2: The
Placeholderinstance is the deliberate swap target rather than an unfinished avatar — the consumer instance-swaps their own content into it, and the DS is not prescribing Avatar specifically, since a detail hero also fronts merchants and transactions that have a logo or an icon rather than a person. Attested rather than verified: instance-swap property definitions are not readable through the review tooling, so this is recorded on the owner’s confirmation. (C4 · Composition) C4 · Native Mappability - Single metadata row confirmed as the intended scope. v2.2:
SenderDetailsholds one label-value pair by design. A detail hero introduces the subject of the screen; the full metadata list belongs to the rows below it, not to the hero. Confirmed by the owner rather than left as an implied limitation, so a consumer needing several rows knows to compose them beneath rather than to extend this component. (C2 · Property) C2 · Variant & Property Naming - Spacer instances confirmed a deliberate convention. v2.2: The
_space_8/_space_12/_space_16instances are a system-wide spacing-annotation device, not layout elements left in by accident — the same pattern appears in Chip. Confirmed by the owner. Attested rather than verified: layer visibility flags are not readable through the review tooling, so the reviewer cannot see whether they render, only that they exist in the tree. (C1 · Docs) C1 · Layer Structure & Naming - Label-value typography confirmed intentional. v2.2: The row is Proxima Soft 14 here where Page Banner’s equivalent is BarkAda 14. Confirmed by the owner as a deliberate difference rather than drift — the two components carry different weight in their screens, and the review flagged it as a type-system question rather than a defect. Recorded so the split reads as a decision to anyone comparing the two. (C3 · Token) C3 · Token Coverage
- Avatar is static — no pressed state needed. v2.2: The hero is informational; nothing in it is tappable, so the absence of pressed and disabled coverage is correct rather than missing. Consistent with the rest of this family, where interaction lives in the surfaces below the hero. (C5) C5 · Interaction State Coverage
- Stays grouped with the header family in the docs. v2.3: Detail Hero is a card hero rather than a header by anatomy, and the rename records that. It nonetheless stays filed alongside Section Header, Page Banner and Brand App Bar, because that is where a designer looks for it — all four answer the question “what goes at the top of this screen?”, and splitting them across groups would hide the one comparison that matters. The naming distinction is carried by the component name, not by the filing. (Docs) C1 · Layer Structure & Naming
The minimal variant — avatar + title + divider + description. Used when the profile/transaction has no extra metadata to show.
Add Label Here
Add description here.
Add description here.
Transaction-screen header on brand surface, with avatar + title + description split by a divider.
| Role | Token | Default |
|---|---|---|
| Surface bg | main/header-transaction/bg | #1972F9 |
| Title | main/header-transaction/title | #FFFFFF |
| Description | main/header-transaction/description | #FFFFFF @ 80% |
| Divider | main/header-transaction/divider | #FFFFFF @ 24% |
Adds an inline <code>email: value</code> row between the divider and the description. Used on recipient profile cards.
Add Label Here
Add description here.
Add description here.
Same brand surface as Card 1 plus a sender-details cluster (name + email) above the description.
| Role | Token | Default |
|---|---|---|
| Surface bg | main/header-transaction/bg | #1972F9 |
| Title | main/header-transaction/title | #FFFFFF |
| Sender label | main/header-transaction/sender | #FFFFFF |
| Sender email | main/header-transaction/email | #FFFFFF @ 80% |
| Description | main/header-transaction/description | #FFFFFF @ 80% |
| Divider | main/header-transaction/divider | #FFFFFF @ 24% |
| Figma Property | SwiftUI | Compose |
|---|---|---|
| (implicit) | title: String | title: String |
| (placeholder) | avatar: Avatar (instance) | avatar: EBAvatar |
email: boolean | metadata: [LabelValuePair] | metadata: [EBLabelValue] |
| (implicit) | description?: String | description: String? |
| (implicit brand) | surface: brand | default | .ebSurface(.brand) modifier |
| Requirement | iOS | Android |
|---|---|---|
| Heading trait | Apply to the title line. | Modifier.semantics { heading() } on the title. |
| Avatar a11y | If decorative, mark .accessibilityHidden(true). If identifying, label with person's name. | Same — contentDescription empty when decorative, or person's name when identifying. |
| Label-value pairs | Group each pair with .accessibilityElement(children: .combine) so VoiceOver reads "email, juan@gmail.com" as one utterance. | Use Modifier.semantics(mergeDescendants = true) per row. |
| Contrast on brand surface | White text on #005CE5 = 8.5:1 ✓. Muted #C8D8F5 on #005CE5 = 2.1:1 — fails AA body text. Use only for secondary labels ≥14pt bold. | Same ratios — reserve muted color for label text, not body copy. |
| ID | Criterion | Status | Notes |
|---|---|---|---|
| C1 | Layer Structure & Naming | Requires Rework | "Header - Transaction" misfiled. Rename to Detail Hero. |
| C2 | Variant & Property Naming | Requires Rework | email=yes|no should become metadata: [LabelValuePair]. |
| C3 | Token Coverage | Ready | Surface, title, description tokens bound. |
| C4 | Native Mappability | Requires Rework | Avatar should be a real instance; metadata should be structured, not drawn. |
| C5 | Interaction State Coverage | Needs Refinement | Avatar pressed state not defined — needed if tappable. |
| C6 | Asset & Icon Quality | Needs Refinement | Avatar is a drawn placeholder, not a vector Avatar instance. |
| C7 | Code Connect Linkability | Not Mapped | Blocked on rehome + avatar-instance decisions. |
| # | Node | Dimensions | |
|---|---|---|---|
| 1 | 18430:2906 | no | 360 × 220 |
| 2 | 18430:2898 | yes | 360 × 191 |
email=yes|no with a flexible metadata: [LabelValuePair] slot. Open