Pular para o conteúdo

Callout card pattern

patterns specs/patterns/callout-card.kmd

Dismissible in-product nudge — illustration + heading + body + CTA — placed inside a primary surface (settings, dashboard) to surface a new capability without interrupting. Distinct from banners (status) and modals (interruption). Modeled after Polaris CalloutCard.

Quando este padrão se aplica

Triggers primários

Todos os triggers

Corpo da especificação

Pattern — Callout card

Status: v0.1.0 — Draft. Lives in specs/patterns/; rendered at kds.koder.dev/<locale>/patterns/patterns-callout-card.html.

R1 — When to use

Use a callout card when:

  • A new capability is available and you want users to discover it without forcing them to act.
  • The nudge can be safely dismissed and never re-shown without harm.

Do NOT use a callout card when:

  • The message is urgent or status-blocking (use a banner per specs/components/banners.kmd).
  • The action is required to proceed (use a modal — separate spec).
  • The user has already engaged with the feature (don't nudge what's in use).

R2 — Anatomy

ElementRequiredNotes
Illustration / iconRecommendedDecorative; supports the message
HeadingYesSingle short sentence; the value proposition
BodyYes1–2 sentences expanding the value + setting expectations
Primary actionYesOne CTA; verb form (Try it, Set up shipping rules)
Secondary linkOptionalInline Learn more link
Dismiss (X)YesTop-right close affordance; keyboard-accessible

R3 — Placement rules

  • One callout card maximum per surface (page or settings drawer).
  • Inside the primary canvas — never floating, never modal.
  • Beneath the surface's main heading, above the primary content.
  • Width: full width of the canvas; padding consistent with surrounding cards.

R4 — Dismissal

  • Dismissal MUST be persisted per-user + per-callout-id.
  • After dismissal, the callout NEVER re-shows (no "retry next session").
  • Per-user persistence backed by the Koder ID profile (cross-device); fallback to localStorage when unauthenticated.
  • A11y: the dismiss button has accessible name Dismiss {heading}.

R5 — Tone

Per specs/content/voice-and-tone.kmd marketing tone column:

  • Decisive but never pushy (Try shipping rules, not Don't miss out on shipping rules).
  • Second-person.
  • No exclamation marks.
  • No fake urgency ("Last chance", "Today only" forbidden).

R6 — i18n + Accessibility

  • All strings translatable per specs/i18n/contract.kmd.
  • Live-region announce on first appearance (role="region" aria-labelledby="callout-heading-id").
  • Keyboard navigation: Tab through heading → body → primary action → secondary link → dismiss.
  • Esc on focus within the callout dismisses it.

Não-escopo

  • A/B-tested CTA copy (product-level concern).
  • Cross-device dismissal sync mechanics (handled by Koder ID).
  • Auto-dismiss on primary-action click (product decides whether acting auto-dismisses).

Referências