Skip to content

Design system

The hyperverse visual language. Every value below is a CSS custom property defined once per theme in src/styles/tokens/. Components reference them throughvar(--hv-*) and are written a single time for both themes. Toggle the theme in the nav: every swatch updates live.

Colour

Surfaces & borders

--hv-bgpage background
--hv-bg-elevatedelevated surface
--hv-surfacecard fill
--hv-surface-solidopaque surface
--hv-surface-hoverhover fill
--hv-borderdefault border
--hv-border-strongstrong border
--hv-border-hoverhover border
--hv-dotbackground grid dot

Text

--hv-text-strongheadings
--hv-textbody
--hv-text-mutedsecondary
--hv-text-faintcaptions

Accent, link & call to action

--hv-accent-fgaccent: fills, rules, headline type
--hv-accent-textaccent at label sizes
--hv-linklinks
--hv-link-hoverlink hover
--hv-cta-bgCTA fill

Code panel

The code panel never flips to light: code reads better on a dark ground, so every code surface uses the always-dark --hv-code-* family in both themes.

--hv-code-bgcode ground (Dracula)
--hv-code-surfacepanel section ground
--hv-code-insetreturned fragment
--hv-code-borderpanel border
--hv-code-accentaccent inside a panel
--hv-code-oksuccess inside a panel

Status

CRAN 0.2.0In developmentPlanned

Spacing

8px base rhythm. Use var(--hv-space-N), never a raw pixel value.

--hv-space-14px
--hv-space-28px
--hv-space-312px
--hv-space-416px
--hv-space-520px
--hv-space-624px
--hv-space-832px
--hv-space-1040px
--hv-space-1248px
--hv-space-1664px
--hv-space-2080px
--hv-space-30120px

Radii

--hv-radius-sm4px · inline code, micro badges
--hv-radius-md6px · buttons, inputs, chips
--hv-radius-lg12px · cards, panels
--hv-radius-xl16px · large surfaces
--hv-radius-pill999px · CTA buttons, tags

Typography

hyperverse

Ag--hv-text-xs0.75rem · micro labels, badges
Ag--hv-text-sm0.875rem · secondary, code
Ag--hv-text-base1rem · body
Ag--hv-text-md1.15rem · lead paragraph
Ag--hv-text-lg1.5rem · section heading
Ag--hv-text-xl2rem
Ag--hv-text-2xl2.75rem

Iconography

Lucide, because the brand ships lucidr. 24×24, 2px stroke, round caps, currentColor. Rendered inline at build time.

arrow-right
arrow-up-right
check
circle-check
info
lightbulb
triangle-alert
terminal
copy
package
book-open
layers
rocket
zap
github
search
code
play
sun
moon
server
globe
database

Components

Buttons

Package card

htmxr
Core: htmx primitives and plumber2 integration. Build server-driven web apps without writing JavaScript.
CRAN 0.2.0
htmxr.daisy
Opinionated DaisyUI layer on top of htmxr. Modern, accessible components with a minimal footprint.
Planned

Callouts

Note
HTML over the wire: your server returns HTML fragments, not JSON.
Safe in development
If no DSN is set, gt_connect() returns an inactive connection.
Watch the port
ignite() takes no port argument. Pass it to api_run().

Code panel

R console
install.packages("htmxr")

# development version
pak::pak("hyperverse-r/htmxr")

Shiny ↔ htmxr comparison

The signature block for the "coming from Shiny" docs: server logic on the left, the htmxr equivalent on the right.

Shiny
output$tbl <- renderTable({
  filter(df, type == input$type)
})
htmxr
#* @get /rows
function(query) {
  hx_table_rows(filter(df, type == query$type))
}

The server reacts on the left. The browser asks on the right.

DocRow, the two-column learning layout

Prose left, its code panel right, top-aligned, stacking under 720px. The right column can also carry tabs. Below, the second tab shows what the returned markup renders to, which needs no server. A genuinely live demo would be an iframe onto a running plumber2 app, and this site is static.

The fragment endpoint

The /plot route returns an HTML fragment rather than a page. When the slider moves, htmx swaps that fragment into #plot. No JSON, no manual DOM work.

#* @get /plot
#* @query bins:integer(30)
#* @serializer none
function(query) {
  generate_plot(query$bins)
}

CodeDemo

The same tabs over a larger surface, with optional browser chrome. Pass demoUrlonly when something is really served there.

api.R
#* @get /plot
#* @query bins:integer(30)
#* @serializer none
function(query) {
  generate_plot(query$bins)
}

ApiReference

Signature, description and parameter table, for reference pages. The site does not have one.htmxr's pkgdown is the reference, and duplicating it here would drift from the package.

hx_slider_input(id, label = NULL, value = 50, min = 0, max = 100, step = 1, get = NULL, trigger = NULL, target = NULL, ...)

A range input already wired to htmx attributes.

idcharacter
Element id. Also the default for name, so it becomes the query parameter.
labelcharacter = NULL
Text rendered in the <label> above the input.
valuenumeric = 50
Initial position of the slider.
minnumeric = 0
Lower bound.
maxnumeric = 100
Upper bound.
stepnumeric = 1
Granularity of the range input.
getcharacter = NULL
URL to GET when the trigger fires. Becomes hx-get.
triggercharacter = NULL
What fires the request, for example "input changed delay:300ms". Becomes hx-trigger.
targetcharacter = NULL
CSS selector of the element to swap. Becomes hx-target.

ReturnsAn htmltools <div> containing a <label> and an <input type='range'>.