Dev-only component gallery at /dev/mail/gallery.
Renders every shared component × every state × light, dark, and inherited-theme side-by-side from an in-code specimen list. No DB access. No mailable scan. No preview_session assigns.
Each specimen cell is anchored with a stable data-testid="gallery-{component}-{state}"
and contains data-theme="mailglass-light", data-theme="mailglass-dark", and
no-explicit-theme system wrappers so a single structural assertion covers all theme modes.
Route: /dev/mail/gallery (mounted inside the preview live_session — dev-only by
the adopter's if dev_routes wrapping).
Coverage
- icon
- logo
- flash (error, info, success, warning kinds)
- badge (warning, stub)
- status_badge (22 atoms + phantom nil)
- nav_link, nav_pill (active, inactive, hover-ready, focus-visible, disabled, long-label)
- tenant_chip (with-tenant, no-tenant, long-tenant, non-ascii-tenant)
- theme_picker (system-selected, light-selected, dark-selected, hover-ready, focus-visible, disabled)
- stat_card (neutral, info, success, warning, error, empty, loading, unavailable, long-label, long-value)
- orientation_strip (deliveries, inbound, preview)
- shell is the full page layout — not a gallery specimen
- deliveries_list (populated-unselected, populated-selected, empty)
- detail_header (shown, absent) — operator variant only
- filters_form (empty, filled) — static assigns, no phx-submit
- filter_field (text-empty, select-filled, invalid, disabled, readonly-text, readonly-select-display, section)
- filters_form (empty, filled, invalid) — static assigns, no phx-submit
- support_cards (tier1-shown, tier1-hidden)
- suppression_card (present, absent)
- timeline (populated, highlighted-event, empty)
- replay_modal (closed) — open states require live event
- routing_trace (empty, all-passing, first-failing)
- evidence_card (no-evidence, redacted, revealed, denied)
- device_frame (inactive-btn)
- tabs (inactive-tab)
- sidebar (mailable-collapsed, mailable-expanded, scenario-active)
- data_state (empty, error, permission-denied, stale)
- deliveries_list-table (populated table/cards, data-state, long-value stress)
- records_list-table (populated table/cards, data-state, long-value stress)
- fjordline_stress (non-ascii-names, long-id, long-mailable, nil-reject) —
library-pure mirrors of the
fjordline-apspersona edge values (RATCHET-02)
fjordline-aps persona mirror (RATCHET-02 / 116-04)
The :fjordline_stress specimens reproduce — with the EXACT literals the
fjordline-aps demo persona uses (MailglassDemo.Personas.specimen_literals/0,
plan 116-01) — the four non-ASCII / long-ID / long-module-name / nil-reject edge
values so the persona drift-guard (persona_drift_guard_test.exs) stays green.
The literals are inlined here as source text (NOT a runtime call) because the
persona spec is compiled only into the admin :test build, never :dev/prod —
the dev gallery route cannot reference it. The drift-guard reads this file as
text and asserts byte-consistency with the spec. Long values use
truncate/overflow-hidden text-ellipsis at weight 400 so they never overflow.
Boundary classification: submodule auto-classifies into the
MailglassAdmin root boundary.