Overview
IRD is the markup language used to customize a profile page on iridescent.lol. It replaces the older custom HTML/CSS feature.
An IRD source file is a sequence of directives and elements. The browser parses it on every page load and renders the result as plain React components. There is no JavaScript execution, no raw HTML output, and no CSS parsing.
When to use IRD
- Adding extra cards, headings, links, or images to your profile.
- Replacing the default profile layout entirely with a custom one.
- Hiding specific built-in pieces (music plate, badges, etc.).
When not to use IRD
- Changing your accent color, particles, or avatar — those live in the regular editor tabs.
- Embedding third-party widgets (YouTube, Spotify, etc.) — not supported in v1.
Getting started
Write your first IRD program in under a minute.
- Sign in at iridescent.lol and open the editor.
- Click the IRD tab.
- Turn the IRD enabled switch on.
- Paste the snippet below into the source box.
- Click Save. View your page at
iridescent.lol/<username>.
Minimal example
@theme dark @accent #9D4CDD card padding=lg radius=20 { heading "hello" level=1 color=accent text "this is my page" color=#cccccc }
Live preview
The right-hand pane of the editor renders your IRD as you type. Parse errors appear in a panel beneath the source box with line and column numbers.
Migrating from custom HTML/CSS
If you previously had custom HTML or CSS, it is no longer rendered. Open the IRD tab and click Clear legacy HTML/CSS after porting your changes.
Syntax
An IRD file contains three kinds of statements: directives, elements, and blocks.
Directives
Top-level configuration. Always begin with @.
@theme dark @accent #9D4CDD @hide music badges
Elements
Leaf nodes that render content. The general shape is:
tag "label" -> https://url attr=value attr=value
The label and URL are optional. Attributes are name=value pairs.
text "hi" size=lg color=#fff link "github" -> https://github.com image -> https://example.com/a.png width=300
Blocks
Containers that hold other statements. Open with { and close with }.
card padding=md { text "inside the card" stack direction=row gap=sm { badge "a" badge "b" } }
Comments
Lines starting with # or // are ignored.
# this is a comment // so is this
# followed by valid hex digits is a color, not a comment. #a78bfa stays a color; #hello starts a comment.
Directives
Page-level settings. Place them at the top of your IRD source.
| Directive | Arguments | Description |
|---|---|---|
| @theme | dark · light | Default color scheme. |
| @accent | #hex | Brand color. Use color=accent on any element to reference it. |
| @font | font name | Body font for IRD content. See value types for the allowed list. |
| @bg | #hex or https URL | Background color or image for the page. |
| @hide | target list | Hide built-in profile pieces. See hiding defaults. |
| @cursor | default · pointer · none | Cursor style for the page. |
| @maxwidth | 200–1600 | Max content width in pixels. |
| @align | left · center · right | Default text alignment. |
Example
@theme dark @accent #9D4CDD @font Syne @maxwidth 800 @align center @hide profile-card music
Elements
Leaf nodes that render content.
text
A paragraph of text. Accepts a single label.
| Attribute | Values |
|---|---|
| size | xs · sm · md · lg · xl · 2xl · 3xl |
| color | #hex · accent |
| weight | light · normal · medium · semibold · bold · black |
| align | left · center · right |
| italic | true · false |
| opacity | 0–100 |
text "hello there" text "big & bold" size=2xl weight=bold
heading
Display heading at level 1, 2, or 3.
| Attribute | Values |
|---|---|
| level | 1 · 2 · 3 |
| color | #hex · accent |
| align | left · center · right |
| size | override default size |
heading "about" level=2
link
Inline anchor. Always opens in a new tab with rel="noopener noreferrer nofollow".
| Attribute | Values |
|---|---|
| -> url | https URL (required) |
| color | #hex · accent |
| underline | true · false |
| size | xs–3xl |
link "github" -> https://github.com
image
An image. HTTPS only. Images load with referrerpolicy="no-referrer".
| Attribute | Values |
|---|---|
| -> url | https URL |
| width | 16–1200 (px) |
| height | 16–1200 (px) |
| radius | 0–64 |
| alt | "caption" |
image -> https://cdn.example.com/a.png width=300 radius=12
button
Pill-shaped call to action. The URL is optional.
| Attribute | Values |
|---|---|
| -> url | https URL (optional) |
| variant | solid · outline · ghost |
| color | #hex · accent |
| size | sm · md · lg |
button "subscribe" -> https://youtube.com color=accent
badge
Small pill label.
badge "open to work" color=#10B981
divider
Horizontal rule.
divider color=#ffffff22 thickness=1
quote
Blockquote with a left border in the accent color.
quote "a line worth pulling out" color=accent
spacer
Vertical gap.
spacer size=lg
Blocks
Containers that hold other statements. Maximum nesting depth is 8.
card
A bordered panel with padding. Supports an optional label.
| Attribute | Values |
|---|---|
| padding | none · xs · sm · md · lg · xl |
| radius | 0–48 |
| bg | #rrggbbaa |
| border | #hex |
| shadow | none · sm · md · lg · glow |
| opacity | 0–100 |
| align | left · center · right |
card padding=lg radius=20 shadow=glow { heading "hi" text "inside" }
stack
Flex row or column.
| Attribute | Values |
|---|---|
| direction | row · col |
| gap | none · xs · sm · md · lg · xl |
| justify | start · center · end · between · around |
| items | start · center · end · stretch |
| wrap | true · false |
stack direction=row gap=md justify=center { badge "a" badge "b" }
grid
CSS grid with equal-width columns.
| Attribute | Values |
|---|---|
| cols | 1–6 |
| gap | none · xs · sm · md · lg · xl |
grid cols=3 gap=md { card { text "a" } card { text "b" } card { text "c" } }
section
Full-width content band.
section padding=xl { heading "manifesto" level=2 }
Animations
Add animate=name to any element or block. Optionally pair with delay=ms (0–4000).
| Name | Behaviour |
|---|---|
| none | Disable animation. |
| fade-in | Soft opacity ramp on mount. |
| slide-up | Rises into place from below. |
| slide-down | Drops in from above. |
| slide-left | Enters from the right. |
| slide-right | Enters from the left. |
| pulse | Subtle scale loop. |
| float | Up-and-down bob. |
| glow | Opacity breath. |
| shake | Periodic shake. |
| spin-slow | Continuous slow rotation. |
Stagger example
stack gap=sm { text "one" animate=slide-up delay=0 text "two" animate=slide-up delay=120 text "three" animate=slide-up delay=240 }
Value types
Every attribute accepts one of a small set of value shapes. Invalid values are silently ignored.
Strings
Wrapped in double or single quotes. Supports \n, \t, \\, and escaped quotes. Hard cap of 1000 characters per string.
"double quotes" 'single quotes'
Numbers
Plain integers or decimals. Each attribute has a bounded range; out-of-range values fall back to a default.
Colors
Hex only: #rgb, #rrggbb, or #rrggbbaa. Named colors like red are rejected.
URLs
Must start with https://. Other schemes (http, data, javascript) are rejected at the lexer.
Idents
Bare words like dark, md, row. Each attribute has its own whitelist of valid idents.
Allowed fonts
One of: Space Grotesk, Syne, DM Sans, Fira Code, Outfit, Inter, Poppins, Montserrat, Roboto Mono, Bebas Neue, Playfair Display, Lora, JetBrains Mono, Quicksand, Caveat.
Hiding default UI
Use the @hide directive to suppress built-in profile pieces and replace them with your own IRD.
| Target | Hides |
|---|---|
| profile-card | The entire default profile card. |
| avatar | The avatar circle. |
| name | The display name and username row. |
| bio | The bio text under the name. |
| badges | The badges row. |
| links | The links list. |
| music | The audio player plate. |
| follow | The follow button in the top bar. |
| enter-gate | The click-to-enter splash. |
| background | Particles, image, or video background. |
Example: replace the card entirely
@hide profile-card card padding=xl radius=24 align=center { heading "my custom page" level=1 text "100% IRD" color=#aaa }
Combining multiple targets
@hide music badges follow
Recipes
Copy-paste starting points for common layouts.
Linktree-style stack
@hide profile-card @accent #EC4899 card padding=lg radius=24 align=center { heading "@you" level=1 spacer size=sm stack gap=sm { button "twitter" -> https://twitter.com variant=outline color=accent button "youtube" -> https://youtube.com variant=outline color=accent button "spotify" -> https://spotify.com variant=outline color=accent } }
Two-column grid
@maxwidth 900 grid cols=2 gap=md { card padding=md animate=fade-in { heading "first" level=3 text "description" size=sm } card padding=md animate=fade-in delay=200 { heading "second" level=3 text "description" size=sm } }
Hide just the music plate
@hide music
Errors and limits
The parser reports errors with line and column numbers in the editor's diagnostics panel.
Hard limits
| Limit | Value |
|---|---|
| Source size | 16 KB |
| Total statements | 500 |
| Nesting depth | 8 |
| String length | 1000 chars |
| URL length | 2048 chars |
Common errors
Unterminated string literal— a quoted string was not closed on the same line.Unknown tag 'X'— the element or block name is not in the IRD vocabulary.Unknown directive '@X'— directive name is not one of the supported ones.Missing '}' for block 'X'— a block was opened but never closed.Nesting too deep (>8)— flatten your structure.Expected value for 'name='— an attribute was declared with no value.