R RenDS v0.13.0
Layer 1 · Foundation

Primitive Zero

The lowest layer of the design system: every semantic HTML tag styled globally with tokens — no classes required.

A <blockquote> looks right because RenDS dresses it. A <kbd> has its own typographic identity. A <details> works as a basic accordion. Designers should know these tags as their base vocabulary — RenDS guarantees that each one ships with accessible typography, color, shape, and proportions by default.

When does a tag "graduate" from Primitive Zero to Primitive (with a class)?

When it needs one or more of these things: (a) variants — a <button> that also has ghost, secondary, danger; (b) sub-elements — a Card with header, body, and footer; (c) a public token API — --ren-{component}-*; (d) JavaScript for accessibility — focus trap, roving tabindex, coordination across items.

If the native HTML tag + classless is enough, it stays here.

Text & Typography

<h1> — <h6>

Heading hierarchy on the Display → Headline type scale.

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>

Use the --display-*, --title-*, and --headline-* tokens. Apply text-wrap: balance for nicer line breaks. The first heading on a page loses its top margin automatically.

<p>

Text paragraph. Use role="doc-subtitle" for a "lead" variant.

This is a lead paragraph — use it for subtitles or intros.

And this is a regular paragraph, with text-wrap: pretty and vertical margins driven by spacing tokens.

<p role="doc-subtitle">Lead paragraph</p>
<p>Regular paragraph.</p>

<a>

Link. Selector a:not([class]) — never overrides ren-link.

This is an internal link inside running text.

<a href="/path">Link text</a>

For links with variants (subtle, destructive, standalone) or icon affordances, use the ren-link primitive.

<strong> <em> <b> <i>

Strong emphasis (semibold) and soft emphasis (italic).

Text with strong emphasis, with soft emphasis, and also plain bold or plain italic.

<strong>strong emphasis</strong>
<em>soft emphasis</em>

<small>

Secondary / legal text. Caption size, muted color.

Price: $99 + tax. 12 monthly payments, 0% APR.

$99 <small>+ tax</small>

<mark>

Highlighted text (yellow highlight).

The word found appears in this text.

the word <mark>found</mark> here

<time>

Semantic date / time. Tabular-nums for column alignment.

Published

·

·

<time datetime="2026-04-16">Apr 16, 2026</time>

<code>

Inline code. Mono font with a subtle pill background.

Run npm install to install the dependencies.

run <code>npm install</code>

<pre>

Preformatted code block. Mono, overflow-x, tab-size.

function hello(name) {
  return `Hello, ${name}`;
}
<pre><code>function hello(name) {
  return `Hello, ${name}`;
}</code></pre>

<kbd>

Keyboard key. "3D" effect via a 2px bottom border.

Press Cmd + K to open search.

<kbd>Cmd</kbd> + <kbd>K</kbd>

<samp>

Program output. Mono and muted to distinguish from <code>.

Output: added 1 package in 2s

Output: <samp>added 1 package</samp>

<var>

Mathematical or programmatic variable. Italic, tabular-nums.

The formula is E = mc², where c = 299,792,458 m/s.

<var>E</var> = <var>mc</var>²

<blockquote> + <cite>

Block quotation with an accent border. A nested <cite> is treated as the byline.

Simplicity is the ultimate sophistication.

Leonardo da Vinci
<blockquote>
  <p>Simplicity is the ultimate...</p>
  <cite>Leonardo da Vinci</cite>
</blockquote>

Contextual combination: when <cite> lives inside <blockquote>, it becomes a block with an automatic em-dash prefix.

<q>

Inline quotation. Italic, secondary color, native quote marks.

As Ada said: the only real mistake is the one from which we learn nothing.

<q>the only real mistake</q>

<del> + <ins>

Edit tracking: removed and added. Together they form a visual diff.

The price dropped from $99 $79.

The team should must write clear code readable code.

price went from <del>$99</del> <ins>$79</ins>

Contextual combination: adjacent <del> and <ins> form a visual diff (subtle red + subtle green). Great for changelogs, edits, AI suggestions.

<abbr>

Abbreviation with a tooltip. Dotted underline, help cursor.

The WHO published a new report.

<abbr title="...">WHO</abbr>

<sub> <sup>

Subscript and superscript. 75% size.

H2O, E = mc2, 10-9

H<sub>2</sub>O
mc<sup>2</sup>

Lists

<ul>

Unordered list. Disc → circle → square in nested levels.

  • First item
  • Second item with a nested list
    • Nested item one
    • Nested item two
  • Third item
<ul>
  <li>Item</li>
  <li>Item with nested list
    <ul><li>nested</li></ul>
  </li>
</ul>

<ol>

Ordered list. Decimal numbering, tabular-nums on the markers.

  1. Install the dependencies
  2. Run the build
  3. Deploy to production
<ol>
  <li>Step one</li>
  <li>Step two</li>
</ol>

<dl> + <dt> + <dd>

Description list. <dt> semibold, <dd> indented and muted.

Primitive Zero
Foundational layer where every HTML tag receives global styling via classless.css.
Primitive
Atomic component with a ren-* class, variants, and a public token API.
Composed
Component built from multiple primitives. Example: Card uses surface, text, and button.
<dl>
  <dt>Term</dt>
  <dd>Definition for the term.</dd>
</dl>

Useful for glossaries, specs, and technical documentation. A <dt> can have multiple <dd> siblings (one term with several definitions).

Tables

<table> + <thead> + <tbody>

Data table. Subtle borders, optional zebra striping, tabular-nums.

Component Layer Status
ren-button Primitive Stable
ren-card Composed Beta
ren-dialog Primitive RC
<table>
  <thead>
    <tr><th>Col</th></tr>
  </thead>
  <tbody>
    <tr><td>Value</td></tr>
  </tbody>
</table>

For interactive tables (sorting, sticky headers, row selection, pagination), graduate to ren-table.

<caption> + <tfoot>

Accessible table caption and totals row.

Q1 2026 sales by region
Region Units Revenue
North1,240$124,000
South890$89,000
East1,510$151,000
West720$72,000
Total 4,360 $436,000
<table>
  <caption>Caption</caption>
  <thead>...</thead>
  <tbody>...</tbody>
  <tfoot>
    <tr><td>Total</td></tr>
  </tfoot>
</table>

The <caption> is critical for accessibility — screen readers announce it before the table content. Always present in data tables.

<th scope>

Row vs column headers via scope="row" and scope="col".

Free Pro Enterprise
Users 1 10 Unlimited
Support Community Email 24/7
<th scope="col">Column</th>
<th scope="row">Row</th>

Comparison tables and matrices should use scope so screen readers associate each cell with its headers.

Forms

<label> + <input>

Base pair. Block label, full-width input, accent-colored focus ring.

<label for="name">Name</label>
<input id="name" type="text">

For inputs with prefix/suffix, internal icons, or custom validation visuals, graduate to ren-field.

<input type="...">

Native variants: text, email, password, number, date, search, tel, url.

<input type="email">
<input type="password">
<input type="number" min="0" max="100">
<input type="date">
<input type="search">
<input type="tel">

checkbox + radio

Inline controls with accent-color driven by tokens.

<input type="checkbox">
<input type="radio" name="plan">

For groups with elaborate visual states (chip-like, card selection), graduate to ren-toggle-group.

<textarea>

Multi-line text. Vertical resize, min-height of 4 lines.

<textarea rows="3"></textarea>

<select>

Native dropdown with a built-in SVG chevron.

<select>
  <option>One</option>
  <option>Two</option>
</select>

For combobox with search, multi-select, or custom renders, graduate to ren-select.

<fieldset> + <legend>

Groups related fields. Legend at body-size with text color.

Shipping address
<fieldset>
  <legend>Group title</legend>
  <label>...</label>
  <input>
</fieldset>

Semantically critical for long forms — screen readers announce the legend before every input in the group.

<button>

Styled base button. Default variant: accent-filled.

<button>Primary action</button>
<button disabled>Disabled</button>

For secondary, ghost, destructive, icon-only, or loading states, graduate to ren-button.

<output>

Calculated form result. Mono and tabular-nums.

Sum: 100

<output name="result">100</output>

<progress>

Determinate progress. Full-width by default.

<progress value="70" max="100"></progress>

<meter>

Scalar measurement with optimal / sub-optimal / critical ranges. Automatic colors.

<meter value="0.3" min="0" max="1"
  low="0.4" high="0.7" optimum="0.2">
</meter>

Key difference vs <progress>: meter measures a static quantity (disk usage, rating); progress measures something in motion (upload, install).

<datalist>

Native autocomplete. Free-text input plus suggestions.

<input list="browsers">
<datalist id="browsers">
  <option value="Chrome">
  <option value="Firefox">
</datalist>

Interactive

<details> + <summary>

Native accordion. Opens and closes on click — no JS.

What is Primitive Zero?

It's Layer 1 of the design system — every semantic HTML tag gets base styling from tokens, with no classes. See the page intro for the full breakdown.

When should you graduate to a Primitive?

When you need variants, sub-elements, a public token API, or JS for accessibility.

<details>
  <summary>Clickable title</summary>
  <p>Expandable content.</p>
</details>

For accordions with multiple synced items (one-open-at-a-time) or custom animations, graduate to ren-accordion.

<dialog>

Native modal. Automatic backdrop, native focus trap, ESC to close.

Native dialog

This is a <dialog> opened with showModal(). Backdrop, focus trap, and ESC are automatic.

<dialog id="my-dialog">
  <h3>Title</h3>
  <p>Content</p>
  <form method="dialog">
    <button>Close</button>
  </form>
</dialog>

<script>
  dialog.showModal();
</script>

For dialog stacking, transitions, and variants (drawer, sheet), graduate to ren-dialog.

Multimedia

<img>

Responsive image. max-width:100%; height:auto by default.

400×200 placeholder image
<img src="..." alt="Description">

<figure> + <figcaption>

Image with a semantic caption. Margin reset, figcaption at caption-size.

Sample chart
Figure 1. Q1 2026 growth by region.
<figure>
  <img src="..." alt="...">
  <figcaption>Caption</figcaption>
</figure>

<video>

Native full-width player with 16:9 aspect ratio.

<video controls poster="cover.jpg">
  <source src="video.mp4" type="video/mp4">
</video>

<audio>

Native full-width player, consistent with <video>.

<audio controls>
  <source src="song.mp3" type="audio/mp3">
</audio>

<iframe>

16:9 aspect ratio by default, full-width within its container.

<iframe src="https://…" title="..."></iframe>

In production this would be a YouTube embed, Google Maps, etc. The aspect-ratio prevents collapse when no inline width/height is set.

Structure

Landmark elements (<header>, <nav>, <main>, <article>, <section>, <aside>, <footer>) are pure semantic containers. Primitive Zero applies no visual style (no background, border, or padding) — only margin and flow resets. Use them as anchors for skip links, screen reader accessibility, and style scoping.

Semantic landmarks

Containers with no visual style. Pure structure.

<header> — Page or section header
<nav> — Primary navigation menu
<main> — Primary content (one per page)
<article> — Self-contained content (post, card)
<section> — Thematic grouping with a heading
<aside> — Related but secondary content
<footer> — Page or section footer
<body>
  <header>…</header>
  <nav>…</nav>
  <main>
    <article>
      <section>…</section>
    </article>
    <aside>…</aside>
  </main>
  <footer>…</footer>
</body>

These elements never graduate to primitives — they are structure, not components. For complex layouts (sidebar + main + panel) graduate to layouts (ren-layout-*) or owner CSS (grid areas).

<hr>

Thematic separator. Uses --color-border.

First block of content.


Second block after the separator.

<p>…</p>
<hr>
<p>…</p>

<address>

Contact info. Italic reset, block display.

RenDS Team
team@rends.dev
Buenos Aires, Argentina
<address>
  <a href="mailto:…">…</a>
</address>

Contextual combinations

Primitive Zero isn't limited to styling individual tags — it also defines the visual behavior of common semantic combinations. A <cite> inside a <blockquote> changes its role (byline) and therefore its shape (block with em-dash). These rules live in classless.css and activate automatically.

<blockquote> > <cite>

Cite inside blockquote = byline. Block layout, em-dash prefix.

Design is not just what it looks like and feels like. Design is how it works.

Steve Jobs, The New York Times, 2003
<blockquote>
  <p>…</p>
  <cite>Steve Jobs</cite>  /* automatic byline */
</blockquote>

/* vs. standalone cite */
My favorite book is <cite>The Name of the Wind</cite>.

<del> + <ins>

Visual diff. Adjacent = changelog or edit track.

The price dropped from $99 $79.

The team should must write clear code readable, clear code.

price: <del>$99</del> <ins>$79</ins>

/* combinator: del + ins
   subtle red + subtle green = visual diff */

<fieldset> > <legend>

Group of fields. Legend floats over the fieldset border.

Preferences
<fieldset>
  <legend>Group title</legend>
  … inputs …
</fieldset>

<table> > <caption>

Caption as the accessible title for the table.

Recent releases
VersionDate
v3.1.0
v3.0.9
<table>
  <caption>Caption</caption>
  <thead>…</thead>
  <tbody>…</tbody>
</table>

<pre> > <code> + <samp>

Code block with mixed program output. <samp> styling is reset inside <pre> so it doesn't compete.

$ git status
On branch main
nothing to commit, working tree clean

$ npm install rends
added 1 package in 2s
<pre><code>$ git status
<samp>On branch main
nothing to commit, working tree clean</samp>
</code></pre>