OGANIKO DESIGN SYSTEM

Persona card

One person to scan, then open in place.

Also known as audience card.

Example
flat (default and only variant)
Approved

Primary avatar

SMB owner running their own Meta campaigns

  • Already running Facebook/Meta ads
  • Wants fine-tuning, not a takeover

Campaigns underperform. Wants expert help fine-tuning what they already run themselves, not handing the whole thing to an agency.

Hypothesis

Local service business whose website doesn't convert

  • Site gets visits, few enquiries
  • Can't self-diagnose why

Tradesperson or local service company. Pays for clicks or relies on local reputation, but the landing experience loses people.

Variants
Single visual variant (flat card, matches Card's flat treatment). This is a data-review surface, not a marketing surface — no elevated resting style; shadow is reserved for the hover/focus hint only.
How it works
Each card's evidence panel expands in place via a real <button> toggling aria-expanded and the panel's hidden attribute — no modal, no animation on the reveal itself (only the hover shadow is animated, and that's disabled under prefers-reduced-motion). Multiple cards can be expanded at once, because comparing avatars side by side is the actual task this pattern serves. The collection grid is repeat(auto-fill, minmax(280px, 1fr)), collapsing 3→2→1 columns at 1024px/640px using the same breakpoint tokens as the rest of the OGANIKO Design System — no device-named breakpoints. The status pill (Hypothesis/Approved/Validated) is an approval-lifecycle axis, independent of "primary" (which avatar is the anchor) — a primary avatar can still be a hypothesis. An empty avatar set still renders one dashed-border placeholder card, never a blank page.

Known gap: the shared --color-border-focus token (used for the toggle's focus ring) computes to roughly 2.0–2.2:1 contrast against the card/muted backgrounds, under the WCAG 1.4.11 non-text floor of 3:1. Inherited from the existing Button component's own focus treatment (same token) — not patched here alone to avoid a one-off inconsistency; flagged as a design-system-level issue. Full detail in components/persona-card/SPEC.md "Known gaps."
Relationships
Shares its flat surface treatment with Card. No composition dependency on Header, Tabs, Footer, Carousel, or Lightbox.
Parameters
NameTypeDefaultDescription
idstring—Short code shown in the mark badge (e.g. A1)
titlestring—Role framing, one line
statusstring—hypothesis | approved | validated — approval-lifecycle axis, independent of primary
primarybooleanfalseRenders a small text label, not a pill, so it never competes visually with the status pill
traitsstring[]—2–4 short scan tags (pain, buying trigger, budget signal…)
bodystring—Pain statement, 1–3 sentences
evidence{quote, sourceLabel, sourceHref, intakeDate}[][]Zero or more citations shown in the expanded panel
Tokens
--color-bg-card --color-border --color-border-focus --color-bg-muted --color-gray-dark --color-white --color-black --color-success --color-info --color-warning --color-text --color-text-secondary --radius-lg --radius-md --radius-full --shadow-sm --spacing-1 --spacing-2 --spacing-3 --spacing-4 --spacing-6 --text-xs --text-sm --text-lg --weight-bold --weight-semibold --transition-base
Zero proposed tokens — every value above already existed in tokens/base.css / theme-oganiko.css before this component.
Provenance
VariantProven inLive atDate
flatOS-020-AIOS-AdCraft, Product Register v0.2 avatar review (three avatars, Phil-approved 2026-08-07)persona-card-demo.html (Tailscale-only)2026-08-07
Honest note: this is an internal review-tool demo (Operate/Read mode), not yet a client-facing or public surface. If reused outward-facing, the "no decorative accent color" strategy needs revisiting — see components/persona-card/SPEC.md.
Code
os-006 · Source: packages/persona-card.css ▾
<article class="persona-card">
  <div class="persona-card__head">
    <div class="persona-mark" aria-hidden="true">A1</div>
    <span class="persona-status persona-status--approved">Approved</span>
  </div>
  <p class="persona-primary-tag">Primary avatar</p>
  <h3 class="persona-title">Role framing, one line</h3>
  <ul class="persona-traits"><li>Trait</li></ul>
  <p class="persona-body">Pain statement, 1-3 sentences.</p>
  <button class="persona-toggle" type="button" aria-expanded="false"
    aria-controls="ev-a1" aria-label="Show evidence — A1: Role framing, one line">
    Show evidence — A1
  </button>
  <div class="persona-evidence" id="ev-a1" hidden>
    <div class="persona-evidence__item">
      <p class="persona-evidence__quote">&ldquo;Verbatim quote.&rdquo;</p>
      <p class="persona-evidence__source"><strong>Source:</strong> <a href="#">Title</a> · intake YYYY-MM-DD</p>
    </div>
  </div>
</article>