# NIP: Custom Event Kinds ## Event Kinds Overview | Kind | Name | Description | |-------|----------------------|-------------------------------------------------------| | 36767 | Theme Definition | Shareable, named custom UI theme | | 16767 | Active Profile Theme | The user's currently active theme (one per user) | | 16769 | Profile Tabs | The user's custom profile page tabs (one per user) | --- ## Kind 36767: Theme Definition ### Summary Addressable event kind for publishing shareable custom UI themes. A single user may publish multiple themes, each identified by a unique `d` tag. A theme consists of colors, optional fonts, and an optional background. Colors are stored in `c` tags, fonts in `f` tags, and background in a `bg` tag. ### Event Structure ```json { "kind": 36767, "content": "", "tags": [ ["d", "mk-dark-theme"], ["c", "#1a1a2e", "background"], ["c", "#e0e0e0", "text"], ["c", "#6c3ce0", "primary"], ["f", "Inter", "https://example.com/inter.woff2"], ["bg", "url https://example.com/bg.jpg", "mode cover", "m image/jpeg", "dim 1920x1080"], ["title", "MK Dark Theme"], ["alt", "Custom theme: MK Dark Theme"] ] } ``` ### Content The `content` field is unused and MUST be an empty string (`""`). ### Tags | Tag | Required | Description | |---------|----------|---------------------------------------------------------------------------------------| | `d` | Yes | Unique identifier (slug) for this theme, e.g. `"mk-dark-theme"` | | `c` | Yes (×3) | Hex color with marker. See [Color Tags](#color-tags). | | `f` | No | Font declaration. See [Font Tag](#font-tag). | | `bg` | No | Background media. See [Background Tag](#background-tag). | | `title` | Yes | Human-readable theme name | | `alt` | Yes | NIP-31 human-readable fallback | ### Multiple Themes Per User Since kind 36767 is addressable, a user can publish multiple themes by using different `d` tag values. Publishing a new event with the same `d` tag replaces the previous version (this is how editing works). --- ## Kind 16767: Active Profile Theme ### Summary Replaceable event that represents the user's currently active profile theme. Only one per user. When other users visit a profile, they query this kind to determine what theme to display. ### Event Structure ```json { "kind": 16767, "content": "", "tags": [ ["c", "#1a1a2e", "background"], ["c", "#e0e0e0", "text"], ["c", "#6c3ce0", "primary"], ["f", "Inter", "https://example.com/inter.woff2"], ["bg", "url https://example.com/bg.jpg", "mode cover", "m image/jpeg"], ["title", "MK Dark Theme"], ["alt", "Active profile theme"] ] } ``` ### Content The `content` field is unused and MUST be an empty string (`""`). ### Tags | Tag | Required | Description | |---------|----------|---------------------------------------------------------------------------------------| | `c` | Yes (×3) | Hex color with marker. See [Color Tags](#color-tags). | | `f` | No | Font declaration. See [Font Tag](#font-tag). | | `bg` | No | Background media. See [Background Tag](#background-tag). | | `title` | No | Human-readable name for the theme | | `alt` | Yes | NIP-31 human-readable fallback | ### Client Behavior - When visiting a profile, clients query `{ kinds: [16767], authors: [pubkey], limit: 1 }` to get the active theme. - Clients read the `c` tags to extract colors, `f` tags for fonts, and `bg` tag for the background. - Setting a new active theme publishes a new kind 16767 event (replacing the old one). - To remove the active theme, publish a kind 5 deletion event targeting kind 16767. --- ## Shared Tag Definitions The following tag definitions apply to both kind 36767 and kind 16767. ### Color Tags Format: `["c", "#rrggbb", ""]` | Index | Required | Description | |-------|----------|-----------------------------------------------------------------------------------------------| | 0 | Yes | Tag name: `"c"` | | 1 | Yes | Lowercase 6-digit hex color code including the `#` sign (e.g. `"#ff0000"`) | | 2 | Yes | Color role marker: one of `"primary"`, `"text"`, or `"background"` | - All three markers (`"primary"`, `"text"`, `"background"`) MUST be present. - Only one `c` tag per marker is allowed. ### Font Tag Format: `["f", "", ""]` | Index | Required | Description | |-------|----------|-----------------------------------------------------------------------------------------------| | 0 | Yes | Tag name: `"f"` | | 1 | Yes | CSS `font-family` name (e.g. `"Inter"`) | | 2 | Yes | Direct URL to a font file (`.woff2`, `.ttf`, `.otf`) | - The `f` tag is optional on the event. - At most one `f` tag per event is allowed. - The font applies globally to all text (body, headings, UI elements). - If the URL fails to load, the client SHOULD fall back to a default font gracefully. - Variable font files (covering multiple weights in a single file) are preferred. ### Background Tag The `bg` tag uses an `imeta`-style variadic format where each entry (after the tag name) is a space-delimited key/value pair. Format: `["bg", "url ", "mode ", "m ", ...]` | Key | Required | Description | |-------------|----------|------------------------------------------------------------------------------------------| | `url` | Yes | URL to an image or video file | | `mode` | Yes | Display mode: `"cover"` or `"tile"` | | `m` | Yes | MIME type (e.g. `"image/jpeg"`, `"image/png"`, `"video/mp4"`) | | `dim` | No | Dimensions in pixels: `"x"` (e.g. `"1920x1080"`) | | `blurhash` | No | Blurhash placeholder string for progressive loading | - At most one `bg` tag is allowed per event. - Clients MAY choose not to render video backgrounds for performance or bandwidth reasons. - Unknown keys SHOULD be ignored for forward compatibility. --- ## Kind 16769: Profile Tabs ### Summary Replaceable event kind for publishing a user's custom profile page tabs. Exactly one event per user (no `d` tag). Each tab defines a Nostr filter (NIP-01) that clients execute to populate the tab's content. Visitors who load a profile fetch this event to display the custom tabs alongside the standard Posts / Media / Likes / Wall tabs. ### Event Structure ```json { "kind": 16769, "content": "", "tags": [ ["var", "$follows", "p", "a:3:$me:"], ["tab", "Bitcoin Posts", "{\"kinds\":[1],\"authors\":[\"$me\"],\"search\":\"bitcoin\"}"], ["tab", "Feed", "{\"kinds\":[1,6],\"authors\":[\"$follows\"],\"limit\":40}"], ["alt", "Custom profile tabs"] ] } ``` ### Content The `content` field is unused and MUST be an empty string (`""`). ### Tags | Tag | Format | Description | |-------|------------------------------------------------|----------------------------------------------------------------| | `tab` | `["tab", "