This rune is part of @refrakt-md/media. Install with npm install @refrakt-md/media and add "@refrakt-md/media" to the plugins array in your refrakt.config.json.
Audio
An audio player element. Supports waveform visualisation, inline chapter markers, and connection to a named playlist rune. A paragraph becomes the description, and a list becomes inline chapter markers with timestamps.
Basic usage
A simple audio player with a source file.
{% audio src="https://archive.org/download/musopen-chopin/Nocturne%20Op.%209%20no.%202%20in%20E%20flat%20major.mp3" title="Nocturne Op. 9 No. 2 in E-flat major" artist="Frederic Chopin" /%}<div data-rune="audio">
<rf-audio waveform="false">
<script type="application/json">[{"src":"https://archive.org/download/musopen-chopin/Nocturne%20Op.%209%20no.%202%20in%20E%20flat%20major.mp3","name":"Nocturne Op. 9 No. 2 in E-flat major","artist":"Frederic Chopin"}]</script>
</rf-audio>
</div><div class="rf-audio rf-audio--false" data-waveform="false" data-rune="audio" data-density="compact">
<rf-audio waveform="false">
<script type="application/json">[{"src":"https://archive.org/download/musopen-chopin/Nocturne%20Op.%209%20no.%202%20in%20E%20flat%20major.mp3","name":"Nocturne Op. 9 No. 2 in E-flat major","artist":"Frederic Chopin"}]</script>
</rf-audio>
</div>With waveform
Enable waveform visualisation with the waveform attribute.
{% audio src="https://archive.org/download/musopen-chopin/Mazurka%20Op.%207%20no.%204%20in%20A%20flat%20major.mp3" title="Mazurka Op. 7 No. 4 in A-flat major" artist="Frederic Chopin" waveform=true /%}<div data-rune="audio" data-rune-fields="{"waveform":"true"}">
<rf-audio waveform="true">
<script type="application/json">[{"src":"https://archive.org/download/musopen-chopin/Mazurka%20Op.%207%20no.%204%20in%20A%20flat%20major.mp3","name":"Mazurka Op. 7 No. 4 in A-flat major","artist":"Frederic Chopin"}]</script>
</rf-audio>
</div><div class="rf-audio rf-audio--true" data-waveform="true" data-rune="audio" data-density="compact">
<rf-audio waveform="true">
<script type="application/json">[{"src":"https://archive.org/download/musopen-chopin/Mazurka%20Op.%207%20no.%204%20in%20A%20flat%20major.mp3","name":"Mazurka Op. 7 No. 4 in A-flat major","artist":"Frederic Chopin"}]</script>
</rf-audio>
</div>With inline chapters
Add a list inside the rune to define chapter markers. Bold text is the chapter label and parenthetical text is the timestamp.
{% audio src="https://archive.org/download/musopen-chopin/Ballade%20no.%201%20-%20Op.%2023.mp3" title="Ballade No. 1 in G minor, Op. 23" artist="Frederic Chopin" %}
A sweeping narrative arc from brooding introduction through lyrical themes to a fiery conclusion.
1. **Introduction** (0:00) Largo opening over a Neapolitan chord
2. **First Theme** (0:45) Principal theme in G minor
3. **Second Theme** (2:50) Lyrical melody in E-flat major
4. **Development** (4:30) Thematic transformation and modulation
5. **Recapitulation** (7:00) Themes return in reverse order
6. **Coda** (8:30) Presto con fuoco to the dramatic finish
{% /audio %}<div data-rune="audio">
<rf-audio waveform="false">
<script type="application/json">[{"src":"https://archive.org/download/musopen-chopin/Ballade%20no.%201%20-%20Op.%2023.mp3","name":"Ballade No. 1 in G minor, Op. 23","artist":"Frederic Chopin","chapters":[{"name":"Introduction","time":0},{"name":"First Theme","time":45},{"name":"Second Theme","time":170},{"name":"Development","time":270},{"name":"Recapitulation","time":420},{"name":"Coda","time":510}]}]</script>
</rf-audio>
<div data-name="description">
<p>A sweeping narrative arc from brooding introduction through lyrical themes to a fiery conclusion.</p>
</div>
</div>A sweeping narrative arc from brooding introduction through lyrical themes to a fiery conclusion.
<div class="rf-audio rf-audio--false" data-waveform="false" data-rune="audio" data-density="compact">
<rf-audio waveform="false">
<script type="application/json">[{"src":"https://archive.org/download/musopen-chopin/Ballade%20no.%201%20-%20Op.%2023.mp3","name":"Ballade No. 1 in G minor, Op. 23","artist":"Frederic Chopin","chapters":[{"name":"Introduction","time":0},{"name":"First Theme","time":45},{"name":"Second Theme","time":170},{"name":"Development","time":270},{"name":"Recapitulation","time":420},{"name":"Coda","time":510}]}]</script>
</rf-audio>
<div data-name="description" class="rf-audio__description" data-section="description">
<p>A sweeping narrative arc from brooding introduction through lyrical themes to a fiery conclusion.</p>
</div>
</div>Connected to a playlist
Use the playlist attribute to connect the player to a named playlist rune via its id.
{% playlist type="album" artist="Frederic Chopin" id="nocturnes" %}
# Chopin Nocturnes
- **Nocturne Op. 15 No. 1 in F major** [play](https://archive.org/download/musopen-chopin/Nocturne%20Op.%2015%20no.%201%20In%20F%20major.mp3) (5:06)
- **Nocturne Op. 27 No. 1 in C-sharp minor** [play](https://archive.org/download/musopen-chopin/Nocturne%20Op.%2027%20no.%201%20in%20C%20sharp%20minor.mp3) (5:52)
- **Nocturne Op. 32 No. 1 in B major** [play](https://archive.org/download/musopen-chopin/Nocturne%20Op.%2032%20no.%201%20in%20B%20major.mp3) (5:01)
{% /playlist %}
{% audio playlist="nocturnes" /%}<section data-field="content-section" data-rune="playlist" typeof="MusicPlaylist" data-rune-fields="{"type":"album","media-position":"top","artist":"Frederic Chopin","id":"nocturnes"}">
<meta content="Frederic Chopin" property="byArtist">
<h1 id="chopin-nocturnes" data-name="headline" property="name">Chopin Nocturnes</h1>
<ol data-name="tracks">
<li typeof="MusicRecording" data-src="https://archive.org/download/musopen-chopin/Nocturne%20Op.%2015%20no.%201%20In%20F%20major.mp3" data-field="track" property="track">
<span data-name="track-name" property="name">Nocturne Op. 15 No. 1 in F major</span>
<span data-name="track-artist" property="byArtist">Frederic Chopin</span>
<span data-name="track-duration">5:06</span>
<meta property="duration" content="PT306S">
</li>
<li typeof="MusicRecording" data-src="https://archive.org/download/musopen-chopin/Nocturne%20Op.%2027%20no.%201%20in%20C%20sharp%20minor.mp3" data-field="track" property="track">
<span data-name="track-name" property="name">Nocturne Op. 27 No. 1 in C-sharp minor</span>
<span data-name="track-artist" property="byArtist">Frederic Chopin</span>
<span data-name="track-duration">5:52</span>
<meta property="duration" content="PT352S">
</li>
<li typeof="MusicRecording" data-src="https://archive.org/download/musopen-chopin/Nocturne%20Op.%2032%20no.%201%20in%20B%20major.mp3" data-field="track" property="track">
<span data-name="track-name" property="name">Nocturne Op. 32 No. 1 in B major</span>
<span data-name="track-artist" property="byArtist">Frederic Chopin</span>
<span data-name="track-duration">5:01</span>
<meta property="duration" content="PT301S">
</li>
</ol>
</section>
<div data-rune="audio">
<rf-audio waveform="false" playlist="nocturnes">
<script type="application/json">[]</script>
</rf-audio>
</div>Chopin Nocturnes
- Nocturne Op. 15 No. 1 in F majorFrederic Chopin5:06
- Nocturne Op. 27 No. 1 in C-sharp minorFrederic Chopin5:52
- Nocturne Op. 32 No. 1 in B majorFrederic Chopin5:01
<section data-field="content-section" typeof="MusicPlaylist" class="rf-playlist rf-playlist--album" data-type="album" data-media-position="top" data-artist="Frederic Chopin" data-id="nocturnes" data-elevation="flat" data-rune="playlist" data-density="full">
<div data-name="content" class="rf-playlist__content">
<div data-name="eyebrow" data-zone="eyebrow" data-zone-layout="bar" class="rf-playlist__eyebrow">
<span class="rf-badge" data-meta-type="category">album</span>
</div>
<header data-name="preamble" class="rf-playlist__preamble" data-section="preamble">
<h1 id="chopin-nocturnes" data-name="headline" property="name" class="rf-playlist__headline" data-section="title">Chopin Nocturnes</h1>
</header>
<ol data-name="tracks" class="rf-playlist__tracks" data-sequence="numbered">
<li typeof="MusicRecording" data-src="https://archive.org/download/musopen-chopin/Nocturne%20Op.%2015%20no.%201%20In%20F%20major.mp3" data-field="track" property="track">
<span data-name="track-name" property="name">Nocturne Op. 15 No. 1 in F major</span>
<span data-name="track-artist" property="byArtist">Frederic Chopin</span>
<span data-name="track-duration">5:06</span>
<meta property="duration" content="PT306S" />
</li>
<li typeof="MusicRecording" data-src="https://archive.org/download/musopen-chopin/Nocturne%20Op.%2027%20no.%201%20in%20C%20sharp%20minor.mp3" data-field="track" property="track">
<span data-name="track-name" property="name">Nocturne Op. 27 No. 1 in C-sharp minor</span>
<span data-name="track-artist" property="byArtist">Frederic Chopin</span>
<span data-name="track-duration">5:52</span>
<meta property="duration" content="PT352S" />
</li>
<li typeof="MusicRecording" data-src="https://archive.org/download/musopen-chopin/Nocturne%20Op.%2032%20no.%201%20in%20B%20major.mp3" data-field="track" property="track">
<span data-name="track-name" property="name">Nocturne Op. 32 No. 1 in B major</span>
<span data-name="track-artist" property="byArtist">Frederic Chopin</span>
<span data-name="track-duration">5:01</span>
<meta property="duration" content="PT301S" />
</li>
</ol>
</div>
<meta content="Frederic Chopin" property="byArtist" />
</section>
<div class="rf-audio rf-audio--false" data-waveform="false" data-rune="audio" data-density="compact">
<rf-audio waveform="false" playlist="nocturnes">
<script type="application/json">[]</script>
</rf-audio>
</div>Attributes
| Attribute | Type | Required | Description |
|---|---|---|---|
src | string | — | URL of the audio file to play. |
playlist | string | — | ID of a playlist rune to load tracks from. |
title | string | — | Track title shown in the player interface. |
artist | string | — | Artist name displayed alongside the track title. |
waveform | boolean | — | Enable/disable waveform visualization in the player. |
chapters | string | — | URL of an external chapters file (WebVTT or JSON). |
Universal attributes
bg
The background layer (SPEC-088): image, video, gradient, flat overlay wash and legibility scrim, in a single injected layer behind the rune's content.
| Attribute | Type | Required | Description |
|---|---|---|---|
bg | string | — | Background preset applied to this block |
bg-from | string | — | Gradient start colour — a semantic token name (→ var(--rf-color-*)) |
bg-gradient | "to-t" | "to-b" | "to-l" | "to-r" | "to-tr" | "to-br" | "to-bl" | "to-tl" | — | Gradient direction (bounded named set) |
bg-gradient-type | "linear" | "radial" | "conic" | — | Gradient type |
bg-to | string | — | Gradient end colour — a semantic token name |
bg-via | string | — | Optional middle gradient stop — a semantic token name |
scrim | "top" | "bottom" | "left" | "right" | "none" | — | Scrim direction (heaviest edge); presence turns the scrim on, "none" opts out of the default cover scrim |
scrim-blur | "none" | "sm" | "md" | "lg" | — | Frost scrim blur amount |
scrim-strength | "sm" | "md" | "lg" | — | Gradient scrim strength |
scrim-tone | "dark" | "light" | — | Whether the scrim darkens (for light text) or lightens (for dark text) |
scrim-type | "gradient" | "frost" | — | Scrim treatment: gradient (default) or frost (backdrop blur) |
elevation
The chrome/depth ladder (SPEC-107). The skin maps each rung to a chrome bundle by attribute, so there is no BEM class.
| Attribute | Type | Required | Description |
|---|---|---|---|
elevation | "sunken" | "flush" | "flat" | "raised" | "floating" | "overlay" | "none" | "sm" | "md" | "lg" | — | Surface depth on the SPEC-107 ladder (sunken→overlay); none/sm/md/lg are deprecated aliases |
inset
Internal padding override.
| Attribute | Type | Required | Description |
|---|---|---|---|
inset | "flush" | "tight" | "default" | "loose" | "breathe" | — | Inner padding of this block |
motion
Scroll-reveal entrance (SPEC-105). The author declares the character, the theme owns the choreography, a behaviour owns the timing.
| Attribute | Type | Required | Description |
|---|---|---|---|
reveal | "none" | "fade" | "slide" | "scale" | "blur" | — | Scroll-reveal entrance character (none|fade|slide|scale|blur); the theme owns the choreography |
stagger | boolean | — | Cascade this block's items in as it reveals (no-op on single-child runes) |
prominence
Header emphasis (SPEC-107). Scales a rune's page-section header; the skin maps it to a type register by attribute, so there is no BEM class.
| Attribute | Type | Required | Description |
|---|---|---|---|
prominence | "quiet" | "normal" | "prominent" | "display" | — | Section-header emphasis (only on page-section-header family runes) |
spacing
Block-level rhythm override.
| Attribute | Type | Required | Description |
|---|---|---|---|
spacing | "flush" | "tight" | "default" | "loose" | "breathe" | — | Vertical spacing above and below this block |
substrate
Generated pattern fills (SPEC-087). Markers only — the engine sets the attributes and cell/opacity custom properties, CSS draws the pattern.
| Attribute | Type | Required | Description |
|---|---|---|---|
substrate | "dots" | "grid" | "lines" | "cross" | "checker" | "none" | — | Generated surface pattern |
substrate-fill | "inherit" | "inset" | — | Surface fill the pattern sits on (full colour stays with tint) |
substrate-opacity | "sm" | "md" | "lg" | — | Pattern ink strength |
substrate-size | "sm" | "md" | "lg" | — | Pattern cell size |
substrate-target | "self" | "media" | — | Which surface the pattern fills (overrides the rune/theme default) |
tint
Per-rune colour override (SPEC-053): a named tint from the theme registry, with inline per-token overrides layered on top.
| Attribute | Type | Required | Description |
|---|---|---|---|
tint | string | — | Color tint preset applied to this block |
tint-mode | "auto" | "dark" | "light" | — | Whether the tint adapts to auto, dark, or light mode |
width
The track a block rune occupies.
| Attribute | Type | Required | Description |
|---|---|---|---|
width | "compact" | "narrow" | "content" | "wide" | "full" | — | Maximum width constraint for this block |
| Not available | Why |
|---|---|
| dropcap, reading | this rune declares no prose body |
| frame | this rune declares neither a `frameTarget` nor a media section |