Data
Components for labelling, categorising, and presenting structured information. Badges communicate status at a glance; tables display structured tabular data.
Badges
Informational labels — never interactive. Seven semantic variants use opaque palette fills so they read clearly on any surface without dark-mode overrides.
Full reference — Badges
Variants
All seven variants share the same base dimensions. Mix freely within a layout — the distinct fills create their own visual hierarchy.
| Label | Class | Background | Use |
|---|---|---|---|
| General | .badge-general | --bm0-sand | Neutral, uncategorised content |
| Published | .badge-published | --bl3-moss | Active, live, stable, success state |
| Draft | .badge-draft | --bl1-ochre | In-progress, pending, warning state |
| Archived | .badge-archived | --bl0-ember | Deprecated, removed, error state |
| Beta | .badge-beta | --bl4-heather | Experimental feature, preview release |
| Research | .badge-research | --bl2-grain | Discovery phase, annotation, exploration |
| Category | .badge-category | --fo2-forest | Primary content category label |
Usage guidance
Choose variants by semantic meaning, not by colour preference.
| Situation | Variant |
|---|---|
| Content is live and visible to end users | Published |
| Content is being worked on and not yet live | Draft |
| Content is no longer active, or an action has failed | Archived |
| A feature is released but not yet stable | Beta |
| Item is in a discovery or annotation phase | Research |
| Label indicates content type or taxonomy | Category |
| No meaningful status or category applies | General |
One badge per item. Stacking multiple badges signals ambiguity in the data model — resolve it at the data level.
Never make badges interactive. For clickable filters or dismissible tags, use a different component. A badge communicates state; it does not change it.
Anatomy
Apply the base .badge class first, then exactly one variant modifier.
<span class="badge badge-published">Published</span>
<span class="badge badge-beta">Beta</span>CSS reference
Shipped in dist/farn-components.css. Load alongside farn.css or farn-tokens.css.
.badge {
display: inline-flex;
align-items: center;
height: 22px;
padding: 0 8px;
border-radius: var(--radius-sm);
font-size: 11px;
font-weight: 600;
letter-spacing: 0.04em;
}
.badge-general { background: var(--bm0-sand); color: var(--in0-void); }
.badge-published { background: var(--bl3-moss); color: var(--color-accent-text); }
.badge-draft { background: var(--bl1-ochre); color: var(--color-accent-text); }
.badge-archived { background: var(--bl0-ember); color: var(--color-accent-text); }
.badge-beta { background: var(--bl4-heather); color: var(--color-accent-text); }
.badge-research { background: var(--bl2-grain); color: var(--color-accent-text); }
.badge-category { background: var(--fo2-forest); color: var(--color-accent-text); }Table
A lightweight, token-driven table component. The .table base class handles borders, cell padding, and header styling. Compose with .table-striped,.table-hover, .table-sm, or .table-lg for alternating rows, hover highlights, and density variants.
Default
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Grace Hopper | Architect | Active |
| Alan Turing | Researcher | On leave |
| Margaret Hamilton | Lead | Active |
Striped
Add .table-striped for alternating row contrast using --table-row-stripe-bg.
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Grace Hopper | Architect | Active |
| Alan Turing | Researcher | On leave |
| Margaret Hamilton | Lead | Active |
Hover
Add .table-hover for a row highlight on pointer hover. Combines with .table-striped.
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Grace Hopper | Architect | Active |
| Alan Turing | Researcher | On leave |
| Margaret Hamilton | Lead | Active |
Density
.table-sm tightens cell padding for dense data views; the default suits most content; .table-lg adds breathing room for spacious layouts.
Compact — .table-sm (4px / 6px padding)
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Grace Hopper | Architect | Active |
| Alan Turing | Researcher | On leave |
Default — .table (12px / 12px padding)
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Grace Hopper | Architect | Active |
| Alan Turing | Researcher | On leave |
Comfortable — .table-lg (24px / 24px padding)
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Grace Hopper | Architect | Active |
| Alan Turing | Researcher | On leave |
Full reference — Table
Rounded corners
overflow: hidden on a border-collapse: collapse table is cross-browser unreliable. To get rounded corners, wrap the table in a container:
<div style="border-radius: var(--table-radius); overflow: hidden">
<table class="table">...</table>
</div>Scroll wrapper (narrow viewports)
Wrap with an overflow-x: auto container to allow horizontal scrolling on narrow viewports without breaking the layout.
<div style="overflow-x: auto">
<table class="table">...</table>
</div>Both wrappers can be combined on a single div.
Anatomy
<!-- Base -->
<table class="table">
<thead>
<tr><th>Name</th><th>Role</th></tr>
</thead>
<tbody>
<tr><td>Ada Lovelace</td><td>Engineer</td></tr>
</tbody>
</table>
<!-- Striped + hover -->
<table class="table table-striped table-hover">...</table>
<!-- Compact -->
<table class="table table-sm">...</table>
<!-- Comfortable -->
<table class="table table-lg">...</table>Token reference
| Token | Default | Description |
|---|---|---|
--table-border | --color-border | Cell and header border colour |
--table-header-bg | --color-bg-inset | Header row background |
--table-header-text | --color-text | Header row text colour |
--table-row-stripe-bg | --color-bg-inset | Even row background in .table-striped — inset ensures visibility on panel-bg surfaces |
--table-row-hover-bg | var(--table-row-stripe-bg) | Row background on hover in .table-hover |
--table-font-size | 0.875rem | Body cell font size |
--table-cell-padding | 12px 12px | Default cell padding (~38px rows) |
--table-cell-padding-sm | 4px 6px | Compact cell padding (~22px rows) |
--table-cell-padding-lg | 24px 24px | Comfortable cell padding (~62px rows) |
--table-radius | --radius-md | Corner radius — apply to a wrapper element |
CSS reference
.table {
width: 100%;
border-collapse: collapse;
font-size: var(--table-font-size);
}
.table th,
.table td {
padding: var(--table-cell-padding);
text-align: left;
border-bottom: 1px solid var(--table-border);
}
.table thead th {
background: var(--table-header-bg);
color: var(--table-header-text);
font-weight: 600;
font-size: 0.8125rem;
letter-spacing: 0.03em;
text-transform: uppercase;
border-bottom: 2px solid var(--table-border);
}
.table tbody tr:last-child td { border-bottom: none; }
.table-striped tbody tr:nth-child(even) td {
background: var(--table-row-stripe-bg);
}
.table-hover tbody tr:hover td {
background: var(--table-row-hover-bg);
transition: background var(--duration-fast) var(--ease-out);
}
.table-sm th, .table-sm td { padding: var(--table-cell-padding-sm); }
.table-lg th, .table-lg td { padding: var(--table-cell-padding-lg); }Code block
Shipped classes for block and inline code. Both consume --code-* Tier-3 tokens so consumers can retheme code formatting independently without touching the semantic layer. A copy-to-clipboard button is injected automatically by the reference JS module.
Block code
Apply .code-block to a <pre> element. Add <code> inside for proper semantics.
.card {
background: var(--color-bg-panel);
border-radius: var(--radius-lg);
padding: var(--space-md);
}Inline code
Use .inline-code on a <code>element within prose. It uses font-size: 0.875em so it scales with the surrounding text size.
Full reference — Code block
Anatomy
<!-- Block code -->
<pre class="code-block"><code>your code here</code></pre>
<!-- Inline code -->
<p>Set <code class="inline-code">color: var(--color-text)</code> for contrast.</p>Copy button
The .code-copy-btn class styles an icon button absolutely positioned top-right inside a .code-block. The reference implementation injects it automatically via JS:
import { initCodeCopy } from './code-copy.js';
initCodeCopy(); // appends .code-copy-btn to every <pre> that contains <code>The button is only added when JS runs — no-script users never see an inert element.
Token reference
| Token | Default | Use |
|---|---|---|
--code-bg | --color-bg-inset | Background of code blocks and inline code |
--code-text | --color-text | Text color inside code blocks |
--code-border | --color-border | Border around code blocks |
--code-radius | --radius-md | Corner radius on code blocks |
--code-copy-size | 32px | Width and height of the copy button |
--code-copy-radius | --radius-sm | Corner radius of the copy button |
To use a consistently dark code block regardless of page theme, override--code-bg and --code-text locally:
.my-editor {
--code-bg: var(--color-bg-code); /* always dark */
--code-text: var(--bm2-birch); /* always light */
}CSS reference
Shipped in dist/farn-components.css. Load alongside farn.css or farn-tokens.css.
.code-block {
position: relative;
font-family: var(--font-mono);
font-size: 0.8125rem;
background: var(--code-bg);
color: var(--code-text);
border: 1px solid var(--code-border);
border-radius: var(--code-radius);
padding: var(--space-md);
overflow-x: auto;
line-height: 1.6;
}
.inline-code {
font-family: var(--font-mono);
font-size: 0.875em;
background: var(--code-bg);
color: var(--code-text);
padding: 2px 6px;
border-radius: var(--radius-sm);
}