---
title: "The OpenVibe Kit · OpenVibe.Design"
canonical: "https://openvibe.design/kit"
updated: null
---

# The OpenVibe Kit · OpenVibe.Design

HTML: [The OpenVibe Kit · OpenVibe.Design](https://openvibe.design/kit)

The OpenVibe Kit · v4.235.0 · MIT

# Every piece an OpenVibe page is made of

50 parts, each one function call that returns plain HTML: escaped, phone first, on the site's own theme. Pages work without JavaScript; one small file adds the menus, copy buttons and sheets. All of it is 17.8 KB of CSS. How closely each OpenVibe site follows it, read from its code: [design health](https://openvibe.report/design).

  [New in 4.78 **Layout without breakpoints** A fluid type and space scale, eight primitives that lay out by their own width, and a classless base. 3.2 KB.](/kit/layout) 

## Use it

### On your server

Every builder returns a string of HTML with its text escaped. The page is whole before any script runs.

~~~~
// npm i https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.235.0
const kit = require('openvibe-shared/kit');

res.send(kit.head({ title: 'Rooms' })
  + kit.list(rooms.map((r) => kit.row({ href: `/r/${r.slug}`, title: r.name, sub: r.topic }))));
~~~~

### In a page that draws itself

The same builders on `window.OpenVibeKit`, from the CDN with open CORS. Call `enhance` after adding markup.

~~~~
<link rel="stylesheet" href="https://openvibe.network/shared/kit.css">
<script src="https://openvibe.network/shared/kit.js"></script>
<script src="https://openvibe.network/shared/kit-web.js" defer></script>

<script>
  const box = document.querySelector('#rooms');
  box.innerHTML = OpenVibeKit.list(rooms.map((r) => OpenVibeKit.row({ title: r.name, sub: r.topic })));
  OpenVibeKit.enhance(box);
</script>
~~~~

### Copy the HTML

Each part's page prints the HTML its call returns. Keep `kit.css` and it looks the same; without OpenVibe's theme, set `--bg-*`, `--text-*` and `--accent` yourself.

- `kit.css`12.2 KB
- `kit-web.js`6.8 KB
- `kit-data.css`5.6 KB
- `kit-data-web.js`3.0 KB
- `kit.js`33.7 KB

## Actions

8

Buttons, menus and the small marks beside them.

- [Button](/kit/button) `kit.button()`

   

  One clear action: primary, quiet, ghost or danger. A link with href, a form button without.

   

  1.5 KB of CSS
- [Icon button](/kit/icon-button) `kit.iconButton()`

   

  An action that is only an icon. Its label is what a screen reader says and what the tooltip shows.

   

  1.0 KB of CSS
- [Action](/kit/action) `kit.action()`

   

  A button that posts, with an optional confirm: leave, remove, stop.

   

  1.4 KB of CSS · uses kit-web.js
- [More menu](/kit/more) `kit.more()`

   

  The rest of a row's actions, behind one button. Dangerous ones confirm.

   

  1.2 KB of CSS · uses kit-web.js
- [Share](/kit/share) `kit.share()`

   

  The one Share button: it opens the network's Share sheet, or copies the link where there is no sheet.

   

  1.4 KB of CSS · uses kit-web.js
- [Badge](/kit/badge) `kit.badge()`

   

  A word beside a title: live, new, a state. Five tones.

   

  257 B of CSS
- [Unread dot](/kit/dot) `kit.dot()`

   

  How many are new. Nothing at zero; 9+ past nine.

   

  138 B of CSS
- [Ask your agent](/kit/ask-agent) `kit.askAgent()`

   

  The chip that asks: a tap hands the question to your own agent in the Dock, with this page's context, and it never sends for you.

   

  1.5 KB of CSS · needs the shared navbar

## Content

6

Cards, rails, pictures of people and what a page says when it has nothing.

- [Card](/kit/card) `kit.card()`

   

  A stream, a clip, a room or a place: picture first, the title, who, and one line.

   

  1.3 KB of CSS
- [Rail](/kit/rail) `kit.rail()`

   

  A row of cards that scrolls sideways on a phone and wraps on a computer when asked. A long list never makes a long page.

   

  1.3 KB of CSS
- [Mark](/kit/mark) `kit.mark()`

   

  A person or a place: their picture, or up to two letters on a colour that comes from the name.

   

  199 B of CSS
- [Empty state](/kit/empty) `kit.empty()`

   

  What a page says when there is nothing yet, and the one thing to do about it.

   

  1.5 KB of CSS
- [Snippet](/kit/snippet) `kit.snippet()`

   

  Code to copy, with a copy button in the corner.

   

  1.1 KB of CSS · uses kit-web.js
- [Sheet](/kit/sheet) `kit.sheet()`

   

  More choices without leaving the page: up from the bottom on a phone, a dialog on a computer.

   

  1.9 KB of CSS · uses kit-web.js

## Layout

9

The shape of a page: its head, tabs, lists, sections and folds.

- [Head](/kit/head) `kit.head()`

   

  The top of an app page: back, the title, one muted line, icon actions and the tabs. It sticks under the navbar.

   

  1.5 KB of CSS
- [Tabs](/kit/tabs) `kit.tabs()`

   

  Links, so they work without JavaScript. For settings and explainers, never to hide content.

   

  313 B of CSS
- [List](/kit/list) `kit.list()`

   

  Rows under a title, with a link to all of them.

   

  707 B of CSS
- [Row](/kit/row) `kit.row()`

   

  A mark, the title with a badge and the time on one line, one muted line under it. The whole row is the link.

   

  607 B of CSS
- [Page head](/kit/page-head) `kit.pageHead()`

   

  The top of a page: the way back, the page's icon and title, its actions, and one line saying what it is for.

   

  1.5 KB of CSS
- [Section](/kit/section) `kit.section()`

   

  A titled block of a page, with its count and one quiet note.

   

  745 B of CSS
- [Fold](/kit/fold) `kit.fold()`

   

  A card that opens: setup, extras, the danger zone. It says what is inside and how much.

   

  1.5 KB of CSS
- [Sidebar](/kit/sidebar) `kit.sidebar()`

   

  Navigation down the left on a computer, a drawer on a phone.

   

  1.7 KB of CSS · uses kit-web.js
- [Page](/kit/page) `kit.page()`

   

  The whole shape of an app page in one call; the side column sits beside the content from 1024 px, under it below.

   

  1.1 KB of CSS

## Forms

10

Settings rows, search, the composer and the file drop.

- [Find](/kit/find) `kit.find()`

   

  A search, or "add by name": a pill with an icon, the field and a round button.

   

  518 B of CSS
- [Composer](/kit/dock) `kit.dock()`

   

  The one thing you type, pinned at the bottom. Enter sends; it grows as you write.

   

  647 B of CSS · uses kit-web.js
- [Switch row](/kit/switch-row) `kit.switchRow()`

   

  An on/off setting: the label and a hint on the left, the switch on the right.

   

  586 B of CSS
- [Range row](/kit/range-row) `kit.rangeRow()`

   

  An amount: the label, the slider and its value.

   

  463 B of CSS
- [Select row](/kit/select-row) `kit.selectRow()`

   

  One choice of several, as a row.

   

  429 B of CSS
- [Segmented](/kit/seg) `kit.seg()`

   

  Two to four choices you can see at once.

   

  423 B of CSS
- [Segmented, full width](/kit/segmented) `kit.segmented()`

   

  Three or four equal choices filling the row, each with an icon; the radios post without JavaScript.

   

  437 B of CSS
- [Chips](/kit/chips) `kit.chips()`

   

  Filters you can turn on and off, or one of a few.

   

  432 B of CSS
- [Save bar](/kit/save-bar) `kit.saveBar()`

   

  The save button of a settings form, kept in reach above the phone's app bar.

   

  1.3 KB of CSS
- [Drop](/kit/drop) `kit.drop()`

   

  Where a file goes: a real file input, plus drag and drop, paste and the phone's camera.

   

  1.7 KB of CSS · uses kit-web.js

## Data

8

Numbers, steps, tables, charts, rankings and meters.

- [Labels](/kit/labels) `kit.labels()`

   

  What a stream, recording, picture or post carries (nudity, strong language, graphic, 18+, flashing lights, spoilers), in words. Only the labels in force: a suggestion is the creator's to confirm. The page marks the thing itself with kit.labelsAttr so each viewer's own choice (show, blur, hide) applies.

   

  271 B of CSS
- [Numbers](/kit/stats) `kit.stats()`

   

  A strip of numbers that matter. Zero and unknown are left out; it scrolls sideways on a phone.

   

  436 B of CSS
- [Number](/kit/num) `kit.num()`

   

  A number the way a reader wants it: money, compact, percent, time. Missing is "–", never 0.

   

  No CSS of its own
- [Steps](/kit/steps) `kit.steps()`

   

  A flow of a few steps. Done steps link back; later ones never link ahead.

   

  742 B of CSS
- [Table](/kit/table) `kit.table()`

   

  Plans, prices, endpoints: anything compared across columns. On a phone each row becomes a card.

   

  615 B of CSS
- [Chart](/kit/chart) `kit.chart()`

   

  Line, area, bar or scatter. Text stays its real size at every width, and a table with the same numbers sits behind it.

   

  845 B of CSS · uses kit-web.js
- [Ranking](/kit/rank) `kit.rank()`

   

  A leaderboard: the place, the name, the value with its interval, the change, a bar in proportion.

   

  714 B of CSS
- [Meter](/kit/meter) `kit.meter()`

   

  How full something is. With tone auto, a limit turns amber from 75 % and red from 90 %.

   

  164 B of CSS

## Tools

6

One order for every tool page: what it does, the input, the answer, the family.

- [Tool head](/kit/tool-head) `kit.toolHead()`

   

  What the tool does, in its colour, with the facts that matter (free, no sign-in, what is kept).

   

  571 B of CSS
- [Tool input](/kit/tool-input) `kit.toolInput()`

   

  The one field a tool needs, its button, and examples to try.

   

  1.8 KB of CSS
- [Answer](/kit/answer) `kit.answer()`

   

  The answer first, then its rows, then what to do next.

   

  1.6 KB of CSS
- [Family](/kit/family) `kit.family()`

   

  The tools next to this one.

   

  459 B of CSS
- [Tool frame](/kit/tool) `kit.tool()`

   

  One order for every tool page: head, input, answer, family, folds, related.

   

  2.5 KB of CSS
- [Tries](/kit/tries) `kit.tries()`

   

  Examples a person can run with one tap.

   

  308 B of CSS

## Feedback

3

Notices, receipts and the shape of a page while it loads.

- [Notice](/kit/notice) `kit.notice()`

   

  A sentence about what just happened: ok, info, warn or error. Errors are announced.

   

  438 B of CSS
- [Receipt](/kit/receipt) `kit.receipt()`

   

  A result and what it took: the answer first, then one quiet line of facts.

   

  1.5 KB of CSS
- [Skeleton](/kit/skeleton) `kit.skeleton()`

   

  The shape of what is coming, so nothing jumps when it arrives. It never spins.

   

  322 B of CSS

## Helpers

10

Small functions with nothing to draw.

- `kit.esc(text)`: Escapes text for HTML. Every builder already does it for its text arguments.
- `kit.labelsAttr(labels)`: The data-ov-labels attribute for the labelled thing, so ov-labels.js (loaded by the navbar) applies each viewer's show, blur or hide.
- `kit.LABEL_NAMES`: The six content labels and their names in words.
- `kit.url(href)`: Keeps http(s) and same-site links; anything else becomes #.
- `kit.mediaW(url, width)`: A Media picture at a width from its resize ladder (64, 96, 160, 320, 480, 640), so an avatar is not its full upload; any other URL as kit.url gives it.
- `kit.icon(name)`: One of kit.ICONS as inline SVG, in the text's colour. The full set is at /icons.
- `kit.when(ts)`: { iso, text }: 14:05 today, Yesterday, a weekday this week, Oct 20 this year, else the date.
- `kit.hueOf(key)`: The colour a mark wears for a name: the same name, the same hue, everywhere.
- `kit.tabOf(query, keys)`: The open tab: a known key from the query, else the first.
- `kit.enhance(el)`: After a page inserts markup itself: wires copy buttons, menus, sheets and the composer.

Eleven parts are also drawn natively, in Jetpack Compose and SwiftUI: see [Components](/components). The icons are at [Icons](/icons).
