Callout card pattern

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.

Pattern — Callout card

*tatus* 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

Element Required Notes
Illustration / icon Recommended Decorative; supports the message
Heading Yes Single short sentence; the value proposition
Body Yes 1–2 sentences expanding the value + setting expectations
Primary action Yes One CTA; verb form (Try it, Set up shipping rules)
Secondary link Optional Inline Learn more link
Dismiss (X) Yes Topright close affordance; keyboardaccessible

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 peruser + percallout-id.
  • After dismissal, the callout NEVER re-shows (no "retry next session").
  • Peruser persistence backed by the Koder ID profile (crossdevice);

    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"

    arialabelledby="calloutheading-id"`).

  • Keyboard navigation: Tab through heading → body → primary action → secondary link → dismiss.
  • Esc on focus within the callout dismisses it.

Não-escopo

  • A/Btested CTA copy (productlevel concern).
  • Cross-device dismissal sync mechanics (handled by Koder ID).
  • Autodismiss on primaryaction click (product decides whether

    acting auto-dismisses).

Source: ../home/koder/dev/koder/meta/docs/stack/specs/patterns/callout-card.kmd