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 dotText
--hv-text-strongheadings--hv-textbody--hv-text-mutedsecondary--hv-text-faintcaptionsAccent, 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 fillCode 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 panelStatus
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-30120pxRadii
--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, tagsTypography
- Display: Vampiro One. The wordmark and the hero
h1only, never UI labels or body. - Body: Lato. All prose and UI,
h2included. - Mono: JetBrains Mono. Code, signatures, technical labels.
hyperverse
--hv-text-xs0.75rem · micro labels, badges--hv-text-sm0.875rem · secondary, code--hv-text-base1rem · body--hv-text-md1.15rem · lead paragraph--hv-text-lg1.5rem · section heading--hv-text-xl2rem--hv-text-2xl2.75remIconography
Lucide, because the brand ships lucidr. 24×24, 2px stroke, round caps, currentColor. Rendered inline at build time.
Components
Buttons
Package card
Callouts
gt_connect() returns an inactive connection.
ignite() takes no port argument. Pass it to api_run().
Code panel
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.
output$tbl <- renderTable({
filter(df, type == input$type)
})#* @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.
#* @get /plot
#* @query bins:integer(30)
#* @serializer none
function(query) {
generate_plot(query$bins)
}Old Faithful eruptions
What the returned fragment renders to.
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'>.