SPEC-001
ID:SPEC-001Status:accepted

Community Runes — Specification

Package system, namespacing, rune extension, ecosystem architecture


Overview

Community runes are published packages that add domain-specific content types to refrakt.md. They go through the full rendering pipeline — parsing, rune transform, identity transform, theming — and are treated identically to core runes by the system. The only difference is where the rune definition comes from.

Community runes exist because some content types are too domain-specific for the core library but too widely shared to be local rune declarations. A D&D 5e stat block is used by thousands of game masters. A screenplay scene heading is used by thousands of screenwriters. These deserve proper packages with transforms, theme integration, inspector fixtures, and documentation.


Rune Tiers

TierScopeMaintained byInstallExamples
CoreUniversal primitives, ships with refrakt.mdrefrakt.md teamBuilt-in, always availablehint, tabs, figure, datatable, budget
Official packagesDomain-specific rune sets, maintained by refrakt.mdrefrakt.md teamnpm install @refrakt-md/...@refrakt-md/landing, @refrakt-md/storytelling
Community packagesDomain-specific rune sets, maintained by third partiesCommunity authorsnpm install @refrakt-community/...@refrakt-community/dnd-5e, @refrakt-community/screenplay
LocalPer-project declarationsProject authorConfig onlyA custom product card, a pricing calculator

All tiers produce runes that are indistinguishable to the rendering pipeline. A {% stat-block %} from a community package goes through the same parse → rune transform → identity transform → render chain as a {% hint %} from the core.

The @refrakt-md/ namespace signals official packages maintained by the refrakt.md team. @refrakt-community/ signals third-party packages. Both go through the same pipeline. The distinction is trust and maintenance commitment, not technical capability.

New Project Defaults

New projects include official packages relevant to their use case. "Starting a landing page" pre-installs @refrakt-md/landing. "Starting a docs site" pre-installs @refrakt-md/docs. Users can remove packages they don't need or add community packages. Core runes are always available and cannot be removed.


Package Inventory

Core (~27 runes, built-in)

Runes that nearly every refrakt.md project uses regardless of domain. These are content-type primitives — tools for structuring and presenting information, not tied to any specific audience.

Prose & Formatting

RuneAliasesPurpose
hintcallout, alertContextual message (note, warning, caution, check)
detailsCollapsible content with summary label
figureImage with caption
sidenotefootnote, marginnoteMargin note content
annotateMain content with margin annotations
pullquoteStyled excerpt for visual emphasis
textblockStyled block of text (lead, aside, boxed)
mediatextText alongside media layout
revealProgressive disclosure steps
conversationdialogue, chatSpeaker-attributed dialogue
embedAuto-detected media embeds (YouTube, Vimeo, Twitter, CodePen, Spotify)
galleryMulti-image container with grid/carousel layout and lightbox
statmetricKey metric display — big number with label and optional trend indicator

Navigation & Structure

RuneAliasesPurpose
gridcolumnsMulti-column layout
tabsTabbed content panels
accordionfaqCollapsible sections (FAQ support)
toctable-of-contentsAuto-generated table of contents
breadcrumbBreadcrumb navigation path
navNavigation groups with page references
layout / regionPage layout definitions and named content blocks
iconInline SVG from theme icon registry

Data & Code

RuneAliasesPurpose
datatabledata-tableInteractive table with sorting, filtering, pagination
chartData visualization from table data
diagramMermaid, PlantUML, ASCII art diagrams
mathequation, formulaMathematical notation via KaTeX/LaTeX syntax
budget3-level cost breakdown with auto-calculated totals
codegroupLanguage-tabbed code blocks
compareSide-by-side comparison panels
diffBefore/after code comparison
sandboxIsolated HTML/CSS/JS with optional framework loading
formcontact-formInteractive form from list-based field definitions

@refrakt-md/marketing (8 runes)

Marketing sites, product pages, landing pages. If you're building a website that needs to sell, convert, or present a business, you need these. If you're writing docs or a blog, you don't.

RuneAliasesPurpose
heroHero section with title, subtitle, action buttons
ctacall-to-actionCall-to-action block with headline and buttons
bentoBento grid layout with sized cells
featureFeature section with icon/name/description items
stepsStep-by-step process visualization
pricingPricing tiers with feature lists
testimonialreviewCustomer testimonials with attribution
comparisonversus, vsFeature comparison grid with positive/negative indicators

@refrakt-md/docs (3 runes)

Developer documentation. API references, code documentation, changelogs.

RuneAliasesPurpose
apiendpointAPI endpoint with method, parameters, request/response
symbolCode construct documentation (functions, classes, types)
changelogVersioned change history with categorized entries

@refrakt-md/learning (8 runes)

Structured educational and instructional content. Courses, tutorials, training materials, how-to guides, recipes.

RuneAliasesPurposeSchema.org
howtohow-toStep-by-step instructions with tools/materialsHowTo
recipeIngredients, steps, chef tips — a specialised instructional format for foodRecipe
conceptdefinitionTerm definition with explanation and related conceptsDefinedTerm
exercisePractice problem with prompt, hints, and revealable solution
quizAssessment with questions, answer options, and scoringQuiz
glossaryCollection of terms with definitions, auto-linked across the siteDefinedTermSet
prerequisiteDeclares dependencies between content ("complete X before this lesson")
objectivelearning-outcomeLearning outcome statement ("after this lesson you will be able to...")

Audience: Online course creators, tutorial authors, technical educators, bootcamp instructors, corporate training teams, cooking course sites, documentation teams writing getting-started guides.

Implementation note: glossary (auto-linking terms across the site) and prerequisite (dependency graph between content) require build pipeline integration beyond standard rune transforms. These runes are simple to render individually but their full power — site-wide term linking and learning path visualisation — depends on cross-page awareness at build time.

Runes compose naturally within a lesson page: objective at the top declares what the student will learn, concept runes introduce new terminology, howto or recipe runes teach procedures, exercise runes provide practice, and a quiz at the end tests retention. A glossary page collects all concept definitions and auto-links terms wherever they appear across the site. prerequisite runes build a dependency graph between lessons that themes can render as a learning path.

@refrakt-md/storytelling (7 runes)

Writers, game masters, TTRPG players, worldbuilders. See the Storytelling Runes specification for full details.

RunePurpose
characterStructured character profiles scaling from NPC sketch to full protagonist
realmPlace cards with atmosphere and sensory detail
factionGroups with goals, resources, and relationships
loreWorldbuilding knowledge with spoiler support
plotNarrative structure with trackable story beats
bondConnections between entities, relationship map data
storyboardVisual panels with captions for sequential storytelling

@refrakt-md/places (3 runes)

Places, events, and journeys. Geographic and time-based real-world content.

RuneAliasesPurposeSchema.org
eventEvent with speakers, agenda, venue, registrationEvent
mapMap pins with locations and descriptionsPlace
itineraryTravel/schedule planning with stops and timing

Audience: Travel bloggers, city guide creators, event organisers, tourism sites, conference sites. Future candidates for this package: accommodation (hotel/Airbnb card with amenities), venue (restaurant or bar with hours and atmosphere).

@refrakt-md/business (5 runes)

Professional and organisational content. Company sites, agency portfolios, nonprofit pages, careers pages.

RuneAliasesPurposeSchema.org
castteamPeople entries with roles and photosPerson
organizationbusinessOrganization with logo, links, profilesOrganization
timelineDated milestones with descriptionsItemList
partnerclientLogo grid of partners, clients, or investors with optional links
jobpostingJob listing with title, department, location, type, requirementsJobPosting

Audience: Company about pages, agency portfolios, nonprofit sites, startup pitch sites, careers pages, investor relations. Team page, company history, partner logos, job listings.

@refrakt-md/design (5 runes)

Design systems and component libraries. For teams documenting their visual language.

RuneAliasesPurpose
swatchInline color chip
paletteColor system with groups and scales
typographyFont specimens with weights
spacingSpacing, radius, and shadow tokens
previewshowcaseComponent preview with theme toggle, viewport simulation, source view

@refrakt-md/media (6 runes)

Time-based media content: music, podcasts, audiobooks, video, talks. Covers both metadata (describing media that lives on external platforms) and playback (embedding self-hosted media). embed in core handles third-party player widgets (YouTube, Spotify embeds). This package handles everything else.

Metadata runes — describe media with structured cards and schema.org output:

RunePurposeSchema.org (varies by type attribute)
trackSingle media item — song, podcast episode, audiobook chapter, talkMusicRecording / PodcastEpisode / AudioObject / VideoObject
playlistOrdered collection — album tracklist, podcast feed, video series, audiobookMusicPlaylist / PodcastSeries / ItemList
albumGrouped release — music album, podcast season, video season, lecture seriesMusicAlbum / PodcastSeason / TVSeason
artistCreator profile — musician, podcaster, narrator, filmmaker, speakerMusicGroup / Person

The type attribute on track, playlist, and album determines which schema.org type is generated and which attributes the AI suggests. A track with type="episode" generates PodcastEpisode schema and expects show, season, and episode number. The same rune with type="song" generates MusicRecording and expects artist and album.

Player runes — embed self-hosted media directly in the page:

RunePurposeSchema.org
videoSelf-hosted video with poster image, captions, subtitles, responsive sizingVideoObject
audioSelf-hosted audio with waveform visualization, chapters, transcriptAudioObject

The distinction: you reference a track (metadata card with links to where you listen), you play a video or audio (embedded player in the page).

Audience: Band and artist sites, podcast sites, audiobook publishers, video creators, conference talk archives, record label catalogues, film portfolios, sound design showcases, DJ mix archives.

Summary

PackageRunesAudience
Core (built-in)~30Everyone
@refrakt-md/marketing8Marketing sites, product pages
@refrakt-md/docs3Developer documentation
@refrakt-md/learning8Courses, tutorials, training materials
@refrakt-md/storytelling7Writers, game masters, worldbuilders
@refrakt-md/places3Travel, events, local guides
@refrakt-md/business5Company sites, agency portfolios
@refrakt-md/design5Design systems, component libraries
@refrakt-md/media6Music, podcasts, video, audio content
Total~75

Package Structure

A community rune package is a standard npm package with a defined structure:

@refrakt-community/dnd-5e/
  package.json
  index.ts rune registration and exports
  runes/
    item.ts rune transform for {% item %}
    item.schema.ts attribute validation schema
    stat-block.ts rune transform for {% stat-block %}
    stat-block.schema.ts
    spell.ts
    spell.schema.ts
    encounter.ts
    encounter.schema.ts
  theme/
    dnd-5e.config.ts identity transform config for all runes
    dnd-5e.css default visual styling
    assets/
      icons/ SVG icons (damage types, schools of magic, etc.)
  behaviors/
    initiative.ts interactive behaviors (encounter tracker, dice roller)
  fixtures/
    item.md inspector fixtures for each rune
    stat-block.md
    spell.md
    encounter.md
  prompt/ optional: for third-party chat products
    rune-descriptions.md AI prompt descriptions for third-party chat integration
  README.md

Registration

The package exports a registration function that the refrakt.md pipeline calls:

// index.ts
import type { RunePackage } from '@refrakt-md/types';

import { itemTransform, itemSchema } from './runes/item';
import { statBlockTransform, statBlockSchema } from './runes/stat-block';
import { spellTransform, spellSchema } from './runes/spell';
import { encounterTransform, encounterSchema } from './runes/encounter';
import { themeConfig } from './theme/dnd-5e.config';
import { behaviors } from './behaviors';

export const dnd5e: RunePackage = {
  name: 'dnd-5e',
  displayName: 'D&D 5th Edition',
  version: '1.0.0',
  
  runes: {
    'item': {
      transform: itemTransform,
      schema: itemSchema,
    },
    'stat-block': {
      transform: statBlockTransform,
      schema: statBlockSchema,
    },
    'spell': {
      transform: spellTransform,
      schema: spellSchema,
    },
    'encounter': {
      transform: encounterTransform,
      schema: encounterSchema,
    },
  },

  // Extensions to core runes (does not replace them)
  extends: {
    'character': {
      schema: {
        class: { type: 'string' },
        level: { type: 'number' },
        race: { type: 'string' },
        hp: { type: 'number' },
      }
    }
  },
  
  theme: themeConfig,
  behaviors,
};

Installation

npm install @refrakt-community/dnd-5e

Then register in the project config:

{
  "packages": ["@refrakt-community/dnd-5e"]
}

The pipeline discovers the package, registers its runes, merges schema extensions, loads its theme config and behaviors, and makes its fixtures available to the inspector.


Namespacing

Markdoc Parser Constraint

Markdoc's parser uses the dot (.) character for class shorthand syntax ({% .my-class %} equals {% class="my-class" %}), and for variable access ($markdoc.frontmatter.title). This means dots cannot appear in tag names — {% dnd-5e.item %} would be parsed as tag dnd-5e with class item, not as a namespaced rune.

This constraint shapes the namespacing design: collision resolution happens in project config, not in Markdoc syntax. Authors always write clean, unqualified rune names in their content. The project config determines which package provides each rune.

Resolution Order

When the pipeline encounters a rune tag, it resolves the name in this order:

1. Local runes      (project-level, highest priority)
2. Community runes  (installed packages)
3. Core runes       (built-in, lowest priority)

Local runes override everything — the project author is explicitly saying "I want my own version." A build warning alerts them to the shadow.

No Collision (Common Case)

Most projects install one community package per domain. The runes it defines don't collide with core runes or each other. Authors write short names with no prefix:

{% item name="Resonance Staff" rarity="legendary" %}
...
{% /item %}

{% character name="Veshra" role="antagonist" class="Warlock" level="12" %}
...
{% /character %}

{% item %} resolves to dnd-5e:item because it's the only package defining that rune. {% character %} resolves to the core character rune, extended with 5e attributes. No disambiguation needed.

Collision (Edge Case)

If two packages define the same rune name, the build fails with a clear error:

Error: Rune name 'item' is ambiguous.
  Found in: @refrakt-community/dnd-5e, @refrakt-community/pathfinder-2e
  
  Resolve by setting a preference in refrakt.config.json:
  
    "runes": {
      "prefer": {
        "item": "dnd-5e"
      }
    }

Project-Level Preference (Only Resolution Mechanism)

{
  "packages": [
    "@refrakt-community/dnd-5e",
    "@refrakt-community/pathfinder-2e"
  ],
  "runes": {
    "prefer": {
      "item": "dnd-5e",
      "spell": "dnd-5e"
    }
  }
}

Now {% item %} resolves to dnd-5e:item. The Pathfinder item rune is not available in this project — the preference is exclusive. If an author genuinely needs both packages' versions of the same rune in a single project, they should use local runes to alias one:

{
  "runes": {
    "prefer": {
      "item": "dnd-5e"
    },
    "aliases": {
      "pf-item": "pathfinder-2e:item"
    }
  }
}

Now {% item %} is the D&D version and {% pf-item %} is the Pathfinder version. The alias creates a new short name that maps to a specific package's rune. The aliased name is a first-class tag name — it works in Markdoc, in the inspector, and in theme selectors.

This keeps the Markdoc content clean:

{% item name="Longsword +1" %}
...
{% /item %}

{% pf-item name="Longsword +1" %}
...
{% /pf-item %}

No dots, no special syntax, no parser modifications. Just short names resolved by config.

Internal Qualified Identifiers

Every rune has an internal fully qualified name used by the pipeline, inspector, schema generation, and error messages:

core:callout
core:character
core:realm
dnd-5e:item
dnd-5e:stat-block
pathfinder-2e:item
local:pricing-calculator

The colon separator is used only internally — it never appears in Markdoc content. Authors never write these identifiers. They exist for tooling, error messages, and config references (like the aliases map above).

The inspector uses them in output:

$ refrakt inspect item --theme=dnd-beyond

Rune: dnd-5e:item (resolved from 'item')
...

Extending Core Runes

Community packages can extend core runes without replacing them. Extensions are additive — they add attributes, identity transform structure, and AI prompt suggestions. They never modify the core rune's transform code.

Extension Mechanism

Extension operates on three layers, none of which touch core rune transform code:

LayerWhat it doesMechanism
SchemaAdds valid attributesConfig merge at registration
IdentityUses new attributes in HTML outputThemeConfig extension
AI promptSuggests new sections and vocabularyPrompt layer addition

Schema Extension

The core character schema says "name is required, role is optional." The 5e package adds additional attributes:

// In package registration
extends: {
  'character': {
    schema: {
      class: { type: 'string' },
      level: { type: 'number' },
      race: { type: 'string' },
      hp: { type: 'number' },
      ac: { type: 'number' },
      alignment: { type: 'string' },
    }
  }
}

At registration time, the schemas are merged. The core transform runs exactly as before — it produces the same AST node with the same typeof and meta. Extra attributes pass through as data on the node. The core transform doesn't reject unknown attributes.

Identity Transform Extension

The community package provides ThemeConfig entries that use the extended attributes:

// dnd-5e.config.ts — extending character identity transform
character: {
  modifiers: {
    class: { source: 'attribute' },
    level: { source: 'attribute' },
  },
  structure: {
    statsBar: {
      tag: 'div',
      ref: 'stats-bar',
      before: true,
      condition: 'class',
      children: [
        { tag: 'span', ref: 'class-badge', metaText: 'class' },
        { tag: 'span', ref: 'level-badge', metaText: 'level', textPrefix: 'Lvl ' },
        { tag: 'span', ref: 'race-badge', metaText: 'race', condition: 'race' },
      ]
    },
    hpBar: {
      tag: 'div',
      ref: 'hp-bar',
      condition: 'hp',
      attrs: {
        'data-hp': { fromModifier: 'hp' },
        'data-ac': { fromModifier: 'ac' },
      }
    }
  }
}

A character with class="Warlock" level="12" gets a stats bar with class and level badges. A character without those attributes renders exactly as the core defines — the condition checks skip the injection.

The identity transform merges the community config with the core config for that rune. Community additions are appended, never replacing core structure:

Core config:       block, modifiers, contentWrapper
+ Community config: additional modifiers, additional structure
= Merged config:   everything, community additions layered on top

AI Prompt Extension

The community package provides additional rune descriptions for the chat AI:

<!-- prompt/rune-descriptions.md -->

When the dnd-5e package is installed:

For {% character %}, also consider these sections:
- **Stats** — Ability scores (STR, DEX, CON, INT, WIS, CHA)
- **Class Features** — Abilities from their class and level
- **Equipment** — Items they carry (can reference {% item %} runes)
- **Spells Known** — For spellcasters (can reference {% spell %} runes)

Use the `class`, `level`, `race`, `hp`, and `ac` attributes when 
the character is a game-playable entity with mechanical stats.
Omit them for narrative-only characters.

These additions are appended to the character rune's description in the mode prompt. The AI knows to generate Stats and Class Features sections when appropriate and to use the extended attributes.

What Extension Cannot Do

  • Modify core transform logic — the core rune transform is untouched
  • Remove core attributes — extensions only add, never subtract
  • Override core identity config — community structure is appended, not merged destructively
  • Change core rendering — the base rendering of the rune is unchanged; extensions add to it

The core rune is closed for modification and open for extension, through configuration rather than code inheritance.


Theme Integration

Community packages can include theme contributions at two levels:

Default Theme

A minimal CSS file that makes the package's runes look acceptable with any theme. Provides basic layout and structure without strong aesthetic opinions:

theme/
  dnd-5e.css structural styling for stat blocks, item cards, etc.

This CSS uses the design token custom properties so it adapts to whatever theme the project uses. Blue accent tokens in a corporate theme, parchment tones in a fantasy theme — the community rune's default styling follows the active design tokens.

Theme Packs

Separate packages that provide opinionated styling for community runes within a specific aesthetic:

@refrakt-community/theme-dndbeyond-style/
  theme.config.ts identity config targeting core + dnd-5e BEM classes
  theme.css full visual styling
  assets/ icons, decorative SVGs

A theme pack can target both core runes and community runes in a single package. A "D&D Beyond-style" theme styles character cards, realm cards, and faction cards (core) alongside stat blocks, item cards, and spell cards (community) in a cohesive visual language.

Inspector Integration

The inspector automatically discovers community rune fixtures and includes them in audits:

$ refrakt inspect --all --theme=dnd-beyond --audit

  CORE RUNES
  callout          8/8   selectors complete
  character        15/18 selectors 3 unstyled (dnd-5e extensions)
  ...

  COMMUNITY RUNES (dnd-5e)
  item             12/12 selectors complete
  stat-block       20/20 selectors complete
  spell            9/14  selectors 5 unstyled
  encounter        0/16  selectors not started

The audit distinguishes between core and community rune coverage and identifies which unstyled selectors come from community extensions to core runes.


Behavior Integration

Community packages can register additional behaviors for the vanilla JS behavior library:

// behaviors/index.ts
import type { BehaviorRegistry } from '@refrakt-md/behaviors';

export const behaviors: BehaviorRegistry = {
  'encounter': (el) => {
    // Initiative tracker, round counter
    const tracker = el.querySelector('[data-name="initiative"]');
    // ... wire up interactive encounter management
  },
  'spell': (el) => {
    // Spell slot tracker, concentration indicator
    // ...
  },
};

These behaviors are registered alongside the base behaviors at startup. The same detection mechanism applies — if a theme has injected Alpine or Stimulus attributes for these runes, the community behaviors step aside.


Product Boundaries

The refrakt.md Chat — Core Runes Only

The refrakt.md chat product (chat.refrakt.md) supports core runes exclusively. It does not load, render, or generate community rune content. This is a deliberate product decision, not a technical limitation.

The chat is a curated experience. Every rune the AI can generate has been tested for prompt reliability, rendering quality, and user experience. The mode prompts are tuned to specific rune vocabularies. The rendering pipeline in the chat is optimised for the known set of core runes. Opening this to arbitrary community packages would introduce untested prompt interactions, rendering edge cases, and quality variance that undermines the product.

Community runes live in the project system and site editor, where content is authored manually or imported — not generated by AI in real-time.

The Site Editor & Project System — All Tiers

The site editor and project system support all three rune tiers: core, community, and local. A refrakt.md project can install any combination of community packages. The rendering pipeline handles them identically. The inspector, audit, and theme tooling work across all tiers.

Content flows one direction: from the chat (core runes) into the site editor (all runes). A user builds a story bible with core storytelling runes in the chat, imports it into the editor, then enriches it with community runes (D&D stat blocks, items, spells) in the editor using Markdoc directly.

Third-Party Chat Products

If a domain community wants an AI-driven chat experience with their community runes — a D&D worldbuilding assistant that generates stat blocks and encounters, a screenwriting tool that generates scenes and dialogue — they build that themselves as a separate product.

The refrakt.md rendering pipeline, identity transform, theme system, and base layer are all available as infrastructure. A third party can build their own chat product using:

  • @refrakt-md/transform — the rune and identity transform pipeline
  • @refrakt-md/behaviors — the vanilla JS behavior library
  • @refrakt-md/base — base config and structural CSS
  • Their own community rune package — domain-specific transforms
  • Their own AI prompts — tuned to their rune vocabulary and domain

The refrakt.md chat is the reference implementation that demonstrates what's possible. Third parties build domain-specific chat experiences on the same foundation, with their own quality control over prompt engineering and rune generation.

This is a stronger ecosystem play than opening the chat to arbitrary packages. Every third-party chat product built on refrakt.md infrastructure validates the platform and expands the ecosystem without diluting the quality of the core product.


Publishing

Package Requirements

A community rune package must include:

RequirementPurpose
Rune transformsThe actual content transforms
Attribute schemasValidation for each rune's attributes
Inspector fixturesSample content for every rune with all variants
Default theme CSSMinimal styling that works with any theme
READMEDocumentation, usage examples, attribute reference

Optional but recommended:

OptionalPurpose
BehaviorsInteractive features for the runes
Theme configIdentity transform structural additions
Core extensionsSchema and identity additions for core runes
Prompt descriptionsAI rune descriptions for third-party chat products building on the refrakt.md pipeline

Naming Convention

@refrakt-community/[domain] rune packages
@refrakt-community/theme-[name] theme packages

Examples:

  • @refrakt-community/dnd-5e
  • @refrakt-community/pathfinder-2e
  • @refrakt-community/screenplay
  • @refrakt-community/music-theory
  • @refrakt-community/recipe-extended
  • @refrakt-community/theme-dndbeyond-style
  • @refrakt-community/theme-parchment
  • @refrakt-community/theme-cyberpunk

Validation

Before publishing, packages should pass:

# Validate package structure and requirements
refrakt package validate

# Run inspector tests against all fixtures
refrakt inspect --all --package=. --test

# Audit default theme coverage
refrakt inspect --all --package=. --audit

The refrakt package validate command checks for required files, valid schemas, correct export structure, and fixture coverage.


Example: D&D 5e Package

Runes Provided

RunePurpose
{% item %}Magic items and equipment with stats, rarity, properties
{% stat-block %}Creature/NPC stat blocks with abilities, actions, legendary actions
{% spell %}Spell cards with level, school, components, duration, description
{% encounter %}Combat scenarios with enemies, terrain, tactics, difficulty
{% class-feature %}Class and subclass abilities with level requirements

Core Extensions

Core RuneAdded AttributesAdded Sections
{% character %}class, level, race, hp, ac, alignmentStats, Class Features, Equipment, Spells Known
{% realm %}difficulty, encounter-tableEncounters, Treasure, Traps
{% faction %}base-of-operations, ally-dc, enemy-dcNPC Roster, Quest Hooks
{% lore %}dc (knowledge check DC)

Sample Usage

{% character name="Veshra" role="antagonist" class="Warlock" level="14" 
   race="Human" hp="87" ac="15" alignment="Neutral Evil" %}

![Ancient woman, white hair, dark robes, bone staff](/images/veshra.png)

## Overview
High priestess of the Waking Choir and warlock of the Sleeper.

## Stats
| STR | DEX | CON | INT | WIS | CHA |
|-----|-----|-----|-----|-----|-----|
| 8   | 12  | 14  | 16  | 18  | 20  |

## Class Features
- **Pact of the Old One** — her patron is the Sleeper itself
- **Resonance Conduit** — can channel the Sleeper's heartbeat as thunder damage
- **Tremor Sense** — 60ft, always active near the Sleeper's body

## Equipment
- {% item name="Resonance Staff" /%} (attuned)
- Robes of the Choir (no mechanical benefit)
- Component pouch

## Spells Known
- {% spell name="Eldritch Blast" /%}
- {% spell name="Thunder Step" /%}
- {% spell name="Earthquake" /%} (1/day, Sleeper patron gift)

{% /character %}

The character rune is the core rune, extended with 5e attributes and sections. The {% item %} and {% spell %} references are community runes that can render as inline links or compact cards depending on the context.


Example: Screenplay Package

Runes Provided

RunePurpose
{% scene %}Scene heading with INT/EXT, location, time of day
{% dialogue %}Character dialogue with parentheticals and cues
{% action %}Action/description lines in screenplay format
{% transition %}Scene transitions (CUT TO, FADE IN, DISSOLVE)
{% montage %}Montage sequence with individual shots

Core Extensions

Core RuneAdded AttributesAdded Sections
{% character %}first-appearance (scene number)Voice, Physicality, Casting Notes
{% realm %}set-requirementsProduction Notes, Shooting Location
{% plot %}format="episode" added to type options

This demonstrates that the community package system serves domains far beyond gaming — any structured content domain with shared conventions can benefit.


Ecosystem Vision

refrakt.md products (controlled experience)
├── Chat product (chat.refrakt.md)
   └── Core runes only curated AI experience
├── Site editor
   └── Core + official + community + local runes full authoring
└── Published sites
    └── Core + official + community + local runes full rendering

refrakt.md infrastructure (available to all)
├── @refrakt-md/transform rune + identity transform pipeline
├── @refrakt-md/behaviors vanilla JS behavior library
├── @refrakt-md/base base config + structural CSS
├── @refrakt-md/cli inspector, audit, scaffold tooling
└── Theme system identity transform, BEM contract

Official packages (maintained by refrakt.md team)
├── @refrakt-md/marketing hero, cta, bento, feature, steps, pricing, testimonial, comparison
├── @refrakt-md/docs api, symbol, changelog
├── @refrakt-md/learning howto, recipe, concept, exercise, quiz, glossary, prerequisite, objective
├── @refrakt-md/storytelling character, realm, faction, lore, plot, bond, storyboard
├── @refrakt-md/places event, map, itinerary
├── @refrakt-md/business cast, organization, timeline, partner, job
├── @refrakt-md/design swatch, palette, typography, spacing, preview
└── @refrakt-md/media track, playlist, album, artist, video, audio

Community packages (npm ecosystem)
├── Domain rune sets (dnd-5e, pathfinder-2e, screenplay, music-theory, ...)
├── Theme packs (dndbeyond-style, parchment, cyberpunk, ...)
├── Rune + theme bundles (complete domain experiences)
└── Core/official extensions (enriching built-in runes per domain)

Third-party products (built on refrakt.md infrastructure)
├── Domain-specific chat products (D&D worldbuilder, screenwriting assistant, ...)
├── Custom editors and tools
└── Specialised publishing platforms

Local runes (per-project)
└── Custom one-off runes for specific project needs

The refrakt.md chat demonstrates what's possible with AI-driven rune generation. The infrastructure makes it possible for anyone to build on the same foundation. Official packages provide curated domain rune sets maintained to the same quality standard as core. Community packages extend the ecosystem into domains that the refrakt.md team doesn't serve directly. Third-party products build independent experiences on the shared infrastructure.

The core provides the foundation. Official packages cover the common domains. The community builds everything else.