# Content Type: Contact

Changes to how this Type behaves are requested through a GitHub Issue and implemented, together with this reference page, through the repository's normal workflow. See /_docs/posts for how Content Types, Roles, and Rank work in general, and docs/Internal/type-doc-templates.md for the Content Type Doc template this file follows.

A way to get in touch — one Contact Content Element can hold several related entries at once (e.g. a Work and a Private Mail address under the same card), each rendered as an actionable link.

## Fields

A Contact Content Element holds zero or more ordered **entries**. Each entry has:

- **Kind** (mandatory) — one of a fixed, ordered list: Mail, Mobile (SMS Capable), Phone, Signal, Telegram, WhatsApp, Facebook, LinkedIn, Instagram, Home Page.
- **Value** (mandatory) — the address, number, or service handle — never a complete service URL. Kartotek builds the actual link itself; pasting a full URL is rejected with an explanation, except for Home Page, where a URL/domain is exactly what's expected.
- **Description** (optional) — free text describing the purpose of that one entry, e.g. "Work", "Private", "Press enquiries", "Booking". Repeated Kinds are allowed (e.g. two Mail entries).

## Handle storage and generated links

The Value is stored as a bare handle, not a generated URL — Kartotek owns the canonical link template per Kind (`mailto:`, `tel:`, `wa.me/…`, `signal.me/…`, `t.me/…`, `instagram.com/…`, `facebook.com/…`, `linkedin.com/…`, and a plain `https://` prefix for Home Page). A leading `@` on a handle-based Kind is stripped automatically; a telephone number's own readable spacing (e.g. "+45 12 34 56 78") is preserved in what's stored and displayed — only the generated `tel:`/`wa.me:` link itself is normalized to bare digits. Mobile and Phone are visually distinct Kinds, but both link via `tel:`; SMS is a capability of Mobile, not a second action.

A legacy entry whose stored Value still looks like a full URL (from before this Issue) remains fully functional — the link still works — but is flagged for Admin repair rather than silently accepted as the new normal.

## Semantic HTML and accessibility

Each entry renders as a native `<a>` with the Kind's own generated `href` (see above), a small fixed icon per Kind (decorative, `aria-hidden` — the Kind is understandable without color and without recognizing the icon shape, since an accessible name/hover title carrying the full Kind label always accompanies it), and the entry's own Value as the visible link text. `mailto:`/`tel:` links invoke the platform's own handler; every other Kind opens a normal external link.

## Role, Rank, and Reference

A Post can hold several Contact Content Elements at once, each its own card of one or more entries, typically distinguished by Role (e.g. `presentation`) and Rank — see /_docs/posts. Entry order *within* one element is preserved as authored. Every Contact element also has an optional **Reference** — a separate, Post-unique name for addressing it inline instead of by Role/Rank — see /_docs/posts's "Reference: inline addressing" for the full detail.

## Editing

In the admin Post editor, the Contacts section holds one block per Content Element, each with a Role field, a Position (Rank) field, and its own nested list of entries — a Kind selector, a Value field (with a live preview of the generated link, and a warning if the value still looks like a full URL), and an optional Description, with Add/Remove controls for entries within the block. Every Post Type's editor shows the same Contacts section regardless of which Type is active — used most heavily by the Category Presentation Post Type (/_docs/category-presentation), which requires at least one.

## Rendering contexts

### Inline

`{{role}}` or `{{contact:reference}}` embeds one Contact element's compact block at that position in the text: every entry, icon + linked Value, in authored order. A Description shows in parentheses after its entry's Value only when that entry's own Kind is repeated more than once *within this element* — never merely because a Description happens to be set.

### Additional Information group

Every eligible Contact Content Element gathers into one Contacts group — the same icon + linked-Value rows as inline, Rank then stable Version order for elements, entry order preserved within each. Here the Description-shown-only-when-duplicated rule is scoped to the *whole group*, not just one element — a Kind appearing twice across two different Contact cards still triggers the Description display for both. Equal Values are never deduplicated; separately authored entries stay separately shown. **Contact is a documented duplication exception** (alongside Image): a Contact element referenced inline still also appears here, unlike every other kind.

### Post metadata-page traversal

Every Contact element the Post has ever held (current Version, or full history via `/metadata/history`) is enumerated with its full entries array (Kind/Value/Description each) as JSON-LD/native JSON — see /_docs/posts's Metadata page section.

### Standalone Content Element page

`/_element/contact/:id` shows every entry on that one Content Element — Kind, the generated actionable link, and its Description always shown as text (never gated on whether the Kind repeats, unlike the compact inline/Additional Information views) — gated exactly like the owning Post's own page.

## Migration note

Existing Contact rows (an earlier `email`/`phone`/`social` model) were migrated automatically: each became its own single-entry element at its existing Role/Rank/address, with `email` → Mail, `phone` → Phone, and `social` → Home Page (the closest generic fit, since `social` previously covered six now-distinct services with no way to tell which one a given row meant). Nothing was merged — a genuinely multi-entry card only exists from this point forward, built explicitly in the admin editor.
